/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved. 
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0  
 
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
MERCHANTABLITY OR NON-INFRINGEMENT. 
 
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */

"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
    if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
    return cooked;
};
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var ts;
(function (ts) {
    // WARNING: The script `configureNightly.ts` uses a regexp to parse out these values.
    // If changing the text in this section, be sure to test `configureNightly` too.
    ts.versionMajorMinor = "3.5";
    /** The version of the TypeScript compiler release */
    ts.version = ts.versionMajorMinor + ".3";
})(ts || (ts = {}));
(function (ts) {
    /* @internal */
    var Comparison;
    (function (Comparison) {
        Comparison[Comparison["LessThan"] = -1] = "LessThan";
        Comparison[Comparison["EqualTo"] = 0] = "EqualTo";
        Comparison[Comparison["GreaterThan"] = 1] = "GreaterThan";
    })(Comparison = ts.Comparison || (ts.Comparison = {}));
})(ts || (ts = {}));
/* @internal */
(function (ts) {
    ts.emptyArray = [];
    /** Create a MapLike with good performance. */
    function createDictionaryObject() {
        var map = Object.create(/*prototype*/ null); // tslint:disable-line:no-null-keyword
        // Using 'delete' on an object causes V8 to put the object in dictionary mode.
        // This disables creation of hidden classes, which are expensive when an object is
        // constantly changing shape.
        map.__ = undefined;
        delete map.__;
        return map;
    }
    /** Create a new map. If a template object is provided, the map will copy entries from it. */
    function createMap() {
        return new ts.MapCtr();
    }
    ts.createMap = createMap;
    function createMapFromEntries(entries) {
        var map = createMap();
        for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
            var _a = entries_1[_i], key = _a[0], value = _a[1];
            map.set(key, value);
        }
        return map;
    }
    ts.createMapFromEntries = createMapFromEntries;
    function createMapFromTemplate(template) {
        var map = new ts.MapCtr();
        // Copies keys/values from template. Note that for..in will not throw if
        // template is undefined, and instead will just exit the loop.
        for (var key in template) {
            if (hasOwnProperty.call(template, key)) {
                map.set(key, template[key]);
            }
        }
        return map;
    }
    ts.createMapFromTemplate = createMapFromTemplate;
    // Internet Explorer's Map doesn't support iteration, so don't use it.
    // tslint:disable-next-line no-in-operator variable-name
    ts.MapCtr = typeof Map !== "undefined" && "entries" in Map.prototype ? Map : shimMap();
    // Keep the class inside a function so it doesn't get compiled if it's not used.
    function shimMap() {
        var MapIterator = /** @class */ (function () {
            function MapIterator(currentEntry, selector) {
                this.currentEntry = currentEntry;
                this.selector = selector;
            }
            MapIterator.prototype.next = function () {
                // Navigate to the next entry.
                while (this.currentEntry) {
                    var skipNext = !!this.currentEntry.skipNext;
                    this.currentEntry = this.currentEntry.nextEntry;
                    if (!skipNext) {
                        break;
                    }
                }
                if (this.currentEntry) {
                    return { value: this.selector(this.currentEntry.key, this.currentEntry.value), done: false };
                }
                else {
                    return { value: undefined, done: true };
                }
            };
            return MapIterator;
        }());
        return /** @class */ (function () {
            function class_1() {
                this.data = createDictionaryObject();
                this.size = 0;
                // Create a first (stub) map entry that will not contain a key
                // and value but serves as starting point for iterators.
                this.firstEntry = {};
                // When the map is empty, the last entry is the same as the
                // first one.
                this.lastEntry = this.firstEntry;
            }
            class_1.prototype.get = function (key) {
                var entry = this.data[key];
                return entry && entry.value;
            };
            class_1.prototype.set = function (key, value) {
                if (!this.has(key)) {
                    this.size++;
                    // Create a new entry that will be appended at the
                    // end of the linked list.
                    var newEntry = {
                        key: key,
                        value: value
                    };
                    this.data[key] = newEntry;
                    // Adjust the references.
                    var previousLastEntry = this.lastEntry;
                    previousLastEntry.nextEntry = newEntry;
                    newEntry.previousEntry = previousLastEntry;
                    this.lastEntry = newEntry;
                }
                else {
                    this.data[key].value = value;
                }
                return this;
            };
            class_1.prototype.has = function (key) {
                // tslint:disable-next-line:no-in-operator
                return key in this.data;
            };
            class_1.prototype.delete = function (key) {
                if (this.has(key)) {
                    this.size--;
                    var entry = this.data[key];
                    delete this.data[key];
                    // Adjust the linked list references of the neighbor entries.
                    var previousEntry = entry.previousEntry;
                    previousEntry.nextEntry = entry.nextEntry;
                    if (entry.nextEntry) {
                        entry.nextEntry.previousEntry = previousEntry;
                    }
                    // When the deleted entry was the last one, we need to
                    // adjust the lastEntry reference.
                    if (this.lastEntry === entry) {
                        this.lastEntry = previousEntry;
                    }
                    // Adjust the forward reference of the deleted entry
                    // in case an iterator still references it. This allows us
                    // to throw away the entry, but when an active iterator
                    // (which points to the current entry) continues, it will
                    // navigate to the entry that originally came before the
                    // current one and skip it.
                    entry.previousEntry = undefined;
                    entry.nextEntry = previousEntry;
                    entry.skipNext = true;
                    return true;
                }
                return false;
            };
            class_1.prototype.clear = function () {
                this.data = createDictionaryObject();
                this.size = 0;
                // Reset the linked list. Note that we must adjust the forward
                // references of the deleted entries to ensure iterators stuck
                // in the middle of the list don't continue with deleted entries,
                // but can continue with new entries added after the clear()
                // operation.
                var firstEntry = this.firstEntry;
                var currentEntry = firstEntry.nextEntry;
                while (currentEntry) {
                    var nextEntry = currentEntry.nextEntry;
                    currentEntry.previousEntry = undefined;
                    currentEntry.nextEntry = firstEntry;
                    currentEntry.skipNext = true;
                    currentEntry = nextEntry;
                }
                firstEntry.nextEntry = undefined;
                this.lastEntry = firstEntry;
            };
            class_1.prototype.keys = function () {
                return new MapIterator(this.firstEntry, function (key) { return key; });
            };
            class_1.prototype.values = function () {
                return new MapIterator(this.firstEntry, function (_key, value) { return value; });
            };
            class_1.prototype.entries = function () {
                return new MapIterator(this.firstEntry, function (key, value) { return [key, value]; });
            };
            class_1.prototype.forEach = function (action) {
                var iterator = this.entries();
                while (true) {
                    var _a = iterator.next(), entry = _a.value, done = _a.done;
                    if (done) {
                        break;
                    }
                    action(entry[1], entry[0]);
                }
            };
            return class_1;
        }());
    }
    ts.shimMap = shimMap;
    function length(array) {
        return array ? array.length : 0;
    }
    ts.length = length;
    /**
     * Iterates through 'array' by index and performs the callback on each element of array until the callback
     * returns a truthy value, then returns that value.
     * If no such value is found, the callback is applied to each element of array and undefined is returned.
     */
    function forEach(array, callback) {
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var result = callback(array[i], i);
                if (result) {
                    return result;
                }
            }
        }
        return undefined;
    }
    ts.forEach = forEach;
    /** Like `forEach`, but suitable for use with numbers and strings (which may be falsy). */
    function firstDefined(array, callback) {
        if (array === undefined) {
            return undefined;
        }
        for (var i = 0; i < array.length; i++) {
            var result = callback(array[i], i);
            if (result !== undefined) {
                return result;
            }
        }
        return undefined;
    }
    ts.firstDefined = firstDefined;
    function firstDefinedIterator(iter, callback) {
        while (true) {
            var _a = iter.next(), value = _a.value, done = _a.done;
            if (done) {
                return undefined;
            }
            var result = callback(value);
            if (result !== undefined) {
                return result;
            }
        }
    }
    ts.firstDefinedIterator = firstDefinedIterator;
    function zipWith(arrayA, arrayB, callback) {
        var result = [];
        ts.Debug.assertEqual(arrayA.length, arrayB.length);
        for (var i = 0; i < arrayA.length; i++) {
            result.push(callback(arrayA[i], arrayB[i], i));
        }
        return result;
    }
    ts.zipWith = zipWith;
    function zipToIterator(arrayA, arrayB) {
        ts.Debug.assertEqual(arrayA.length, arrayB.length);
        var i = 0;
        return {
            next: function () {
                if (i === arrayA.length) {
                    return { value: undefined, done: true };
                }
                i++;
                return { value: [arrayA[i - 1], arrayB[i - 1]], done: false };
            }
        };
    }
    ts.zipToIterator = zipToIterator;
    function zipToMap(keys, values) {
        ts.Debug.assert(keys.length === values.length);
        var map = createMap();
        for (var i = 0; i < keys.length; ++i) {
            map.set(keys[i], values[i]);
        }
        return map;
    }
    ts.zipToMap = zipToMap;
    /**
     * Iterates through `array` by index and performs the callback on each element of array until the callback
     * returns a falsey value, then returns false.
     * If no such value is found, the callback is applied to each element of array and `true` is returned.
     */
    function every(array, callback) {
        if (array) {
            for (var i = 0; i < array.length; i++) {
                if (!callback(array[i], i)) {
                    return false;
                }
            }
        }
        return true;
    }
    ts.every = every;
    function find(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            var value = array[i];
            if (predicate(value, i)) {
                return value;
            }
        }
        return undefined;
    }
    ts.find = find;
    function findLast(array, predicate) {
        for (var i = array.length - 1; i >= 0; i--) {
            var value = array[i];
            if (predicate(value, i)) {
                return value;
            }
        }
        return undefined;
    }
    ts.findLast = findLast;
    /** Works like Array.prototype.findIndex, returning `-1` if no element satisfying the predicate is found. */
    function findIndex(array, predicate, startIndex) {
        for (var i = startIndex || 0; i < array.length; i++) {
            if (predicate(array[i], i)) {
                return i;
            }
        }
        return -1;
    }
    ts.findIndex = findIndex;
    function findLastIndex(array, predicate, startIndex) {
        for (var i = startIndex === undefined ? array.length - 1 : startIndex; i >= 0; i--) {
            if (predicate(array[i], i)) {
                return i;
            }
        }
        return -1;
    }
    ts.findLastIndex = findLastIndex;
    /**
     * Returns the first truthy result of `callback`, or else fails.
     * This is like `forEach`, but never returns undefined.
     */
    function findMap(array, callback) {
        for (var i = 0; i < array.length; i++) {
            var result = callback(array[i], i);
            if (result) {
                return result;
            }
        }
        return ts.Debug.fail();
    }
    ts.findMap = findMap;
    function contains(array, value, equalityComparer) {
        if (equalityComparer === void 0) { equalityComparer = equateValues; }
        if (array) {
            for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
                var v = array_1[_i];
                if (equalityComparer(v, value)) {
                    return true;
                }
            }
        }
        return false;
    }
    ts.contains = contains;
    function arraysEqual(a, b, equalityComparer) {
        if (equalityComparer === void 0) { equalityComparer = equateValues; }
        return a.length === b.length && a.every(function (x, i) { return equalityComparer(x, b[i]); });
    }
    ts.arraysEqual = arraysEqual;
    function indexOfAnyCharCode(text, charCodes, start) {
        for (var i = start || 0; i < text.length; i++) {
            if (contains(charCodes, text.charCodeAt(i))) {
                return i;
            }
        }
        return -1;
    }
    ts.indexOfAnyCharCode = indexOfAnyCharCode;
    function countWhere(array, predicate) {
        var count = 0;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var v = array[i];
                if (predicate(v, i)) {
                    count++;
                }
            }
        }
        return count;
    }
    ts.countWhere = countWhere;
    function filter(array, f) {
        if (array) {
            var len = array.length;
            var i = 0;
            while (i < len && f(array[i]))
                i++;
            if (i < len) {
                var result = array.slice(0, i);
                i++;
                while (i < len) {
                    var item = array[i];
                    if (f(item)) {
                        result.push(item);
                    }
                    i++;
                }
                return result;
            }
        }
        return array;
    }
    ts.filter = filter;
    function filterMutate(array, f) {
        var outIndex = 0;
        for (var i = 0; i < array.length; i++) {
            if (f(array[i], i, array)) {
                array[outIndex] = array[i];
                outIndex++;
            }
        }
        array.length = outIndex;
    }
    ts.filterMutate = filterMutate;
    function clear(array) {
        array.length = 0;
    }
    ts.clear = clear;
    function map(array, f) {
        var result;
        if (array) {
            result = [];
            for (var i = 0; i < array.length; i++) {
                result.push(f(array[i], i));
            }
        }
        return result;
    }
    ts.map = map;
    function mapIterator(iter, mapFn) {
        return {
            next: function () {
                var iterRes = iter.next();
                return iterRes.done ? iterRes : { value: mapFn(iterRes.value), done: false };
            }
        };
    }
    ts.mapIterator = mapIterator;
    function sameMap(array, f) {
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var item = array[i];
                var mapped = f(item, i);
                if (item !== mapped) {
                    var result = array.slice(0, i);
                    result.push(mapped);
                    for (i++; i < array.length; i++) {
                        result.push(f(array[i], i));
                    }
                    return result;
                }
            }
        }
        return array;
    }
    ts.sameMap = sameMap;
    function flatten(array) {
        var result;
        if (array) {
            result = [];
            for (var _i = 0, array_2 = array; _i < array_2.length; _i++) {
                var v = array_2[_i];
                if (v) {
                    if (isArray(v)) {
                        addRange(result, v);
                    }
                    else {
                        result.push(v);
                    }
                }
            }
        }
        return result;
    }
    ts.flatten = flatten;
    /**
     * Maps an array. If the mapped value is an array, it is spread into the result.
     *
     * @param array The array to map.
     * @param mapfn The callback used to map the result into one or more values.
     */
    function flatMap(array, mapfn) {
        var result;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var v = mapfn(array[i], i);
                if (v) {
                    if (isArray(v)) {
                        result = addRange(result, v);
                    }
                    else {
                        result = append(result, v);
                    }
                }
            }
        }
        return result || ts.emptyArray;
    }
    ts.flatMap = flatMap;
    function flatMapToMutable(array, mapfn) {
        var result = [];
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var v = mapfn(array[i], i);
                if (v) {
                    if (isArray(v)) {
                        addRange(result, v);
                    }
                    else {
                        result.push(v);
                    }
                }
            }
        }
        return result;
    }
    ts.flatMapToMutable = flatMapToMutable;
    function flatMapIterator(iter, mapfn) {
        var first = iter.next();
        if (first.done) {
            return ts.emptyIterator;
        }
        var currentIter = getIterator(first.value);
        return {
            next: function () {
                while (true) {
                    var currentRes = currentIter.next();
                    if (!currentRes.done) {
                        return currentRes;
                    }
                    var iterRes = iter.next();
                    if (iterRes.done) {
                        return iterRes;
                    }
                    currentIter = getIterator(iterRes.value);
                }
            },
        };
        function getIterator(x) {
            var res = mapfn(x);
            return res === undefined ? ts.emptyIterator : isArray(res) ? arrayIterator(res) : res;
        }
    }
    ts.flatMapIterator = flatMapIterator;
    function sameFlatMap(array, mapfn) {
        var result;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var item = array[i];
                var mapped = mapfn(item, i);
                if (result || item !== mapped || isArray(mapped)) {
                    if (!result) {
                        result = array.slice(0, i);
                    }
                    if (isArray(mapped)) {
                        addRange(result, mapped);
                    }
                    else {
                        result.push(mapped);
                    }
                }
            }
        }
        return result || array;
    }
    ts.sameFlatMap = sameFlatMap;
    function mapAllOrFail(array, mapFn) {
        var result = [];
        for (var i = 0; i < array.length; i++) {
            var mapped = mapFn(array[i], i);
            if (mapped === undefined) {
                return undefined;
            }
            result.push(mapped);
        }
        return result;
    }
    ts.mapAllOrFail = mapAllOrFail;
    function mapDefined(array, mapFn) {
        var result = [];
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var mapped = mapFn(array[i], i);
                if (mapped !== undefined) {
                    result.push(mapped);
                }
            }
        }
        return result;
    }
    ts.mapDefined = mapDefined;
    function mapDefinedIterator(iter, mapFn) {
        return {
            next: function () {
                while (true) {
                    var res = iter.next();
                    if (res.done) {
                        return res;
                    }
                    var value = mapFn(res.value);
                    if (value !== undefined) {
                        return { value: value, done: false };
                    }
                }
            }
        };
    }
    ts.mapDefinedIterator = mapDefinedIterator;
    ts.emptyIterator = { next: function () { return ({ value: undefined, done: true }); } };
    function singleIterator(value) {
        var done = false;
        return {
            next: function () {
                var wasDone = done;
                done = true;
                return wasDone ? { value: undefined, done: true } : { value: value, done: false };
            }
        };
    }
    ts.singleIterator = singleIterator;
    function spanMap(array, keyfn, mapfn) {
        var result;
        if (array) {
            result = [];
            var len = array.length;
            var previousKey = void 0;
            var key = void 0;
            var start = 0;
            var pos = 0;
            while (start < len) {
                while (pos < len) {
                    var value = array[pos];
                    key = keyfn(value, pos);
                    if (pos === 0) {
                        previousKey = key;
                    }
                    else if (key !== previousKey) {
                        break;
                    }
                    pos++;
                }
                if (start < pos) {
                    var v = mapfn(array.slice(start, pos), previousKey, start, pos);
                    if (v) {
                        result.push(v);
                    }
                    start = pos;
                }
                previousKey = key;
                pos++;
            }
        }
        return result;
    }
    ts.spanMap = spanMap;
    function mapEntries(map, f) {
        if (!map) {
            return undefined;
        }
        var result = createMap();
        map.forEach(function (value, key) {
            var _a = f(key, value), newKey = _a[0], newValue = _a[1];
            result.set(newKey, newValue);
        });
        return result;
    }
    ts.mapEntries = mapEntries;
    function some(array, predicate) {
        if (array) {
            if (predicate) {
                for (var _i = 0, array_3 = array; _i < array_3.length; _i++) {
                    var v = array_3[_i];
                    if (predicate(v)) {
                        return true;
                    }
                }
            }
            else {
                return array.length > 0;
            }
        }
        return false;
    }
    ts.some = some;
    /** Calls the callback with (start, afterEnd) index pairs for each range where 'pred' is true. */
    function getRangesWhere(arr, pred, cb) {
        var start;
        for (var i = 0; i < arr.length; i++) {
            if (pred(arr[i])) {
                start = start === undefined ? i : start;
            }
            else {
                if (start !== undefined) {
                    cb(start, i);
                    start = undefined;
                }
            }
        }
        if (start !== undefined)
            cb(start, arr.length);
    }
    ts.getRangesWhere = getRangesWhere;
    function concatenate(array1, array2) {
        if (!some(array2))
            return array1;
        if (!some(array1))
            return array2;
        return array1.concat(array2);
    }
    ts.concatenate = concatenate;
    function deduplicateRelational(array, equalityComparer, comparer) {
        // Perform a stable sort of the array. This ensures the first entry in a list of
        // duplicates remains the first entry in the result.
        var indices = array.map(function (_, i) { return i; });
        stableSortIndices(array, indices, comparer);
        var last = array[indices[0]];
        var deduplicated = [indices[0]];
        for (var i = 1; i < indices.length; i++) {
            var index = indices[i];
            var item = array[index];
            if (!equalityComparer(last, item)) {
                deduplicated.push(index);
                last = item;
            }
        }
        // restore original order
        deduplicated.sort();
        return deduplicated.map(function (i) { return array[i]; });
    }
    function deduplicateEquality(array, equalityComparer) {
        var result = [];
        for (var _i = 0, array_4 = array; _i < array_4.length; _i++) {
            var item = array_4[_i];
            pushIfUnique(result, item, equalityComparer);
        }
        return result;
    }
    /**
     * Deduplicates an unsorted array.
     * @param equalityComparer An `EqualityComparer` used to determine if two values are duplicates.
     * @param comparer An optional `Comparer` used to sort entries before comparison, though the
     * result will remain in the original order in `array`.
     */
    function deduplicate(array, equalityComparer, comparer) {
        return array.length === 0 ? [] :
            array.length === 1 ? array.slice() :
                comparer ? deduplicateRelational(array, equalityComparer, comparer) :
                    deduplicateEquality(array, equalityComparer);
    }
    ts.deduplicate = deduplicate;
    /**
     * Deduplicates an array that has already been sorted.
     */
    function deduplicateSorted(array, comparer) {
        if (array.length === 0)
            return ts.emptyArray;
        var last = array[0];
        var deduplicated = [last];
        for (var i = 1; i < array.length; i++) {
            var next = array[i];
            switch (comparer(next, last)) {
                // equality comparison
                case true:
                // relational comparison
                case 0 /* EqualTo */:
                    continue;
                case -1 /* LessThan */:
                    // If `array` is sorted, `next` should **never** be less than `last`.
                    return ts.Debug.fail("Array is unsorted.");
            }
            deduplicated.push(last = next);
        }
        return deduplicated;
    }
    function insertSorted(array, insert, compare) {
        if (array.length === 0) {
            array.push(insert);
            return;
        }
        var insertIndex = binarySearch(array, insert, identity, compare);
        if (insertIndex < 0) {
            array.splice(~insertIndex, 0, insert);
        }
    }
    ts.insertSorted = insertSorted;
    function sortAndDeduplicate(array, comparer, equalityComparer) {
        return deduplicateSorted(sort(array, comparer), equalityComparer || comparer || compareStringsCaseSensitive);
    }
    ts.sortAndDeduplicate = sortAndDeduplicate;
    function arrayIsEqualTo(array1, array2, equalityComparer) {
        if (equalityComparer === void 0) { equalityComparer = equateValues; }
        if (!array1 || !array2) {
            return array1 === array2;
        }
        if (array1.length !== array2.length) {
            return false;
        }
        for (var i = 0; i < array1.length; i++) {
            if (!equalityComparer(array1[i], array2[i], i)) {
                return false;
            }
        }
        return true;
    }
    ts.arrayIsEqualTo = arrayIsEqualTo;
    function compact(array) {
        var result;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var v = array[i];
                if (result || !v) {
                    if (!result) {
                        result = array.slice(0, i);
                    }
                    if (v) {
                        result.push(v);
                    }
                }
            }
        }
        return result || array;
    }
    ts.compact = compact;
    /**
     * Gets the relative complement of `arrayA` with respect to `arrayB`, returning the elements that
     * are not present in `arrayA` but are present in `arrayB`. Assumes both arrays are sorted
     * based on the provided comparer.
     */
    function relativeComplement(arrayA, arrayB, comparer) {
        if (!arrayB || !arrayA || arrayB.length === 0 || arrayA.length === 0)
            return arrayB;
        var result = [];
        loopB: for (var offsetA = 0, offsetB = 0; offsetB < arrayB.length; offsetB++) {
            if (offsetB > 0) {
                // Ensure `arrayB` is properly sorted.
                ts.Debug.assertGreaterThanOrEqual(comparer(arrayB[offsetB], arrayB[offsetB - 1]), 0 /* EqualTo */);
            }
            loopA: for (var startA = offsetA; offsetA < arrayA.length; offsetA++) {
                if (offsetA > startA) {
                    // Ensure `arrayA` is properly sorted. We only need to perform this check if
                    // `offsetA` has changed since we entered the loop.
                    ts.Debug.assertGreaterThanOrEqual(comparer(arrayA[offsetA], arrayA[offsetA - 1]), 0 /* EqualTo */);
                }
                switch (comparer(arrayB[offsetB], arrayA[offsetA])) {
                    case -1 /* LessThan */:
                        // If B is less than A, B does not exist in arrayA. Add B to the result and
                        // move to the next element in arrayB without changing the current position
                        // in arrayA.
                        result.push(arrayB[offsetB]);
                        continue loopB;
                    case 0 /* EqualTo */:
                        // If B is equal to A, B exists in arrayA. Move to the next element in
                        // arrayB without adding B to the result or changing the current position
                        // in arrayA.
                        continue loopB;
                    case 1 /* GreaterThan */:
                        // If B is greater than A, we need to keep looking for B in arrayA. Move to
                        // the next element in arrayA and recheck.
                        continue loopA;
                }
            }
        }
        return result;
    }
    ts.relativeComplement = relativeComplement;
    function sum(array, prop) {
        var result = 0;
        for (var _i = 0, array_5 = array; _i < array_5.length; _i++) {
            var v = array_5[_i];
            result += v[prop];
        }
        return result;
    }
    ts.sum = sum;
    function append(to, value) {
        if (value === undefined)
            return to;
        if (to === undefined)
            return [value];
        to.push(value);
        return to;
    }
    ts.append = append;
    /**
     * Gets the actual offset into an array for a relative offset. Negative offsets indicate a
     * position offset from the end of the array.
     */
    function toOffset(array, offset) {
        return offset < 0 ? array.length + offset : offset;
    }
    function addRange(to, from, start, end) {
        if (from === undefined || from.length === 0)
            return to;
        if (to === undefined)
            return from.slice(start, end);
        start = start === undefined ? 0 : toOffset(from, start);
        end = end === undefined ? from.length : toOffset(from, end);
        for (var i = start; i < end && i < from.length; i++) {
            if (from[i] !== undefined) {
                to.push(from[i]);
            }
        }
        return to;
    }
    ts.addRange = addRange;
    /**
     * @return Whether the value was added.
     */
    function pushIfUnique(array, toAdd, equalityComparer) {
        if (contains(array, toAdd, equalityComparer)) {
            return false;
        }
        else {
            array.push(toAdd);
            return true;
        }
    }
    ts.pushIfUnique = pushIfUnique;
    /**
     * Unlike `pushIfUnique`, this can take `undefined` as an input, and returns a new array.
     */
    function appendIfUnique(array, toAdd, equalityComparer) {
        if (array) {
            pushIfUnique(array, toAdd, equalityComparer);
            return array;
        }
        else {
            return [toAdd];
        }
    }
    ts.appendIfUnique = appendIfUnique;
    function stableSortIndices(array, indices, comparer) {
        // sort indices by value then position
        indices.sort(function (x, y) { return comparer(array[x], array[y]) || compareValues(x, y); });
    }
    /**
     * Returns a new sorted array.
     */
    function sort(array, comparer) {
        return (array.length === 0 ? array : array.slice().sort(comparer));
    }
    ts.sort = sort;
    function arrayIterator(array) {
        var i = 0;
        return { next: function () {
                if (i === array.length) {
                    return { value: undefined, done: true };
                }
                else {
                    i++;
                    return { value: array[i - 1], done: false };
                }
            } };
    }
    ts.arrayIterator = arrayIterator;
    function arrayReverseIterator(array) {
        var i = array.length;
        return {
            next: function () {
                if (i === 0) {
                    return { value: undefined, done: true };
                }
                else {
                    i--;
                    return { value: array[i], done: false };
                }
            }
        };
    }
    ts.arrayReverseIterator = arrayReverseIterator;
    /**
     * Stable sort of an array. Elements equal to each other maintain their relative position in the array.
     */
    function stableSort(array, comparer) {
        var indices = array.map(function (_, i) { return i; });
        stableSortIndices(array, indices, comparer);
        return indices.map(function (i) { return array[i]; });
    }
    ts.stableSort = stableSort;
    function rangeEquals(array1, array2, pos, end) {
        while (pos < end) {
            if (array1[pos] !== array2[pos]) {
                return false;
            }
            pos++;
        }
        return true;
    }
    ts.rangeEquals = rangeEquals;
    /**
     * Returns the element at a specific offset in an array if non-empty, `undefined` otherwise.
     * A negative offset indicates the element should be retrieved from the end of the array.
     */
    function elementAt(array, offset) {
        if (array) {
            offset = toOffset(array, offset);
            if (offset < array.length) {
                return array[offset];
            }
        }
        return undefined;
    }
    ts.elementAt = elementAt;
    /**
     * Returns the first element of an array if non-empty, `undefined` otherwise.
     */
    function firstOrUndefined(array) {
        return array.length === 0 ? undefined : array[0];
    }
    ts.firstOrUndefined = firstOrUndefined;
    function first(array) {
        ts.Debug.assert(array.length !== 0);
        return array[0];
    }
    ts.first = first;
    /**
     * Returns the last element of an array if non-empty, `undefined` otherwise.
     */
    function lastOrUndefined(array) {
        return array.length === 0 ? undefined : array[array.length - 1];
    }
    ts.lastOrUndefined = lastOrUndefined;
    function last(array) {
        ts.Debug.assert(array.length !== 0);
        return array[array.length - 1];
    }
    ts.last = last;
    /**
     * Returns the only element of an array if it contains only one element, `undefined` otherwise.
     */
    function singleOrUndefined(array) {
        return array && array.length === 1
            ? array[0]
            : undefined;
    }
    ts.singleOrUndefined = singleOrUndefined;
    function singleOrMany(array) {
        return array && array.length === 1
            ? array[0]
            : array;
    }
    ts.singleOrMany = singleOrMany;
    function replaceElement(array, index, value) {
        var result = array.slice(0);
        result[index] = value;
        return result;
    }
    ts.replaceElement = replaceElement;
    /**
     * Performs a binary search, finding the index at which `value` occurs in `array`.
     * If no such index is found, returns the 2's-complement of first index at which
     * `array[index]` exceeds `value`.
     * @param array A sorted array whose first element must be no larger than number
     * @param value The value to be searched for in the array.
     * @param keySelector A callback used to select the search key from `value` and each element of
     * `array`.
     * @param keyComparer A callback used to compare two keys in a sorted array.
     * @param offset An offset into `array` at which to start the search.
     */
    function binarySearch(array, value, keySelector, keyComparer, offset) {
        return binarySearchKey(array, keySelector(value), keySelector, keyComparer, offset);
    }
    ts.binarySearch = binarySearch;
    /**
     * Performs a binary search, finding the index at which an object with `key` occurs in `array`.
     * If no such index is found, returns the 2's-complement of first index at which
     * `array[index]` exceeds `key`.
     * @param array A sorted array whose first element must be no larger than number
     * @param key The key to be searched for in the array.
     * @param keySelector A callback used to select the search key from each element of `array`.
     * @param keyComparer A callback used to compare two keys in a sorted array.
     * @param offset An offset into `array` at which to start the search.
     */
    function binarySearchKey(array, key, keySelector, keyComparer, offset) {
        if (!some(array)) {
            return -1;
        }
        var low = offset || 0;
        var high = array.length - 1;
        while (low <= high) {
            var middle = low + ((high - low) >> 1);
            var midKey = keySelector(array[middle]);
            switch (keyComparer(midKey, key)) {
                case -1 /* LessThan */:
                    low = middle + 1;
                    break;
                case 0 /* EqualTo */:
                    return middle;
                case 1 /* GreaterThan */:
                    high = middle - 1;
                    break;
            }
        }
        return ~low;
    }
    ts.binarySearchKey = binarySearchKey;
    function reduceLeft(array, f, initial, start, count) {
        if (array && array.length > 0) {
            var size = array.length;
            if (size > 0) {
                var pos = start === undefined || start < 0 ? 0 : start;
                var end = count === undefined || pos + count > size - 1 ? size - 1 : pos + count;
                var result = void 0;
                if (arguments.length <= 2) {
                    result = array[pos];
                    pos++;
                }
                else {
                    result = initial;
                }
                while (pos <= end) {
                    result = f(result, array[pos], pos);
                    pos++;
                }
                return result;
            }
        }
        return initial;
    }
    ts.reduceLeft = reduceLeft;
    var hasOwnProperty = Object.prototype.hasOwnProperty;
    /**
     * Indicates whether a map-like contains an own property with the specified key.
     *
     * @param map A map-like.
     * @param key A property key.
     */
    function hasProperty(map, key) {
        return hasOwnProperty.call(map, key);
    }
    ts.hasProperty = hasProperty;
    /**
     * Gets the value of an owned property in a map-like.
     *
     * @param map A map-like.
     * @param key A property key.
     */
    function getProperty(map, key) {
        return hasOwnProperty.call(map, key) ? map[key] : undefined;
    }
    ts.getProperty = getProperty;
    /**
     * Gets the owned, enumerable property keys of a map-like.
     */
    function getOwnKeys(map) {
        var keys = [];
        for (var key in map) {
            if (hasOwnProperty.call(map, key)) {
                keys.push(key);
            }
        }
        return keys;
    }
    ts.getOwnKeys = getOwnKeys;
    function getOwnValues(sparseArray) {
        var values = [];
        for (var key in sparseArray) {
            if (hasOwnProperty.call(sparseArray, key)) {
                values.push(sparseArray[key]);
            }
        }
        return values;
    }
    ts.getOwnValues = getOwnValues;
    function arrayFrom(iterator, map) {
        var _a;
        var result = [];
        for (var _b = iterator.next(), value = _b.value, done = _b.done; !done; _a = iterator.next(), value = _a.value, done = _a.done, _a) {
            result.push(map ? map(value) : value);
        }
        return result;
    }
    ts.arrayFrom = arrayFrom;
    function assign(t) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {
            var arg = args_1[_a];
            if (arg === undefined)
                continue;
            for (var p in arg) {
                if (hasProperty(arg, p)) {
                    t[p] = arg[p];
                }
            }
        }
        return t;
    }
    ts.assign = assign;
    /**
     * Performs a shallow equality comparison of the contents of two map-likes.
     *
     * @param left A map-like whose properties should be compared.
     * @param right A map-like whose properties should be compared.
     */
    function equalOwnProperties(left, right, equalityComparer) {
        if (equalityComparer === void 0) { equalityComparer = equateValues; }
        if (left === right)
            return true;
        if (!left || !right)
            return false;
        for (var key in left) {
            if (hasOwnProperty.call(left, key)) {
                if (!hasOwnProperty.call(right, key))
                    return false;
                if (!equalityComparer(left[key], right[key]))
                    return false;
            }
        }
        for (var key in right) {
            if (hasOwnProperty.call(right, key)) {
                if (!hasOwnProperty.call(left, key))
                    return false;
            }
        }
        return true;
    }
    ts.equalOwnProperties = equalOwnProperties;
    function arrayToMap(array, makeKey, makeValue) {
        if (makeValue === void 0) { makeValue = identity; }
        var result = createMap();
        for (var _i = 0, array_6 = array; _i < array_6.length; _i++) {
            var value = array_6[_i];
            var key = makeKey(value);
            if (key !== undefined)
                result.set(key, makeValue(value));
        }
        return result;
    }
    ts.arrayToMap = arrayToMap;
    function arrayToNumericMap(array, makeKey, makeValue) {
        if (makeValue === void 0) { makeValue = identity; }
        var result = [];
        for (var _i = 0, array_7 = array; _i < array_7.length; _i++) {
            var value = array_7[_i];
            result[makeKey(value)] = makeValue(value);
        }
        return result;
    }
    ts.arrayToNumericMap = arrayToNumericMap;
    function arrayToMultiMap(values, makeKey, makeValue) {
        if (makeValue === void 0) { makeValue = identity; }
        var result = createMultiMap();
        for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {
            var value = values_1[_i];
            result.add(makeKey(value), makeValue(value));
        }
        return result;
    }
    ts.arrayToMultiMap = arrayToMultiMap;
    function group(values, getGroupId) {
        return arrayFrom(arrayToMultiMap(values, getGroupId).values());
    }
    ts.group = group;
    function clone(object) {
        var result = {};
        for (var id in object) {
            if (hasOwnProperty.call(object, id)) {
                result[id] = object[id];
            }
        }
        return result;
    }
    ts.clone = clone;
    function extend(first, second) {
        var result = {};
        for (var id in second) {
            if (hasOwnProperty.call(second, id)) {
                result[id] = second[id];
            }
        }
        for (var id in first) {
            if (hasOwnProperty.call(first, id)) {
                result[id] = first[id];
            }
        }
        return result;
    }
    ts.extend = extend;
    function copyProperties(first, second) {
        for (var id in second) {
            if (hasOwnProperty.call(second, id)) {
                first[id] = second[id];
            }
        }
    }
    ts.copyProperties = copyProperties;
    function maybeBind(obj, fn) {
        return fn ? fn.bind(obj) : undefined;
    }
    ts.maybeBind = maybeBind;
    function createMultiMap() {
        var map = createMap();
        map.add = multiMapAdd;
        map.remove = multiMapRemove;
        return map;
    }
    ts.createMultiMap = createMultiMap;
    function multiMapAdd(key, value) {
        var values = this.get(key);
        if (values) {
            values.push(value);
        }
        else {
            this.set(key, values = [value]);
        }
        return values;
    }
    function multiMapRemove(key, value) {
        var values = this.get(key);
        if (values) {
            unorderedRemoveItem(values, value);
            if (!values.length) {
                this.delete(key);
            }
        }
    }
    /**
     * Tests whether a value is an array.
     */
    function isArray(value) {
        return Array.isArray ? Array.isArray(value) : value instanceof Array;
    }
    ts.isArray = isArray;
    function toArray(value) {
        return isArray(value) ? value : [value];
    }
    ts.toArray = toArray;
    /**
     * Tests whether a value is string
     */
    function isString(text) {
        return typeof text === "string";
    }
    ts.isString = isString;
    function isNumber(x) {
        return typeof x === "number";
    }
    ts.isNumber = isNumber;
    function tryCast(value, test) {
        return value !== undefined && test(value) ? value : undefined;
    }
    ts.tryCast = tryCast;
    function cast(value, test) {
        if (value !== undefined && test(value))
            return value;
        return ts.Debug.fail("Invalid cast. The supplied value " + value + " did not pass the test '" + ts.Debug.getFunctionName(test) + "'.");
    }
    ts.cast = cast;
    /** Does nothing. */
    function noop(_) { } // tslint:disable-line no-empty
    ts.noop = noop;
    /** Do nothing and return false */
    function returnFalse() { return false; }
    ts.returnFalse = returnFalse;
    /** Do nothing and return true */
    function returnTrue() { return true; }
    ts.returnTrue = returnTrue;
    /** Do nothing and return undefined */
    function returnUndefined() { return undefined; }
    ts.returnUndefined = returnUndefined;
    /** Returns its argument. */
    function identity(x) { return x; }
    ts.identity = identity;
    /** Returns lower case string */
    function toLowerCase(x) { return x.toLowerCase(); }
    ts.toLowerCase = toLowerCase;
    /** Throws an error because a function is not implemented. */
    function notImplemented() {
        throw new Error("Not implemented");
    }
    ts.notImplemented = notImplemented;
    function memoize(callback) {
        var value;
        return function () {
            if (callback) {
                value = callback();
                callback = undefined;
            }
            return value;
        };
    }
    ts.memoize = memoize;
    function compose(a, b, c, d, e) {
        if (e) {
            var args_2 = [];
            for (var i = 0; i < arguments.length; i++) {
                args_2[i] = arguments[i];
            }
            return function (t) { return reduceLeft(args_2, function (u, f) { return f(u); }, t); };
        }
        else if (d) {
            return function (t) { return d(c(b(a(t)))); };
        }
        else if (c) {
            return function (t) { return c(b(a(t))); };
        }
        else if (b) {
            return function (t) { return b(a(t)); };
        }
        else if (a) {
            return function (t) { return a(t); };
        }
        else {
            return function (t) { return t; };
        }
    }
    ts.compose = compose;
    var AssertionLevel;
    (function (AssertionLevel) {
        AssertionLevel[AssertionLevel["None"] = 0] = "None";
        AssertionLevel[AssertionLevel["Normal"] = 1] = "Normal";
        AssertionLevel[AssertionLevel["Aggressive"] = 2] = "Aggressive";
        AssertionLevel[AssertionLevel["VeryAggressive"] = 3] = "VeryAggressive";
    })(AssertionLevel = ts.AssertionLevel || (ts.AssertionLevel = {}));
    function equateValues(a, b) {
        return a === b;
    }
    ts.equateValues = equateValues;
    /**
     * Compare the equality of two strings using a case-sensitive ordinal comparison.
     *
     * Case-sensitive comparisons compare both strings one code-point at a time using the integer
     * value of each code-point after applying `toUpperCase` to each string. We always map both
     * strings to their upper-case form as some unicode characters do not properly round-trip to
     * lowercase (such as `ẞ` (German sharp capital s)).
     */
    function equateStringsCaseInsensitive(a, b) {
        return a === b
            || a !== undefined
                && b !== undefined
                && a.toUpperCase() === b.toUpperCase();
    }
    ts.equateStringsCaseInsensitive = equateStringsCaseInsensitive;
    /**
     * Compare the equality of two strings using a case-sensitive ordinal comparison.
     *
     * Case-sensitive comparisons compare both strings one code-point at a time using the
     * integer value of each code-point.
     */
    function equateStringsCaseSensitive(a, b) {
        return equateValues(a, b);
    }
    ts.equateStringsCaseSensitive = equateStringsCaseSensitive;
    function compareComparableValues(a, b) {
        return a === b ? 0 /* EqualTo */ :
            a === undefined ? -1 /* LessThan */ :
                b === undefined ? 1 /* GreaterThan */ :
                    a < b ? -1 /* LessThan */ :
                        1 /* GreaterThan */;
    }
    /**
     * Compare two numeric values for their order relative to each other.
     * To compare strings, use any of the `compareStrings` functions.
     */
    function compareValues(a, b) {
        return compareComparableValues(a, b);
    }
    ts.compareValues = compareValues;
    function min(a, b, compare) {
        return compare(a, b) === -1 /* LessThan */ ? a : b;
    }
    ts.min = min;
    /**
     * Compare two strings using a case-insensitive ordinal comparison.
     *
     * Ordinal comparisons are based on the difference between the unicode code points of both
     * strings. Characters with multiple unicode representations are considered unequal. Ordinal
     * comparisons provide predictable ordering, but place "a" after "B".
     *
     * Case-insensitive comparisons compare both strings one code-point at a time using the integer
     * value of each code-point after applying `toUpperCase` to each string. We always map both
     * strings to their upper-case form as some unicode characters do not properly round-trip to
     * lowercase (such as `áºž` (German sharp capital s)).
     */
    function compareStringsCaseInsensitive(a, b) {
        if (a === b)
            return 0 /* EqualTo */;
        if (a === undefined)
            return -1 /* LessThan */;
        if (b === undefined)
            return 1 /* GreaterThan */;
        a = a.toUpperCase();
        b = b.toUpperCase();
        return a < b ? -1 /* LessThan */ : a > b ? 1 /* GreaterThan */ : 0 /* EqualTo */;
    }
    ts.compareStringsCaseInsensitive = compareStringsCaseInsensitive;
    /**
     * Compare two strings using a case-sensitive ordinal comparison.
     *
     * Ordinal comparisons are based on the difference between the unicode code points of both
     * strings. Characters with multiple unicode representations are considered unequal. Ordinal
     * comparisons provide predictable ordering, but place "a" after "B".
     *
     * Case-sensitive comparisons compare both strings one code-point at a time using the integer
     * value of each code-point.
     */
    function compareStringsCaseSensitive(a, b) {
        return compareComparableValues(a, b);
    }
    ts.compareStringsCaseSensitive = compareStringsCaseSensitive;
    function getStringComparer(ignoreCase) {
        return ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive;
    }
    ts.getStringComparer = getStringComparer;
    /**
     * Creates a string comparer for use with string collation in the UI.
     */
    var createUIStringComparer = (function () {
        var defaultComparer;
        var enUSComparer;
        var stringComparerFactory = getStringComparerFactory();
        return createStringComparer;
        function compareWithCallback(a, b, comparer) {
            if (a === b)
                return 0 /* EqualTo */;
            if (a === undefined)
                return -1 /* LessThan */;
            if (b === undefined)
                return 1 /* GreaterThan */;
            var value = comparer(a, b);
            return value < 0 ? -1 /* LessThan */ : value > 0 ? 1 /* GreaterThan */ : 0 /* EqualTo */;
        }
        function createIntlCollatorStringComparer(locale) {
            // Intl.Collator.prototype.compare is bound to the collator. See NOTE in
            // http://www.ecma-international.org/ecma-402/2.0/#sec-Intl.Collator.prototype.compare
            var comparer = new Intl.Collator(locale, { usage: "sort", sensitivity: "variant" }).compare;
            return function (a, b) { return compareWithCallback(a, b, comparer); };
        }
        function createLocaleCompareStringComparer(locale) {
            // if the locale is not the default locale (`undefined`), use the fallback comparer.
            if (locale !== undefined)
                return createFallbackStringComparer();
            return function (a, b) { return compareWithCallback(a, b, compareStrings); };
            function compareStrings(a, b) {
                return a.localeCompare(b);
            }
        }
        function createFallbackStringComparer() {
            // An ordinal comparison puts "A" after "b", but for the UI we want "A" before "b".
            // We first sort case insensitively.  So "Aaa" will come before "baa".
            // Then we sort case sensitively, so "aaa" will come before "Aaa".
            //
            // For case insensitive comparisons we always map both strings to their
            // upper-case form as some unicode characters do not properly round-trip to
            // lowercase (such as `áºž` (German sharp capital s)).
            return function (a, b) { return compareWithCallback(a, b, compareDictionaryOrder); };
            function compareDictionaryOrder(a, b) {
                return compareStrings(a.toUpperCase(), b.toUpperCase()) || compareStrings(a, b);
            }
            function compareStrings(a, b) {
                return a < b ? -1 /* LessThan */ : a > b ? 1 /* GreaterThan */ : 0 /* EqualTo */;
            }
        }
        function getStringComparerFactory() {
            // If the host supports Intl, we use it for comparisons using the default locale.
            if (typeof Intl === "object" && typeof Intl.Collator === "function") {
                return createIntlCollatorStringComparer;
            }
            // If the host does not support Intl, we fall back to localeCompare.
            // localeCompare in Node v0.10 is just an ordinal comparison, so don't use it.
            if (typeof String.prototype.localeCompare === "function" &&
                typeof String.prototype.toLocaleUpperCase === "function" &&
                "a".localeCompare("B") < 0) {
                return createLocaleCompareStringComparer;
            }
            // Otherwise, fall back to ordinal comparison:
            return createFallbackStringComparer;
        }
        function createStringComparer(locale) {
            // Hold onto common string comparers. This avoids constantly reallocating comparers during
            // tests.
            if (locale === undefined) {
                return defaultComparer || (defaultComparer = stringComparerFactory(locale));
            }
            else if (locale === "en-US") {
                return enUSComparer || (enUSComparer = stringComparerFactory(locale));
            }
            else {
                return stringComparerFactory(locale);
            }
        }
    })();
    var uiComparerCaseSensitive;
    var uiLocale;
    function getUILocale() {
        return uiLocale;
    }
    ts.getUILocale = getUILocale;
    function setUILocale(value) {
        if (uiLocale !== value) {
            uiLocale = value;
            uiComparerCaseSensitive = undefined;
        }
    }
    ts.setUILocale = setUILocale;
    /**
     * Compare two strings in a using the case-sensitive sort behavior of the UI locale.
     *
     * Ordering is not predictable between different host locales, but is best for displaying
     * ordered data for UI presentation. Characters with multiple unicode representations may
     * be considered equal.
     *
     * Case-sensitive comparisons compare strings that differ in base characters, or
     * accents/diacritic marks, or case as unequal.
     */
    function compareStringsCaseSensitiveUI(a, b) {
        var comparer = uiComparerCaseSensitive || (uiComparerCaseSensitive = createUIStringComparer(uiLocale));
        return comparer(a, b);
    }
    ts.compareStringsCaseSensitiveUI = compareStringsCaseSensitiveUI;
    function compareProperties(a, b, key, comparer) {
        return a === b ? 0 /* EqualTo */ :
            a === undefined ? -1 /* LessThan */ :
                b === undefined ? 1 /* GreaterThan */ :
                    comparer(a[key], b[key]);
    }
    ts.compareProperties = compareProperties;
    /** True is greater than false. */
    function compareBooleans(a, b) {
        return compareValues(a ? 1 : 0, b ? 1 : 0);
    }
    ts.compareBooleans = compareBooleans;
    /**
     * Given a name and a list of names that are *not* equal to the name, return a spelling suggestion if there is one that is close enough.
     * Names less than length 3 only check for case-insensitive equality, not Levenshtein distance.
     *
     * If there is a candidate that's the same except for case, return that.
     * If there is a candidate that's within one edit of the name, return that.
     * Otherwise, return the candidate with the smallest Levenshtein distance,
     *    except for candidates:
     *      * With no name
     *      * Whose length differs from the target name by more than 0.34 of the length of the name.
     *      * Whose levenshtein distance is more than 0.4 of the length of the name
     *        (0.4 allows 1 substitution/transposition for every 5 characters,
     *         and 1 insertion/deletion at 3 characters)
     */
    function getSpellingSuggestion(name, candidates, getName) {
        var maximumLengthDifference = Math.min(2, Math.floor(name.length * 0.34));
        var bestDistance = Math.floor(name.length * 0.4) + 1; // If the best result isn't better than this, don't bother.
        var bestCandidate;
        var justCheckExactMatches = false;
        var nameLowerCase = name.toLowerCase();
        for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
            var candidate = candidates_1[_i];
            var candidateName = getName(candidate);
            if (candidateName !== undefined && Math.abs(candidateName.length - nameLowerCase.length) <= maximumLengthDifference) {
                var candidateNameLowerCase = candidateName.toLowerCase();
                if (candidateNameLowerCase === nameLowerCase) {
                    if (candidateName === name) {
                        continue;
                    }
                    return candidate;
                }
                if (justCheckExactMatches) {
                    continue;
                }
                if (candidateName.length < 3) {
                    // Don't bother, user would have noticed a 2-character name having an extra character
                    continue;
                }
                // Only care about a result better than the best so far.
                var distance = levenshteinWithMax(nameLowerCase, candidateNameLowerCase, bestDistance - 1);
                if (distance === undefined) {
                    continue;
                }
                if (distance < 3) {
                    justCheckExactMatches = true;
                    bestCandidate = candidate;
                }
                else {
                    ts.Debug.assert(distance < bestDistance); // Else `levenshteinWithMax` should return undefined
                    bestDistance = distance;
                    bestCandidate = candidate;
                }
            }
        }
        return bestCandidate;
    }
    ts.getSpellingSuggestion = getSpellingSuggestion;
    function levenshteinWithMax(s1, s2, max) {
        var previous = new Array(s2.length + 1);
        var current = new Array(s2.length + 1);
        /** Represents any value > max. We don't care about the particular value. */
        var big = max + 1;
        for (var i = 0; i <= s2.length; i++) {
            previous[i] = i;
        }
        for (var i = 1; i <= s1.length; i++) {
            var c1 = s1.charCodeAt(i - 1);
            var minJ = i > max ? i - max : 1;
            var maxJ = s2.length > max + i ? max + i : s2.length;
            current[0] = i;
            /** Smallest value of the matrix in the ith column. */
            var colMin = i;
            for (var j = 1; j < minJ; j++) {
                current[j] = big;
            }
            for (var j = minJ; j <= maxJ; j++) {
                var dist = c1 === s2.charCodeAt(j - 1)
                    ? previous[j - 1]
                    : Math.min(/*delete*/ previous[j] + 1, /*insert*/ current[j - 1] + 1, /*substitute*/ previous[j - 1] + 2);
                current[j] = dist;
                colMin = Math.min(colMin, dist);
            }
            for (var j = maxJ + 1; j <= s2.length; j++) {
                current[j] = big;
            }
            if (colMin > max) {
                // Give up -- everything in this column is > max and it can't get better in future columns.
                return undefined;
            }
            var temp = previous;
            previous = current;
            current = temp;
        }
        var res = previous[s2.length];
        return res > max ? undefined : res;
    }
    function endsWith(str, suffix) {
        var expectedPos = str.length - suffix.length;
        return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
    }
    ts.endsWith = endsWith;
    function removeSuffix(str, suffix) {
        return endsWith(str, suffix) ? str.slice(0, str.length - suffix.length) : str;
    }
    ts.removeSuffix = removeSuffix;
    function tryRemoveSuffix(str, suffix) {
        return endsWith(str, suffix) ? str.slice(0, str.length - suffix.length) : undefined;
    }
    ts.tryRemoveSuffix = tryRemoveSuffix;
    function stringContains(str, substring) {
        return str.indexOf(substring) !== -1;
    }
    ts.stringContains = stringContains;
    function fileExtensionIs(path, extension) {
        return path.length > extension.length && endsWith(path, extension);
    }
    ts.fileExtensionIs = fileExtensionIs;
    function fileExtensionIsOneOf(path, extensions) {
        for (var _i = 0, extensions_1 = extensions; _i < extensions_1.length; _i++) {
            var extension = extensions_1[_i];
            if (fileExtensionIs(path, extension)) {
                return true;
            }
        }
        return false;
    }
    ts.fileExtensionIsOneOf = fileExtensionIsOneOf;
    /**
     * Takes a string like "jquery-min.4.2.3" and returns "jquery"
     */
    function removeMinAndVersionNumbers(fileName) {
        // Match a "." or "-" followed by a version number or 'min' at the end of the name
        var trailingMinOrVersion = /[.-]((min)|(\d+(\.\d+)*))$/;
        // The "min" or version may both be present, in either order, so try applying the above twice.
        return fileName.replace(trailingMinOrVersion, "").replace(trailingMinOrVersion, "");
    }
    ts.removeMinAndVersionNumbers = removeMinAndVersionNumbers;
    /** Remove an item from an array, moving everything to its right one space left. */
    function orderedRemoveItem(array, item) {
        for (var i = 0; i < array.length; i++) {
            if (array[i] === item) {
                orderedRemoveItemAt(array, i);
                return true;
            }
        }
        return false;
    }
    ts.orderedRemoveItem = orderedRemoveItem;
    /** Remove an item by index from an array, moving everything to its right one space left. */
    function orderedRemoveItemAt(array, index) {
        // This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`.
        for (var i = index; i < array.length - 1; i++) {
            array[i] = array[i + 1];
        }
        array.pop();
    }
    ts.orderedRemoveItemAt = orderedRemoveItemAt;
    function unorderedRemoveItemAt(array, index) {
        // Fill in the "hole" left at `index`.
        array[index] = array[array.length - 1];
        array.pop();
    }
    ts.unorderedRemoveItemAt = unorderedRemoveItemAt;
    /** Remove the *first* occurrence of `item` from the array. */
    function unorderedRemoveItem(array, item) {
        return unorderedRemoveFirstItemWhere(array, function (element) { return element === item; });
    }
    ts.unorderedRemoveItem = unorderedRemoveItem;
    /** Remove the *first* element satisfying `predicate`. */
    function unorderedRemoveFirstItemWhere(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            if (predicate(array[i])) {
                unorderedRemoveItemAt(array, i);
                return true;
            }
        }
        return false;
    }
    function createGetCanonicalFileName(useCaseSensitiveFileNames) {
        return useCaseSensitiveFileNames ? identity : toLowerCase;
    }
    ts.createGetCanonicalFileName = createGetCanonicalFileName;
    function patternText(_a) {
        var prefix = _a.prefix, suffix = _a.suffix;
        return prefix + "*" + suffix;
    }
    ts.patternText = patternText;
    /**
     * Given that candidate matches pattern, returns the text matching the '*'.
     * E.g.: matchedText(tryParsePattern("foo*baz"), "foobarbaz") === "bar"
     */
    function matchedText(pattern, candidate) {
        ts.Debug.assert(isPatternMatch(pattern, candidate));
        return candidate.substring(pattern.prefix.length, candidate.length - pattern.suffix.length);
    }
    ts.matchedText = matchedText;
    /** Return the object corresponding to the best pattern to match `candidate`. */
    function findBestPatternMatch(values, getPattern, candidate) {
        var matchedValue;
        // use length of prefix as betterness criteria
        var longestMatchPrefixLength = -1;
        for (var _i = 0, values_2 = values; _i < values_2.length; _i++) {
            var v = values_2[_i];
            var pattern = getPattern(v);
            if (isPatternMatch(pattern, candidate) && pattern.prefix.length > longestMatchPrefixLength) {
                longestMatchPrefixLength = pattern.prefix.length;
                matchedValue = v;
            }
        }
        return matchedValue;
    }
    ts.findBestPatternMatch = findBestPatternMatch;
    function startsWith(str, prefix) {
        return str.lastIndexOf(prefix, 0) === 0;
    }
    ts.startsWith = startsWith;
    function removePrefix(str, prefix) {
        return startsWith(str, prefix) ? str.substr(prefix.length) : str;
    }
    ts.removePrefix = removePrefix;
    function tryRemovePrefix(str, prefix, getCanonicalFileName) {
        if (getCanonicalFileName === void 0) { getCanonicalFileName = identity; }
        return startsWith(getCanonicalFileName(str), getCanonicalFileName(prefix)) ? str.substring(prefix.length) : undefined;
    }
    ts.tryRemovePrefix = tryRemovePrefix;
    function isPatternMatch(_a, candidate) {
        var prefix = _a.prefix, suffix = _a.suffix;
        return candidate.length >= prefix.length + suffix.length &&
            startsWith(candidate, prefix) &&
            endsWith(candidate, suffix);
    }
    function and(f, g) {
        return function (arg) { return f(arg) && g(arg); };
    }
    ts.and = and;
    function or(f, g) {
        return function (arg) { return f(arg) || g(arg); };
    }
    ts.or = or;
    function assertType(_) { } // tslint:disable-line no-empty
    ts.assertType = assertType;
    function singleElementArray(t) {
        return t === undefined ? undefined : [t];
    }
    ts.singleElementArray = singleElementArray;
    function enumerateInsertsAndDeletes(newItems, oldItems, comparer, inserted, deleted, unchanged) {
        unchanged = unchanged || noop;
        var newIndex = 0;
        var oldIndex = 0;
        var newLen = newItems.length;
        var oldLen = oldItems.length;
        while (newIndex < newLen && oldIndex < oldLen) {
            var newItem = newItems[newIndex];
            var oldItem = oldItems[oldIndex];
            var compareResult = comparer(newItem, oldItem);
            if (compareResult === -1 /* LessThan */) {
                inserted(newItem);
                newIndex++;
            }
            else if (compareResult === 1 /* GreaterThan */) {
                deleted(oldItem);
                oldIndex++;
            }
            else {
                unchanged(oldItem, newItem);
                newIndex++;
                oldIndex++;
            }
        }
        while (newIndex < newLen) {
            inserted(newItems[newIndex++]);
        }
        while (oldIndex < oldLen) {
            deleted(oldItems[oldIndex++]);
        }
    }
    ts.enumerateInsertsAndDeletes = enumerateInsertsAndDeletes;
    function fill(length, cb) {
        var result = Array(length);
        for (var i = 0; i < length; i++) {
            result[i] = cb(i);
        }
        return result;
    }
    ts.fill = fill;
    function cartesianProduct(arrays) {
        var result = [];
        cartesianProductWorker(arrays, result, /*outer*/ undefined, 0);
        return result;
    }
    ts.cartesianProduct = cartesianProduct;
    function cartesianProductWorker(arrays, result, outer, index) {
        for (var _i = 0, _a = arrays[index]; _i < _a.length; _i++) {
            var element = _a[_i];
            var inner = void 0;
            if (outer) {
                inner = outer.slice();
                inner.push(element);
            }
            else {
                inner = [element];
            }
            if (index === arrays.length - 1) {
                result.push(inner);
            }
            else {
                cartesianProductWorker(arrays, result, inner, index + 1);
            }
        }
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var Debug;
    (function (Debug) {
        Debug.currentAssertionLevel = 0 /* None */;
        Debug.isDebugging = false;
        function shouldAssert(level) {
            return Debug.currentAssertionLevel >= level;
        }
        Debug.shouldAssert = shouldAssert;
        function assert(expression, message, verboseDebugInfo, stackCrawlMark) {
            if (!expression) {
                if (verboseDebugInfo) {
                    message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo());
                }
                fail(message ? "False expression: " + message : "False expression.", stackCrawlMark || assert);
            }
        }
        Debug.assert = assert;
        function assertEqual(a, b, msg, msg2) {
            if (a !== b) {
                var message = msg ? msg2 ? msg + " " + msg2 : msg : "";
                fail("Expected " + a + " === " + b + ". " + message);
            }
        }
        Debug.assertEqual = assertEqual;
        function assertLessThan(a, b, msg) {
            if (a >= b) {
                fail("Expected " + a + " < " + b + ". " + (msg || ""));
            }
        }
        Debug.assertLessThan = assertLessThan;
        function assertLessThanOrEqual(a, b) {
            if (a > b) {
                fail("Expected " + a + " <= " + b);
            }
        }
        Debug.assertLessThanOrEqual = assertLessThanOrEqual;
        function assertGreaterThanOrEqual(a, b) {
            if (a < b) {
                fail("Expected " + a + " >= " + b);
            }
        }
        Debug.assertGreaterThanOrEqual = assertGreaterThanOrEqual;
        function fail(message, stackCrawlMark) {
            debugger;
            var e = new Error(message ? "Debug Failure. " + message : "Debug Failure.");
            if (Error.captureStackTrace) {
                Error.captureStackTrace(e, stackCrawlMark || fail);
            }
            throw e;
        }
        Debug.fail = fail;
        function assertDefined(value, message) {
            if (value === undefined || value === null)
                return fail(message);
            return value;
        }
        Debug.assertDefined = assertDefined;
        function assertEachDefined(value, message) {
            for (var _i = 0, value_1 = value; _i < value_1.length; _i++) {
                var v = value_1[_i];
                assertDefined(v, message);
            }
            return value;
        }
        Debug.assertEachDefined = assertEachDefined;
        function assertNever(member, message, stackCrawlMark) {
            if (message === void 0) { message = "Illegal value:"; }
            var detail = typeof member === "object" && "kind" in member && "pos" in member && formatSyntaxKind ? "SyntaxKind: " + formatSyntaxKind(member.kind) : JSON.stringify(member);
            return fail(message + " " + detail, stackCrawlMark || assertNever);
        }
        Debug.assertNever = assertNever;
        function getFunctionName(func) {
            if (typeof func !== "function") {
                return "";
            }
            else if (func.hasOwnProperty("name")) {
                return func.name;
            }
            else {
                var text = Function.prototype.toString.call(func);
                var match = /^function\s+([\w\$]+)\s*\(/.exec(text);
                return match ? match[1] : "";
            }
        }
        Debug.getFunctionName = getFunctionName;
        function formatSymbol(symbol) {
            return "{ name: " + ts.unescapeLeadingUnderscores(symbol.escapedName) + "; flags: " + formatSymbolFlags(symbol.flags) + "; declarations: " + ts.map(symbol.declarations, function (node) { return formatSyntaxKind(node.kind); }) + " }";
        }
        Debug.formatSymbol = formatSymbol;
        /**
         * Formats an enum value as a string for debugging and debug assertions.
         */
        function formatEnum(value, enumObject, isFlags) {
            if (value === void 0) { value = 0; }
            var members = getEnumMembers(enumObject);
            if (value === 0) {
                return members.length > 0 && members[0][0] === 0 ? members[0][1] : "0";
            }
            if (isFlags) {
                var result = "";
                var remainingFlags = value;
                for (var i = members.length - 1; i >= 0 && remainingFlags !== 0; i--) {
                    var _a = members[i], enumValue = _a[0], enumName = _a[1];
                    if (enumValue !== 0 && (remainingFlags & enumValue) === enumValue) {
                        remainingFlags &= ~enumValue;
                        result = "" + enumName + (result ? "|" : "") + result;
                    }
                }
                if (remainingFlags === 0) {
                    return result;
                }
            }
            else {
                for (var _i = 0, members_1 = members; _i < members_1.length; _i++) {
                    var _b = members_1[_i], enumValue = _b[0], enumName = _b[1];
                    if (enumValue === value) {
                        return enumName;
                    }
                }
            }
            return value.toString();
        }
        Debug.formatEnum = formatEnum;
        function getEnumMembers(enumObject) {
            var result = [];
            for (var name in enumObject) {
                var value = enumObject[name];
                if (typeof value === "number") {
                    result.push([value, name]);
                }
            }
            return ts.stableSort(result, function (x, y) { return ts.compareValues(x[0], y[0]); });
        }
        function formatSyntaxKind(kind) {
            return formatEnum(kind, ts.SyntaxKind, /*isFlags*/ false);
        }
        Debug.formatSyntaxKind = formatSyntaxKind;
        function formatNodeFlags(flags) {
            return formatEnum(flags, ts.NodeFlags, /*isFlags*/ true);
        }
        Debug.formatNodeFlags = formatNodeFlags;
        function formatModifierFlags(flags) {
            return formatEnum(flags, ts.ModifierFlags, /*isFlags*/ true);
        }
        Debug.formatModifierFlags = formatModifierFlags;
        function formatTransformFlags(flags) {
            return formatEnum(flags, ts.TransformFlags, /*isFlags*/ true);
        }
        Debug.formatTransformFlags = formatTransformFlags;
        function formatEmitFlags(flags) {
            return formatEnum(flags, ts.EmitFlags, /*isFlags*/ true);
        }
        Debug.formatEmitFlags = formatEmitFlags;
        function formatSymbolFlags(flags) {
            return formatEnum(flags, ts.SymbolFlags, /*isFlags*/ true);
        }
        Debug.formatSymbolFlags = formatSymbolFlags;
        function formatTypeFlags(flags) {
            return formatEnum(flags, ts.TypeFlags, /*isFlags*/ true);
        }
        Debug.formatTypeFlags = formatTypeFlags;
        function formatObjectFlags(flags) {
            return formatEnum(flags, ts.ObjectFlags, /*isFlags*/ true);
        }
        Debug.formatObjectFlags = formatObjectFlags;
        function failBadSyntaxKind(node, message) {
            return fail((message || "Unexpected node.") + "\r\nNode " + formatSyntaxKind(node.kind) + " was unexpected.", failBadSyntaxKind);
        }
        Debug.failBadSyntaxKind = failBadSyntaxKind;
        Debug.assertEachNode = shouldAssert(1 /* Normal */)
            ? function (nodes, test, message) { return assert(test === undefined || ts.every(nodes, test), message || "Unexpected node.", function () { return "Node array did not pass test '" + getFunctionName(test) + "'."; }, Debug.assertEachNode); }
            : ts.noop;
        Debug.assertNode = shouldAssert(1 /* Normal */)
            ? function (node, test, message) { return assert(test === undefined || test(node), message || "Unexpected node.", function () { return "Node " + formatSyntaxKind(node.kind) + " did not pass test '" + getFunctionName(test) + "'."; }, Debug.assertNode); }
            : ts.noop;
        Debug.assertOptionalNode = shouldAssert(1 /* Normal */)
            ? function (node, test, message) { return assert(test === undefined || node === undefined || test(node), message || "Unexpected node.", function () { return "Node " + formatSyntaxKind(node.kind) + " did not pass test '" + getFunctionName(test) + "'."; }, Debug.assertOptionalNode); }
            : ts.noop;
        Debug.assertOptionalToken = shouldAssert(1 /* Normal */)
            ? function (node, kind, message) { return assert(kind === undefined || node === undefined || node.kind === kind, message || "Unexpected node.", function () { return "Node " + formatSyntaxKind(node.kind) + " was not a '" + formatSyntaxKind(kind) + "' token."; }, Debug.assertOptionalToken); }
            : ts.noop;
        Debug.assertMissingNode = shouldAssert(1 /* Normal */)
            ? function (node, message) { return assert(node === undefined, message || "Unexpected node.", function () { return "Node " + formatSyntaxKind(node.kind) + " was unexpected'."; }, Debug.assertMissingNode); }
            : ts.noop;
        var isDebugInfoEnabled = false;
        /**
         * Injects debug information into frequently used types.
         */
        function enableDebugInfo() {
            if (isDebugInfoEnabled)
                return;
            // Add additional properties in debug mode to assist with debugging.
            Object.defineProperties(ts.objectAllocator.getSymbolConstructor().prototype, {
                __debugFlags: { get: function () { return formatSymbolFlags(this.flags); } }
            });
            Object.defineProperties(ts.objectAllocator.getTypeConstructor().prototype, {
                __debugFlags: { get: function () { return formatTypeFlags(this.flags); } },
                __debugObjectFlags: { get: function () { return this.flags & 524288 /* Object */ ? formatObjectFlags(this.objectFlags) : ""; } },
                __debugTypeToString: { value: function () { return this.checker.typeToString(this); } },
            });
            var nodeConstructors = [
                ts.objectAllocator.getNodeConstructor(),
                ts.objectAllocator.getIdentifierConstructor(),
                ts.objectAllocator.getTokenConstructor(),
                ts.objectAllocator.getSourceFileConstructor()
            ];
            for (var _i = 0, nodeConstructors_1 = nodeConstructors; _i < nodeConstructors_1.length; _i++) {
                var ctor = nodeConstructors_1[_i];
                if (!ctor.prototype.hasOwnProperty("__debugKind")) {
                    Object.defineProperties(ctor.prototype, {
                        __debugKind: { get: function () { return formatSyntaxKind(this.kind); } },
                        __debugNodeFlags: { get: function () { return formatNodeFlags(this.flags); } },
                        __debugModifierFlags: { get: function () { return formatModifierFlags(ts.getModifierFlagsNoCache(this)); } },
                        __debugTransformFlags: { get: function () { return formatTransformFlags(this.transformFlags); } },
                        __debugIsParseTreeNode: { get: function () { return ts.isParseTreeNode(this); } },
                        __debugEmitFlags: { get: function () { return formatEmitFlags(ts.getEmitFlags(this)); } },
                        __debugGetText: {
                            value: function (includeTrivia) {
                                if (ts.nodeIsSynthesized(this))
                                    return "";
                                var parseNode = ts.getParseTreeNode(this);
                                var sourceFile = parseNode && ts.getSourceFileOfNode(parseNode);
                                return sourceFile ? ts.getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
                            }
                        }
                    });
                }
            }
            isDebugInfoEnabled = true;
        }
        Debug.enableDebugInfo = enableDebugInfo;
    })(Debug = ts.Debug || (ts.Debug = {}));
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    /** Gets a timestamp with (at least) ms resolution */
    ts.timestamp = typeof performance !== "undefined" && performance.now ? function () { return performance.now(); } : Date.now ? Date.now : function () { return +(new Date()); };
})(ts || (ts = {}));
/*@internal*/
/** Performance measurements for the compiler. */
(function (ts) {
    var performance;
    (function (performance) {
        // NOTE: cannot use ts.noop as core.ts loads after this
        var profilerEvent = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true ? onProfilerEvent : function () { };
        var enabled = false;
        var profilerStart = 0;
        var counts;
        var marks;
        var measures;
        function createTimerIf(condition, measureName, startMarkName, endMarkName) {
            return condition ? createTimer(measureName, startMarkName, endMarkName) : performance.nullTimer;
        }
        performance.createTimerIf = createTimerIf;
        function createTimer(measureName, startMarkName, endMarkName) {
            var enterCount = 0;
            return {
                enter: enter,
                exit: exit
            };
            function enter() {
                if (++enterCount === 1) {
                    mark(startMarkName);
                }
            }
            function exit() {
                if (--enterCount === 0) {
                    mark(endMarkName);
                    measure(measureName, startMarkName, endMarkName);
                }
                else if (enterCount < 0) {
                    ts.Debug.fail("enter/exit count does not match.");
                }
            }
        }
        performance.createTimer = createTimer;
        performance.nullTimer = { enter: ts.noop, exit: ts.noop };
        /**
         * Marks a performance event.
         *
         * @param markName The name of the mark.
         */
        function mark(markName) {
            if (enabled) {
                marks.set(markName, ts.timestamp());
                counts.set(markName, (counts.get(markName) || 0) + 1);
                profilerEvent(markName);
            }
        }
        performance.mark = mark;
        /**
         * Adds a performance measurement with the specified name.
         *
         * @param measureName The name of the performance measurement.
         * @param startMarkName The name of the starting mark. If not supplied, the point at which the
         *      profiler was enabled is used.
         * @param endMarkName The name of the ending mark. If not supplied, the current timestamp is
         *      used.
         */
        function measure(measureName, startMarkName, endMarkName) {
            if (enabled) {
                var end = endMarkName && marks.get(endMarkName) || ts.timestamp();
                var start = startMarkName && marks.get(startMarkName) || profilerStart;
                measures.set(measureName, (measures.get(measureName) || 0) + (end - start));
            }
        }
        performance.measure = measure;
        /**
         * Gets the number of times a marker was encountered.
         *
         * @param markName The name of the mark.
         */
        function getCount(markName) {
            return counts && counts.get(markName) || 0;
        }
        performance.getCount = getCount;
        /**
         * Gets the total duration of all measurements with the supplied name.
         *
         * @param measureName The name of the measure whose durations should be accumulated.
         */
        function getDuration(measureName) {
            return measures && measures.get(measureName) || 0;
        }
        performance.getDuration = getDuration;
        /**
         * Iterate over each measure, performing some action
         *
         * @param cb The action to perform for each measure
         */
        function forEachMeasure(cb) {
            measures.forEach(function (measure, key) {
                cb(key, measure);
            });
        }
        performance.forEachMeasure = forEachMeasure;
        /** Enables (and resets) performance measurements for the compiler. */
        function enable() {
            counts = ts.createMap();
            marks = ts.createMap();
            measures = ts.createMap();
            enabled = true;
            profilerStart = ts.timestamp();
        }
        performance.enable = enable;
        /** Disables performance measurements for the compiler. */
        function disable() {
            enabled = false;
        }
        performance.disable = disable;
    })(performance = ts.performance || (ts.performance = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    // https://semver.org/#spec-item-2
    // > A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative
    // > integers, and MUST NOT contain leading zeroes. X is the major version, Y is the minor
    // > version, and Z is the patch version. Each element MUST increase numerically.
    //
    // NOTE: We differ here in that we allow X and X.Y, with missing parts having the default
    // value of `0`.
    var versionRegExp = /^(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\-([a-z0-9-.]+))?(?:\+([a-z0-9-.]+))?)?)?$/i;
    // https://semver.org/#spec-item-9
    // > A pre-release version MAY be denoted by appending a hyphen and a series of dot separated
    // > identifiers immediately following the patch version. Identifiers MUST comprise only ASCII
    // > alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers
    // > MUST NOT include leading zeroes.
    var prereleaseRegExp = /^(?:0|[1-9]\d*|[a-z-][a-z0-9-]*)(?:\.(?:0|[1-9]\d*|[a-z-][a-z0-9-]*))*$/i;
    // https://semver.org/#spec-item-10
    // > Build metadata MAY be denoted by appending a plus sign and a series of dot separated
    // > identifiers immediately following the patch or pre-release version. Identifiers MUST
    // > comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty.
    var buildRegExp = /^[a-z0-9-]+(?:\.[a-z0-9-]+)*$/i;
    // https://semver.org/#spec-item-9
    // > Numeric identifiers MUST NOT include leading zeroes.
    var numericIdentifierRegExp = /^(0|[1-9]\d*)$/;
    /**
     * Describes a precise semantic version number, https://semver.org
     */
    var Version = /** @class */ (function () {
        function Version(major, minor, patch, prerelease, build) {
            if (minor === void 0) { minor = 0; }
            if (patch === void 0) { patch = 0; }
            if (prerelease === void 0) { prerelease = ""; }
            if (build === void 0) { build = ""; }
            if (typeof major === "string") {
                var result = ts.Debug.assertDefined(tryParseComponents(major), "Invalid version");
                (major = result.major, minor = result.minor, patch = result.patch, prerelease = result.prerelease, build = result.build);
            }
            ts.Debug.assert(major >= 0, "Invalid argument: major");
            ts.Debug.assert(minor >= 0, "Invalid argument: minor");
            ts.Debug.assert(patch >= 0, "Invalid argument: patch");
            ts.Debug.assert(!prerelease || prereleaseRegExp.test(prerelease), "Invalid argument: prerelease");
            ts.Debug.assert(!build || buildRegExp.test(build), "Invalid argument: build");
            this.major = major;
            this.minor = minor;
            this.patch = patch;
            this.prerelease = prerelease ? prerelease.split(".") : ts.emptyArray;
            this.build = build ? build.split(".") : ts.emptyArray;
        }
        Version.tryParse = function (text) {
            var result = tryParseComponents(text);
            if (!result)
                return undefined;
            var major = result.major, minor = result.minor, patch = result.patch, prerelease = result.prerelease, build = result.build;
            return new Version(major, minor, patch, prerelease, build);
        };
        Version.prototype.compareTo = function (other) {
            // https://semver.org/#spec-item-11
            // > Precedence is determined by the first difference when comparing each of these
            // > identifiers from left to right as follows: Major, minor, and patch versions are
            // > always compared numerically.
            //
            // https://semver.org/#spec-item-11
            // > Precedence for two pre-release versions with the same major, minor, and patch version
            // > MUST be determined by comparing each dot separated identifier from left to right until
            // > a difference is found [...]
            //
            // https://semver.org/#spec-item-11
            // > Build metadata does not figure into precedence
            if (this === other)
                return 0 /* EqualTo */;
            if (other === undefined)
                return 1 /* GreaterThan */;
            return ts.compareValues(this.major, other.major)
                || ts.compareValues(this.minor, other.minor)
                || ts.compareValues(this.patch, other.patch)
                || comparePrerelaseIdentifiers(this.prerelease, other.prerelease);
        };
        Version.prototype.increment = function (field) {
            switch (field) {
                case "major": return new Version(this.major + 1, 0, 0);
                case "minor": return new Version(this.major, this.minor + 1, 0);
                case "patch": return new Version(this.major, this.minor, this.patch + 1);
                default: return ts.Debug.assertNever(field);
            }
        };
        Version.prototype.toString = function () {
            var result = this.major + "." + this.minor + "." + this.patch;
            if (ts.some(this.prerelease))
                result += "-" + this.prerelease.join(".");
            if (ts.some(this.build))
                result += "+" + this.build.join(".");
            return result;
        };
        Version.zero = new Version(0, 0, 0);
        return Version;
    }());
    ts.Version = Version;
    function tryParseComponents(text) {
        var match = versionRegExp.exec(text);
        if (!match)
            return undefined;
        var major = match[1], _a = match[2], minor = _a === void 0 ? "0" : _a, _b = match[3], patch = _b === void 0 ? "0" : _b, _c = match[4], prerelease = _c === void 0 ? "" : _c, _d = match[5], build = _d === void 0 ? "" : _d;
        if (prerelease && !prereleaseRegExp.test(prerelease))
            return undefined;
        if (build && !buildRegExp.test(build))
            return undefined;
        return {
            major: parseInt(major, 10),
            minor: parseInt(minor, 10),
            patch: parseInt(patch, 10),
            prerelease: prerelease,
            build: build
        };
    }
    function comparePrerelaseIdentifiers(left, right) {
        // https://semver.org/#spec-item-11
        // > When major, minor, and patch are equal, a pre-release version has lower precedence
        // > than a normal version.
        if (left === right)
            return 0 /* EqualTo */;
        if (left.length === 0)
            return right.length === 0 ? 0 /* EqualTo */ : 1 /* GreaterThan */;
        if (right.length === 0)
            return -1 /* LessThan */;
        // https://semver.org/#spec-item-11
        // > Precedence for two pre-release versions with the same major, minor, and patch version
        // > MUST be determined by comparing each dot separated identifier from left to right until
        // > a difference is found [...]
        var length = Math.min(left.length, right.length);
        for (var i = 0; i < length; i++) {
            var leftIdentifier = left[i];
            var rightIdentifier = right[i];
            if (leftIdentifier === rightIdentifier)
                continue;
            var leftIsNumeric = numericIdentifierRegExp.test(leftIdentifier);
            var rightIsNumeric = numericIdentifierRegExp.test(rightIdentifier);
            if (leftIsNumeric || rightIsNumeric) {
                // https://semver.org/#spec-item-11
                // > Numeric identifiers always have lower precedence than non-numeric identifiers.
                if (leftIsNumeric !== rightIsNumeric)
                    return leftIsNumeric ? -1 /* LessThan */ : 1 /* GreaterThan */;
                // https://semver.org/#spec-item-11
                // > identifiers consisting of only digits are compared numerically
                var result = ts.compareValues(+leftIdentifier, +rightIdentifier);
                if (result)
                    return result;
            }
            else {
                // https://semver.org/#spec-item-11
                // > identifiers with letters or hyphens are compared lexically in ASCII sort order.
                var result = ts.compareStringsCaseSensitive(leftIdentifier, rightIdentifier);
                if (result)
                    return result;
            }
        }
        // https://semver.org/#spec-item-11
        // > A larger set of pre-release fields has a higher precedence than a smaller set, if all
        // > of the preceding identifiers are equal.
        return ts.compareValues(left.length, right.length);
    }
    /**
     * Describes a semantic version range, per https://github.com/npm/node-semver#ranges
     */
    var VersionRange = /** @class */ (function () {
        function VersionRange(spec) {
            this._alternatives = spec ? ts.Debug.assertDefined(parseRange(spec), "Invalid range spec.") : ts.emptyArray;
        }
        VersionRange.tryParse = function (text) {
            var sets = parseRange(text);
            if (sets) {
                var range = new VersionRange("");
                range._alternatives = sets;
                return range;
            }
            return undefined;
        };
        VersionRange.prototype.test = function (version) {
            if (typeof version === "string")
                version = new Version(version);
            return testDisjunction(version, this._alternatives);
        };
        VersionRange.prototype.toString = function () {
            return formatDisjunction(this._alternatives);
        };
        return VersionRange;
    }());
    ts.VersionRange = VersionRange;
    // https://github.com/npm/node-semver#range-grammar
    //
    // range-set    ::= range ( logical-or range ) *
    // range        ::= hyphen | simple ( ' ' simple ) * | ''
    // logical-or   ::= ( ' ' ) * '||' ( ' ' ) *
    var logicalOrRegExp = /\s*\|\|\s*/g;
    var whitespaceRegExp = /\s+/g;
    // https://github.com/npm/node-semver#range-grammar
    //
    // partial      ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
    // xr           ::= 'x' | 'X' | '*' | nr
    // nr           ::= '0' | ['1'-'9'] ( ['0'-'9'] ) *
    // qualifier    ::= ( '-' pre )? ( '+' build )?
    // pre          ::= parts
    // build        ::= parts
    // parts        ::= part ( '.' part ) *
    // part         ::= nr | [-0-9A-Za-z]+
    var partialRegExp = /^([xX*0]|[1-9]\d*)(?:\.([xX*0]|[1-9]\d*)(?:\.([xX*0]|[1-9]\d*)(?:-([a-z0-9-.]+))?(?:\+([a-z0-9-.]+))?)?)?$/i;
    // https://github.com/npm/node-semver#range-grammar
    //
    // hyphen       ::= partial ' - ' partial
    var hyphenRegExp = /^\s*([a-z0-9-+.*]+)\s+-\s+([a-z0-9-+.*]+)\s*$/i;
    // https://github.com/npm/node-semver#range-grammar
    //
    // simple       ::= primitive | partial | tilde | caret
    // primitive    ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
    // tilde        ::= '~' partial
    // caret        ::= '^' partial
    var rangeRegExp = /^\s*(~|\^|<|<=|>|>=|=)?\s*([a-z0-9-+.*]+)$/i;
    function parseRange(text) {
        var alternatives = [];
        for (var _i = 0, _a = text.trim().split(logicalOrRegExp); _i < _a.length; _i++) {
            var range = _a[_i];
            if (!range)
                continue;
            var comparators = [];
            var match = hyphenRegExp.exec(range);
            if (match) {
                if (!parseHyphen(match[1], match[2], comparators))
                    return undefined;
            }
            else {
                for (var _b = 0, _c = range.split(whitespaceRegExp); _b < _c.length; _b++) {
                    var simple = _c[_b];
                    var match_1 = rangeRegExp.exec(simple);
                    if (!match_1 || !parseComparator(match_1[1], match_1[2], comparators))
                        return undefined;
                }
            }
            alternatives.push(comparators);
        }
        return alternatives;
    }
    function parsePartial(text) {
        var match = partialRegExp.exec(text);
        if (!match)
            return undefined;
        var major = match[1], _a = match[2], minor = _a === void 0 ? "*" : _a, _b = match[3], patch = _b === void 0 ? "*" : _b, prerelease = match[4], build = match[5];
        var version = new Version(isWildcard(major) ? 0 : parseInt(major, 10), isWildcard(major) || isWildcard(minor) ? 0 : parseInt(minor, 10), isWildcard(major) || isWildcard(minor) || isWildcard(patch) ? 0 : parseInt(patch, 10), prerelease, build);
        return { version: version, major: major, minor: minor, patch: patch };
    }
    function parseHyphen(left, right, comparators) {
        var leftResult = parsePartial(left);
        if (!leftResult)
            return false;
        var rightResult = parsePartial(right);
        if (!rightResult)
            return false;
        if (!isWildcard(leftResult.major)) {
            comparators.push(createComparator(">=", leftResult.version));
        }
        if (!isWildcard(rightResult.major)) {
            comparators.push(isWildcard(rightResult.minor) ? createComparator("<", rightResult.version.increment("major")) :
                isWildcard(rightResult.patch) ? createComparator("<", rightResult.version.increment("minor")) :
                    createComparator("<=", rightResult.version));
        }
        return true;
    }
    function parseComparator(operator, text, comparators) {
        var result = parsePartial(text);
        if (!result)
            return false;
        var version = result.version, major = result.major, minor = result.minor, patch = result.patch;
        if (!isWildcard(major)) {
            switch (operator) {
                case "~":
                    comparators.push(createComparator(">=", version));
                    comparators.push(createComparator("<", version.increment(isWildcard(minor) ? "major" :
                        "minor")));
                    break;
                case "^":
                    comparators.push(createComparator(">=", version));
                    comparators.push(createComparator("<", version.increment(version.major > 0 || isWildcard(minor) ? "major" :
                        version.minor > 0 || isWildcard(patch) ? "minor" :
                            "patch")));
                    break;
                case "<":
                case ">=":
                    comparators.push(createComparator(operator, version));
                    break;
                case "<=":
                case ">":
                    comparators.push(isWildcard(minor) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("major")) :
                        isWildcard(patch) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("minor")) :
                            createComparator(operator, version));
                    break;
                case "=":
                case undefined:
                    if (isWildcard(minor) || isWildcard(patch)) {
                        comparators.push(createComparator(">=", version));
                        comparators.push(createComparator("<", version.increment(isWildcard(minor) ? "major" : "minor")));
                    }
                    else {
                        comparators.push(createComparator("=", version));
                    }
                    break;
                default:
                    // unrecognized
                    return false;
            }
        }
        else if (operator === "<" || operator === ">") {
            comparators.push(createComparator("<", Version.zero));
        }
        return true;
    }
    function isWildcard(part) {
        return part === "*" || part === "x" || part === "X";
    }
    function createComparator(operator, operand) {
        return { operator: operator, operand: operand };
    }
    function testDisjunction(version, alternatives) {
        // an empty disjunction is treated as "*" (all versions)
        if (alternatives.length === 0)
            return true;
        for (var _i = 0, alternatives_1 = alternatives; _i < alternatives_1.length; _i++) {
            var alternative = alternatives_1[_i];
            if (testAlternative(version, alternative))
                return true;
        }
        return false;
    }
    function testAlternative(version, comparators) {
        for (var _i = 0, comparators_1 = comparators; _i < comparators_1.length; _i++) {
            var comparator = comparators_1[_i];
            if (!testComparator(version, comparator.operator, comparator.operand))
                return false;
        }
        return true;
    }
    function testComparator(version, operator, operand) {
        var cmp = version.compareTo(operand);
        switch (operator) {
            case "<": return cmp < 0;
            case "<=": return cmp <= 0;
            case ">": return cmp > 0;
            case ">=": return cmp >= 0;
            case "=": return cmp === 0;
            default: return ts.Debug.assertNever(operator);
        }
    }
    function formatDisjunction(alternatives) {
        return ts.map(alternatives, formatAlternative).join(" || ") || "*";
    }
    function formatAlternative(comparators) {
        return ts.map(comparators, formatComparator).join(" ");
    }
    function formatComparator(comparator) {
        return "" + comparator.operator + comparator.operand;
    }
})(ts || (ts = {}));
var ts;
(function (ts) {
    // token > SyntaxKind.Identifier => token is a keyword
    // Also, If you add a new SyntaxKind be sure to keep the `Markers` section at the bottom in sync
    var SyntaxKind;
    (function (SyntaxKind) {
        SyntaxKind[SyntaxKind["Unknown"] = 0] = "Unknown";
        SyntaxKind[SyntaxKind["EndOfFileToken"] = 1] = "EndOfFileToken";
        SyntaxKind[SyntaxKind["SingleLineCommentTrivia"] = 2] = "SingleLineCommentTrivia";
        SyntaxKind[SyntaxKind["MultiLineCommentTrivia"] = 3] = "MultiLineCommentTrivia";
        SyntaxKind[SyntaxKind["NewLineTrivia"] = 4] = "NewLineTrivia";
        SyntaxKind[SyntaxKind["WhitespaceTrivia"] = 5] = "WhitespaceTrivia";
        // We detect and preserve #! on the first line
        SyntaxKind[SyntaxKind["ShebangTrivia"] = 6] = "ShebangTrivia";
        // We detect and provide better error recovery when we encounter a git merge marker.  This
        // allows us to edit files with git-conflict markers in them in a much more pleasant manner.
        SyntaxKind[SyntaxKind["ConflictMarkerTrivia"] = 7] = "ConflictMarkerTrivia";
        // Literals
        SyntaxKind[SyntaxKind["NumericLiteral"] = 8] = "NumericLiteral";
        SyntaxKind[SyntaxKind["BigIntLiteral"] = 9] = "BigIntLiteral";
        SyntaxKind[SyntaxKind["StringLiteral"] = 10] = "StringLiteral";
        SyntaxKind[SyntaxKind["JsxText"] = 11] = "JsxText";
        SyntaxKind[SyntaxKind["JsxTextAllWhiteSpaces"] = 12] = "JsxTextAllWhiteSpaces";
        SyntaxKind[SyntaxKind["RegularExpressionLiteral"] = 13] = "RegularExpressionLiteral";
        SyntaxKind[SyntaxKind["NoSubstitutionTemplateLiteral"] = 14] = "NoSubstitutionTemplateLiteral";
        // Pseudo-literals
        SyntaxKind[SyntaxKind["TemplateHead"] = 15] = "TemplateHead";
        SyntaxKind[SyntaxKind["TemplateMiddle"] = 16] = "TemplateMiddle";
        SyntaxKind[SyntaxKind["TemplateTail"] = 17] = "TemplateTail";
        // Punctuation
        SyntaxKind[SyntaxKind["OpenBraceToken"] = 18] = "OpenBraceToken";
        SyntaxKind[SyntaxKind["CloseBraceToken"] = 19] = "CloseBraceToken";
        SyntaxKind[SyntaxKind["OpenParenToken"] = 20] = "OpenParenToken";
        SyntaxKind[SyntaxKind["CloseParenToken"] = 21] = "CloseParenToken";
        SyntaxKind[SyntaxKind["OpenBracketToken"] = 22] = "OpenBracketToken";
        SyntaxKind[SyntaxKind["CloseBracketToken"] = 23] = "CloseBracketToken";
        SyntaxKind[SyntaxKind["DotToken"] = 24] = "DotToken";
        SyntaxKind[SyntaxKind["DotDotDotToken"] = 25] = "DotDotDotToken";
        SyntaxKind[SyntaxKind["SemicolonToken"] = 26] = "SemicolonToken";
        SyntaxKind[SyntaxKind["CommaToken"] = 27] = "CommaToken";
        SyntaxKind[SyntaxKind["LessThanToken"] = 28] = "LessThanToken";
        SyntaxKind[SyntaxKind["LessThanSlashToken"] = 29] = "LessThanSlashToken";
        SyntaxKind[SyntaxKind["GreaterThanToken"] = 30] = "GreaterThanToken";
        SyntaxKind[SyntaxKind["LessThanEqualsToken"] = 31] = "LessThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanEqualsToken"] = 32] = "GreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["EqualsEqualsToken"] = 33] = "EqualsEqualsToken";
        SyntaxKind[SyntaxKind["ExclamationEqualsToken"] = 34] = "ExclamationEqualsToken";
        SyntaxKind[SyntaxKind["EqualsEqualsEqualsToken"] = 35] = "EqualsEqualsEqualsToken";
        SyntaxKind[SyntaxKind["ExclamationEqualsEqualsToken"] = 36] = "ExclamationEqualsEqualsToken";
        SyntaxKind[SyntaxKind["EqualsGreaterThanToken"] = 37] = "EqualsGreaterThanToken";
        SyntaxKind[SyntaxKind["PlusToken"] = 38] = "PlusToken";
        SyntaxKind[SyntaxKind["MinusToken"] = 39] = "MinusToken";
        SyntaxKind[SyntaxKind["AsteriskToken"] = 40] = "AsteriskToken";
        SyntaxKind[SyntaxKind["AsteriskAsteriskToken"] = 41] = "AsteriskAsteriskToken";
        SyntaxKind[SyntaxKind["SlashToken"] = 42] = "SlashToken";
        SyntaxKind[SyntaxKind["PercentToken"] = 43] = "PercentToken";
        SyntaxKind[SyntaxKind["PlusPlusToken"] = 44] = "PlusPlusToken";
        SyntaxKind[SyntaxKind["MinusMinusToken"] = 45] = "MinusMinusToken";
        SyntaxKind[SyntaxKind["LessThanLessThanToken"] = 46] = "LessThanLessThanToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanToken"] = 47] = "GreaterThanGreaterThanToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanToken"] = 48] = "GreaterThanGreaterThanGreaterThanToken";
        SyntaxKind[SyntaxKind["AmpersandToken"] = 49] = "AmpersandToken";
        SyntaxKind[SyntaxKind["BarToken"] = 50] = "BarToken";
        SyntaxKind[SyntaxKind["CaretToken"] = 51] = "CaretToken";
        SyntaxKind[SyntaxKind["ExclamationToken"] = 52] = "ExclamationToken";
        SyntaxKind[SyntaxKind["TildeToken"] = 53] = "TildeToken";
        SyntaxKind[SyntaxKind["AmpersandAmpersandToken"] = 54] = "AmpersandAmpersandToken";
        SyntaxKind[SyntaxKind["BarBarToken"] = 55] = "BarBarToken";
        SyntaxKind[SyntaxKind["QuestionToken"] = 56] = "QuestionToken";
        SyntaxKind[SyntaxKind["ColonToken"] = 57] = "ColonToken";
        SyntaxKind[SyntaxKind["AtToken"] = 58] = "AtToken";
        /** Only the JSDoc scanner produces BacktickToken. The normal scanner produces NoSubstitutionTemplateLiteral and related kinds. */
        SyntaxKind[SyntaxKind["BacktickToken"] = 59] = "BacktickToken";
        // Assignments
        SyntaxKind[SyntaxKind["EqualsToken"] = 60] = "EqualsToken";
        SyntaxKind[SyntaxKind["PlusEqualsToken"] = 61] = "PlusEqualsToken";
        SyntaxKind[SyntaxKind["MinusEqualsToken"] = 62] = "MinusEqualsToken";
        SyntaxKind[SyntaxKind["AsteriskEqualsToken"] = 63] = "AsteriskEqualsToken";
        SyntaxKind[SyntaxKind["AsteriskAsteriskEqualsToken"] = 64] = "AsteriskAsteriskEqualsToken";
        SyntaxKind[SyntaxKind["SlashEqualsToken"] = 65] = "SlashEqualsToken";
        SyntaxKind[SyntaxKind["PercentEqualsToken"] = 66] = "PercentEqualsToken";
        SyntaxKind[SyntaxKind["LessThanLessThanEqualsToken"] = 67] = "LessThanLessThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanEqualsToken"] = 68] = "GreaterThanGreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanEqualsToken"] = 69] = "GreaterThanGreaterThanGreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["AmpersandEqualsToken"] = 70] = "AmpersandEqualsToken";
        SyntaxKind[SyntaxKind["BarEqualsToken"] = 71] = "BarEqualsToken";
        SyntaxKind[SyntaxKind["CaretEqualsToken"] = 72] = "CaretEqualsToken";
        // Identifiers
        SyntaxKind[SyntaxKind["Identifier"] = 73] = "Identifier";
        // Reserved words
        SyntaxKind[SyntaxKind["BreakKeyword"] = 74] = "BreakKeyword";
        SyntaxKind[SyntaxKind["CaseKeyword"] = 75] = "CaseKeyword";
        SyntaxKind[SyntaxKind["CatchKeyword"] = 76] = "CatchKeyword";
        SyntaxKind[SyntaxKind["ClassKeyword"] = 77] = "ClassKeyword";
        SyntaxKind[SyntaxKind["ConstKeyword"] = 78] = "ConstKeyword";
        SyntaxKind[SyntaxKind["ContinueKeyword"] = 79] = "ContinueKeyword";
        SyntaxKind[SyntaxKind["DebuggerKeyword"] = 80] = "DebuggerKeyword";
        SyntaxKind[SyntaxKind["DefaultKeyword"] = 81] = "DefaultKeyword";
        SyntaxKind[SyntaxKind["DeleteKeyword"] = 82] = "DeleteKeyword";
        SyntaxKind[SyntaxKind["DoKeyword"] = 83] = "DoKeyword";
        SyntaxKind[SyntaxKind["ElseKeyword"] = 84] = "ElseKeyword";
        SyntaxKind[SyntaxKind["EnumKeyword"] = 85] = "EnumKeyword";
        SyntaxKind[SyntaxKind["ExportKeyword"] = 86] = "ExportKeyword";
        SyntaxKind[SyntaxKind["ExtendsKeyword"] = 87] = "ExtendsKeyword";
        SyntaxKind[SyntaxKind["FalseKeyword"] = 88] = "FalseKeyword";
        SyntaxKind[SyntaxKind["FinallyKeyword"] = 89] = "FinallyKeyword";
        SyntaxKind[SyntaxKind["ForKeyword"] = 90] = "ForKeyword";
        SyntaxKind[SyntaxKind["FunctionKeyword"] = 91] = "FunctionKeyword";
        SyntaxKind[SyntaxKind["IfKeyword"] = 92] = "IfKeyword";
        SyntaxKind[SyntaxKind["ImportKeyword"] = 93] = "ImportKeyword";
        SyntaxKind[SyntaxKind["InKeyword"] = 94] = "InKeyword";
        SyntaxKind[SyntaxKind["InstanceOfKeyword"] = 95] = "InstanceOfKeyword";
        SyntaxKind[SyntaxKind["NewKeyword"] = 96] = "NewKeyword";
        SyntaxKind[SyntaxKind["NullKeyword"] = 97] = "NullKeyword";
        SyntaxKind[SyntaxKind["ReturnKeyword"] = 98] = "ReturnKeyword";
        SyntaxKind[SyntaxKind["SuperKeyword"] = 99] = "SuperKeyword";
        SyntaxKind[SyntaxKind["SwitchKeyword"] = 100] = "SwitchKeyword";
        SyntaxKind[SyntaxKind["ThisKeyword"] = 101] = "ThisKeyword";
        SyntaxKind[SyntaxKind["ThrowKeyword"] = 102] = "ThrowKeyword";
        SyntaxKind[SyntaxKind["TrueKeyword"] = 103] = "TrueKeyword";
        SyntaxKind[SyntaxKind["TryKeyword"] = 104] = "TryKeyword";
        SyntaxKind[SyntaxKind["TypeOfKeyword"] = 105] = "TypeOfKeyword";
        SyntaxKind[SyntaxKind["VarKeyword"] = 106] = "VarKeyword";
        SyntaxKind[SyntaxKind["VoidKeyword"] = 107] = "VoidKeyword";
        SyntaxKind[SyntaxKind["WhileKeyword"] = 108] = "WhileKeyword";
        SyntaxKind[SyntaxKind["WithKeyword"] = 109] = "WithKeyword";
        // Strict mode reserved words
        SyntaxKind[SyntaxKind["ImplementsKeyword"] = 110] = "ImplementsKeyword";
        SyntaxKind[SyntaxKind["InterfaceKeyword"] = 111] = "InterfaceKeyword";
        SyntaxKind[SyntaxKind["LetKeyword"] = 112] = "LetKeyword";
        SyntaxKind[SyntaxKind["PackageKeyword"] = 113] = "PackageKeyword";
        SyntaxKind[SyntaxKind["PrivateKeyword"] = 114] = "PrivateKeyword";
        SyntaxKind[SyntaxKind["ProtectedKeyword"] = 115] = "ProtectedKeyword";
        SyntaxKind[SyntaxKind["PublicKeyword"] = 116] = "PublicKeyword";
        SyntaxKind[SyntaxKind["StaticKeyword"] = 117] = "StaticKeyword";
        SyntaxKind[SyntaxKind["YieldKeyword"] = 118] = "YieldKeyword";
        // Contextual keywords
        SyntaxKind[SyntaxKind["AbstractKeyword"] = 119] = "AbstractKeyword";
        SyntaxKind[SyntaxKind["AsKeyword"] = 120] = "AsKeyword";
        SyntaxKind[SyntaxKind["AnyKeyword"] = 121] = "AnyKeyword";
        SyntaxKind[SyntaxKind["AsyncKeyword"] = 122] = "AsyncKeyword";
        SyntaxKind[SyntaxKind["AwaitKeyword"] = 123] = "AwaitKeyword";
        SyntaxKind[SyntaxKind["BooleanKeyword"] = 124] = "BooleanKeyword";
        SyntaxKind[SyntaxKind["ConstructorKeyword"] = 125] = "ConstructorKeyword";
        SyntaxKind[SyntaxKind["DeclareKeyword"] = 126] = "DeclareKeyword";
        SyntaxKind[SyntaxKind["GetKeyword"] = 127] = "GetKeyword";
        SyntaxKind[SyntaxKind["InferKeyword"] = 128] = "InferKeyword";
        SyntaxKind[SyntaxKind["IsKeyword"] = 129] = "IsKeyword";
        SyntaxKind[SyntaxKind["KeyOfKeyword"] = 130] = "KeyOfKeyword";
        SyntaxKind[SyntaxKind["ModuleKeyword"] = 131] = "ModuleKeyword";
        SyntaxKind[SyntaxKind["NamespaceKeyword"] = 132] = "NamespaceKeyword";
        SyntaxKind[SyntaxKind["NeverKeyword"] = 133] = "NeverKeyword";
        SyntaxKind[SyntaxKind["ReadonlyKeyword"] = 134] = "ReadonlyKeyword";
        SyntaxKind[SyntaxKind["RequireKeyword"] = 135] = "RequireKeyword";
        SyntaxKind[SyntaxKind["NumberKeyword"] = 136] = "NumberKeyword";
        SyntaxKind[SyntaxKind["ObjectKeyword"] = 137] = "ObjectKeyword";
        SyntaxKind[SyntaxKind["SetKeyword"] = 138] = "SetKeyword";
        SyntaxKind[SyntaxKind["StringKeyword"] = 139] = "StringKeyword";
        SyntaxKind[SyntaxKind["SymbolKeyword"] = 140] = "SymbolKeyword";
        SyntaxKind[SyntaxKind["TypeKeyword"] = 141] = "TypeKeyword";
        SyntaxKind[SyntaxKind["UndefinedKeyword"] = 142] = "UndefinedKeyword";
        SyntaxKind[SyntaxKind["UniqueKeyword"] = 143] = "UniqueKeyword";
        SyntaxKind[SyntaxKind["UnknownKeyword"] = 144] = "UnknownKeyword";
        SyntaxKind[SyntaxKind["FromKeyword"] = 145] = "FromKeyword";
        SyntaxKind[SyntaxKind["GlobalKeyword"] = 146] = "GlobalKeyword";
        SyntaxKind[SyntaxKind["BigIntKeyword"] = 147] = "BigIntKeyword";
        SyntaxKind[SyntaxKind["OfKeyword"] = 148] = "OfKeyword";
        // Parse tree nodes
        // Names
        SyntaxKind[SyntaxKind["QualifiedName"] = 149] = "QualifiedName";
        SyntaxKind[SyntaxKind["ComputedPropertyName"] = 150] = "ComputedPropertyName";
        // Signature elements
        SyntaxKind[SyntaxKind["TypeParameter"] = 151] = "TypeParameter";
        SyntaxKind[SyntaxKind["Parameter"] = 152] = "Parameter";
        SyntaxKind[SyntaxKind["Decorator"] = 153] = "Decorator";
        // TypeMember
        SyntaxKind[SyntaxKind["PropertySignature"] = 154] = "PropertySignature";
        SyntaxKind[SyntaxKind["PropertyDeclaration"] = 155] = "PropertyDeclaration";
        SyntaxKind[SyntaxKind["MethodSignature"] = 156] = "MethodSignature";
        SyntaxKind[SyntaxKind["MethodDeclaration"] = 157] = "MethodDeclaration";
        SyntaxKind[SyntaxKind["Constructor"] = 158] = "Constructor";
        SyntaxKind[SyntaxKind["GetAccessor"] = 159] = "GetAccessor";
        SyntaxKind[SyntaxKind["SetAccessor"] = 160] = "SetAccessor";
        SyntaxKind[SyntaxKind["CallSignature"] = 161] = "CallSignature";
        SyntaxKind[SyntaxKind["ConstructSignature"] = 162] = "ConstructSignature";
        SyntaxKind[SyntaxKind["IndexSignature"] = 163] = "IndexSignature";
        // Type
        SyntaxKind[SyntaxKind["TypePredicate"] = 164] = "TypePredicate";
        SyntaxKind[SyntaxKind["TypeReference"] = 165] = "TypeReference";
        SyntaxKind[SyntaxKind["FunctionType"] = 166] = "FunctionType";
        SyntaxKind[SyntaxKind["ConstructorType"] = 167] = "ConstructorType";
        SyntaxKind[SyntaxKind["TypeQuery"] = 168] = "TypeQuery";
        SyntaxKind[SyntaxKind["TypeLiteral"] = 169] = "TypeLiteral";
        SyntaxKind[SyntaxKind["ArrayType"] = 170] = "ArrayType";
        SyntaxKind[SyntaxKind["TupleType"] = 171] = "TupleType";
        SyntaxKind[SyntaxKind["OptionalType"] = 172] = "OptionalType";
        SyntaxKind[SyntaxKind["RestType"] = 173] = "RestType";
        SyntaxKind[SyntaxKind["UnionType"] = 174] = "UnionType";
        SyntaxKind[SyntaxKind["IntersectionType"] = 175] = "IntersectionType";
        SyntaxKind[SyntaxKind["ConditionalType"] = 176] = "ConditionalType";
        SyntaxKind[SyntaxKind["InferType"] = 177] = "InferType";
        SyntaxKind[SyntaxKind["ParenthesizedType"] = 178] = "ParenthesizedType";
        SyntaxKind[SyntaxKind["ThisType"] = 179] = "ThisType";
        SyntaxKind[SyntaxKind["TypeOperator"] = 180] = "TypeOperator";
        SyntaxKind[SyntaxKind["IndexedAccessType"] = 181] = "IndexedAccessType";
        SyntaxKind[SyntaxKind["MappedType"] = 182] = "MappedType";
        SyntaxKind[SyntaxKind["LiteralType"] = 183] = "LiteralType";
        SyntaxKind[SyntaxKind["ImportType"] = 184] = "ImportType";
        // Binding patterns
        SyntaxKind[SyntaxKind["ObjectBindingPattern"] = 185] = "ObjectBindingPattern";
        SyntaxKind[SyntaxKind["ArrayBindingPattern"] = 186] = "ArrayBindingPattern";
        SyntaxKind[SyntaxKind["BindingElement"] = 187] = "BindingElement";
        // Expression
        SyntaxKind[SyntaxKind["ArrayLiteralExpression"] = 188] = "ArrayLiteralExpression";
        SyntaxKind[SyntaxKind["ObjectLiteralExpression"] = 189] = "ObjectLiteralExpression";
        SyntaxKind[SyntaxKind["PropertyAccessExpression"] = 190] = "PropertyAccessExpression";
        SyntaxKind[SyntaxKind["ElementAccessExpression"] = 191] = "ElementAccessExpression";
        SyntaxKind[SyntaxKind["CallExpression"] = 192] = "CallExpression";
        SyntaxKind[SyntaxKind["NewExpression"] = 193] = "NewExpression";
        SyntaxKind[SyntaxKind["TaggedTemplateExpression"] = 194] = "TaggedTemplateExpression";
        SyntaxKind[SyntaxKind["TypeAssertionExpression"] = 195] = "TypeAssertionExpression";
        SyntaxKind[SyntaxKind["ParenthesizedExpression"] = 196] = "ParenthesizedExpression";
        SyntaxKind[SyntaxKind["FunctionExpression"] = 197] = "FunctionExpression";
        SyntaxKind[SyntaxKind["ArrowFunction"] = 198] = "ArrowFunction";
        SyntaxKind[SyntaxKind["DeleteExpression"] = 199] = "DeleteExpression";
        SyntaxKind[SyntaxKind["TypeOfExpression"] = 200] = "TypeOfExpression";
        SyntaxKind[SyntaxKind["VoidExpression"] = 201] = "VoidExpression";
        SyntaxKind[SyntaxKind["AwaitExpression"] = 202] = "AwaitExpression";
        SyntaxKind[SyntaxKind["PrefixUnaryExpression"] = 203] = "PrefixUnaryExpression";
        SyntaxKind[SyntaxKind["PostfixUnaryExpression"] = 204] = "PostfixUnaryExpression";
        SyntaxKind[SyntaxKind["BinaryExpression"] = 205] = "BinaryExpression";
        SyntaxKind[SyntaxKind["ConditionalExpression"] = 206] = "ConditionalExpression";
        SyntaxKind[SyntaxKind["TemplateExpression"] = 207] = "TemplateExpression";
        SyntaxKind[SyntaxKind["YieldExpression"] = 208] = "YieldExpression";
        SyntaxKind[SyntaxKind["SpreadElement"] = 209] = "SpreadElement";
        SyntaxKind[SyntaxKind["ClassExpression"] = 210] = "ClassExpression";
        SyntaxKind[SyntaxKind["OmittedExpression"] = 211] = "OmittedExpression";
        SyntaxKind[SyntaxKind["ExpressionWithTypeArguments"] = 212] = "ExpressionWithTypeArguments";
        SyntaxKind[SyntaxKind["AsExpression"] = 213] = "AsExpression";
        SyntaxKind[SyntaxKind["NonNullExpression"] = 214] = "NonNullExpression";
        SyntaxKind[SyntaxKind["MetaProperty"] = 215] = "MetaProperty";
        SyntaxKind[SyntaxKind["SyntheticExpression"] = 216] = "SyntheticExpression";
        // Misc
        SyntaxKind[SyntaxKind["TemplateSpan"] = 217] = "TemplateSpan";
        SyntaxKind[SyntaxKind["SemicolonClassElement"] = 218] = "SemicolonClassElement";
        // Element
        SyntaxKind[SyntaxKind["Block"] = 219] = "Block";
        SyntaxKind[SyntaxKind["VariableStatement"] = 220] = "VariableStatement";
        SyntaxKind[SyntaxKind["EmptyStatement"] = 221] = "EmptyStatement";
        SyntaxKind[SyntaxKind["ExpressionStatement"] = 222] = "ExpressionStatement";
        SyntaxKind[SyntaxKind["IfStatement"] = 223] = "IfStatement";
        SyntaxKind[SyntaxKind["DoStatement"] = 224] = "DoStatement";
        SyntaxKind[SyntaxKind["WhileStatement"] = 225] = "WhileStatement";
        SyntaxKind[SyntaxKind["ForStatement"] = 226] = "ForStatement";
        SyntaxKind[SyntaxKind["ForInStatement"] = 227] = "ForInStatement";
        SyntaxKind[SyntaxKind["ForOfStatement"] = 228] = "ForOfStatement";
        SyntaxKind[SyntaxKind["ContinueStatement"] = 229] = "ContinueStatement";
        SyntaxKind[SyntaxKind["BreakStatement"] = 230] = "BreakStatement";
        SyntaxKind[SyntaxKind["ReturnStatement"] = 231] = "ReturnStatement";
        SyntaxKind[SyntaxKind["WithStatement"] = 232] = "WithStatement";
        SyntaxKind[SyntaxKind["SwitchStatement"] = 233] = "SwitchStatement";
        SyntaxKind[SyntaxKind["LabeledStatement"] = 234] = "LabeledStatement";
        SyntaxKind[SyntaxKind["ThrowStatement"] = 235] = "ThrowStatement";
        SyntaxKind[SyntaxKind["TryStatement"] = 236] = "TryStatement";
        SyntaxKind[SyntaxKind["DebuggerStatement"] = 237] = "DebuggerStatement";
        SyntaxKind[SyntaxKind["VariableDeclaration"] = 238] = "VariableDeclaration";
        SyntaxKind[SyntaxKind["VariableDeclarationList"] = 239] = "VariableDeclarationList";
        SyntaxKind[SyntaxKind["FunctionDeclaration"] = 240] = "FunctionDeclaration";
        SyntaxKind[SyntaxKind["ClassDeclaration"] = 241] = "ClassDeclaration";
        SyntaxKind[SyntaxKind["InterfaceDeclaration"] = 242] = "InterfaceDeclaration";
        SyntaxKind[SyntaxKind["TypeAliasDeclaration"] = 243] = "TypeAliasDeclaration";
        SyntaxKind[SyntaxKind["EnumDeclaration"] = 244] = "EnumDeclaration";
        SyntaxKind[SyntaxKind["ModuleDeclaration"] = 245] = "ModuleDeclaration";
        SyntaxKind[SyntaxKind["ModuleBlock"] = 246] = "ModuleBlock";
        SyntaxKind[SyntaxKind["CaseBlock"] = 247] = "CaseBlock";
        SyntaxKind[SyntaxKind["NamespaceExportDeclaration"] = 248] = "NamespaceExportDeclaration";
        SyntaxKind[SyntaxKind["ImportEqualsDeclaration"] = 249] = "ImportEqualsDeclaration";
        SyntaxKind[SyntaxKind["ImportDeclaration"] = 250] = "ImportDeclaration";
        SyntaxKind[SyntaxKind["ImportClause"] = 251] = "ImportClause";
        SyntaxKind[SyntaxKind["NamespaceImport"] = 252] = "NamespaceImport";
        SyntaxKind[SyntaxKind["NamedImports"] = 253] = "NamedImports";
        SyntaxKind[SyntaxKind["ImportSpecifier"] = 254] = "ImportSpecifier";
        SyntaxKind[SyntaxKind["ExportAssignment"] = 255] = "ExportAssignment";
        SyntaxKind[SyntaxKind["ExportDeclaration"] = 256] = "ExportDeclaration";
        SyntaxKind[SyntaxKind["NamedExports"] = 257] = "NamedExports";
        SyntaxKind[SyntaxKind["ExportSpecifier"] = 258] = "ExportSpecifier";
        SyntaxKind[SyntaxKind["MissingDeclaration"] = 259] = "MissingDeclaration";
        // Module references
        SyntaxKind[SyntaxKind["ExternalModuleReference"] = 260] = "ExternalModuleReference";
        // JSX
        SyntaxKind[SyntaxKind["JsxElement"] = 261] = "JsxElement";
        SyntaxKind[SyntaxKind["JsxSelfClosingElement"] = 262] = "JsxSelfClosingElement";
        SyntaxKind[SyntaxKind["JsxOpeningElement"] = 263] = "JsxOpeningElement";
        SyntaxKind[SyntaxKind["JsxClosingElement"] = 264] = "JsxClosingElement";
        SyntaxKind[SyntaxKind["JsxFragment"] = 265] = "JsxFragment";
        SyntaxKind[SyntaxKind["JsxOpeningFragment"] = 266] = "JsxOpeningFragment";
        SyntaxKind[SyntaxKind["JsxClosingFragment"] = 267] = "JsxClosingFragment";
        SyntaxKind[SyntaxKind["JsxAttribute"] = 268] = "JsxAttribute";
        SyntaxKind[SyntaxKind["JsxAttributes"] = 269] = "JsxAttributes";
        SyntaxKind[SyntaxKind["JsxSpreadAttribute"] = 270] = "JsxSpreadAttribute";
        SyntaxKind[SyntaxKind["JsxExpression"] = 271] = "JsxExpression";
        // Clauses
        SyntaxKind[SyntaxKind["CaseClause"] = 272] = "CaseClause";
        SyntaxKind[SyntaxKind["DefaultClause"] = 273] = "DefaultClause";
        SyntaxKind[SyntaxKind["HeritageClause"] = 274] = "HeritageClause";
        SyntaxKind[SyntaxKind["CatchClause"] = 275] = "CatchClause";
        // Property assignments
        SyntaxKind[SyntaxKind["PropertyAssignment"] = 276] = "PropertyAssignment";
        SyntaxKind[SyntaxKind["ShorthandPropertyAssignment"] = 277] = "ShorthandPropertyAssignment";
        SyntaxKind[SyntaxKind["SpreadAssignment"] = 278] = "SpreadAssignment";
        // Enum
        SyntaxKind[SyntaxKind["EnumMember"] = 279] = "EnumMember";
        // Unparsed
        SyntaxKind[SyntaxKind["UnparsedPrologue"] = 280] = "UnparsedPrologue";
        SyntaxKind[SyntaxKind["UnparsedPrepend"] = 281] = "UnparsedPrepend";
        SyntaxKind[SyntaxKind["UnparsedText"] = 282] = "UnparsedText";
        SyntaxKind[SyntaxKind["UnparsedInternalText"] = 283] = "UnparsedInternalText";
        SyntaxKind[SyntaxKind["UnparsedSyntheticReference"] = 284] = "UnparsedSyntheticReference";
        // Top-level nodes
        SyntaxKind[SyntaxKind["SourceFile"] = 285] = "SourceFile";
        SyntaxKind[SyntaxKind["Bundle"] = 286] = "Bundle";
        SyntaxKind[SyntaxKind["UnparsedSource"] = 287] = "UnparsedSource";
        SyntaxKind[SyntaxKind["InputFiles"] = 288] = "InputFiles";
        // JSDoc nodes
        SyntaxKind[SyntaxKind["JSDocTypeExpression"] = 289] = "JSDocTypeExpression";
        // The * type
        SyntaxKind[SyntaxKind["JSDocAllType"] = 290] = "JSDocAllType";
        // The ? type
        SyntaxKind[SyntaxKind["JSDocUnknownType"] = 291] = "JSDocUnknownType";
        SyntaxKind[SyntaxKind["JSDocNullableType"] = 292] = "JSDocNullableType";
        SyntaxKind[SyntaxKind["JSDocNonNullableType"] = 293] = "JSDocNonNullableType";
        SyntaxKind[SyntaxKind["JSDocOptionalType"] = 294] = "JSDocOptionalType";
        SyntaxKind[SyntaxKind["JSDocFunctionType"] = 295] = "JSDocFunctionType";
        SyntaxKind[SyntaxKind["JSDocVariadicType"] = 296] = "JSDocVariadicType";
        SyntaxKind[SyntaxKind["JSDocComment"] = 297] = "JSDocComment";
        SyntaxKind[SyntaxKind["JSDocTypeLiteral"] = 298] = "JSDocTypeLiteral";
        SyntaxKind[SyntaxKind["JSDocSignature"] = 299] = "JSDocSignature";
        SyntaxKind[SyntaxKind["JSDocTag"] = 300] = "JSDocTag";
        SyntaxKind[SyntaxKind["JSDocAugmentsTag"] = 301] = "JSDocAugmentsTag";
        SyntaxKind[SyntaxKind["JSDocClassTag"] = 302] = "JSDocClassTag";
        SyntaxKind[SyntaxKind["JSDocCallbackTag"] = 303] = "JSDocCallbackTag";
        SyntaxKind[SyntaxKind["JSDocEnumTag"] = 304] = "JSDocEnumTag";
        SyntaxKind[SyntaxKind["JSDocParameterTag"] = 305] = "JSDocParameterTag";
        SyntaxKind[SyntaxKind["JSDocReturnTag"] = 306] = "JSDocReturnTag";
        SyntaxKind[SyntaxKind["JSDocThisTag"] = 307] = "JSDocThisTag";
        SyntaxKind[SyntaxKind["JSDocTypeTag"] = 308] = "JSDocTypeTag";
        SyntaxKind[SyntaxKind["JSDocTemplateTag"] = 309] = "JSDocTemplateTag";
        SyntaxKind[SyntaxKind["JSDocTypedefTag"] = 310] = "JSDocTypedefTag";
        SyntaxKind[SyntaxKind["JSDocPropertyTag"] = 311] = "JSDocPropertyTag";
        // Synthesized list
        SyntaxKind[SyntaxKind["SyntaxList"] = 312] = "SyntaxList";
        // Transformation nodes
        SyntaxKind[SyntaxKind["NotEmittedStatement"] = 313] = "NotEmittedStatement";
        SyntaxKind[SyntaxKind["PartiallyEmittedExpression"] = 314] = "PartiallyEmittedExpression";
        SyntaxKind[SyntaxKind["CommaListExpression"] = 315] = "CommaListExpression";
        SyntaxKind[SyntaxKind["MergeDeclarationMarker"] = 316] = "MergeDeclarationMarker";
        SyntaxKind[SyntaxKind["EndOfDeclarationMarker"] = 317] = "EndOfDeclarationMarker";
        // Enum value count
        SyntaxKind[SyntaxKind["Count"] = 318] = "Count";
        // Markers
        SyntaxKind[SyntaxKind["FirstAssignment"] = 60] = "FirstAssignment";
        SyntaxKind[SyntaxKind["LastAssignment"] = 72] = "LastAssignment";
        SyntaxKind[SyntaxKind["FirstCompoundAssignment"] = 61] = "FirstCompoundAssignment";
        SyntaxKind[SyntaxKind["LastCompoundAssignment"] = 72] = "LastCompoundAssignment";
        SyntaxKind[SyntaxKind["FirstReservedWord"] = 74] = "FirstReservedWord";
        SyntaxKind[SyntaxKind["LastReservedWord"] = 109] = "LastReservedWord";
        SyntaxKind[SyntaxKind["FirstKeyword"] = 74] = "FirstKeyword";
        SyntaxKind[SyntaxKind["LastKeyword"] = 148] = "LastKeyword";
        SyntaxKind[SyntaxKind["FirstFutureReservedWord"] = 110] = "FirstFutureReservedWord";
        SyntaxKind[SyntaxKind["LastFutureReservedWord"] = 118] = "LastFutureReservedWord";
        SyntaxKind[SyntaxKind["FirstTypeNode"] = 164] = "FirstTypeNode";
        SyntaxKind[SyntaxKind["LastTypeNode"] = 184] = "LastTypeNode";
        SyntaxKind[SyntaxKind["FirstPunctuation"] = 18] = "FirstPunctuation";
        SyntaxKind[SyntaxKind["LastPunctuation"] = 72] = "LastPunctuation";
        SyntaxKind[SyntaxKind["FirstToken"] = 0] = "FirstToken";
        SyntaxKind[SyntaxKind["LastToken"] = 148] = "LastToken";
        SyntaxKind[SyntaxKind["FirstTriviaToken"] = 2] = "FirstTriviaToken";
        SyntaxKind[SyntaxKind["LastTriviaToken"] = 7] = "LastTriviaToken";
        SyntaxKind[SyntaxKind["FirstLiteralToken"] = 8] = "FirstLiteralToken";
        SyntaxKind[SyntaxKind["LastLiteralToken"] = 14] = "LastLiteralToken";
        SyntaxKind[SyntaxKind["FirstTemplateToken"] = 14] = "FirstTemplateToken";
        SyntaxKind[SyntaxKind["LastTemplateToken"] = 17] = "LastTemplateToken";
        SyntaxKind[SyntaxKind["FirstBinaryOperator"] = 28] = "FirstBinaryOperator";
        SyntaxKind[SyntaxKind["LastBinaryOperator"] = 72] = "LastBinaryOperator";
        SyntaxKind[SyntaxKind["FirstNode"] = 149] = "FirstNode";
        SyntaxKind[SyntaxKind["FirstJSDocNode"] = 289] = "FirstJSDocNode";
        SyntaxKind[SyntaxKind["LastJSDocNode"] = 311] = "LastJSDocNode";
        SyntaxKind[SyntaxKind["FirstJSDocTagNode"] = 300] = "FirstJSDocTagNode";
        SyntaxKind[SyntaxKind["LastJSDocTagNode"] = 311] = "LastJSDocTagNode";
        /* @internal */ SyntaxKind[SyntaxKind["FirstContextualKeyword"] = 119] = "FirstContextualKeyword";
        /* @internal */ SyntaxKind[SyntaxKind["LastContextualKeyword"] = 148] = "LastContextualKeyword";
    })(SyntaxKind = ts.SyntaxKind || (ts.SyntaxKind = {}));
    var NodeFlags;
    (function (NodeFlags) {
        NodeFlags[NodeFlags["None"] = 0] = "None";
        NodeFlags[NodeFlags["Let"] = 1] = "Let";
        NodeFlags[NodeFlags["Const"] = 2] = "Const";
        NodeFlags[NodeFlags["NestedNamespace"] = 4] = "NestedNamespace";
        NodeFlags[NodeFlags["Synthesized"] = 8] = "Synthesized";
        NodeFlags[NodeFlags["Namespace"] = 16] = "Namespace";
        NodeFlags[NodeFlags["ExportContext"] = 32] = "ExportContext";
        NodeFlags[NodeFlags["ContainsThis"] = 64] = "ContainsThis";
        NodeFlags[NodeFlags["HasImplicitReturn"] = 128] = "HasImplicitReturn";
        NodeFlags[NodeFlags["HasExplicitReturn"] = 256] = "HasExplicitReturn";
        NodeFlags[NodeFlags["GlobalAugmentation"] = 512] = "GlobalAugmentation";
        NodeFlags[NodeFlags["HasAsyncFunctions"] = 1024] = "HasAsyncFunctions";
        NodeFlags[NodeFlags["DisallowInContext"] = 2048] = "DisallowInContext";
        NodeFlags[NodeFlags["YieldContext"] = 4096] = "YieldContext";
        NodeFlags[NodeFlags["DecoratorContext"] = 8192] = "DecoratorContext";
        NodeFlags[NodeFlags["AwaitContext"] = 16384] = "AwaitContext";
        NodeFlags[NodeFlags["ThisNodeHasError"] = 32768] = "ThisNodeHasError";
        NodeFlags[NodeFlags["JavaScriptFile"] = 65536] = "JavaScriptFile";
        NodeFlags[NodeFlags["ThisNodeOrAnySubNodesHasError"] = 131072] = "ThisNodeOrAnySubNodesHasError";
        NodeFlags[NodeFlags["HasAggregatedChildData"] = 262144] = "HasAggregatedChildData";
        // These flags will be set when the parser encounters a dynamic import expression or 'import.meta' to avoid
        // walking the tree if the flags are not set. However, these flags are just a approximation
        // (hence why it's named "PossiblyContainsDynamicImport") because once set, the flags never get cleared.
        // During editing, if a dynamic import is removed, incremental parsing will *NOT* clear this flag.
        // This means that the tree will always be traversed during module resolution, or when looking for external module indicators.
        // However, the removal operation should not occur often and in the case of the
        // removal, it is likely that users will add the import anyway.
        // The advantage of this approach is its simplicity. For the case of batch compilation,
        // we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used.
        /* @internal */ NodeFlags[NodeFlags["PossiblyContainsDynamicImport"] = 524288] = "PossiblyContainsDynamicImport";
        /* @internal */ NodeFlags[NodeFlags["PossiblyContainsImportMeta"] = 1048576] = "PossiblyContainsImportMeta";
        NodeFlags[NodeFlags["JSDoc"] = 2097152] = "JSDoc";
        /* @internal */ NodeFlags[NodeFlags["Ambient"] = 4194304] = "Ambient";
        /* @internal */ NodeFlags[NodeFlags["InWithStatement"] = 8388608] = "InWithStatement";
        NodeFlags[NodeFlags["JsonFile"] = 16777216] = "JsonFile";
        NodeFlags[NodeFlags["BlockScoped"] = 3] = "BlockScoped";
        NodeFlags[NodeFlags["ReachabilityCheckFlags"] = 384] = "ReachabilityCheckFlags";
        NodeFlags[NodeFlags["ReachabilityAndEmitFlags"] = 1408] = "ReachabilityAndEmitFlags";
        // Parsing context flags
        NodeFlags[NodeFlags["ContextFlags"] = 12679168] = "ContextFlags";
        // Exclude these flags when parsing a Type
        NodeFlags[NodeFlags["TypeExcludesFlags"] = 20480] = "TypeExcludesFlags";
        // Represents all flags that are potentially set once and
        // never cleared on SourceFiles which get re-used in between incremental parses.
        // See the comment above on `PossiblyContainsDynamicImport` and `PossiblyContainsImportMeta`.
        /* @internal */ NodeFlags[NodeFlags["PermanentlySetIncrementalFlags"] = 1572864] = "PermanentlySetIncrementalFlags";
    })(NodeFlags = ts.NodeFlags || (ts.NodeFlags = {}));
    var ModifierFlags;
    (function (ModifierFlags) {
        ModifierFlags[ModifierFlags["None"] = 0] = "None";
        ModifierFlags[ModifierFlags["Export"] = 1] = "Export";
        ModifierFlags[ModifierFlags["Ambient"] = 2] = "Ambient";
        ModifierFlags[ModifierFlags["Public"] = 4] = "Public";
        ModifierFlags[ModifierFlags["Private"] = 8] = "Private";
        ModifierFlags[ModifierFlags["Protected"] = 16] = "Protected";
        ModifierFlags[ModifierFlags["Static"] = 32] = "Static";
        ModifierFlags[ModifierFlags["Readonly"] = 64] = "Readonly";
        ModifierFlags[ModifierFlags["Abstract"] = 128] = "Abstract";
        ModifierFlags[ModifierFlags["Async"] = 256] = "Async";
        ModifierFlags[ModifierFlags["Default"] = 512] = "Default";
        ModifierFlags[ModifierFlags["Const"] = 2048] = "Const";
        ModifierFlags[ModifierFlags["HasComputedFlags"] = 536870912] = "HasComputedFlags";
        ModifierFlags[ModifierFlags["AccessibilityModifier"] = 28] = "AccessibilityModifier";
        // Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property.
        ModifierFlags[ModifierFlags["ParameterPropertyModifier"] = 92] = "ParameterPropertyModifier";
        ModifierFlags[ModifierFlags["NonPublicAccessibilityModifier"] = 24] = "NonPublicAccessibilityModifier";
        ModifierFlags[ModifierFlags["TypeScriptModifier"] = 2270] = "TypeScriptModifier";
        ModifierFlags[ModifierFlags["ExportDefault"] = 513] = "ExportDefault";
        ModifierFlags[ModifierFlags["All"] = 3071] = "All";
    })(ModifierFlags = ts.ModifierFlags || (ts.ModifierFlags = {}));
    var JsxFlags;
    (function (JsxFlags) {
        JsxFlags[JsxFlags["None"] = 0] = "None";
        /** An element from a named property of the JSX.IntrinsicElements interface */
        JsxFlags[JsxFlags["IntrinsicNamedElement"] = 1] = "IntrinsicNamedElement";
        /** An element inferred from the string index signature of the JSX.IntrinsicElements interface */
        JsxFlags[JsxFlags["IntrinsicIndexedElement"] = 2] = "IntrinsicIndexedElement";
        JsxFlags[JsxFlags["IntrinsicElement"] = 3] = "IntrinsicElement";
    })(JsxFlags = ts.JsxFlags || (ts.JsxFlags = {}));
    /* @internal */
    var RelationComparisonResult;
    (function (RelationComparisonResult) {
        RelationComparisonResult[RelationComparisonResult["Succeeded"] = 1] = "Succeeded";
        RelationComparisonResult[RelationComparisonResult["Failed"] = 2] = "Failed";
        RelationComparisonResult[RelationComparisonResult["FailedAndReported"] = 3] = "FailedAndReported";
    })(RelationComparisonResult = ts.RelationComparisonResult || (ts.RelationComparisonResult = {}));
    /*@internal*/
    var GeneratedIdentifierFlags;
    (function (GeneratedIdentifierFlags) {
        // Kinds
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["None"] = 0] = "None";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["Auto"] = 1] = "Auto";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["Loop"] = 2] = "Loop";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["Unique"] = 3] = "Unique";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["Node"] = 4] = "Node";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["KindMask"] = 7] = "KindMask";
        // Flags
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["ReservedInNestedScopes"] = 8] = "ReservedInNestedScopes";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["Optimistic"] = 16] = "Optimistic";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["FileLevel"] = 32] = "FileLevel";
    })(GeneratedIdentifierFlags = ts.GeneratedIdentifierFlags || (ts.GeneratedIdentifierFlags = {}));
    var TokenFlags;
    (function (TokenFlags) {
        TokenFlags[TokenFlags["None"] = 0] = "None";
        /* @internal */
        TokenFlags[TokenFlags["PrecedingLineBreak"] = 1] = "PrecedingLineBreak";
        /* @internal */
        TokenFlags[TokenFlags["PrecedingJSDocComment"] = 2] = "PrecedingJSDocComment";
        /* @internal */
        TokenFlags[TokenFlags["Unterminated"] = 4] = "Unterminated";
        /* @internal */
        TokenFlags[TokenFlags["ExtendedUnicodeEscape"] = 8] = "ExtendedUnicodeEscape";
        TokenFlags[TokenFlags["Scientific"] = 16] = "Scientific";
        TokenFlags[TokenFlags["Octal"] = 32] = "Octal";
        TokenFlags[TokenFlags["HexSpecifier"] = 64] = "HexSpecifier";
        TokenFlags[TokenFlags["BinarySpecifier"] = 128] = "BinarySpecifier";
        TokenFlags[TokenFlags["OctalSpecifier"] = 256] = "OctalSpecifier";
        /* @internal */
        TokenFlags[TokenFlags["ContainsSeparator"] = 512] = "ContainsSeparator";
        /* @internal */
        TokenFlags[TokenFlags["BinaryOrOctalSpecifier"] = 384] = "BinaryOrOctalSpecifier";
        /* @internal */
        TokenFlags[TokenFlags["NumericLiteralFlags"] = 1008] = "NumericLiteralFlags";
    })(TokenFlags = ts.TokenFlags || (ts.TokenFlags = {}));
    var FlowFlags;
    (function (FlowFlags) {
        FlowFlags[FlowFlags["Unreachable"] = 1] = "Unreachable";
        FlowFlags[FlowFlags["Start"] = 2] = "Start";
        FlowFlags[FlowFlags["BranchLabel"] = 4] = "BranchLabel";
        FlowFlags[FlowFlags["LoopLabel"] = 8] = "LoopLabel";
        FlowFlags[FlowFlags["Assignment"] = 16] = "Assignment";
        FlowFlags[FlowFlags["TrueCondition"] = 32] = "TrueCondition";
        FlowFlags[FlowFlags["FalseCondition"] = 64] = "FalseCondition";
        FlowFlags[FlowFlags["SwitchClause"] = 128] = "SwitchClause";
        FlowFlags[FlowFlags["ArrayMutation"] = 256] = "ArrayMutation";
        FlowFlags[FlowFlags["Referenced"] = 512] = "Referenced";
        FlowFlags[FlowFlags["Shared"] = 1024] = "Shared";
        FlowFlags[FlowFlags["PreFinally"] = 2048] = "PreFinally";
        FlowFlags[FlowFlags["AfterFinally"] = 4096] = "AfterFinally";
        /** @internal */
        FlowFlags[FlowFlags["Cached"] = 8192] = "Cached";
        FlowFlags[FlowFlags["Label"] = 12] = "Label";
        FlowFlags[FlowFlags["Condition"] = 96] = "Condition";
    })(FlowFlags = ts.FlowFlags || (ts.FlowFlags = {}));
    var OperationCanceledException = /** @class */ (function () {
        function OperationCanceledException() {
        }
        return OperationCanceledException;
    }());
    ts.OperationCanceledException = OperationCanceledException;
    /* @internal */
    var StructureIsReused;
    (function (StructureIsReused) {
        StructureIsReused[StructureIsReused["Not"] = 0] = "Not";
        StructureIsReused[StructureIsReused["SafeModules"] = 1] = "SafeModules";
        StructureIsReused[StructureIsReused["Completely"] = 2] = "Completely";
    })(StructureIsReused = ts.StructureIsReused || (ts.StructureIsReused = {}));
    /** Return code used by getEmitOutput function to indicate status of the function */
    var ExitStatus;
    (function (ExitStatus) {
        // Compiler ran successfully.  Either this was a simple do-nothing compilation (for example,
        // when -version or -help was provided, or this was a normal compilation, no diagnostics
        // were produced, and all outputs were generated successfully.
        ExitStatus[ExitStatus["Success"] = 0] = "Success";
        // Diagnostics were produced and because of them no code was generated.
        ExitStatus[ExitStatus["DiagnosticsPresent_OutputsSkipped"] = 1] = "DiagnosticsPresent_OutputsSkipped";
        // Diagnostics were produced and outputs were generated in spite of them.
        ExitStatus[ExitStatus["DiagnosticsPresent_OutputsGenerated"] = 2] = "DiagnosticsPresent_OutputsGenerated";
    })(ExitStatus = ts.ExitStatus || (ts.ExitStatus = {}));
    /* @internal */
    var UnionReduction;
    (function (UnionReduction) {
        UnionReduction[UnionReduction["None"] = 0] = "None";
        UnionReduction[UnionReduction["Literal"] = 1] = "Literal";
        UnionReduction[UnionReduction["Subtype"] = 2] = "Subtype";
    })(UnionReduction = ts.UnionReduction || (ts.UnionReduction = {}));
    // NOTE: If modifying this enum, must modify `TypeFormatFlags` too!
    var NodeBuilderFlags;
    (function (NodeBuilderFlags) {
        NodeBuilderFlags[NodeBuilderFlags["None"] = 0] = "None";
        // Options
        NodeBuilderFlags[NodeBuilderFlags["NoTruncation"] = 1] = "NoTruncation";
        NodeBuilderFlags[NodeBuilderFlags["WriteArrayAsGenericType"] = 2] = "WriteArrayAsGenericType";
        NodeBuilderFlags[NodeBuilderFlags["GenerateNamesForShadowedTypeParams"] = 4] = "GenerateNamesForShadowedTypeParams";
        NodeBuilderFlags[NodeBuilderFlags["UseStructuralFallback"] = 8] = "UseStructuralFallback";
        NodeBuilderFlags[NodeBuilderFlags["ForbidIndexedAccessSymbolReferences"] = 16] = "ForbidIndexedAccessSymbolReferences";
        NodeBuilderFlags[NodeBuilderFlags["WriteTypeArgumentsOfSignature"] = 32] = "WriteTypeArgumentsOfSignature";
        NodeBuilderFlags[NodeBuilderFlags["UseFullyQualifiedType"] = 64] = "UseFullyQualifiedType";
        NodeBuilderFlags[NodeBuilderFlags["UseOnlyExternalAliasing"] = 128] = "UseOnlyExternalAliasing";
        NodeBuilderFlags[NodeBuilderFlags["SuppressAnyReturnType"] = 256] = "SuppressAnyReturnType";
        NodeBuilderFlags[NodeBuilderFlags["WriteTypeParametersInQualifiedName"] = 512] = "WriteTypeParametersInQualifiedName";
        NodeBuilderFlags[NodeBuilderFlags["MultilineObjectLiterals"] = 1024] = "MultilineObjectLiterals";
        NodeBuilderFlags[NodeBuilderFlags["WriteClassExpressionAsTypeLiteral"] = 2048] = "WriteClassExpressionAsTypeLiteral";
        NodeBuilderFlags[NodeBuilderFlags["UseTypeOfFunction"] = 4096] = "UseTypeOfFunction";
        NodeBuilderFlags[NodeBuilderFlags["OmitParameterModifiers"] = 8192] = "OmitParameterModifiers";
        NodeBuilderFlags[NodeBuilderFlags["UseAliasDefinedOutsideCurrentScope"] = 16384] = "UseAliasDefinedOutsideCurrentScope";
        // Error handling
        NodeBuilderFlags[NodeBuilderFlags["AllowThisInObjectLiteral"] = 32768] = "AllowThisInObjectLiteral";
        NodeBuilderFlags[NodeBuilderFlags["AllowQualifedNameInPlaceOfIdentifier"] = 65536] = "AllowQualifedNameInPlaceOfIdentifier";
        NodeBuilderFlags[NodeBuilderFlags["AllowAnonymousIdentifier"] = 131072] = "AllowAnonymousIdentifier";
        NodeBuilderFlags[NodeBuilderFlags["AllowEmptyUnionOrIntersection"] = 262144] = "AllowEmptyUnionOrIntersection";
        NodeBuilderFlags[NodeBuilderFlags["AllowEmptyTuple"] = 524288] = "AllowEmptyTuple";
        NodeBuilderFlags[NodeBuilderFlags["AllowUniqueESSymbolType"] = 1048576] = "AllowUniqueESSymbolType";
        NodeBuilderFlags[NodeBuilderFlags["AllowEmptyIndexInfoType"] = 2097152] = "AllowEmptyIndexInfoType";
        // Errors (cont.)
        NodeBuilderFlags[NodeBuilderFlags["AllowNodeModulesRelativePaths"] = 67108864] = "AllowNodeModulesRelativePaths";
        /* @internal */ NodeBuilderFlags[NodeBuilderFlags["DoNotIncludeSymbolChain"] = 134217728] = "DoNotIncludeSymbolChain";
        NodeBuilderFlags[NodeBuilderFlags["IgnoreErrors"] = 70221824] = "IgnoreErrors";
        // State
        NodeBuilderFlags[NodeBuilderFlags["InObjectTypeLiteral"] = 4194304] = "InObjectTypeLiteral";
        NodeBuilderFlags[NodeBuilderFlags["InTypeAlias"] = 8388608] = "InTypeAlias";
        NodeBuilderFlags[NodeBuilderFlags["InInitialEntityName"] = 16777216] = "InInitialEntityName";
        NodeBuilderFlags[NodeBuilderFlags["InReverseMappedType"] = 33554432] = "InReverseMappedType";
    })(NodeBuilderFlags = ts.NodeBuilderFlags || (ts.NodeBuilderFlags = {}));
    // Ensure the shared flags between this and `NodeBuilderFlags` stay in alignment
    var TypeFormatFlags;
    (function (TypeFormatFlags) {
        TypeFormatFlags[TypeFormatFlags["None"] = 0] = "None";
        TypeFormatFlags[TypeFormatFlags["NoTruncation"] = 1] = "NoTruncation";
        TypeFormatFlags[TypeFormatFlags["WriteArrayAsGenericType"] = 2] = "WriteArrayAsGenericType";
        // hole because there's a hole in node builder flags
        TypeFormatFlags[TypeFormatFlags["UseStructuralFallback"] = 8] = "UseStructuralFallback";
        // hole because there's a hole in node builder flags
        TypeFormatFlags[TypeFormatFlags["WriteTypeArgumentsOfSignature"] = 32] = "WriteTypeArgumentsOfSignature";
        TypeFormatFlags[TypeFormatFlags["UseFullyQualifiedType"] = 64] = "UseFullyQualifiedType";
        // hole because `UseOnlyExternalAliasing` is here in node builder flags, but functions which take old flags use `SymbolFormatFlags` instead
        TypeFormatFlags[TypeFormatFlags["SuppressAnyReturnType"] = 256] = "SuppressAnyReturnType";
        // hole because `WriteTypeParametersInQualifiedName` is here in node builder flags, but functions which take old flags use `SymbolFormatFlags` for this instead
        TypeFormatFlags[TypeFormatFlags["MultilineObjectLiterals"] = 1024] = "MultilineObjectLiterals";
        TypeFormatFlags[TypeFormatFlags["WriteClassExpressionAsTypeLiteral"] = 2048] = "WriteClassExpressionAsTypeLiteral";
        TypeFormatFlags[TypeFormatFlags["UseTypeOfFunction"] = 4096] = "UseTypeOfFunction";
        TypeFormatFlags[TypeFormatFlags["OmitParameterModifiers"] = 8192] = "OmitParameterModifiers";
        TypeFormatFlags[TypeFormatFlags["UseAliasDefinedOutsideCurrentScope"] = 16384] = "UseAliasDefinedOutsideCurrentScope";
        // even though `T` can't be accessed in the current scope.
        // Error Handling
        TypeFormatFlags[TypeFormatFlags["AllowUniqueESSymbolType"] = 1048576] = "AllowUniqueESSymbolType";
        // TypeFormatFlags exclusive
        TypeFormatFlags[TypeFormatFlags["AddUndefined"] = 131072] = "AddUndefined";
        TypeFormatFlags[TypeFormatFlags["WriteArrowStyleSignature"] = 262144] = "WriteArrowStyleSignature";
        // State
        TypeFormatFlags[TypeFormatFlags["InArrayType"] = 524288] = "InArrayType";
        TypeFormatFlags[TypeFormatFlags["InElementType"] = 2097152] = "InElementType";
        TypeFormatFlags[TypeFormatFlags["InFirstTypeArgument"] = 4194304] = "InFirstTypeArgument";
        TypeFormatFlags[TypeFormatFlags["InTypeAlias"] = 8388608] = "InTypeAlias";
        /** @deprecated */ TypeFormatFlags[TypeFormatFlags["WriteOwnNameForAnyLike"] = 0] = "WriteOwnNameForAnyLike";
        TypeFormatFlags[TypeFormatFlags["NodeBuilderFlagsMask"] = 9469291] = "NodeBuilderFlagsMask";
    })(TypeFormatFlags = ts.TypeFormatFlags || (ts.TypeFormatFlags = {}));
    var SymbolFormatFlags;
    (function (SymbolFormatFlags) {
        SymbolFormatFlags[SymbolFormatFlags["None"] = 0] = "None";
        // Write symbols's type argument if it is instantiated symbol
        // eg. class C<T> { p: T }   <-- Show p as C<T>.p here
        //     var a: C<number>;
        //     var p = a.p; <--- Here p is property of C<number> so show it as C<number>.p instead of just C.p
        SymbolFormatFlags[SymbolFormatFlags["WriteTypeParametersOrArguments"] = 1] = "WriteTypeParametersOrArguments";
        // Use only external alias information to get the symbol name in the given context
        // eg.  module m { export class c { } } import x = m.c;
        // When this flag is specified m.c will be used to refer to the class instead of alias symbol x
        SymbolFormatFlags[SymbolFormatFlags["UseOnlyExternalAliasing"] = 2] = "UseOnlyExternalAliasing";
        // Build symbol name using any nodes needed, instead of just components of an entity name
        SymbolFormatFlags[SymbolFormatFlags["AllowAnyNodeKind"] = 4] = "AllowAnyNodeKind";
        // Prefer aliases which are not directly visible
        SymbolFormatFlags[SymbolFormatFlags["UseAliasDefinedOutsideCurrentScope"] = 8] = "UseAliasDefinedOutsideCurrentScope";
        // Skip building an accessible symbol chain
        /* @internal */ SymbolFormatFlags[SymbolFormatFlags["DoNotIncludeSymbolChain"] = 16] = "DoNotIncludeSymbolChain";
    })(SymbolFormatFlags = ts.SymbolFormatFlags || (ts.SymbolFormatFlags = {}));
    /* @internal */
    var SymbolAccessibility;
    (function (SymbolAccessibility) {
        SymbolAccessibility[SymbolAccessibility["Accessible"] = 0] = "Accessible";
        SymbolAccessibility[SymbolAccessibility["NotAccessible"] = 1] = "NotAccessible";
        SymbolAccessibility[SymbolAccessibility["CannotBeNamed"] = 2] = "CannotBeNamed";
    })(SymbolAccessibility = ts.SymbolAccessibility || (ts.SymbolAccessibility = {}));
    /* @internal */
    var SyntheticSymbolKind;
    (function (SyntheticSymbolKind) {
        SyntheticSymbolKind[SyntheticSymbolKind["UnionOrIntersection"] = 0] = "UnionOrIntersection";
        SyntheticSymbolKind[SyntheticSymbolKind["Spread"] = 1] = "Spread";
    })(SyntheticSymbolKind = ts.SyntheticSymbolKind || (ts.SyntheticSymbolKind = {}));
    var TypePredicateKind;
    (function (TypePredicateKind) {
        TypePredicateKind[TypePredicateKind["This"] = 0] = "This";
        TypePredicateKind[TypePredicateKind["Identifier"] = 1] = "Identifier";
    })(TypePredicateKind = ts.TypePredicateKind || (ts.TypePredicateKind = {}));
    /** Indicates how to serialize the name for a TypeReferenceNode when emitting decorator metadata */
    /* @internal */
    var TypeReferenceSerializationKind;
    (function (TypeReferenceSerializationKind) {
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["Unknown"] = 0] = "Unknown";
        // should be emitted using a safe fallback.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["TypeWithConstructSignatureAndValue"] = 1] = "TypeWithConstructSignatureAndValue";
        // function that can be reached at runtime (e.g. a `class`
        // declaration or a `var` declaration for the static side
        // of a type, such as the global `Promise` type in lib.d.ts).
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["VoidNullableOrNeverType"] = 2] = "VoidNullableOrNeverType";
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["NumberLikeType"] = 3] = "NumberLikeType";
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["BigIntLikeType"] = 4] = "BigIntLikeType";
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["StringLikeType"] = 5] = "StringLikeType";
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["BooleanType"] = 6] = "BooleanType";
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ArrayLikeType"] = 7] = "ArrayLikeType";
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ESSymbolType"] = 8] = "ESSymbolType";
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["Promise"] = 9] = "Promise";
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["TypeWithCallSignature"] = 10] = "TypeWithCallSignature";
        // with call signatures.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ObjectType"] = 11] = "ObjectType";
    })(TypeReferenceSerializationKind = ts.TypeReferenceSerializationKind || (ts.TypeReferenceSerializationKind = {}));
    var SymbolFlags;
    (function (SymbolFlags) {
        SymbolFlags[SymbolFlags["None"] = 0] = "None";
        SymbolFlags[SymbolFlags["FunctionScopedVariable"] = 1] = "FunctionScopedVariable";
        SymbolFlags[SymbolFlags["BlockScopedVariable"] = 2] = "BlockScopedVariable";
        SymbolFlags[SymbolFlags["Property"] = 4] = "Property";
        SymbolFlags[SymbolFlags["EnumMember"] = 8] = "EnumMember";
        SymbolFlags[SymbolFlags["Function"] = 16] = "Function";
        SymbolFlags[SymbolFlags["Class"] = 32] = "Class";
        SymbolFlags[SymbolFlags["Interface"] = 64] = "Interface";
        SymbolFlags[SymbolFlags["ConstEnum"] = 128] = "ConstEnum";
        SymbolFlags[SymbolFlags["RegularEnum"] = 256] = "RegularEnum";
        SymbolFlags[SymbolFlags["ValueModule"] = 512] = "ValueModule";
        SymbolFlags[SymbolFlags["NamespaceModule"] = 1024] = "NamespaceModule";
        SymbolFlags[SymbolFlags["TypeLiteral"] = 2048] = "TypeLiteral";
        SymbolFlags[SymbolFlags["ObjectLiteral"] = 4096] = "ObjectLiteral";
        SymbolFlags[SymbolFlags["Method"] = 8192] = "Method";
        SymbolFlags[SymbolFlags["Constructor"] = 16384] = "Constructor";
        SymbolFlags[SymbolFlags["GetAccessor"] = 32768] = "GetAccessor";
        SymbolFlags[SymbolFlags["SetAccessor"] = 65536] = "SetAccessor";
        SymbolFlags[SymbolFlags["Signature"] = 131072] = "Signature";
        SymbolFlags[SymbolFlags["TypeParameter"] = 262144] = "TypeParameter";
        SymbolFlags[SymbolFlags["TypeAlias"] = 524288] = "TypeAlias";
        SymbolFlags[SymbolFlags["ExportValue"] = 1048576] = "ExportValue";
        SymbolFlags[SymbolFlags["Alias"] = 2097152] = "Alias";
        SymbolFlags[SymbolFlags["Prototype"] = 4194304] = "Prototype";
        SymbolFlags[SymbolFlags["ExportStar"] = 8388608] = "ExportStar";
        SymbolFlags[SymbolFlags["Optional"] = 16777216] = "Optional";
        SymbolFlags[SymbolFlags["Transient"] = 33554432] = "Transient";
        SymbolFlags[SymbolFlags["Assignment"] = 67108864] = "Assignment";
        SymbolFlags[SymbolFlags["ModuleExports"] = 134217728] = "ModuleExports";
        /* @internal */
        SymbolFlags[SymbolFlags["All"] = 67108863] = "All";
        SymbolFlags[SymbolFlags["Enum"] = 384] = "Enum";
        SymbolFlags[SymbolFlags["Variable"] = 3] = "Variable";
        SymbolFlags[SymbolFlags["Value"] = 67220415] = "Value";
        SymbolFlags[SymbolFlags["Type"] = 67897832] = "Type";
        SymbolFlags[SymbolFlags["Namespace"] = 1920] = "Namespace";
        SymbolFlags[SymbolFlags["Module"] = 1536] = "Module";
        SymbolFlags[SymbolFlags["Accessor"] = 98304] = "Accessor";
        // Variables can be redeclared, but can not redeclare a block-scoped declaration with the
        // same name, or any other value that is not a variable, e.g. ValueModule or Class
        SymbolFlags[SymbolFlags["FunctionScopedVariableExcludes"] = 67220414] = "FunctionScopedVariableExcludes";
        // Block-scoped declarations are not allowed to be re-declared
        // they can not merge with anything in the value space
        SymbolFlags[SymbolFlags["BlockScopedVariableExcludes"] = 67220415] = "BlockScopedVariableExcludes";
        SymbolFlags[SymbolFlags["ParameterExcludes"] = 67220415] = "ParameterExcludes";
        SymbolFlags[SymbolFlags["PropertyExcludes"] = 0] = "PropertyExcludes";
        SymbolFlags[SymbolFlags["EnumMemberExcludes"] = 68008959] = "EnumMemberExcludes";
        SymbolFlags[SymbolFlags["FunctionExcludes"] = 67219887] = "FunctionExcludes";
        SymbolFlags[SymbolFlags["ClassExcludes"] = 68008383] = "ClassExcludes";
        SymbolFlags[SymbolFlags["InterfaceExcludes"] = 67897736] = "InterfaceExcludes";
        SymbolFlags[SymbolFlags["RegularEnumExcludes"] = 68008191] = "RegularEnumExcludes";
        SymbolFlags[SymbolFlags["ConstEnumExcludes"] = 68008831] = "ConstEnumExcludes";
        SymbolFlags[SymbolFlags["ValueModuleExcludes"] = 110735] = "ValueModuleExcludes";
        SymbolFlags[SymbolFlags["NamespaceModuleExcludes"] = 0] = "NamespaceModuleExcludes";
        SymbolFlags[SymbolFlags["MethodExcludes"] = 67212223] = "MethodExcludes";
        SymbolFlags[SymbolFlags["GetAccessorExcludes"] = 67154879] = "GetAccessorExcludes";
        SymbolFlags[SymbolFlags["SetAccessorExcludes"] = 67187647] = "SetAccessorExcludes";
        SymbolFlags[SymbolFlags["TypeParameterExcludes"] = 67635688] = "TypeParameterExcludes";
        SymbolFlags[SymbolFlags["TypeAliasExcludes"] = 67897832] = "TypeAliasExcludes";
        SymbolFlags[SymbolFlags["AliasExcludes"] = 2097152] = "AliasExcludes";
        SymbolFlags[SymbolFlags["ModuleMember"] = 2623475] = "ModuleMember";
        SymbolFlags[SymbolFlags["ExportHasLocal"] = 944] = "ExportHasLocal";
        SymbolFlags[SymbolFlags["BlockScoped"] = 418] = "BlockScoped";
        SymbolFlags[SymbolFlags["PropertyOrAccessor"] = 98308] = "PropertyOrAccessor";
        SymbolFlags[SymbolFlags["ClassMember"] = 106500] = "ClassMember";
        /* @internal */
        // The set of things we consider semantically classifiable.  Used to speed up the LS during
        // classification.
        SymbolFlags[SymbolFlags["Classifiable"] = 2885600] = "Classifiable";
        /* @internal */
        SymbolFlags[SymbolFlags["LateBindingContainer"] = 6240] = "LateBindingContainer";
    })(SymbolFlags = ts.SymbolFlags || (ts.SymbolFlags = {}));
    /* @internal */
    var EnumKind;
    (function (EnumKind) {
        EnumKind[EnumKind["Numeric"] = 0] = "Numeric";
        EnumKind[EnumKind["Literal"] = 1] = "Literal"; // Literal enum (each member has a TypeFlags.EnumLiteral type)
    })(EnumKind = ts.EnumKind || (ts.EnumKind = {}));
    /* @internal */
    var CheckFlags;
    (function (CheckFlags) {
        CheckFlags[CheckFlags["Instantiated"] = 1] = "Instantiated";
        CheckFlags[CheckFlags["SyntheticProperty"] = 2] = "SyntheticProperty";
        CheckFlags[CheckFlags["SyntheticMethod"] = 4] = "SyntheticMethod";
        CheckFlags[CheckFlags["Readonly"] = 8] = "Readonly";
        CheckFlags[CheckFlags["ReadPartial"] = 16] = "ReadPartial";
        CheckFlags[CheckFlags["WritePartial"] = 32] = "WritePartial";
        CheckFlags[CheckFlags["HasNonUniformType"] = 64] = "HasNonUniformType";
        CheckFlags[CheckFlags["HasLiteralType"] = 128] = "HasLiteralType";
        CheckFlags[CheckFlags["ContainsPublic"] = 256] = "ContainsPublic";
        CheckFlags[CheckFlags["ContainsProtected"] = 512] = "ContainsProtected";
        CheckFlags[CheckFlags["ContainsPrivate"] = 1024] = "ContainsPrivate";
        CheckFlags[CheckFlags["ContainsStatic"] = 2048] = "ContainsStatic";
        CheckFlags[CheckFlags["Late"] = 4096] = "Late";
        CheckFlags[CheckFlags["ReverseMapped"] = 8192] = "ReverseMapped";
        CheckFlags[CheckFlags["OptionalParameter"] = 16384] = "OptionalParameter";
        CheckFlags[CheckFlags["RestParameter"] = 32768] = "RestParameter";
        CheckFlags[CheckFlags["DeferredType"] = 65536] = "DeferredType";
        CheckFlags[CheckFlags["Synthetic"] = 6] = "Synthetic";
        CheckFlags[CheckFlags["Discriminant"] = 192] = "Discriminant";
        CheckFlags[CheckFlags["Partial"] = 48] = "Partial";
    })(CheckFlags = ts.CheckFlags || (ts.CheckFlags = {}));
    var InternalSymbolName;
    (function (InternalSymbolName) {
        InternalSymbolName["Call"] = "__call";
        InternalSymbolName["Constructor"] = "__constructor";
        InternalSymbolName["New"] = "__new";
        InternalSymbolName["Index"] = "__index";
        InternalSymbolName["ExportStar"] = "__export";
        InternalSymbolName["Global"] = "__global";
        InternalSymbolName["Missing"] = "__missing";
        InternalSymbolName["Type"] = "__type";
        InternalSymbolName["Object"] = "__object";
        InternalSymbolName["JSXAttributes"] = "__jsxAttributes";
        InternalSymbolName["Class"] = "__class";
        InternalSymbolName["Function"] = "__function";
        InternalSymbolName["Computed"] = "__computed";
        InternalSymbolName["Resolving"] = "__resolving__";
        InternalSymbolName["ExportEquals"] = "export=";
        InternalSymbolName["Default"] = "default";
        InternalSymbolName["This"] = "this";
    })(InternalSymbolName = ts.InternalSymbolName || (ts.InternalSymbolName = {}));
    /* @internal */
    var NodeCheckFlags;
    (function (NodeCheckFlags) {
        NodeCheckFlags[NodeCheckFlags["TypeChecked"] = 1] = "TypeChecked";
        NodeCheckFlags[NodeCheckFlags["LexicalThis"] = 2] = "LexicalThis";
        NodeCheckFlags[NodeCheckFlags["CaptureThis"] = 4] = "CaptureThis";
        NodeCheckFlags[NodeCheckFlags["CaptureNewTarget"] = 8] = "CaptureNewTarget";
        NodeCheckFlags[NodeCheckFlags["SuperInstance"] = 256] = "SuperInstance";
        NodeCheckFlags[NodeCheckFlags["SuperStatic"] = 512] = "SuperStatic";
        NodeCheckFlags[NodeCheckFlags["ContextChecked"] = 1024] = "ContextChecked";
        NodeCheckFlags[NodeCheckFlags["AsyncMethodWithSuper"] = 2048] = "AsyncMethodWithSuper";
        NodeCheckFlags[NodeCheckFlags["AsyncMethodWithSuperBinding"] = 4096] = "AsyncMethodWithSuperBinding";
        NodeCheckFlags[NodeCheckFlags["CaptureArguments"] = 8192] = "CaptureArguments";
        NodeCheckFlags[NodeCheckFlags["EnumValuesComputed"] = 16384] = "EnumValuesComputed";
        NodeCheckFlags[NodeCheckFlags["LexicalModuleMergesWithClass"] = 32768] = "LexicalModuleMergesWithClass";
        NodeCheckFlags[NodeCheckFlags["LoopWithCapturedBlockScopedBinding"] = 65536] = "LoopWithCapturedBlockScopedBinding";
        NodeCheckFlags[NodeCheckFlags["ContainsCapturedBlockScopeBinding"] = 131072] = "ContainsCapturedBlockScopeBinding";
        NodeCheckFlags[NodeCheckFlags["CapturedBlockScopedBinding"] = 262144] = "CapturedBlockScopedBinding";
        NodeCheckFlags[NodeCheckFlags["BlockScopedBindingInLoop"] = 524288] = "BlockScopedBindingInLoop";
        NodeCheckFlags[NodeCheckFlags["ClassWithBodyScopedClassBinding"] = 1048576] = "ClassWithBodyScopedClassBinding";
        NodeCheckFlags[NodeCheckFlags["BodyScopedClassBinding"] = 2097152] = "BodyScopedClassBinding";
        NodeCheckFlags[NodeCheckFlags["NeedsLoopOutParameter"] = 4194304] = "NeedsLoopOutParameter";
        NodeCheckFlags[NodeCheckFlags["AssignmentsMarked"] = 8388608] = "AssignmentsMarked";
        NodeCheckFlags[NodeCheckFlags["ClassWithConstructorReference"] = 16777216] = "ClassWithConstructorReference";
        NodeCheckFlags[NodeCheckFlags["ConstructorReferenceInClass"] = 33554432] = "ConstructorReferenceInClass";
    })(NodeCheckFlags = ts.NodeCheckFlags || (ts.NodeCheckFlags = {}));
    var TypeFlags;
    (function (TypeFlags) {
        TypeFlags[TypeFlags["Any"] = 1] = "Any";
        TypeFlags[TypeFlags["Unknown"] = 2] = "Unknown";
        TypeFlags[TypeFlags["String"] = 4] = "String";
        TypeFlags[TypeFlags["Number"] = 8] = "Number";
        TypeFlags[TypeFlags["Boolean"] = 16] = "Boolean";
        TypeFlags[TypeFlags["Enum"] = 32] = "Enum";
        TypeFlags[TypeFlags["BigInt"] = 64] = "BigInt";
        TypeFlags[TypeFlags["StringLiteral"] = 128] = "StringLiteral";
        TypeFlags[TypeFlags["NumberLiteral"] = 256] = "NumberLiteral";
        TypeFlags[TypeFlags["BooleanLiteral"] = 512] = "BooleanLiteral";
        TypeFlags[TypeFlags["EnumLiteral"] = 1024] = "EnumLiteral";
        TypeFlags[TypeFlags["BigIntLiteral"] = 2048] = "BigIntLiteral";
        TypeFlags[TypeFlags["ESSymbol"] = 4096] = "ESSymbol";
        TypeFlags[TypeFlags["UniqueESSymbol"] = 8192] = "UniqueESSymbol";
        TypeFlags[TypeFlags["Void"] = 16384] = "Void";
        TypeFlags[TypeFlags["Undefined"] = 32768] = "Undefined";
        TypeFlags[TypeFlags["Null"] = 65536] = "Null";
        TypeFlags[TypeFlags["Never"] = 131072] = "Never";
        TypeFlags[TypeFlags["TypeParameter"] = 262144] = "TypeParameter";
        TypeFlags[TypeFlags["Object"] = 524288] = "Object";
        TypeFlags[TypeFlags["Union"] = 1048576] = "Union";
        TypeFlags[TypeFlags["Intersection"] = 2097152] = "Intersection";
        TypeFlags[TypeFlags["Index"] = 4194304] = "Index";
        TypeFlags[TypeFlags["IndexedAccess"] = 8388608] = "IndexedAccess";
        TypeFlags[TypeFlags["Conditional"] = 16777216] = "Conditional";
        TypeFlags[TypeFlags["Substitution"] = 33554432] = "Substitution";
        TypeFlags[TypeFlags["NonPrimitive"] = 67108864] = "NonPrimitive";
        /* @internal */
        TypeFlags[TypeFlags["AnyOrUnknown"] = 3] = "AnyOrUnknown";
        /* @internal */
        TypeFlags[TypeFlags["Nullable"] = 98304] = "Nullable";
        TypeFlags[TypeFlags["Literal"] = 2944] = "Literal";
        TypeFlags[TypeFlags["Unit"] = 109440] = "Unit";
        TypeFlags[TypeFlags["StringOrNumberLiteral"] = 384] = "StringOrNumberLiteral";
        /* @internal */
        TypeFlags[TypeFlags["StringOrNumberLiteralOrUnique"] = 8576] = "StringOrNumberLiteralOrUnique";
        /* @internal */
        TypeFlags[TypeFlags["DefinitelyFalsy"] = 117632] = "DefinitelyFalsy";
        TypeFlags[TypeFlags["PossiblyFalsy"] = 117724] = "PossiblyFalsy";
        /* @internal */
        TypeFlags[TypeFlags["Intrinsic"] = 67359327] = "Intrinsic";
        /* @internal */
        TypeFlags[TypeFlags["Primitive"] = 131068] = "Primitive";
        TypeFlags[TypeFlags["StringLike"] = 132] = "StringLike";
        TypeFlags[TypeFlags["NumberLike"] = 296] = "NumberLike";
        TypeFlags[TypeFlags["BigIntLike"] = 2112] = "BigIntLike";
        TypeFlags[TypeFlags["BooleanLike"] = 528] = "BooleanLike";
        TypeFlags[TypeFlags["EnumLike"] = 1056] = "EnumLike";
        TypeFlags[TypeFlags["ESSymbolLike"] = 12288] = "ESSymbolLike";
        TypeFlags[TypeFlags["VoidLike"] = 49152] = "VoidLike";
        /* @internal */
        TypeFlags[TypeFlags["DisjointDomains"] = 67238908] = "DisjointDomains";
        TypeFlags[TypeFlags["UnionOrIntersection"] = 3145728] = "UnionOrIntersection";
        TypeFlags[TypeFlags["StructuredType"] = 3670016] = "StructuredType";
        TypeFlags[TypeFlags["TypeVariable"] = 8650752] = "TypeVariable";
        TypeFlags[TypeFlags["InstantiableNonPrimitive"] = 58982400] = "InstantiableNonPrimitive";
        TypeFlags[TypeFlags["InstantiablePrimitive"] = 4194304] = "InstantiablePrimitive";
        TypeFlags[TypeFlags["Instantiable"] = 63176704] = "Instantiable";
        TypeFlags[TypeFlags["StructuredOrInstantiable"] = 66846720] = "StructuredOrInstantiable";
        /* @internal */
        TypeFlags[TypeFlags["ObjectFlagsType"] = 3899392] = "ObjectFlagsType";
        /* @internal */
        TypeFlags[TypeFlags["Simplifiable"] = 25165824] = "Simplifiable";
        // 'Narrowable' types are types where narrowing actually narrows.
        // This *should* be every type other than null, undefined, void, and never
        TypeFlags[TypeFlags["Narrowable"] = 133970943] = "Narrowable";
        TypeFlags[TypeFlags["NotUnionOrUnit"] = 67637251] = "NotUnionOrUnit";
        /* @internal */
        TypeFlags[TypeFlags["NotPrimitiveUnion"] = 66994211] = "NotPrimitiveUnion";
        // The following flags are aggregated during union and intersection type construction
        /* @internal */
        TypeFlags[TypeFlags["IncludesMask"] = 1835007] = "IncludesMask";
        // The following flags are used for different purposes during union and intersection type construction
        /* @internal */
        TypeFlags[TypeFlags["IncludesStructuredOrInstantiable"] = 262144] = "IncludesStructuredOrInstantiable";
        /* @internal */
        TypeFlags[TypeFlags["IncludesNonWideningType"] = 2097152] = "IncludesNonWideningType";
        /* @internal */
        TypeFlags[TypeFlags["IncludesWildcard"] = 4194304] = "IncludesWildcard";
        /* @internal */
        TypeFlags[TypeFlags["IncludesEmptyObject"] = 8388608] = "IncludesEmptyObject";
        // The following flag is used for different purposes by maybeTypeOfKind
        /* @internal */
        TypeFlags[TypeFlags["GenericMappedType"] = 131072] = "GenericMappedType";
    })(TypeFlags = ts.TypeFlags || (ts.TypeFlags = {}));
    var ObjectFlags;
    (function (ObjectFlags) {
        ObjectFlags[ObjectFlags["Class"] = 1] = "Class";
        ObjectFlags[ObjectFlags["Interface"] = 2] = "Interface";
        ObjectFlags[ObjectFlags["Reference"] = 4] = "Reference";
        ObjectFlags[ObjectFlags["Tuple"] = 8] = "Tuple";
        ObjectFlags[ObjectFlags["Anonymous"] = 16] = "Anonymous";
        ObjectFlags[ObjectFlags["Mapped"] = 32] = "Mapped";
        ObjectFlags[ObjectFlags["Instantiated"] = 64] = "Instantiated";
        ObjectFlags[ObjectFlags["ObjectLiteral"] = 128] = "ObjectLiteral";
        ObjectFlags[ObjectFlags["EvolvingArray"] = 256] = "EvolvingArray";
        ObjectFlags[ObjectFlags["ObjectLiteralPatternWithComputedProperties"] = 512] = "ObjectLiteralPatternWithComputedProperties";
        ObjectFlags[ObjectFlags["ContainsSpread"] = 1024] = "ContainsSpread";
        ObjectFlags[ObjectFlags["ReverseMapped"] = 2048] = "ReverseMapped";
        ObjectFlags[ObjectFlags["JsxAttributes"] = 4096] = "JsxAttributes";
        ObjectFlags[ObjectFlags["MarkerType"] = 8192] = "MarkerType";
        ObjectFlags[ObjectFlags["JSLiteral"] = 16384] = "JSLiteral";
        ObjectFlags[ObjectFlags["FreshLiteral"] = 32768] = "FreshLiteral";
        /* @internal */
        ObjectFlags[ObjectFlags["PrimitiveUnion"] = 65536] = "PrimitiveUnion";
        /* @internal */
        ObjectFlags[ObjectFlags["ContainsWideningType"] = 131072] = "ContainsWideningType";
        /* @internal */
        ObjectFlags[ObjectFlags["ContainsObjectLiteral"] = 262144] = "ContainsObjectLiteral";
        /* @internal */
        ObjectFlags[ObjectFlags["NonInferrableType"] = 524288] = "NonInferrableType";
        ObjectFlags[ObjectFlags["ClassOrInterface"] = 3] = "ClassOrInterface";
        /* @internal */
        ObjectFlags[ObjectFlags["RequiresWidening"] = 393216] = "RequiresWidening";
        /* @internal */
        ObjectFlags[ObjectFlags["PropagatingFlags"] = 917504] = "PropagatingFlags";
    })(ObjectFlags = ts.ObjectFlags || (ts.ObjectFlags = {}));
    /* @internal */
    var VarianceFlags;
    (function (VarianceFlags) {
        VarianceFlags[VarianceFlags["Invariant"] = 0] = "Invariant";
        VarianceFlags[VarianceFlags["Covariant"] = 1] = "Covariant";
        VarianceFlags[VarianceFlags["Contravariant"] = 2] = "Contravariant";
        VarianceFlags[VarianceFlags["Bivariant"] = 3] = "Bivariant";
        VarianceFlags[VarianceFlags["Independent"] = 4] = "Independent";
        VarianceFlags[VarianceFlags["VarianceMask"] = 7] = "VarianceMask";
        VarianceFlags[VarianceFlags["Unmeasurable"] = 8] = "Unmeasurable";
        VarianceFlags[VarianceFlags["Unreliable"] = 16] = "Unreliable";
        VarianceFlags[VarianceFlags["AllowsStructuralFallback"] = 24] = "AllowsStructuralFallback";
    })(VarianceFlags = ts.VarianceFlags || (ts.VarianceFlags = {}));
    /* @internal */
    var JsxReferenceKind;
    (function (JsxReferenceKind) {
        JsxReferenceKind[JsxReferenceKind["Component"] = 0] = "Component";
        JsxReferenceKind[JsxReferenceKind["Function"] = 1] = "Function";
        JsxReferenceKind[JsxReferenceKind["Mixed"] = 2] = "Mixed";
    })(JsxReferenceKind = ts.JsxReferenceKind || (ts.JsxReferenceKind = {}));
    var SignatureKind;
    (function (SignatureKind) {
        SignatureKind[SignatureKind["Call"] = 0] = "Call";
        SignatureKind[SignatureKind["Construct"] = 1] = "Construct";
    })(SignatureKind = ts.SignatureKind || (ts.SignatureKind = {}));
    var IndexKind;
    (function (IndexKind) {
        IndexKind[IndexKind["String"] = 0] = "String";
        IndexKind[IndexKind["Number"] = 1] = "Number";
    })(IndexKind = ts.IndexKind || (ts.IndexKind = {}));
    var InferencePriority;
    (function (InferencePriority) {
        InferencePriority[InferencePriority["NakedTypeVariable"] = 1] = "NakedTypeVariable";
        InferencePriority[InferencePriority["HomomorphicMappedType"] = 2] = "HomomorphicMappedType";
        InferencePriority[InferencePriority["PartialHomomorphicMappedType"] = 4] = "PartialHomomorphicMappedType";
        InferencePriority[InferencePriority["MappedTypeConstraint"] = 8] = "MappedTypeConstraint";
        InferencePriority[InferencePriority["ReturnType"] = 16] = "ReturnType";
        InferencePriority[InferencePriority["LiteralKeyof"] = 32] = "LiteralKeyof";
        InferencePriority[InferencePriority["NoConstraints"] = 64] = "NoConstraints";
        InferencePriority[InferencePriority["AlwaysStrict"] = 128] = "AlwaysStrict";
        InferencePriority[InferencePriority["PriorityImpliesCombination"] = 56] = "PriorityImpliesCombination";
    })(InferencePriority = ts.InferencePriority || (ts.InferencePriority = {}));
    /* @internal */
    var InferenceFlags;
    (function (InferenceFlags) {
        InferenceFlags[InferenceFlags["None"] = 0] = "None";
        InferenceFlags[InferenceFlags["NoDefault"] = 1] = "NoDefault";
        InferenceFlags[InferenceFlags["AnyDefault"] = 2] = "AnyDefault";
        InferenceFlags[InferenceFlags["SkippedGenericFunction"] = 4] = "SkippedGenericFunction";
    })(InferenceFlags = ts.InferenceFlags || (ts.InferenceFlags = {}));
    /**
     * Ternary values are defined such that
     * x & y is False if either x or y is False.
     * x & y is Maybe if either x or y is Maybe, but neither x or y is False.
     * x & y is True if both x and y are True.
     * x | y is False if both x and y are False.
     * x | y is Maybe if either x or y is Maybe, but neither x or y is True.
     * x | y is True if either x or y is True.
     */
    /* @internal */
    var Ternary;
    (function (Ternary) {
        Ternary[Ternary["False"] = 0] = "False";
        Ternary[Ternary["Maybe"] = 1] = "Maybe";
        Ternary[Ternary["True"] = -1] = "True";
    })(Ternary = ts.Ternary || (ts.Ternary = {}));
    /* @internal */
    var AssignmentDeclarationKind;
    (function (AssignmentDeclarationKind) {
        AssignmentDeclarationKind[AssignmentDeclarationKind["None"] = 0] = "None";
        /// exports.name = expr
        AssignmentDeclarationKind[AssignmentDeclarationKind["ExportsProperty"] = 1] = "ExportsProperty";
        /// module.exports = expr
        AssignmentDeclarationKind[AssignmentDeclarationKind["ModuleExports"] = 2] = "ModuleExports";
        /// className.prototype.name = expr
        AssignmentDeclarationKind[AssignmentDeclarationKind["PrototypeProperty"] = 3] = "PrototypeProperty";
        /// this.name = expr
        AssignmentDeclarationKind[AssignmentDeclarationKind["ThisProperty"] = 4] = "ThisProperty";
        // F.name = expr
        AssignmentDeclarationKind[AssignmentDeclarationKind["Property"] = 5] = "Property";
        // F.prototype = { ... }
        AssignmentDeclarationKind[AssignmentDeclarationKind["Prototype"] = 6] = "Prototype";
        // Object.defineProperty(x, 'name', { value: any, writable?: boolean (false by default) });
        // Object.defineProperty(x, 'name', { get: Function, set: Function });
        // Object.defineProperty(x, 'name', { get: Function });
        // Object.defineProperty(x, 'name', { set: Function });
        AssignmentDeclarationKind[AssignmentDeclarationKind["ObjectDefinePropertyValue"] = 7] = "ObjectDefinePropertyValue";
        // Object.defineProperty(exports || module.exports, 'name', ...);
        AssignmentDeclarationKind[AssignmentDeclarationKind["ObjectDefinePropertyExports"] = 8] = "ObjectDefinePropertyExports";
        // Object.defineProperty(Foo.prototype, 'name', ...);
        AssignmentDeclarationKind[AssignmentDeclarationKind["ObjectDefinePrototypeProperty"] = 9] = "ObjectDefinePrototypeProperty";
    })(AssignmentDeclarationKind = ts.AssignmentDeclarationKind || (ts.AssignmentDeclarationKind = {}));
    var DiagnosticCategory;
    (function (DiagnosticCategory) {
        DiagnosticCategory[DiagnosticCategory["Warning"] = 0] = "Warning";
        DiagnosticCategory[DiagnosticCategory["Error"] = 1] = "Error";
        DiagnosticCategory[DiagnosticCategory["Suggestion"] = 2] = "Suggestion";
        DiagnosticCategory[DiagnosticCategory["Message"] = 3] = "Message";
    })(DiagnosticCategory = ts.DiagnosticCategory || (ts.DiagnosticCategory = {}));
    /* @internal */
    function diagnosticCategoryName(d, lowerCase) {
        if (lowerCase === void 0) { lowerCase = true; }
        var name = DiagnosticCategory[d.category];
        return lowerCase ? name.toLowerCase() : name;
    }
    ts.diagnosticCategoryName = diagnosticCategoryName;
    var ModuleResolutionKind;
    (function (ModuleResolutionKind) {
        ModuleResolutionKind[ModuleResolutionKind["Classic"] = 1] = "Classic";
        ModuleResolutionKind[ModuleResolutionKind["NodeJs"] = 2] = "NodeJs";
    })(ModuleResolutionKind = ts.ModuleResolutionKind || (ts.ModuleResolutionKind = {}));
    var ModuleKind;
    (function (ModuleKind) {
        ModuleKind[ModuleKind["None"] = 0] = "None";
        ModuleKind[ModuleKind["CommonJS"] = 1] = "CommonJS";
        ModuleKind[ModuleKind["AMD"] = 2] = "AMD";
        ModuleKind[ModuleKind["UMD"] = 3] = "UMD";
        ModuleKind[ModuleKind["System"] = 4] = "System";
        ModuleKind[ModuleKind["ES2015"] = 5] = "ES2015";
        ModuleKind[ModuleKind["ESNext"] = 6] = "ESNext";
    })(ModuleKind = ts.ModuleKind || (ts.ModuleKind = {}));
    var JsxEmit;
    (function (JsxEmit) {
        JsxEmit[JsxEmit["None"] = 0] = "None";
        JsxEmit[JsxEmit["Preserve"] = 1] = "Preserve";
        JsxEmit[JsxEmit["React"] = 2] = "React";
        JsxEmit[JsxEmit["ReactNative"] = 3] = "ReactNative";
    })(JsxEmit = ts.JsxEmit || (ts.JsxEmit = {}));
    var NewLineKind;
    (function (NewLineKind) {
        NewLineKind[NewLineKind["CarriageReturnLineFeed"] = 0] = "CarriageReturnLineFeed";
        NewLineKind[NewLineKind["LineFeed"] = 1] = "LineFeed";
    })(NewLineKind = ts.NewLineKind || (ts.NewLineKind = {}));
    var ScriptKind;
    (function (ScriptKind) {
        ScriptKind[ScriptKind["Unknown"] = 0] = "Unknown";
        ScriptKind[ScriptKind["JS"] = 1] = "JS";
        ScriptKind[ScriptKind["JSX"] = 2] = "JSX";
        ScriptKind[ScriptKind["TS"] = 3] = "TS";
        ScriptKind[ScriptKind["TSX"] = 4] = "TSX";
        ScriptKind[ScriptKind["External"] = 5] = "External";
        ScriptKind[ScriptKind["JSON"] = 6] = "JSON";
        /**
         * Used on extensions that doesn't define the ScriptKind but the content defines it.
         * Deferred extensions are going to be included in all project contexts.
         */
        ScriptKind[ScriptKind["Deferred"] = 7] = "Deferred";
    })(ScriptKind = ts.ScriptKind || (ts.ScriptKind = {}));
    var ScriptTarget;
    (function (ScriptTarget) {
        ScriptTarget[ScriptTarget["ES3"] = 0] = "ES3";
        ScriptTarget[ScriptTarget["ES5"] = 1] = "ES5";
        ScriptTarget[ScriptTarget["ES2015"] = 2] = "ES2015";
        ScriptTarget[ScriptTarget["ES2016"] = 3] = "ES2016";
        ScriptTarget[ScriptTarget["ES2017"] = 4] = "ES2017";
        ScriptTarget[ScriptTarget["ES2018"] = 5] = "ES2018";
        ScriptTarget[ScriptTarget["ES2019"] = 6] = "ES2019";
        ScriptTarget[ScriptTarget["ES2020"] = 7] = "ES2020";
        ScriptTarget[ScriptTarget["ESNext"] = 8] = "ESNext";
        ScriptTarget[ScriptTarget["JSON"] = 100] = "JSON";
        ScriptTarget[ScriptTarget["Latest"] = 8] = "Latest";
    })(ScriptTarget = ts.ScriptTarget || (ts.ScriptTarget = {}));
    var LanguageVariant;
    (function (LanguageVariant) {
        LanguageVariant[LanguageVariant["Standard"] = 0] = "Standard";
        LanguageVariant[LanguageVariant["JSX"] = 1] = "JSX";
    })(LanguageVariant = ts.LanguageVariant || (ts.LanguageVariant = {}));
    var WatchDirectoryFlags;
    (function (WatchDirectoryFlags) {
        WatchDirectoryFlags[WatchDirectoryFlags["None"] = 0] = "None";
        WatchDirectoryFlags[WatchDirectoryFlags["Recursive"] = 1] = "Recursive";
    })(WatchDirectoryFlags = ts.WatchDirectoryFlags || (ts.WatchDirectoryFlags = {}));
    /* @internal */
    var CharacterCodes;
    (function (CharacterCodes) {
        CharacterCodes[CharacterCodes["nullCharacter"] = 0] = "nullCharacter";
        CharacterCodes[CharacterCodes["maxAsciiCharacter"] = 127] = "maxAsciiCharacter";
        CharacterCodes[CharacterCodes["lineFeed"] = 10] = "lineFeed";
        CharacterCodes[CharacterCodes["carriageReturn"] = 13] = "carriageReturn";
        CharacterCodes[CharacterCodes["lineSeparator"] = 8232] = "lineSeparator";
        CharacterCodes[CharacterCodes["paragraphSeparator"] = 8233] = "paragraphSeparator";
        CharacterCodes[CharacterCodes["nextLine"] = 133] = "nextLine";
        // Unicode 3.0 space characters
        CharacterCodes[CharacterCodes["space"] = 32] = "space";
        CharacterCodes[CharacterCodes["nonBreakingSpace"] = 160] = "nonBreakingSpace";
        CharacterCodes[CharacterCodes["enQuad"] = 8192] = "enQuad";
        CharacterCodes[CharacterCodes["emQuad"] = 8193] = "emQuad";
        CharacterCodes[CharacterCodes["enSpace"] = 8194] = "enSpace";
        CharacterCodes[CharacterCodes["emSpace"] = 8195] = "emSpace";
        CharacterCodes[CharacterCodes["threePerEmSpace"] = 8196] = "threePerEmSpace";
        CharacterCodes[CharacterCodes["fourPerEmSpace"] = 8197] = "fourPerEmSpace";
        CharacterCodes[CharacterCodes["sixPerEmSpace"] = 8198] = "sixPerEmSpace";
        CharacterCodes[CharacterCodes["figureSpace"] = 8199] = "figureSpace";
        CharacterCodes[CharacterCodes["punctuationSpace"] = 8200] = "punctuationSpace";
        CharacterCodes[CharacterCodes["thinSpace"] = 8201] = "thinSpace";
        CharacterCodes[CharacterCodes["hairSpace"] = 8202] = "hairSpace";
        CharacterCodes[CharacterCodes["zeroWidthSpace"] = 8203] = "zeroWidthSpace";
        CharacterCodes[CharacterCodes["narrowNoBreakSpace"] = 8239] = "narrowNoBreakSpace";
        CharacterCodes[CharacterCodes["ideographicSpace"] = 12288] = "ideographicSpace";
        CharacterCodes[CharacterCodes["mathematicalSpace"] = 8287] = "mathematicalSpace";
        CharacterCodes[CharacterCodes["ogham"] = 5760] = "ogham";
        CharacterCodes[CharacterCodes["_"] = 95] = "_";
        CharacterCodes[CharacterCodes["$"] = 36] = "$";
        CharacterCodes[CharacterCodes["_0"] = 48] = "_0";
        CharacterCodes[CharacterCodes["_1"] = 49] = "_1";
        CharacterCodes[CharacterCodes["_2"] = 50] = "_2";
        CharacterCodes[CharacterCodes["_3"] = 51] = "_3";
        CharacterCodes[CharacterCodes["_4"] = 52] = "_4";
        CharacterCodes[CharacterCodes["_5"] = 53] = "_5";
        CharacterCodes[CharacterCodes["_6"] = 54] = "_6";
        CharacterCodes[CharacterCodes["_7"] = 55] = "_7";
        CharacterCodes[CharacterCodes["_8"] = 56] = "_8";
        CharacterCodes[CharacterCodes["_9"] = 57] = "_9";
        CharacterCodes[CharacterCodes["a"] = 97] = "a";
        CharacterCodes[CharacterCodes["b"] = 98] = "b";
        CharacterCodes[CharacterCodes["c"] = 99] = "c";
        CharacterCodes[CharacterCodes["d"] = 100] = "d";
        CharacterCodes[CharacterCodes["e"] = 101] = "e";
        CharacterCodes[CharacterCodes["f"] = 102] = "f";
        CharacterCodes[CharacterCodes["g"] = 103] = "g";
        CharacterCodes[CharacterCodes["h"] = 104] = "h";
        CharacterCodes[CharacterCodes["i"] = 105] = "i";
        CharacterCodes[CharacterCodes["j"] = 106] = "j";
        CharacterCodes[CharacterCodes["k"] = 107] = "k";
        CharacterCodes[CharacterCodes["l"] = 108] = "l";
        CharacterCodes[CharacterCodes["m"] = 109] = "m";
        CharacterCodes[CharacterCodes["n"] = 110] = "n";
        CharacterCodes[CharacterCodes["o"] = 111] = "o";
        CharacterCodes[CharacterCodes["p"] = 112] = "p";
        CharacterCodes[CharacterCodes["q"] = 113] = "q";
        CharacterCodes[CharacterCodes["r"] = 114] = "r";
        CharacterCodes[CharacterCodes["s"] = 115] = "s";
        CharacterCodes[CharacterCodes["t"] = 116] = "t";
        CharacterCodes[CharacterCodes["u"] = 117] = "u";
        CharacterCodes[CharacterCodes["v"] = 118] = "v";
        CharacterCodes[CharacterCodes["w"] = 119] = "w";
        CharacterCodes[CharacterCodes["x"] = 120] = "x";
        CharacterCodes[CharacterCodes["y"] = 121] = "y";
        CharacterCodes[CharacterCodes["z"] = 122] = "z";
        CharacterCodes[CharacterCodes["A"] = 65] = "A";
        CharacterCodes[CharacterCodes["B"] = 66] = "B";
        CharacterCodes[CharacterCodes["C"] = 67] = "C";
        CharacterCodes[CharacterCodes["D"] = 68] = "D";
        CharacterCodes[CharacterCodes["E"] = 69] = "E";
        CharacterCodes[CharacterCodes["F"] = 70] = "F";
        CharacterCodes[CharacterCodes["G"] = 71] = "G";
        CharacterCodes[CharacterCodes["H"] = 72] = "H";
        CharacterCodes[CharacterCodes["I"] = 73] = "I";
        CharacterCodes[CharacterCodes["J"] = 74] = "J";
        CharacterCodes[CharacterCodes["K"] = 75] = "K";
        CharacterCodes[CharacterCodes["L"] = 76] = "L";
        CharacterCodes[CharacterCodes["M"] = 77] = "M";
        CharacterCodes[CharacterCodes["N"] = 78] = "N";
        CharacterCodes[CharacterCodes["O"] = 79] = "O";
        CharacterCodes[CharacterCodes["P"] = 80] = "P";
        CharacterCodes[CharacterCodes["Q"] = 81] = "Q";
        CharacterCodes[CharacterCodes["R"] = 82] = "R";
        CharacterCodes[CharacterCodes["S"] = 83] = "S";
        CharacterCodes[CharacterCodes["T"] = 84] = "T";
        CharacterCodes[CharacterCodes["U"] = 85] = "U";
        CharacterCodes[CharacterCodes["V"] = 86] = "V";
        CharacterCodes[CharacterCodes["W"] = 87] = "W";
        CharacterCodes[CharacterCodes["X"] = 88] = "X";
        CharacterCodes[CharacterCodes["Y"] = 89] = "Y";
        CharacterCodes[CharacterCodes["Z"] = 90] = "Z";
        CharacterCodes[CharacterCodes["ampersand"] = 38] = "ampersand";
        CharacterCodes[CharacterCodes["asterisk"] = 42] = "asterisk";
        CharacterCodes[CharacterCodes["at"] = 64] = "at";
        CharacterCodes[CharacterCodes["backslash"] = 92] = "backslash";
        CharacterCodes[CharacterCodes["backtick"] = 96] = "backtick";
        CharacterCodes[CharacterCodes["bar"] = 124] = "bar";
        CharacterCodes[CharacterCodes["caret"] = 94] = "caret";
        CharacterCodes[CharacterCodes["closeBrace"] = 125] = "closeBrace";
        CharacterCodes[CharacterCodes["closeBracket"] = 93] = "closeBracket";
        CharacterCodes[CharacterCodes["closeParen"] = 41] = "closeParen";
        CharacterCodes[CharacterCodes["colon"] = 58] = "colon";
        CharacterCodes[CharacterCodes["comma"] = 44] = "comma";
        CharacterCodes[CharacterCodes["dot"] = 46] = "dot";
        CharacterCodes[CharacterCodes["doubleQuote"] = 34] = "doubleQuote";
        CharacterCodes[CharacterCodes["equals"] = 61] = "equals";
        CharacterCodes[CharacterCodes["exclamation"] = 33] = "exclamation";
        CharacterCodes[CharacterCodes["greaterThan"] = 62] = "greaterThan";
        CharacterCodes[CharacterCodes["hash"] = 35] = "hash";
        CharacterCodes[CharacterCodes["lessThan"] = 60] = "lessThan";
        CharacterCodes[CharacterCodes["minus"] = 45] = "minus";
        CharacterCodes[CharacterCodes["openBrace"] = 123] = "openBrace";
        CharacterCodes[CharacterCodes["openBracket"] = 91] = "openBracket";
        CharacterCodes[CharacterCodes["openParen"] = 40] = "openParen";
        CharacterCodes[CharacterCodes["percent"] = 37] = "percent";
        CharacterCodes[CharacterCodes["plus"] = 43] = "plus";
        CharacterCodes[CharacterCodes["question"] = 63] = "question";
        CharacterCodes[CharacterCodes["semicolon"] = 59] = "semicolon";
        CharacterCodes[CharacterCodes["singleQuote"] = 39] = "singleQuote";
        CharacterCodes[CharacterCodes["slash"] = 47] = "slash";
        CharacterCodes[CharacterCodes["tilde"] = 126] = "tilde";
        CharacterCodes[CharacterCodes["backspace"] = 8] = "backspace";
        CharacterCodes[CharacterCodes["formFeed"] = 12] = "formFeed";
        CharacterCodes[CharacterCodes["byteOrderMark"] = 65279] = "byteOrderMark";
        CharacterCodes[CharacterCodes["tab"] = 9] = "tab";
        CharacterCodes[CharacterCodes["verticalTab"] = 11] = "verticalTab";
    })(CharacterCodes = ts.CharacterCodes || (ts.CharacterCodes = {}));
    var Extension;
    (function (Extension) {
        Extension["Ts"] = ".ts";
        Extension["Tsx"] = ".tsx";
        Extension["Dts"] = ".d.ts";
        Extension["Js"] = ".js";
        Extension["Jsx"] = ".jsx";
        Extension["Json"] = ".json";
        Extension["TsBuildInfo"] = ".tsbuildinfo";
    })(Extension = ts.Extension || (ts.Extension = {}));
    /* @internal */
    var TransformFlags;
    (function (TransformFlags) {
        TransformFlags[TransformFlags["None"] = 0] = "None";
        // Facts
        // - Flags used to indicate that a node or subtree contains syntax that requires transformation.
        TransformFlags[TransformFlags["ContainsTypeScript"] = 1] = "ContainsTypeScript";
        TransformFlags[TransformFlags["ContainsJsx"] = 2] = "ContainsJsx";
        TransformFlags[TransformFlags["ContainsESNext"] = 4] = "ContainsESNext";
        TransformFlags[TransformFlags["ContainsES2019"] = 8] = "ContainsES2019";
        TransformFlags[TransformFlags["ContainsES2018"] = 16] = "ContainsES2018";
        TransformFlags[TransformFlags["ContainsES2017"] = 32] = "ContainsES2017";
        TransformFlags[TransformFlags["ContainsES2016"] = 64] = "ContainsES2016";
        TransformFlags[TransformFlags["ContainsES2015"] = 128] = "ContainsES2015";
        TransformFlags[TransformFlags["ContainsGenerator"] = 256] = "ContainsGenerator";
        TransformFlags[TransformFlags["ContainsDestructuringAssignment"] = 512] = "ContainsDestructuringAssignment";
        // Markers
        // - Flags used to indicate that a subtree contains a specific transformation.
        TransformFlags[TransformFlags["ContainsTypeScriptClassSyntax"] = 1024] = "ContainsTypeScriptClassSyntax";
        TransformFlags[TransformFlags["ContainsLexicalThis"] = 2048] = "ContainsLexicalThis";
        TransformFlags[TransformFlags["ContainsRestOrSpread"] = 4096] = "ContainsRestOrSpread";
        TransformFlags[TransformFlags["ContainsObjectRestOrSpread"] = 8192] = "ContainsObjectRestOrSpread";
        TransformFlags[TransformFlags["ContainsComputedPropertyName"] = 16384] = "ContainsComputedPropertyName";
        TransformFlags[TransformFlags["ContainsBlockScopedBinding"] = 32768] = "ContainsBlockScopedBinding";
        TransformFlags[TransformFlags["ContainsBindingPattern"] = 65536] = "ContainsBindingPattern";
        TransformFlags[TransformFlags["ContainsYield"] = 131072] = "ContainsYield";
        TransformFlags[TransformFlags["ContainsHoistedDeclarationOrCompletion"] = 262144] = "ContainsHoistedDeclarationOrCompletion";
        TransformFlags[TransformFlags["ContainsDynamicImport"] = 524288] = "ContainsDynamicImport";
        // Please leave this as 1 << 29.
        // It is the maximum bit we can set before we outgrow the size of a v8 small integer (SMI) on an x86 system.
        // It is a good reminder of how much room we have left
        TransformFlags[TransformFlags["HasComputedFlags"] = 536870912] = "HasComputedFlags";
        // Assertions
        // - Bitmasks that are used to assert facts about the syntax of a node and its subtree.
        TransformFlags[TransformFlags["AssertTypeScript"] = 1] = "AssertTypeScript";
        TransformFlags[TransformFlags["AssertJsx"] = 2] = "AssertJsx";
        TransformFlags[TransformFlags["AssertESNext"] = 4] = "AssertESNext";
        TransformFlags[TransformFlags["AssertES2019"] = 8] = "AssertES2019";
        TransformFlags[TransformFlags["AssertES2018"] = 16] = "AssertES2018";
        TransformFlags[TransformFlags["AssertES2017"] = 32] = "AssertES2017";
        TransformFlags[TransformFlags["AssertES2016"] = 64] = "AssertES2016";
        TransformFlags[TransformFlags["AssertES2015"] = 128] = "AssertES2015";
        TransformFlags[TransformFlags["AssertGenerator"] = 256] = "AssertGenerator";
        TransformFlags[TransformFlags["AssertDestructuringAssignment"] = 512] = "AssertDestructuringAssignment";
        // Scope Exclusions
        // - Bitmasks that exclude flags from propagating out of a specific context
        //   into the subtree flags of their container.
        TransformFlags[TransformFlags["OuterExpressionExcludes"] = 536870912] = "OuterExpressionExcludes";
        TransformFlags[TransformFlags["PropertyAccessExcludes"] = 536870912] = "PropertyAccessExcludes";
        TransformFlags[TransformFlags["NodeExcludes"] = 536870912] = "NodeExcludes";
        TransformFlags[TransformFlags["ArrowFunctionExcludes"] = 537371648] = "ArrowFunctionExcludes";
        TransformFlags[TransformFlags["FunctionExcludes"] = 537373696] = "FunctionExcludes";
        TransformFlags[TransformFlags["ConstructorExcludes"] = 537372672] = "ConstructorExcludes";
        TransformFlags[TransformFlags["MethodOrAccessorExcludes"] = 537372672] = "MethodOrAccessorExcludes";
        TransformFlags[TransformFlags["PropertyExcludes"] = 536872960] = "PropertyExcludes";
        TransformFlags[TransformFlags["ClassExcludes"] = 536888320] = "ClassExcludes";
        TransformFlags[TransformFlags["ModuleExcludes"] = 537168896] = "ModuleExcludes";
        TransformFlags[TransformFlags["TypeExcludes"] = -2] = "TypeExcludes";
        TransformFlags[TransformFlags["ObjectLiteralExcludes"] = 536896512] = "ObjectLiteralExcludes";
        TransformFlags[TransformFlags["ArrayLiteralOrCallOrNewExcludes"] = 536875008] = "ArrayLiteralOrCallOrNewExcludes";
        TransformFlags[TransformFlags["VariableDeclarationListExcludes"] = 536944640] = "VariableDeclarationListExcludes";
        TransformFlags[TransformFlags["ParameterExcludes"] = 536870912] = "ParameterExcludes";
        TransformFlags[TransformFlags["CatchClauseExcludes"] = 536879104] = "CatchClauseExcludes";
        TransformFlags[TransformFlags["BindingPatternExcludes"] = 536875008] = "BindingPatternExcludes";
        // Propagating flags
        // - Bitmasks for flags that should propagate from a child
        TransformFlags[TransformFlags["PropertyNamePropagatingFlags"] = 2048] = "PropertyNamePropagatingFlags";
        // Masks
        // - Additional bitmasks
    })(TransformFlags = ts.TransformFlags || (ts.TransformFlags = {}));
    var EmitFlags;
    (function (EmitFlags) {
        EmitFlags[EmitFlags["None"] = 0] = "None";
        EmitFlags[EmitFlags["SingleLine"] = 1] = "SingleLine";
        EmitFlags[EmitFlags["AdviseOnEmitNode"] = 2] = "AdviseOnEmitNode";
        EmitFlags[EmitFlags["NoSubstitution"] = 4] = "NoSubstitution";
        EmitFlags[EmitFlags["CapturesThis"] = 8] = "CapturesThis";
        EmitFlags[EmitFlags["NoLeadingSourceMap"] = 16] = "NoLeadingSourceMap";
        EmitFlags[EmitFlags["NoTrailingSourceMap"] = 32] = "NoTrailingSourceMap";
        EmitFlags[EmitFlags["NoSourceMap"] = 48] = "NoSourceMap";
        EmitFlags[EmitFlags["NoNestedSourceMaps"] = 64] = "NoNestedSourceMaps";
        EmitFlags[EmitFlags["NoTokenLeadingSourceMaps"] = 128] = "NoTokenLeadingSourceMaps";
        EmitFlags[EmitFlags["NoTokenTrailingSourceMaps"] = 256] = "NoTokenTrailingSourceMaps";
        EmitFlags[EmitFlags["NoTokenSourceMaps"] = 384] = "NoTokenSourceMaps";
        EmitFlags[EmitFlags["NoLeadingComments"] = 512] = "NoLeadingComments";
        EmitFlags[EmitFlags["NoTrailingComments"] = 1024] = "NoTrailingComments";
        EmitFlags[EmitFlags["NoComments"] = 1536] = "NoComments";
        EmitFlags[EmitFlags["NoNestedComments"] = 2048] = "NoNestedComments";
        EmitFlags[EmitFlags["HelperName"] = 4096] = "HelperName";
        EmitFlags[EmitFlags["ExportName"] = 8192] = "ExportName";
        EmitFlags[EmitFlags["LocalName"] = 16384] = "LocalName";
        EmitFlags[EmitFlags["InternalName"] = 32768] = "InternalName";
        EmitFlags[EmitFlags["Indented"] = 65536] = "Indented";
        EmitFlags[EmitFlags["NoIndentation"] = 131072] = "NoIndentation";
        EmitFlags[EmitFlags["AsyncFunctionBody"] = 262144] = "AsyncFunctionBody";
        EmitFlags[EmitFlags["ReuseTempVariableScope"] = 524288] = "ReuseTempVariableScope";
        EmitFlags[EmitFlags["CustomPrologue"] = 1048576] = "CustomPrologue";
        EmitFlags[EmitFlags["NoHoisting"] = 2097152] = "NoHoisting";
        EmitFlags[EmitFlags["HasEndOfDeclarationMarker"] = 4194304] = "HasEndOfDeclarationMarker";
        EmitFlags[EmitFlags["Iterator"] = 8388608] = "Iterator";
        EmitFlags[EmitFlags["NoAsciiEscaping"] = 16777216] = "NoAsciiEscaping";
        /*@internal*/ EmitFlags[EmitFlags["TypeScriptClassWrapper"] = 33554432] = "TypeScriptClassWrapper";
        /*@internal*/ EmitFlags[EmitFlags["NeverApplyImportHelper"] = 67108864] = "NeverApplyImportHelper";
    })(EmitFlags = ts.EmitFlags || (ts.EmitFlags = {}));
    /**
     * Used by the checker, this enum keeps track of external emit helpers that should be type
     * checked.
     */
    /* @internal */
    var ExternalEmitHelpers;
    (function (ExternalEmitHelpers) {
        ExternalEmitHelpers[ExternalEmitHelpers["Extends"] = 1] = "Extends";
        ExternalEmitHelpers[ExternalEmitHelpers["Assign"] = 2] = "Assign";
        ExternalEmitHelpers[ExternalEmitHelpers["Rest"] = 4] = "Rest";
        ExternalEmitHelpers[ExternalEmitHelpers["Decorate"] = 8] = "Decorate";
        ExternalEmitHelpers[ExternalEmitHelpers["Metadata"] = 16] = "Metadata";
        ExternalEmitHelpers[ExternalEmitHelpers["Param"] = 32] = "Param";
        ExternalEmitHelpers[ExternalEmitHelpers["Awaiter"] = 64] = "Awaiter";
        ExternalEmitHelpers[ExternalEmitHelpers["Generator"] = 128] = "Generator";
        ExternalEmitHelpers[ExternalEmitHelpers["Values"] = 256] = "Values";
        ExternalEmitHelpers[ExternalEmitHelpers["Read"] = 512] = "Read";
        ExternalEmitHelpers[ExternalEmitHelpers["Spread"] = 1024] = "Spread";
        ExternalEmitHelpers[ExternalEmitHelpers["Await"] = 2048] = "Await";
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncGenerator"] = 4096] = "AsyncGenerator";
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncDelegator"] = 8192] = "AsyncDelegator";
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncValues"] = 16384] = "AsyncValues";
        ExternalEmitHelpers[ExternalEmitHelpers["ExportStar"] = 32768] = "ExportStar";
        ExternalEmitHelpers[ExternalEmitHelpers["MakeTemplateObject"] = 65536] = "MakeTemplateObject";
        ExternalEmitHelpers[ExternalEmitHelpers["FirstEmitHelper"] = 1] = "FirstEmitHelper";
        ExternalEmitHelpers[ExternalEmitHelpers["LastEmitHelper"] = 65536] = "LastEmitHelper";
        // Helpers included by ES2015 for..of
        ExternalEmitHelpers[ExternalEmitHelpers["ForOfIncludes"] = 256] = "ForOfIncludes";
        // Helpers included by ES2017 for..await..of
        ExternalEmitHelpers[ExternalEmitHelpers["ForAwaitOfIncludes"] = 16384] = "ForAwaitOfIncludes";
        // Helpers included by ES2017 async generators
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncGeneratorIncludes"] = 6144] = "AsyncGeneratorIncludes";
        // Helpers included by yield* in ES2017 async generators
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncDelegatorIncludes"] = 26624] = "AsyncDelegatorIncludes";
        // Helpers included by ES2015 spread
        ExternalEmitHelpers[ExternalEmitHelpers["SpreadIncludes"] = 1536] = "SpreadIncludes";
    })(ExternalEmitHelpers = ts.ExternalEmitHelpers || (ts.ExternalEmitHelpers = {}));
    var EmitHint;
    (function (EmitHint) {
        EmitHint[EmitHint["SourceFile"] = 0] = "SourceFile";
        EmitHint[EmitHint["Expression"] = 1] = "Expression";
        EmitHint[EmitHint["IdentifierName"] = 2] = "IdentifierName";
        EmitHint[EmitHint["MappedTypeParameter"] = 3] = "MappedTypeParameter";
        EmitHint[EmitHint["Unspecified"] = 4] = "Unspecified";
        EmitHint[EmitHint["EmbeddedStatement"] = 5] = "EmbeddedStatement";
    })(EmitHint = ts.EmitHint || (ts.EmitHint = {}));
    /*@internal*/
    var BundleFileSectionKind;
    (function (BundleFileSectionKind) {
        BundleFileSectionKind["Prologue"] = "prologue";
        BundleFileSectionKind["EmitHelpers"] = "emitHelpers";
        BundleFileSectionKind["NoDefaultLib"] = "no-default-lib";
        BundleFileSectionKind["Reference"] = "reference";
        BundleFileSectionKind["Type"] = "type";
        BundleFileSectionKind["Lib"] = "lib";
        BundleFileSectionKind["Prepend"] = "prepend";
        BundleFileSectionKind["Text"] = "text";
        BundleFileSectionKind["Internal"] = "internal";
        // comments?
    })(BundleFileSectionKind = ts.BundleFileSectionKind || (ts.BundleFileSectionKind = {}));
    var ListFormat;
    (function (ListFormat) {
        ListFormat[ListFormat["None"] = 0] = "None";
        // Line separators
        ListFormat[ListFormat["SingleLine"] = 0] = "SingleLine";
        ListFormat[ListFormat["MultiLine"] = 1] = "MultiLine";
        ListFormat[ListFormat["PreserveLines"] = 2] = "PreserveLines";
        ListFormat[ListFormat["LinesMask"] = 3] = "LinesMask";
        // Delimiters
        ListFormat[ListFormat["NotDelimited"] = 0] = "NotDelimited";
        ListFormat[ListFormat["BarDelimited"] = 4] = "BarDelimited";
        ListFormat[ListFormat["AmpersandDelimited"] = 8] = "AmpersandDelimited";
        ListFormat[ListFormat["CommaDelimited"] = 16] = "CommaDelimited";
        ListFormat[ListFormat["AsteriskDelimited"] = 32] = "AsteriskDelimited";
        ListFormat[ListFormat["DelimitersMask"] = 60] = "DelimitersMask";
        ListFormat[ListFormat["AllowTrailingComma"] = 64] = "AllowTrailingComma";
        // Whitespace
        ListFormat[ListFormat["Indented"] = 128] = "Indented";
        ListFormat[ListFormat["SpaceBetweenBraces"] = 256] = "SpaceBetweenBraces";
        ListFormat[ListFormat["SpaceBetweenSiblings"] = 512] = "SpaceBetweenSiblings";
        // Brackets/Braces
        ListFormat[ListFormat["Braces"] = 1024] = "Braces";
        ListFormat[ListFormat["Parenthesis"] = 2048] = "Parenthesis";
        ListFormat[ListFormat["AngleBrackets"] = 4096] = "AngleBrackets";
        ListFormat[ListFormat["SquareBrackets"] = 8192] = "SquareBrackets";
        ListFormat[ListFormat["BracketsMask"] = 15360] = "BracketsMask";
        ListFormat[ListFormat["OptionalIfUndefined"] = 16384] = "OptionalIfUndefined";
        ListFormat[ListFormat["OptionalIfEmpty"] = 32768] = "OptionalIfEmpty";
        ListFormat[ListFormat["Optional"] = 49152] = "Optional";
        // Other
        ListFormat[ListFormat["PreferNewLine"] = 65536] = "PreferNewLine";
        ListFormat[ListFormat["NoTrailingNewLine"] = 131072] = "NoTrailingNewLine";
        ListFormat[ListFormat["NoInterveningComments"] = 262144] = "NoInterveningComments";
        ListFormat[ListFormat["NoSpaceIfEmpty"] = 524288] = "NoSpaceIfEmpty";
        ListFormat[ListFormat["SingleElement"] = 1048576] = "SingleElement";
        // Precomputed Formats
        ListFormat[ListFormat["Modifiers"] = 262656] = "Modifiers";
        ListFormat[ListFormat["HeritageClauses"] = 512] = "HeritageClauses";
        ListFormat[ListFormat["SingleLineTypeLiteralMembers"] = 768] = "SingleLineTypeLiteralMembers";
        ListFormat[ListFormat["MultiLineTypeLiteralMembers"] = 32897] = "MultiLineTypeLiteralMembers";
        ListFormat[ListFormat["TupleTypeElements"] = 528] = "TupleTypeElements";
        ListFormat[ListFormat["UnionTypeConstituents"] = 516] = "UnionTypeConstituents";
        ListFormat[ListFormat["IntersectionTypeConstituents"] = 520] = "IntersectionTypeConstituents";
        ListFormat[ListFormat["ObjectBindingPatternElements"] = 525136] = "ObjectBindingPatternElements";
        ListFormat[ListFormat["ArrayBindingPatternElements"] = 524880] = "ArrayBindingPatternElements";
        ListFormat[ListFormat["ObjectLiteralExpressionProperties"] = 526226] = "ObjectLiteralExpressionProperties";
        ListFormat[ListFormat["ArrayLiteralExpressionElements"] = 8914] = "ArrayLiteralExpressionElements";
        ListFormat[ListFormat["CommaListElements"] = 528] = "CommaListElements";
        ListFormat[ListFormat["CallExpressionArguments"] = 2576] = "CallExpressionArguments";
        ListFormat[ListFormat["NewExpressionArguments"] = 18960] = "NewExpressionArguments";
        ListFormat[ListFormat["TemplateExpressionSpans"] = 262144] = "TemplateExpressionSpans";
        ListFormat[ListFormat["SingleLineBlockStatements"] = 768] = "SingleLineBlockStatements";
        ListFormat[ListFormat["MultiLineBlockStatements"] = 129] = "MultiLineBlockStatements";
        ListFormat[ListFormat["VariableDeclarationList"] = 528] = "VariableDeclarationList";
        ListFormat[ListFormat["SingleLineFunctionBodyStatements"] = 768] = "SingleLineFunctionBodyStatements";
        ListFormat[ListFormat["MultiLineFunctionBodyStatements"] = 1] = "MultiLineFunctionBodyStatements";
        ListFormat[ListFormat["ClassHeritageClauses"] = 0] = "ClassHeritageClauses";
        ListFormat[ListFormat["ClassMembers"] = 129] = "ClassMembers";
        ListFormat[ListFormat["InterfaceMembers"] = 129] = "InterfaceMembers";
        ListFormat[ListFormat["EnumMembers"] = 145] = "EnumMembers";
        ListFormat[ListFormat["CaseBlockClauses"] = 129] = "CaseBlockClauses";
        ListFormat[ListFormat["NamedImportsOrExportsElements"] = 525136] = "NamedImportsOrExportsElements";
        ListFormat[ListFormat["JsxElementOrFragmentChildren"] = 262144] = "JsxElementOrFragmentChildren";
        ListFormat[ListFormat["JsxElementAttributes"] = 262656] = "JsxElementAttributes";
        ListFormat[ListFormat["CaseOrDefaultClauseStatements"] = 163969] = "CaseOrDefaultClauseStatements";
        ListFormat[ListFormat["HeritageClauseTypes"] = 528] = "HeritageClauseTypes";
        ListFormat[ListFormat["SourceFileStatements"] = 131073] = "SourceFileStatements";
        ListFormat[ListFormat["Decorators"] = 49153] = "Decorators";
        ListFormat[ListFormat["TypeArguments"] = 53776] = "TypeArguments";
        ListFormat[ListFormat["TypeParameters"] = 53776] = "TypeParameters";
        ListFormat[ListFormat["Parameters"] = 2576] = "Parameters";
        ListFormat[ListFormat["IndexSignatureParameters"] = 8848] = "IndexSignatureParameters";
        ListFormat[ListFormat["JSDocComment"] = 33] = "JSDocComment";
    })(ListFormat = ts.ListFormat || (ts.ListFormat = {}));
    /* @internal */
    var PragmaKindFlags;
    (function (PragmaKindFlags) {
        PragmaKindFlags[PragmaKindFlags["None"] = 0] = "None";
        /**
         * Triple slash comment of the form
         * /// <pragma-name argname="value" />
         */
        PragmaKindFlags[PragmaKindFlags["TripleSlashXML"] = 1] = "TripleSlashXML";
        /**
         * Single line comment of the form
         * // @pragma-name argval1 argval2
         * or
         * /// @pragma-name argval1 argval2
         */
        PragmaKindFlags[PragmaKindFlags["SingleLine"] = 2] = "SingleLine";
        /**
         * Multiline non-jsdoc pragma of the form
         * /* @pragma-name argval1 argval2 * /
         */
        PragmaKindFlags[PragmaKindFlags["MultiLine"] = 4] = "MultiLine";
        PragmaKindFlags[PragmaKindFlags["All"] = 7] = "All";
        PragmaKindFlags[PragmaKindFlags["Default"] = 7] = "Default";
    })(PragmaKindFlags = ts.PragmaKindFlags || (ts.PragmaKindFlags = {}));
    // While not strictly a type, this is here because `PragmaMap` needs to be here to be used with `SourceFile`, and we don't
    //  fancy effectively defining it twice, once in value-space and once in type-space
    /* @internal */
    ts.commentPragmas = {
        "reference": {
            args: [
                { name: "types", optional: true, captureSpan: true },
                { name: "lib", optional: true, captureSpan: true },
                { name: "path", optional: true, captureSpan: true },
                { name: "no-default-lib", optional: true }
            ],
            kind: 1 /* TripleSlashXML */
        },
        "amd-dependency": {
            args: [{ name: "path" }, { name: "name", optional: true }],
            kind: 1 /* TripleSlashXML */
        },
        "amd-module": {
            args: [{ name: "name" }],
            kind: 1 /* TripleSlashXML */
        },
        "ts-check": {
            kind: 2 /* SingleLine */
        },
        "ts-nocheck": {
            kind: 2 /* SingleLine */
        },
        "jsx": {
            args: [{ name: "factory" }],
            kind: 4 /* MultiLine */
        },
    };
})(ts || (ts = {}));
var ts;
(function (ts) {
    /**
     * djb2 hashing algorithm
     * http://www.cse.yorku.ca/~oz/hash.html
     */
    /* @internal */
    function generateDjb2Hash(data) {
        var acc = 5381;
        for (var i = 0; i < data.length; i++) {
            acc = ((acc << 5) + acc) + data.charCodeAt(i);
        }
        return acc.toString();
    }
    ts.generateDjb2Hash = generateDjb2Hash;
    /**
     * Set a high stack trace limit to provide more information in case of an error.
     * Called for command-line and server use cases.
     * Not called if TypeScript is used as a library.
     */
    /* @internal */
    function setStackTraceLimit() {
        if (Error.stackTraceLimit < 100) { // Also tests that we won't set the property if it doesn't exist.
            Error.stackTraceLimit = 100;
        }
    }
    ts.setStackTraceLimit = setStackTraceLimit;
    var FileWatcherEventKind;
    (function (FileWatcherEventKind) {
        FileWatcherEventKind[FileWatcherEventKind["Created"] = 0] = "Created";
        FileWatcherEventKind[FileWatcherEventKind["Changed"] = 1] = "Changed";
        FileWatcherEventKind[FileWatcherEventKind["Deleted"] = 2] = "Deleted";
    })(FileWatcherEventKind = ts.FileWatcherEventKind || (ts.FileWatcherEventKind = {}));
    /* @internal */
    var PollingInterval;
    (function (PollingInterval) {
        PollingInterval[PollingInterval["High"] = 2000] = "High";
        PollingInterval[PollingInterval["Medium"] = 500] = "Medium";
        PollingInterval[PollingInterval["Low"] = 250] = "Low";
    })(PollingInterval = ts.PollingInterval || (ts.PollingInterval = {}));
    /* @internal */
    ts.missingFileModifiedTime = new Date(0); // Any subsequent modification will occur after this time
    function createPollingIntervalBasedLevels(levels) {
        var _a;
        return _a = {},
            _a[PollingInterval.Low] = levels.Low,
            _a[PollingInterval.Medium] = levels.Medium,
            _a[PollingInterval.High] = levels.High,
            _a;
    }
    var defaultChunkLevels = { Low: 32, Medium: 64, High: 256 };
    var pollingChunkSize = createPollingIntervalBasedLevels(defaultChunkLevels);
    /* @internal */
    ts.unchangedPollThresholds = createPollingIntervalBasedLevels(defaultChunkLevels);
    /* @internal */
    function setCustomPollingValues(system) {
        if (!system.getEnvironmentVariable) {
            return;
        }
        var pollingIntervalChanged = setCustomLevels("TSC_WATCH_POLLINGINTERVAL", PollingInterval);
        pollingChunkSize = getCustomPollingBasedLevels("TSC_WATCH_POLLINGCHUNKSIZE", defaultChunkLevels) || pollingChunkSize;
        ts.unchangedPollThresholds = getCustomPollingBasedLevels("TSC_WATCH_UNCHANGEDPOLLTHRESHOLDS", defaultChunkLevels) || ts.unchangedPollThresholds;
        function getLevel(envVar, level) {
            return system.getEnvironmentVariable(envVar + "_" + level.toUpperCase());
        }
        function getCustomLevels(baseVariable) {
            var customLevels;
            setCustomLevel("Low");
            setCustomLevel("Medium");
            setCustomLevel("High");
            return customLevels;
            function setCustomLevel(level) {
                var customLevel = getLevel(baseVariable, level);
                if (customLevel) {
                    (customLevels || (customLevels = {}))[level] = Number(customLevel);
                }
            }
        }
        function setCustomLevels(baseVariable, levels) {
            var customLevels = getCustomLevels(baseVariable);
            if (customLevels) {
                setLevel("Low");
                setLevel("Medium");
                setLevel("High");
                return true;
            }
            return false;
            function setLevel(level) {
                levels[level] = customLevels[level] || levels[level];
            }
        }
        function getCustomPollingBasedLevels(baseVariable, defaultLevels) {
            var customLevels = getCustomLevels(baseVariable);
            return (pollingIntervalChanged || customLevels) &&
                createPollingIntervalBasedLevels(customLevels ? __assign({}, defaultLevels, customLevels) : defaultLevels);
        }
    }
    ts.setCustomPollingValues = setCustomPollingValues;
    /* @internal */
    function createDynamicPriorityPollingWatchFile(host) {
        var watchedFiles = [];
        var changedFilesInLastPoll = [];
        var lowPollingIntervalQueue = createPollingIntervalQueue(PollingInterval.Low);
        var mediumPollingIntervalQueue = createPollingIntervalQueue(PollingInterval.Medium);
        var highPollingIntervalQueue = createPollingIntervalQueue(PollingInterval.High);
        return watchFile;
        function watchFile(fileName, callback, defaultPollingInterval) {
            var file = {
                fileName: fileName,
                callback: callback,
                unchangedPolls: 0,
                mtime: getModifiedTime(fileName)
            };
            watchedFiles.push(file);
            addToPollingIntervalQueue(file, defaultPollingInterval);
            return {
                close: function () {
                    file.isClosed = true;
                    // Remove from watchedFiles
                    ts.unorderedRemoveItem(watchedFiles, file);
                    // Do not update polling interval queue since that will happen as part of polling
                }
            };
        }
        function createPollingIntervalQueue(pollingInterval) {
            var queue = [];
            queue.pollingInterval = pollingInterval;
            queue.pollIndex = 0;
            queue.pollScheduled = false;
            return queue;
        }
        function pollPollingIntervalQueue(queue) {
            queue.pollIndex = pollQueue(queue, queue.pollingInterval, queue.pollIndex, pollingChunkSize[queue.pollingInterval]);
            // Set the next polling index and timeout
            if (queue.length) {
                scheduleNextPoll(queue.pollingInterval);
            }
            else {
                ts.Debug.assert(queue.pollIndex === 0);
                queue.pollScheduled = false;
            }
        }
        function pollLowPollingIntervalQueue(queue) {
            // Always poll complete list of changedFilesInLastPoll
            pollQueue(changedFilesInLastPoll, PollingInterval.Low, /*pollIndex*/ 0, changedFilesInLastPoll.length);
            // Finally do the actual polling of the queue
            pollPollingIntervalQueue(queue);
            // Schedule poll if there are files in changedFilesInLastPoll but no files in the actual queue
            // as pollPollingIntervalQueue wont schedule for next poll
            if (!queue.pollScheduled && changedFilesInLastPoll.length) {
                scheduleNextPoll(PollingInterval.Low);
            }
        }
        function pollQueue(queue, pollingInterval, pollIndex, chunkSize) {
            // Max visit would be all elements of the queue
            var needsVisit = queue.length;
            var definedValueCopyToIndex = pollIndex;
            for (var polled = 0; polled < chunkSize && needsVisit > 0; nextPollIndex(), needsVisit--) {
                var watchedFile = queue[pollIndex];
                if (!watchedFile) {
                    continue;
                }
                else if (watchedFile.isClosed) {
                    queue[pollIndex] = undefined;
                    continue;
                }
                polled++;
                var fileChanged = onWatchedFileStat(watchedFile, getModifiedTime(watchedFile.fileName));
                if (watchedFile.isClosed) {
                    // Closed watcher as part of callback
                    queue[pollIndex] = undefined;
                }
                else if (fileChanged) {
                    watchedFile.unchangedPolls = 0;
                    // Changed files go to changedFilesInLastPoll queue
                    if (queue !== changedFilesInLastPoll) {
                        queue[pollIndex] = undefined;
                        addChangedFileToLowPollingIntervalQueue(watchedFile);
                    }
                }
                else if (watchedFile.unchangedPolls !== ts.unchangedPollThresholds[pollingInterval]) {
                    watchedFile.unchangedPolls++;
                }
                else if (queue === changedFilesInLastPoll) {
                    // Restart unchangedPollCount for unchanged file and move to low polling interval queue
                    watchedFile.unchangedPolls = 1;
                    queue[pollIndex] = undefined;
                    addToPollingIntervalQueue(watchedFile, PollingInterval.Low);
                }
                else if (pollingInterval !== PollingInterval.High) {
                    watchedFile.unchangedPolls++;
                    queue[pollIndex] = undefined;
                    addToPollingIntervalQueue(watchedFile, pollingInterval === PollingInterval.Low ? PollingInterval.Medium : PollingInterval.High);
                }
                if (queue[pollIndex]) {
                    // Copy this file to the non hole location
                    if (definedValueCopyToIndex < pollIndex) {
                        queue[definedValueCopyToIndex] = watchedFile;
                        queue[pollIndex] = undefined;
                    }
                    definedValueCopyToIndex++;
                }
            }
            // Return next poll index
            return pollIndex;
            function nextPollIndex() {
                pollIndex++;
                if (pollIndex === queue.length) {
                    if (definedValueCopyToIndex < pollIndex) {
                        // There are holes from nextDefinedValueIndex to end of queue, change queue size
                        queue.length = definedValueCopyToIndex;
                    }
                    pollIndex = 0;
                    definedValueCopyToIndex = 0;
                }
            }
        }
        function pollingIntervalQueue(pollingInterval) {
            switch (pollingInterval) {
                case PollingInterval.Low:
                    return lowPollingIntervalQueue;
                case PollingInterval.Medium:
                    return mediumPollingIntervalQueue;
                case PollingInterval.High:
                    return highPollingIntervalQueue;
            }
        }
        function addToPollingIntervalQueue(file, pollingInterval) {
            pollingIntervalQueue(pollingInterval).push(file);
            scheduleNextPollIfNotAlreadyScheduled(pollingInterval);
        }
        function addChangedFileToLowPollingIntervalQueue(file) {
            changedFilesInLastPoll.push(file);
            scheduleNextPollIfNotAlreadyScheduled(PollingInterval.Low);
        }
        function scheduleNextPollIfNotAlreadyScheduled(pollingInterval) {
            if (!pollingIntervalQueue(pollingInterval).pollScheduled) {
                scheduleNextPoll(pollingInterval);
            }
        }
        function scheduleNextPoll(pollingInterval) {
            pollingIntervalQueue(pollingInterval).pollScheduled = host.setTimeout(pollingInterval === PollingInterval.Low ? pollLowPollingIntervalQueue : pollPollingIntervalQueue, pollingInterval, pollingIntervalQueue(pollingInterval));
        }
        function getModifiedTime(fileName) {
            return host.getModifiedTime(fileName) || ts.missingFileModifiedTime;
        }
    }
    ts.createDynamicPriorityPollingWatchFile = createDynamicPriorityPollingWatchFile;
    /**
     * Returns true if file status changed
     */
    /*@internal*/
    function onWatchedFileStat(watchedFile, modifiedTime) {
        var oldTime = watchedFile.mtime.getTime();
        var newTime = modifiedTime.getTime();
        if (oldTime !== newTime) {
            watchedFile.mtime = modifiedTime;
            watchedFile.callback(watchedFile.fileName, getFileWatcherEventKind(oldTime, newTime));
            return true;
        }
        return false;
    }
    ts.onWatchedFileStat = onWatchedFileStat;
    /*@internal*/
    function getFileWatcherEventKind(oldTime, newTime) {
        return oldTime === 0
            ? FileWatcherEventKind.Created
            : newTime === 0
                ? FileWatcherEventKind.Deleted
                : FileWatcherEventKind.Changed;
    }
    ts.getFileWatcherEventKind = getFileWatcherEventKind;
    /*@internal*/
    ts.ignoredPaths = ["/node_modules/.", "/.git"];
    /**
     * Watch the directory recursively using host provided method to watch child directories
     * that means if this is recursive watcher, watch the children directories as well
     * (eg on OS that dont support recursive watch using fs.watch use fs.watchFile)
     */
    /*@internal*/
    function createRecursiveDirectoryWatcher(host) {
        var cache = ts.createMap();
        var callbackCache = ts.createMultiMap();
        var filePathComparer = ts.getStringComparer(!host.useCaseSensitiveFileNames);
        var toCanonicalFilePath = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames);
        return createDirectoryWatcher;
        /**
         * Create the directory watcher for the dirPath.
         */
        function createDirectoryWatcher(dirName, callback) {
            var dirPath = toCanonicalFilePath(dirName);
            var directoryWatcher = cache.get(dirPath);
            if (directoryWatcher) {
                directoryWatcher.refCount++;
            }
            else {
                directoryWatcher = {
                    watcher: host.watchDirectory(dirName, function (fileName) {
                        if (isIgnoredPath(fileName))
                            return;
                        // Call the actual callback
                        callbackCache.forEach(function (callbacks, rootDirName) {
                            if (rootDirName === dirPath || (ts.startsWith(dirPath, rootDirName) && dirPath[rootDirName.length] === ts.directorySeparator)) {
                                callbacks.forEach(function (callback) { return callback(fileName); });
                            }
                        });
                        // Iterate through existing children and update the watches if needed
                        updateChildWatches(dirName, dirPath);
                    }),
                    refCount: 1,
                    childWatches: ts.emptyArray
                };
                cache.set(dirPath, directoryWatcher);
                updateChildWatches(dirName, dirPath);
            }
            if (callback) {
                callbackCache.add(dirPath, callback);
            }
            return {
                dirName: dirName,
                close: function () {
                    var directoryWatcher = ts.Debug.assertDefined(cache.get(dirPath));
                    if (callback)
                        callbackCache.remove(dirPath, callback);
                    directoryWatcher.refCount--;
                    if (directoryWatcher.refCount)
                        return;
                    cache.delete(dirPath);
                    ts.closeFileWatcherOf(directoryWatcher);
                    directoryWatcher.childWatches.forEach(ts.closeFileWatcher);
                }
            };
        }
        function updateChildWatches(dirName, dirPath) {
            // Iterate through existing children and update the watches if needed
            var parentWatcher = cache.get(dirPath);
            if (parentWatcher) {
                parentWatcher.childWatches = watchChildDirectories(dirName, parentWatcher.childWatches);
            }
        }
        /**
         * Watch the directories in the parentDir
         */
        function watchChildDirectories(parentDir, existingChildWatches) {
            var newChildWatches;
            ts.enumerateInsertsAndDeletes(host.directoryExists(parentDir) ? ts.mapDefined(host.getAccessibleSortedChildDirectories(parentDir), function (child) {
                var childFullName = ts.getNormalizedAbsolutePath(child, parentDir);
                // Filter our the symbolic link directories since those arent included in recursive watch
                // which is same behaviour when recursive: true is passed to fs.watch
                return !isIgnoredPath(childFullName) && filePathComparer(childFullName, ts.normalizePath(host.realpath(childFullName))) === 0 /* EqualTo */ ? childFullName : undefined;
            }) : ts.emptyArray, existingChildWatches, function (child, childWatcher) { return filePathComparer(child, childWatcher.dirName); }, createAndAddChildDirectoryWatcher, ts.closeFileWatcher, addChildDirectoryWatcher);
            return newChildWatches || ts.emptyArray;
            /**
             * Create new childDirectoryWatcher and add it to the new ChildDirectoryWatcher list
             */
            function createAndAddChildDirectoryWatcher(childName) {
                var result = createDirectoryWatcher(childName);
                addChildDirectoryWatcher(result);
            }
            /**
             * Add child directory watcher to the new ChildDirectoryWatcher list
             */
            function addChildDirectoryWatcher(childWatcher) {
                (newChildWatches || (newChildWatches = [])).push(childWatcher);
            }
        }
        function isIgnoredPath(path) {
            return ts.some(ts.ignoredPaths, function (searchPath) { return isInPath(path, searchPath); });
        }
        function isInPath(path, searchPath) {
            if (ts.stringContains(path, searchPath))
                return true;
            if (host.useCaseSensitiveFileNames)
                return false;
            return ts.stringContains(toCanonicalFilePath(path), searchPath);
        }
    }
    ts.createRecursiveDirectoryWatcher = createRecursiveDirectoryWatcher;
    function getNodeMajorVersion() {
        if (typeof process === "undefined") {
            return undefined;
        }
        var version = process.version;
        if (!version) {
            return undefined;
        }
        var dot = version.indexOf(".");
        if (dot === -1) {
            return undefined;
        }
        return parseInt(version.substring(1, dot));
    }
    ts.getNodeMajorVersion = getNodeMajorVersion;
    // TODO: GH#18217 this is used as if it's certainly defined in many places.
    ts.sys = (function () {
        // NodeJS detects "\uFEFF" at the start of the string and *replaces* it with the actual
        // byte order mark from the specified encoding. Using any other byte order mark does
        // not actually work.
        var byteOrderMarkIndicator = "\uFEFF";
        function getNodeSystem() {
            var _fs = require("fs");
            var _path = require("path");
            var _os = require("os");
            // crypto can be absent on reduced node installations
            var _crypto;
            try {
                _crypto = require("crypto");
            }
            catch (_a) {
                _crypto = undefined;
            }
            var Buffer = require("buffer").Buffer;
            var nodeVersion = getNodeMajorVersion();
            var isNode4OrLater = nodeVersion >= 4;
            var platform = _os.platform();
            var useCaseSensitiveFileNames = isFileSystemCaseSensitive();
            var FileSystemEntryKind;
            (function (FileSystemEntryKind) {
                FileSystemEntryKind[FileSystemEntryKind["File"] = 0] = "File";
                FileSystemEntryKind[FileSystemEntryKind["Directory"] = 1] = "Directory";
            })(FileSystemEntryKind || (FileSystemEntryKind = {}));
            var useNonPollingWatchers = process.env.TSC_NONPOLLING_WATCHER;
            var tscWatchFile = process.env.TSC_WATCHFILE;
            var tscWatchDirectory = process.env.TSC_WATCHDIRECTORY;
            var dynamicPollingWatchFile;
            var nodeSystem = {
                args: process.argv.slice(2),
                newLine: _os.EOL,
                useCaseSensitiveFileNames: useCaseSensitiveFileNames,
                write: function (s) {
                    process.stdout.write(s);
                },
                writeOutputIsTTY: function () {
                    return process.stdout.isTTY;
                },
                readFile: readFile,
                writeFile: writeFile,
                watchFile: getWatchFile(),
                watchDirectory: getWatchDirectory(),
                resolvePath: function (path) { return _path.resolve(path); },
                fileExists: fileExists,
                directoryExists: directoryExists,
                createDirectory: function (directoryName) {
                    if (!nodeSystem.directoryExists(directoryName)) {
                        // Wrapped in a try-catch to prevent crashing if we are in a race
                        // with another copy of ourselves to create the same directory
                        try {
                            _fs.mkdirSync(directoryName);
                        }
                        catch (e) {
                            if (e.code !== "EEXIST") {
                                // Failed for some other reason (access denied?); still throw
                                throw e;
                            }
                        }
                    }
                },
                getExecutingFilePath: function () {
                    return __filename;
                },
                getCurrentDirectory: function () {
                    return process.cwd();
                },
                getDirectories: getDirectories,
                getEnvironmentVariable: function (name) {
                    return process.env[name] || "";
                },
                readDirectory: readDirectory,
                getModifiedTime: getModifiedTime,
                setModifiedTime: setModifiedTime,
                deleteFile: deleteFile,
                createHash: _crypto ? createSHA256Hash : generateDjb2Hash,
                createSHA256Hash: _crypto ? createSHA256Hash : undefined,
                getMemoryUsage: function () {
                    if (global.gc) {
                        global.gc();
                    }
                    return process.memoryUsage().heapUsed;
                },
                getFileSize: function (path) {
                    try {
                        var stat = _fs.statSync(path);
                        if (stat.isFile()) {
                            return stat.size;
                        }
                    }
                    catch ( /*ignore*/_a) { /*ignore*/ }
                    return 0;
                },
                exit: function (exitCode) {
                    process.exit(exitCode);
                },
                realpath: realpath,
                debugMode: ts.some(process.execArgv, function (arg) { return /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg); }),
                tryEnableSourceMapsForHost: function () {
                    try {
                        require("source-map-support").install();
                    }
                    catch (_a) {
                        // Could not enable source maps.
                    }
                },
                setTimeout: setTimeout,
                clearTimeout: clearTimeout,
                clearScreen: function () {
                    process.stdout.write("\x1Bc");
                },
                setBlocking: function () {
                    if (process.stdout && process.stdout._handle && process.stdout._handle.setBlocking) {
                        process.stdout._handle.setBlocking(true);
                    }
                },
                bufferFrom: bufferFrom,
                base64decode: function (input) { return bufferFrom(input, "base64").toString("utf8"); },
                base64encode: function (input) { return bufferFrom(input).toString("base64"); },
            };
            return nodeSystem;
            function bufferFrom(input, encoding) {
                // See https://github.com/Microsoft/TypeScript/issues/25652
                return Buffer.from && Buffer.from !== Int8Array.from
                    ? Buffer.from(input, encoding)
                    : new Buffer(input, encoding);
            }
            function isFileSystemCaseSensitive() {
                // win32\win64 are case insensitive platforms
                if (platform === "win32" || platform === "win64") {
                    return false;
                }
                // If this file exists under a different case, we must be case-insensitve.
                return !fileExists(swapCase(__filename));
            }
            /** Convert all lowercase chars to uppercase, and vice-versa */
            function swapCase(s) {
                return s.replace(/\w/g, function (ch) {
                    var up = ch.toUpperCase();
                    return ch === up ? ch.toLowerCase() : up;
                });
            }
            function getWatchFile() {
                switch (tscWatchFile) {
                    case "PriorityPollingInterval":
                        // Use polling interval based on priority when create watch using host.watchFile
                        return fsWatchFile;
                    case "DynamicPriorityPolling":
                        // Use polling interval but change the interval depending on file changes and their default polling interval
                        return createDynamicPriorityPollingWatchFile({ getModifiedTime: getModifiedTime, setTimeout: setTimeout });
                    case "UseFsEvents":
                        // Use notifications from FS to watch with falling back to fs.watchFile
                        return watchFileUsingFsWatch;
                    case "UseFsEventsWithFallbackDynamicPolling":
                        // Use notifications from FS to watch with falling back to dynamic watch file
                        dynamicPollingWatchFile = createDynamicPriorityPollingWatchFile({ getModifiedTime: getModifiedTime, setTimeout: setTimeout });
                        return createWatchFileUsingDynamicWatchFile(dynamicPollingWatchFile);
                    case "UseFsEventsOnParentDirectory":
                        // Use notifications from FS to watch with falling back to fs.watchFile
                        return createNonPollingWatchFile();
                }
                return useNonPollingWatchers ?
                    createNonPollingWatchFile() :
                    // Default to do not use polling interval as it is before this experiment branch
                    function (fileName, callback) { return fsWatchFile(fileName, callback); };
            }
            function getWatchDirectory() {
                // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
                // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
                var fsSupportsRecursive = isNode4OrLater && (process.platform === "win32" || process.platform === "darwin");
                if (fsSupportsRecursive) {
                    return watchDirectoryUsingFsWatch;
                }
                var watchDirectory = tscWatchDirectory === "RecursiveDirectoryUsingFsWatchFile" ?
                    createWatchDirectoryUsing(fsWatchFile) :
                    tscWatchDirectory === "RecursiveDirectoryUsingDynamicPriorityPolling" ?
                        createWatchDirectoryUsing(dynamicPollingWatchFile || createDynamicPriorityPollingWatchFile({ getModifiedTime: getModifiedTime, setTimeout: setTimeout })) :
                        watchDirectoryUsingFsWatch;
                var watchDirectoryRecursively = createRecursiveDirectoryWatcher({
                    useCaseSensitiveFileNames: useCaseSensitiveFileNames,
                    directoryExists: directoryExists,
                    getAccessibleSortedChildDirectories: function (path) { return getAccessibleFileSystemEntries(path).directories; },
                    watchDirectory: watchDirectory,
                    realpath: realpath
                });
                return function (directoryName, callback, recursive) {
                    if (recursive) {
                        return watchDirectoryRecursively(directoryName, callback);
                    }
                    return watchDirectory(directoryName, callback);
                };
            }
            function createNonPollingWatchFile() {
                // One file can have multiple watchers
                var fileWatcherCallbacks = ts.createMultiMap();
                var dirWatchers = ts.createMap();
                var toCanonicalName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
                return nonPollingWatchFile;
                function nonPollingWatchFile(fileName, callback) {
                    var filePath = toCanonicalName(fileName);
                    fileWatcherCallbacks.add(filePath, callback);
                    var dirPath = ts.getDirectoryPath(filePath) || ".";
                    var watcher = dirWatchers.get(dirPath) || createDirectoryWatcher(ts.getDirectoryPath(fileName) || ".", dirPath);
                    watcher.referenceCount++;
                    return {
                        close: function () {
                            if (watcher.referenceCount === 1) {
                                watcher.close();
                                dirWatchers.delete(dirPath);
                            }
                            else {
                                watcher.referenceCount--;
                            }
                            fileWatcherCallbacks.remove(filePath, callback);
                        }
                    };
                }
                function createDirectoryWatcher(dirName, dirPath) {
                    var watcher = fsWatchDirectory(dirName, function (_eventName, relativeFileName) {
                        // When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined"
                        if (!ts.isString(relativeFileName)) {
                            return;
                        }
                        var fileName = ts.getNormalizedAbsolutePath(relativeFileName, dirName);
                        // Some applications save a working file via rename operations
                        var callbacks = fileName && fileWatcherCallbacks.get(toCanonicalName(fileName));
                        if (callbacks) {
                            for (var _i = 0, callbacks_1 = callbacks; _i < callbacks_1.length; _i++) {
                                var fileCallback = callbacks_1[_i];
                                fileCallback(fileName, FileWatcherEventKind.Changed);
                            }
                        }
                    });
                    watcher.referenceCount = 0;
                    dirWatchers.set(dirPath, watcher);
                    return watcher;
                }
            }
            function fsWatchFile(fileName, callback, pollingInterval) {
                _fs.watchFile(fileName, { persistent: true, interval: pollingInterval || 250 }, fileChanged);
                var eventKind;
                return {
                    close: function () { return _fs.unwatchFile(fileName, fileChanged); }
                };
                function fileChanged(curr, prev) {
                    // previous event kind check is to ensure we recongnize the file as previously also missing when it is restored or renamed twice (that is it disappears and reappears)
                    // In such case, prevTime returned is same as prev time of event when file was deleted as per node documentation
                    var isPreviouslyDeleted = +prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted;
                    if (+curr.mtime === 0) {
                        if (isPreviouslyDeleted) {
                            // Already deleted file, no need to callback again
                            return;
                        }
                        eventKind = FileWatcherEventKind.Deleted;
                    }
                    else if (isPreviouslyDeleted) {
                        eventKind = FileWatcherEventKind.Created;
                    }
                    // If there is no change in modified time, ignore the event
                    else if (+curr.mtime === +prev.mtime) {
                        return;
                    }
                    else {
                        // File changed
                        eventKind = FileWatcherEventKind.Changed;
                    }
                    callback(fileName, eventKind);
                }
            }
            function createFileWatcherCallback(callback) {
                return function (_fileName, eventKind) { return callback(eventKind === FileWatcherEventKind.Changed ? "change" : "rename", ""); };
            }
            function createFsWatchCallbackForFileWatcherCallback(fileName, callback) {
                return function (eventName) {
                    if (eventName === "rename") {
                        callback(fileName, fileExists(fileName) ? FileWatcherEventKind.Created : FileWatcherEventKind.Deleted);
                    }
                    else {
                        // Change
                        callback(fileName, FileWatcherEventKind.Changed);
                    }
                };
            }
            function createFsWatchCallbackForDirectoryWatcherCallback(directoryName, callback) {
                return function (eventName, relativeFileName) {
                    // In watchDirectory we only care about adding and removing files (when event name is
                    // "rename"); changes made within files are handled by corresponding fileWatchers (when
                    // event name is "change")
                    if (eventName === "rename") {
                        // When deleting a file, the passed baseFileName is null
                        callback(!relativeFileName ? directoryName : ts.normalizePath(ts.combinePaths(directoryName, relativeFileName)));
                    }
                };
            }
            function fsWatch(fileOrDirectory, entryKind, callback, recursive, fallbackPollingWatchFile, pollingInterval) {
                var options;
                /** Watcher for the file system entry depending on whether it is missing or present */
                var watcher = !fileSystemEntryExists(fileOrDirectory, entryKind) ?
                    watchMissingFileSystemEntry() :
                    watchPresentFileSystemEntry();
                return {
                    close: function () {
                        // Close the watcher (either existing file system entry watcher or missing file system entry watcher)
                        watcher.close();
                        watcher = undefined;
                    }
                };
                /**
                 * Invoke the callback with rename and update the watcher if not closed
                 * @param createWatcher
                 */
                function invokeCallbackAndUpdateWatcher(createWatcher) {
                    // Call the callback for current directory
                    callback("rename", "");
                    // If watcher is not closed, update it
                    if (watcher) {
                        watcher.close();
                        watcher = createWatcher();
                    }
                }
                /**
                 * Watch the file or directory that is currently present
                 * and when the watched file or directory is deleted, switch to missing file system entry watcher
                 */
                function watchPresentFileSystemEntry() {
                    // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
                    // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
                    if (options === undefined) {
                        if (isNode4OrLater && (process.platform === "win32" || process.platform === "darwin")) {
                            options = { persistent: true, recursive: !!recursive };
                        }
                        else {
                            options = { persistent: true };
                        }
                    }
                    try {
                        var presentWatcher = _fs.watch(fileOrDirectory, options, callback);
                        // Watch the missing file or directory or error
                        presentWatcher.on("error", function () { return invokeCallbackAndUpdateWatcher(watchMissingFileSystemEntry); });
                        return presentWatcher;
                    }
                    catch (e) {
                        // Catch the exception and use polling instead
                        // Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
                        // so instead of throwing error, use fs.watchFile
                        return watchPresentFileSystemEntryWithFsWatchFile();
                    }
                }
                /**
                 * Watch the file or directory using fs.watchFile since fs.watch threw exception
                 * Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
                 */
                function watchPresentFileSystemEntryWithFsWatchFile() {
                    return fallbackPollingWatchFile(fileOrDirectory, createFileWatcherCallback(callback), pollingInterval);
                }
                /**
                 * Watch the file or directory that is missing
                 * and switch to existing file or directory when the missing filesystem entry is created
                 */
                function watchMissingFileSystemEntry() {
                    return fallbackPollingWatchFile(fileOrDirectory, function (_fileName, eventKind) {
                        if (eventKind === FileWatcherEventKind.Created && fileSystemEntryExists(fileOrDirectory, entryKind)) {
                            // Call the callback for current file or directory
                            // For now it could be callback for the inner directory creation,
                            // but just return current directory, better than current no-op
                            invokeCallbackAndUpdateWatcher(watchPresentFileSystemEntry);
                        }
                    }, pollingInterval);
                }
            }
            function watchFileUsingFsWatch(fileName, callback, pollingInterval) {
                return fsWatch(fileName, 0 /* File */, createFsWatchCallbackForFileWatcherCallback(fileName, callback), /*recursive*/ false, fsWatchFile, pollingInterval);
            }
            function createWatchFileUsingDynamicWatchFile(watchFile) {
                return function (fileName, callback, pollingInterval) { return fsWatch(fileName, 0 /* File */, createFsWatchCallbackForFileWatcherCallback(fileName, callback), /*recursive*/ false, watchFile, pollingInterval); };
            }
            function fsWatchDirectory(directoryName, callback, recursive) {
                return fsWatch(directoryName, 1 /* Directory */, callback, !!recursive, fsWatchFile);
            }
            function watchDirectoryUsingFsWatch(directoryName, callback, recursive) {
                return fsWatchDirectory(directoryName, createFsWatchCallbackForDirectoryWatcherCallback(directoryName, callback), recursive);
            }
            function createWatchDirectoryUsing(fsWatchFile) {
                return function (directoryName, callback) { return fsWatchFile(directoryName, function () { return callback(directoryName); }, PollingInterval.Medium); };
            }
            function readFile(fileName, _encoding) {
                if (!fileExists(fileName)) {
                    return undefined;
                }
                var buffer = _fs.readFileSync(fileName);
                var len = buffer.length;
                if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) {
                    // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js,
                    // flip all byte pairs and treat as little endian.
                    len &= ~1; // Round down to a multiple of 2
                    for (var i = 0; i < len; i += 2) {
                        var temp = buffer[i];
                        buffer[i] = buffer[i + 1];
                        buffer[i + 1] = temp;
                    }
                    return buffer.toString("utf16le", 2);
                }
                if (len >= 2 && buffer[0] === 0xFF && buffer[1] === 0xFE) {
                    // Little endian UTF-16 byte order mark detected
                    return buffer.toString("utf16le", 2);
                }
                if (len >= 3 && buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
                    // UTF-8 byte order mark detected
                    return buffer.toString("utf8", 3);
                }
                // Default is UTF-8 with no byte order mark
                return buffer.toString("utf8");
            }
            function writeFile(fileName, data, writeByteOrderMark) {
                // If a BOM is required, emit one
                if (writeByteOrderMark) {
                    data = byteOrderMarkIndicator + data;
                }
                var fd;
                try {
                    fd = _fs.openSync(fileName, "w");
                    _fs.writeSync(fd, data, /*position*/ undefined, "utf8");
                }
                finally {
                    if (fd !== undefined) {
                        _fs.closeSync(fd);
                    }
                }
            }
            function getAccessibleFileSystemEntries(path) {
                try {
                    var entries = _fs.readdirSync(path || ".").sort();
                    var files = [];
                    var directories = [];
                    for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) {
                        var entry = entries_2[_i];
                        // This is necessary because on some file system node fails to exclude
                        // "." and "..". See https://github.com/nodejs/node/issues/4002
                        if (entry === "." || entry === "..") {
                            continue;
                        }
                        var name = ts.combinePaths(path, entry);
                        var stat = void 0;
                        try {
                            stat = _fs.statSync(name);
                        }
                        catch (e) {
                            continue;
                        }
                        if (stat.isFile()) {
                            files.push(entry);
                        }
                        else if (stat.isDirectory()) {
                            directories.push(entry);
                        }
                    }
                    return { files: files, directories: directories };
                }
                catch (e) {
                    return ts.emptyFileSystemEntries;
                }
            }
            function readDirectory(path, extensions, excludes, includes, depth) {
                return ts.matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries, realpath);
            }
            function fileSystemEntryExists(path, entryKind) {
                try {
                    var stat = _fs.statSync(path);
                    switch (entryKind) {
                        case 0 /* File */: return stat.isFile();
                        case 1 /* Directory */: return stat.isDirectory();
                        default: return false;
                    }
                }
                catch (e) {
                    return false;
                }
            }
            function fileExists(path) {
                return fileSystemEntryExists(path, 0 /* File */);
            }
            function directoryExists(path) {
                return fileSystemEntryExists(path, 1 /* Directory */);
            }
            function getDirectories(path) {
                return ts.filter(_fs.readdirSync(path), function (dir) { return fileSystemEntryExists(ts.combinePaths(path, dir), 1 /* Directory */); });
            }
            function realpath(path) {
                try {
                    return _fs.realpathSync(path);
                }
                catch (_a) {
                    return path;
                }
            }
            function getModifiedTime(path) {
                try {
                    return _fs.statSync(path).mtime;
                }
                catch (e) {
                    return undefined;
                }
            }
            function setModifiedTime(path, time) {
                try {
                    _fs.utimesSync(path, time, time);
                }
                catch (e) {
                    return;
                }
            }
            function deleteFile(path) {
                try {
                    return _fs.unlinkSync(path);
                }
                catch (e) {
                    return;
                }
            }
            function createSHA256Hash(data) {
                var hash = _crypto.createHash("sha256");
                hash.update(data);
                return hash.digest("hex");
            }
        }
        function getChakraSystem() {
            var realpath = ChakraHost.realpath && (function (path) { return ChakraHost.realpath(path); });
            return {
                newLine: ChakraHost.newLine || "\r\n",
                args: ChakraHost.args,
                useCaseSensitiveFileNames: !!ChakraHost.useCaseSensitiveFileNames,
                write: ChakraHost.echo,
                readFile: function (path, _encoding) {
                    // encoding is automatically handled by the implementation in ChakraHost
                    return ChakraHost.readFile(path);
                },
                writeFile: function (path, data, writeByteOrderMark) {
                    // If a BOM is required, emit one
                    if (writeByteOrderMark) {
                        data = byteOrderMarkIndicator + data;
                    }
                    ChakraHost.writeFile(path, data);
                },
                resolvePath: ChakraHost.resolvePath,
                fileExists: ChakraHost.fileExists,
                deleteFile: ChakraHost.deleteFile,
                getModifiedTime: ChakraHost.getModifiedTime,
                setModifiedTime: ChakraHost.setModifiedTime,
                directoryExists: ChakraHost.directoryExists,
                createDirectory: ChakraHost.createDirectory,
                getExecutingFilePath: function () { return ChakraHost.executingFile; },
                getCurrentDirectory: function () { return ChakraHost.currentDirectory; },
                getDirectories: ChakraHost.getDirectories,
                getEnvironmentVariable: ChakraHost.getEnvironmentVariable || (function () { return ""; }),
                readDirectory: function (path, extensions, excludes, includes, _depth) {
                    var pattern = ts.getFileMatcherPatterns(path, excludes, includes, !!ChakraHost.useCaseSensitiveFileNames, ChakraHost.currentDirectory);
                    return ChakraHost.readDirectory(path, extensions, pattern.basePaths, pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern);
                },
                exit: ChakraHost.quit,
                realpath: realpath
            };
        }
        function recursiveCreateDirectory(directoryPath, sys) {
            var basePath = ts.getDirectoryPath(directoryPath);
            var shouldCreateParent = basePath !== "" && directoryPath !== basePath && !sys.directoryExists(basePath);
            if (shouldCreateParent) {
                recursiveCreateDirectory(basePath, sys);
            }
            if (shouldCreateParent || !sys.directoryExists(directoryPath)) {
                sys.createDirectory(directoryPath);
            }
        }
        var sys;
        if (typeof ChakraHost !== "undefined") {
            sys = getChakraSystem();
        }
        else if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof require !== "undefined") {
            // process and process.nextTick checks if current environment is node-like
            // process.browser check excludes webpack and browserify
            sys = getNodeSystem();
        }
        if (sys) {
            // patch writefile to create folder before writing the file
            var originalWriteFile_1 = sys.writeFile;
            sys.writeFile = function (path, data, writeBom) {
                var directoryPath = ts.getDirectoryPath(ts.normalizeSlashes(path));
                if (directoryPath && !sys.directoryExists(directoryPath)) {
                    recursiveCreateDirectory(directoryPath, sys);
                }
                originalWriteFile_1.call(sys, path, data, writeBom);
            };
        }
        return sys;
    })();
    if (ts.sys && ts.sys.getEnvironmentVariable) {
        setCustomPollingValues(ts.sys);
        ts.Debug.currentAssertionLevel = /^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV"))
            ? 1 /* Normal */
            : 0 /* None */;
    }
    if (ts.sys && ts.sys.debugMode) {
        ts.Debug.isDebugging = true;
    }
})(ts || (ts = {}));
// <auto-generated />
// generated from './diagnosticInformationMap.generated.ts' by 'src/compiler'
/* @internal */
var ts;
(function (ts) {
    function diag(code, category, key, message, reportsUnnecessary) {
        return { code: code, category: category, key: key, message: message, reportsUnnecessary: reportsUnnecessary };
    }
    // tslint:disable-next-line variable-name
    ts.Diagnostics = {
        Unterminated_string_literal: diag(1002, ts.DiagnosticCategory.Error, "Unterminated_string_literal_1002", "Unterminated string literal."),
        Identifier_expected: diag(1003, ts.DiagnosticCategory.Error, "Identifier_expected_1003", "Identifier expected."),
        _0_expected: diag(1005, ts.DiagnosticCategory.Error, "_0_expected_1005", "'{0}' expected."),
        A_file_cannot_have_a_reference_to_itself: diag(1006, ts.DiagnosticCategory.Error, "A_file_cannot_have_a_reference_to_itself_1006", "A file cannot have a reference to itself."),
        Trailing_comma_not_allowed: diag(1009, ts.DiagnosticCategory.Error, "Trailing_comma_not_allowed_1009", "Trailing comma not allowed."),
        Asterisk_Slash_expected: diag(1010, ts.DiagnosticCategory.Error, "Asterisk_Slash_expected_1010", "'*/' expected."),
        An_element_access_expression_should_take_an_argument: diag(1011, ts.DiagnosticCategory.Error, "An_element_access_expression_should_take_an_argument_1011", "An element access expression should take an argument."),
        Unexpected_token: diag(1012, ts.DiagnosticCategory.Error, "Unexpected_token_1012", "Unexpected token."),
        A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma: diag(1013, ts.DiagnosticCategory.Error, "A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma_1013", "A rest parameter or binding pattern may not have a trailing comma."),
        A_rest_parameter_must_be_last_in_a_parameter_list: diag(1014, ts.DiagnosticCategory.Error, "A_rest_parameter_must_be_last_in_a_parameter_list_1014", "A rest parameter must be last in a parameter list."),
        Parameter_cannot_have_question_mark_and_initializer: diag(1015, ts.DiagnosticCategory.Error, "Parameter_cannot_have_question_mark_and_initializer_1015", "Parameter cannot have question mark and initializer."),
        A_required_parameter_cannot_follow_an_optional_parameter: diag(1016, ts.DiagnosticCategory.Error, "A_required_parameter_cannot_follow_an_optional_parameter_1016", "A required parameter cannot follow an optional parameter."),
        An_index_signature_cannot_have_a_rest_parameter: diag(1017, ts.DiagnosticCategory.Error, "An_index_signature_cannot_have_a_rest_parameter_1017", "An index signature cannot have a rest parameter."),
        An_index_signature_parameter_cannot_have_an_accessibility_modifier: diag(1018, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_an_accessibility_modifier_1018", "An index signature parameter cannot have an accessibility modifier."),
        An_index_signature_parameter_cannot_have_a_question_mark: diag(1019, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_a_question_mark_1019", "An index signature parameter cannot have a question mark."),
        An_index_signature_parameter_cannot_have_an_initializer: diag(1020, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_an_initializer_1020", "An index signature parameter cannot have an initializer."),
        An_index_signature_must_have_a_type_annotation: diag(1021, ts.DiagnosticCategory.Error, "An_index_signature_must_have_a_type_annotation_1021", "An index signature must have a type annotation."),
        An_index_signature_parameter_must_have_a_type_annotation: diag(1022, ts.DiagnosticCategory.Error, "An_index_signature_parameter_must_have_a_type_annotation_1022", "An index signature parameter must have a type annotation."),
        An_index_signature_parameter_type_must_be_string_or_number: diag(1023, ts.DiagnosticCategory.Error, "An_index_signature_parameter_type_must_be_string_or_number_1023", "An index signature parameter type must be 'string' or 'number'."),
        readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature: diag(1024, ts.DiagnosticCategory.Error, "readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature_1024", "'readonly' modifier can only appear on a property declaration or index signature."),
        Accessibility_modifier_already_seen: diag(1028, ts.DiagnosticCategory.Error, "Accessibility_modifier_already_seen_1028", "Accessibility modifier already seen."),
        _0_modifier_must_precede_1_modifier: diag(1029, ts.DiagnosticCategory.Error, "_0_modifier_must_precede_1_modifier_1029", "'{0}' modifier must precede '{1}' modifier."),
        _0_modifier_already_seen: diag(1030, ts.DiagnosticCategory.Error, "_0_modifier_already_seen_1030", "'{0}' modifier already seen."),
        _0_modifier_cannot_appear_on_a_class_element: diag(1031, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_class_element_1031", "'{0}' modifier cannot appear on a class element."),
        super_must_be_followed_by_an_argument_list_or_member_access: diag(1034, ts.DiagnosticCategory.Error, "super_must_be_followed_by_an_argument_list_or_member_access_1034", "'super' must be followed by an argument list or member access."),
        Only_ambient_modules_can_use_quoted_names: diag(1035, ts.DiagnosticCategory.Error, "Only_ambient_modules_can_use_quoted_names_1035", "Only ambient modules can use quoted names."),
        Statements_are_not_allowed_in_ambient_contexts: diag(1036, ts.DiagnosticCategory.Error, "Statements_are_not_allowed_in_ambient_contexts_1036", "Statements are not allowed in ambient contexts."),
        A_declare_modifier_cannot_be_used_in_an_already_ambient_context: diag(1038, ts.DiagnosticCategory.Error, "A_declare_modifier_cannot_be_used_in_an_already_ambient_context_1038", "A 'declare' modifier cannot be used in an already ambient context."),
        Initializers_are_not_allowed_in_ambient_contexts: diag(1039, ts.DiagnosticCategory.Error, "Initializers_are_not_allowed_in_ambient_contexts_1039", "Initializers are not allowed in ambient contexts."),
        _0_modifier_cannot_be_used_in_an_ambient_context: diag(1040, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_in_an_ambient_context_1040", "'{0}' modifier cannot be used in an ambient context."),
        _0_modifier_cannot_be_used_with_a_class_declaration: diag(1041, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_with_a_class_declaration_1041", "'{0}' modifier cannot be used with a class declaration."),
        _0_modifier_cannot_be_used_here: diag(1042, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_here_1042", "'{0}' modifier cannot be used here."),
        _0_modifier_cannot_appear_on_a_data_property: diag(1043, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_data_property_1043", "'{0}' modifier cannot appear on a data property."),
        _0_modifier_cannot_appear_on_a_module_or_namespace_element: diag(1044, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_module_or_namespace_element_1044", "'{0}' modifier cannot appear on a module or namespace element."),
        A_0_modifier_cannot_be_used_with_an_interface_declaration: diag(1045, ts.DiagnosticCategory.Error, "A_0_modifier_cannot_be_used_with_an_interface_declaration_1045", "A '{0}' modifier cannot be used with an interface declaration."),
        Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier: diag(1046, ts.DiagnosticCategory.Error, "Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier_1046", "Top-level declarations in .d.ts files must start with either a 'declare' or 'export' modifier."),
        A_rest_parameter_cannot_be_optional: diag(1047, ts.DiagnosticCategory.Error, "A_rest_parameter_cannot_be_optional_1047", "A rest parameter cannot be optional."),
        A_rest_parameter_cannot_have_an_initializer: diag(1048, ts.DiagnosticCategory.Error, "A_rest_parameter_cannot_have_an_initializer_1048", "A rest parameter cannot have an initializer."),
        A_set_accessor_must_have_exactly_one_parameter: diag(1049, ts.DiagnosticCategory.Error, "A_set_accessor_must_have_exactly_one_parameter_1049", "A 'set' accessor must have exactly one parameter."),
        A_set_accessor_cannot_have_an_optional_parameter: diag(1051, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_an_optional_parameter_1051", "A 'set' accessor cannot have an optional parameter."),
        A_set_accessor_parameter_cannot_have_an_initializer: diag(1052, ts.DiagnosticCategory.Error, "A_set_accessor_parameter_cannot_have_an_initializer_1052", "A 'set' accessor parameter cannot have an initializer."),
        A_set_accessor_cannot_have_rest_parameter: diag(1053, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_rest_parameter_1053", "A 'set' accessor cannot have rest parameter."),
        A_get_accessor_cannot_have_parameters: diag(1054, ts.DiagnosticCategory.Error, "A_get_accessor_cannot_have_parameters_1054", "A 'get' accessor cannot have parameters."),
        Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value: diag(1055, ts.DiagnosticCategory.Error, "Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Prom_1055", "Type '{0}' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value."),
        Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher: diag(1056, ts.DiagnosticCategory.Error, "Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher_1056", "Accessors are only available when targeting ECMAScript 5 and higher."),
        An_async_function_or_method_must_have_a_valid_awaitable_return_type: diag(1057, ts.DiagnosticCategory.Error, "An_async_function_or_method_must_have_a_valid_awaitable_return_type_1057", "An async function or method must have a valid awaitable return type."),
        The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1058, ts.DiagnosticCategory.Error, "The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_t_1058", "The return type of an async function must either be a valid promise or must not contain a callable 'then' member."),
        A_promise_must_have_a_then_method: diag(1059, ts.DiagnosticCategory.Error, "A_promise_must_have_a_then_method_1059", "A promise must have a 'then' method."),
        The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback: diag(1060, ts.DiagnosticCategory.Error, "The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback_1060", "The first parameter of the 'then' method of a promise must be a callback."),
        Enum_member_must_have_initializer: diag(1061, ts.DiagnosticCategory.Error, "Enum_member_must_have_initializer_1061", "Enum member must have initializer."),
        Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method: diag(1062, ts.DiagnosticCategory.Error, "Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method_1062", "Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method."),
        An_export_assignment_cannot_be_used_in_a_namespace: diag(1063, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_be_used_in_a_namespace_1063", "An export assignment cannot be used in a namespace."),
        The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type: diag(1064, ts.DiagnosticCategory.Error, "The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_1064", "The return type of an async function or method must be the global Promise<T> type."),
        In_ambient_enum_declarations_member_initializer_must_be_constant_expression: diag(1066, ts.DiagnosticCategory.Error, "In_ambient_enum_declarations_member_initializer_must_be_constant_expression_1066", "In ambient enum declarations member initializer must be constant expression."),
        Unexpected_token_A_constructor_method_accessor_or_property_was_expected: diag(1068, ts.DiagnosticCategory.Error, "Unexpected_token_A_constructor_method_accessor_or_property_was_expected_1068", "Unexpected token. A constructor, method, accessor, or property was expected."),
        Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces: diag(1069, ts.DiagnosticCategory.Error, "Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces_1069", "Unexpected token. A type parameter name was expected without curly braces."),
        _0_modifier_cannot_appear_on_a_type_member: diag(1070, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_type_member_1070", "'{0}' modifier cannot appear on a type member."),
        _0_modifier_cannot_appear_on_an_index_signature: diag(1071, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_an_index_signature_1071", "'{0}' modifier cannot appear on an index signature."),
        A_0_modifier_cannot_be_used_with_an_import_declaration: diag(1079, ts.DiagnosticCategory.Error, "A_0_modifier_cannot_be_used_with_an_import_declaration_1079", "A '{0}' modifier cannot be used with an import declaration."),
        Invalid_reference_directive_syntax: diag(1084, ts.DiagnosticCategory.Error, "Invalid_reference_directive_syntax_1084", "Invalid 'reference' directive syntax."),
        Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0: diag(1085, ts.DiagnosticCategory.Error, "Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0_1085", "Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '{0}'."),
        An_accessor_cannot_be_declared_in_an_ambient_context: diag(1086, ts.DiagnosticCategory.Error, "An_accessor_cannot_be_declared_in_an_ambient_context_1086", "An accessor cannot be declared in an ambient context."),
        _0_modifier_cannot_appear_on_a_constructor_declaration: diag(1089, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_constructor_declaration_1089", "'{0}' modifier cannot appear on a constructor declaration."),
        _0_modifier_cannot_appear_on_a_parameter: diag(1090, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_parameter_1090", "'{0}' modifier cannot appear on a parameter."),
        Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement: diag(1091, ts.DiagnosticCategory.Error, "Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement_1091", "Only a single variable declaration is allowed in a 'for...in' statement."),
        Type_parameters_cannot_appear_on_a_constructor_declaration: diag(1092, ts.DiagnosticCategory.Error, "Type_parameters_cannot_appear_on_a_constructor_declaration_1092", "Type parameters cannot appear on a constructor declaration."),
        Type_annotation_cannot_appear_on_a_constructor_declaration: diag(1093, ts.DiagnosticCategory.Error, "Type_annotation_cannot_appear_on_a_constructor_declaration_1093", "Type annotation cannot appear on a constructor declaration."),
        An_accessor_cannot_have_type_parameters: diag(1094, ts.DiagnosticCategory.Error, "An_accessor_cannot_have_type_parameters_1094", "An accessor cannot have type parameters."),
        A_set_accessor_cannot_have_a_return_type_annotation: diag(1095, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_a_return_type_annotation_1095", "A 'set' accessor cannot have a return type annotation."),
        An_index_signature_must_have_exactly_one_parameter: diag(1096, ts.DiagnosticCategory.Error, "An_index_signature_must_have_exactly_one_parameter_1096", "An index signature must have exactly one parameter."),
        _0_list_cannot_be_empty: diag(1097, ts.DiagnosticCategory.Error, "_0_list_cannot_be_empty_1097", "'{0}' list cannot be empty."),
        Type_parameter_list_cannot_be_empty: diag(1098, ts.DiagnosticCategory.Error, "Type_parameter_list_cannot_be_empty_1098", "Type parameter list cannot be empty."),
        Type_argument_list_cannot_be_empty: diag(1099, ts.DiagnosticCategory.Error, "Type_argument_list_cannot_be_empty_1099", "Type argument list cannot be empty."),
        Invalid_use_of_0_in_strict_mode: diag(1100, ts.DiagnosticCategory.Error, "Invalid_use_of_0_in_strict_mode_1100", "Invalid use of '{0}' in strict mode."),
        with_statements_are_not_allowed_in_strict_mode: diag(1101, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_strict_mode_1101", "'with' statements are not allowed in strict mode."),
        delete_cannot_be_called_on_an_identifier_in_strict_mode: diag(1102, ts.DiagnosticCategory.Error, "delete_cannot_be_called_on_an_identifier_in_strict_mode_1102", "'delete' cannot be called on an identifier in strict mode."),
        A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator: diag(1103, ts.DiagnosticCategory.Error, "A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator_1103", "A 'for-await-of' statement is only allowed within an async function or async generator."),
        A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement: diag(1104, ts.DiagnosticCategory.Error, "A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement_1104", "A 'continue' statement can only be used within an enclosing iteration statement."),
        A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement: diag(1105, ts.DiagnosticCategory.Error, "A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement_1105", "A 'break' statement can only be used within an enclosing iteration or switch statement."),
        Jump_target_cannot_cross_function_boundary: diag(1107, ts.DiagnosticCategory.Error, "Jump_target_cannot_cross_function_boundary_1107", "Jump target cannot cross function boundary."),
        A_return_statement_can_only_be_used_within_a_function_body: diag(1108, ts.DiagnosticCategory.Error, "A_return_statement_can_only_be_used_within_a_function_body_1108", "A 'return' statement can only be used within a function body."),
        Expression_expected: diag(1109, ts.DiagnosticCategory.Error, "Expression_expected_1109", "Expression expected."),
        Type_expected: diag(1110, ts.DiagnosticCategory.Error, "Type_expected_1110", "Type expected."),
        A_default_clause_cannot_appear_more_than_once_in_a_switch_statement: diag(1113, ts.DiagnosticCategory.Error, "A_default_clause_cannot_appear_more_than_once_in_a_switch_statement_1113", "A 'default' clause cannot appear more than once in a 'switch' statement."),
        Duplicate_label_0: diag(1114, ts.DiagnosticCategory.Error, "Duplicate_label_0_1114", "Duplicate label '{0}'."),
        A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement: diag(1115, ts.DiagnosticCategory.Error, "A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement_1115", "A 'continue' statement can only jump to a label of an enclosing iteration statement."),
        A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement: diag(1116, ts.DiagnosticCategory.Error, "A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement_1116", "A 'break' statement can only jump to a label of an enclosing statement."),
        An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode: diag(1117, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode_1117", "An object literal cannot have multiple properties with the same name in strict mode."),
        An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name: diag(1118, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name_1118", "An object literal cannot have multiple get/set accessors with the same name."),
        An_object_literal_cannot_have_property_and_accessor_with_the_same_name: diag(1119, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_property_and_accessor_with_the_same_name_1119", "An object literal cannot have property and accessor with the same name."),
        An_export_assignment_cannot_have_modifiers: diag(1120, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_have_modifiers_1120", "An export assignment cannot have modifiers."),
        Octal_literals_are_not_allowed_in_strict_mode: diag(1121, ts.DiagnosticCategory.Error, "Octal_literals_are_not_allowed_in_strict_mode_1121", "Octal literals are not allowed in strict mode."),
        Variable_declaration_list_cannot_be_empty: diag(1123, ts.DiagnosticCategory.Error, "Variable_declaration_list_cannot_be_empty_1123", "Variable declaration list cannot be empty."),
        Digit_expected: diag(1124, ts.DiagnosticCategory.Error, "Digit_expected_1124", "Digit expected."),
        Hexadecimal_digit_expected: diag(1125, ts.DiagnosticCategory.Error, "Hexadecimal_digit_expected_1125", "Hexadecimal digit expected."),
        Unexpected_end_of_text: diag(1126, ts.DiagnosticCategory.Error, "Unexpected_end_of_text_1126", "Unexpected end of text."),
        Invalid_character: diag(1127, ts.DiagnosticCategory.Error, "Invalid_character_1127", "Invalid character."),
        Declaration_or_statement_expected: diag(1128, ts.DiagnosticCategory.Error, "Declaration_or_statement_expected_1128", "Declaration or statement expected."),
        Statement_expected: diag(1129, ts.DiagnosticCategory.Error, "Statement_expected_1129", "Statement expected."),
        case_or_default_expected: diag(1130, ts.DiagnosticCategory.Error, "case_or_default_expected_1130", "'case' or 'default' expected."),
        Property_or_signature_expected: diag(1131, ts.DiagnosticCategory.Error, "Property_or_signature_expected_1131", "Property or signature expected."),
        Enum_member_expected: diag(1132, ts.DiagnosticCategory.Error, "Enum_member_expected_1132", "Enum member expected."),
        Variable_declaration_expected: diag(1134, ts.DiagnosticCategory.Error, "Variable_declaration_expected_1134", "Variable declaration expected."),
        Argument_expression_expected: diag(1135, ts.DiagnosticCategory.Error, "Argument_expression_expected_1135", "Argument expression expected."),
        Property_assignment_expected: diag(1136, ts.DiagnosticCategory.Error, "Property_assignment_expected_1136", "Property assignment expected."),
        Expression_or_comma_expected: diag(1137, ts.DiagnosticCategory.Error, "Expression_or_comma_expected_1137", "Expression or comma expected."),
        Parameter_declaration_expected: diag(1138, ts.DiagnosticCategory.Error, "Parameter_declaration_expected_1138", "Parameter declaration expected."),
        Type_parameter_declaration_expected: diag(1139, ts.DiagnosticCategory.Error, "Type_parameter_declaration_expected_1139", "Type parameter declaration expected."),
        Type_argument_expected: diag(1140, ts.DiagnosticCategory.Error, "Type_argument_expected_1140", "Type argument expected."),
        String_literal_expected: diag(1141, ts.DiagnosticCategory.Error, "String_literal_expected_1141", "String literal expected."),
        Line_break_not_permitted_here: diag(1142, ts.DiagnosticCategory.Error, "Line_break_not_permitted_here_1142", "Line break not permitted here."),
        or_expected: diag(1144, ts.DiagnosticCategory.Error, "or_expected_1144", "'{' or ';' expected."),
        Declaration_expected: diag(1146, ts.DiagnosticCategory.Error, "Declaration_expected_1146", "Declaration expected."),
        Import_declarations_in_a_namespace_cannot_reference_a_module: diag(1147, ts.DiagnosticCategory.Error, "Import_declarations_in_a_namespace_cannot_reference_a_module_1147", "Import declarations in a namespace cannot reference a module."),
        Cannot_use_imports_exports_or_module_augmentations_when_module_is_none: diag(1148, ts.DiagnosticCategory.Error, "Cannot_use_imports_exports_or_module_augmentations_when_module_is_none_1148", "Cannot use imports, exports, or module augmentations when '--module' is 'none'."),
        File_name_0_differs_from_already_included_file_name_1_only_in_casing: diag(1149, ts.DiagnosticCategory.Error, "File_name_0_differs_from_already_included_file_name_1_only_in_casing_1149", "File name '{0}' differs from already included file name '{1}' only in casing."),
        new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: diag(1150, ts.DiagnosticCategory.Error, "new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead_1150", "'new T[]' cannot be used to create an array. Use 'new Array<T>()' instead."),
        const_declarations_must_be_initialized: diag(1155, ts.DiagnosticCategory.Error, "const_declarations_must_be_initialized_1155", "'const' declarations must be initialized."),
        const_declarations_can_only_be_declared_inside_a_block: diag(1156, ts.DiagnosticCategory.Error, "const_declarations_can_only_be_declared_inside_a_block_1156", "'const' declarations can only be declared inside a block."),
        let_declarations_can_only_be_declared_inside_a_block: diag(1157, ts.DiagnosticCategory.Error, "let_declarations_can_only_be_declared_inside_a_block_1157", "'let' declarations can only be declared inside a block."),
        Unterminated_template_literal: diag(1160, ts.DiagnosticCategory.Error, "Unterminated_template_literal_1160", "Unterminated template literal."),
        Unterminated_regular_expression_literal: diag(1161, ts.DiagnosticCategory.Error, "Unterminated_regular_expression_literal_1161", "Unterminated regular expression literal."),
        An_object_member_cannot_be_declared_optional: diag(1162, ts.DiagnosticCategory.Error, "An_object_member_cannot_be_declared_optional_1162", "An object member cannot be declared optional."),
        A_yield_expression_is_only_allowed_in_a_generator_body: diag(1163, ts.DiagnosticCategory.Error, "A_yield_expression_is_only_allowed_in_a_generator_body_1163", "A 'yield' expression is only allowed in a generator body."),
        Computed_property_names_are_not_allowed_in_enums: diag(1164, ts.DiagnosticCategory.Error, "Computed_property_names_are_not_allowed_in_enums_1164", "Computed property names are not allowed in enums."),
        A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1165, ts.DiagnosticCategory.Error, "A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_t_1165", "A computed property name in an ambient context must refer to an expression whose type is a literal type or a 'unique symbol' type."),
        A_computed_property_name_in_a_class_property_declaration_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1166, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_class_property_declaration_must_refer_to_an_expression_whose_type_is_a_1166", "A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type."),
        A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1168, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_ty_1168", "A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type."),
        A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1169, ts.DiagnosticCategory.Error, "A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_1169", "A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type."),
        A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1170, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type__1170", "A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type."),
        A_comma_expression_is_not_allowed_in_a_computed_property_name: diag(1171, ts.DiagnosticCategory.Error, "A_comma_expression_is_not_allowed_in_a_computed_property_name_1171", "A comma expression is not allowed in a computed property name."),
        extends_clause_already_seen: diag(1172, ts.DiagnosticCategory.Error, "extends_clause_already_seen_1172", "'extends' clause already seen."),
        extends_clause_must_precede_implements_clause: diag(1173, ts.DiagnosticCategory.Error, "extends_clause_must_precede_implements_clause_1173", "'extends' clause must precede 'implements' clause."),
        Classes_can_only_extend_a_single_class: diag(1174, ts.DiagnosticCategory.Error, "Classes_can_only_extend_a_single_class_1174", "Classes can only extend a single class."),
        implements_clause_already_seen: diag(1175, ts.DiagnosticCategory.Error, "implements_clause_already_seen_1175", "'implements' clause already seen."),
        Interface_declaration_cannot_have_implements_clause: diag(1176, ts.DiagnosticCategory.Error, "Interface_declaration_cannot_have_implements_clause_1176", "Interface declaration cannot have 'implements' clause."),
        Binary_digit_expected: diag(1177, ts.DiagnosticCategory.Error, "Binary_digit_expected_1177", "Binary digit expected."),
        Octal_digit_expected: diag(1178, ts.DiagnosticCategory.Error, "Octal_digit_expected_1178", "Octal digit expected."),
        Unexpected_token_expected: diag(1179, ts.DiagnosticCategory.Error, "Unexpected_token_expected_1179", "Unexpected token. '{' expected."),
        Property_destructuring_pattern_expected: diag(1180, ts.DiagnosticCategory.Error, "Property_destructuring_pattern_expected_1180", "Property destructuring pattern expected."),
        Array_element_destructuring_pattern_expected: diag(1181, ts.DiagnosticCategory.Error, "Array_element_destructuring_pattern_expected_1181", "Array element destructuring pattern expected."),
        A_destructuring_declaration_must_have_an_initializer: diag(1182, ts.DiagnosticCategory.Error, "A_destructuring_declaration_must_have_an_initializer_1182", "A destructuring declaration must have an initializer."),
        An_implementation_cannot_be_declared_in_ambient_contexts: diag(1183, ts.DiagnosticCategory.Error, "An_implementation_cannot_be_declared_in_ambient_contexts_1183", "An implementation cannot be declared in ambient contexts."),
        Modifiers_cannot_appear_here: diag(1184, ts.DiagnosticCategory.Error, "Modifiers_cannot_appear_here_1184", "Modifiers cannot appear here."),
        Merge_conflict_marker_encountered: diag(1185, ts.DiagnosticCategory.Error, "Merge_conflict_marker_encountered_1185", "Merge conflict marker encountered."),
        A_rest_element_cannot_have_an_initializer: diag(1186, ts.DiagnosticCategory.Error, "A_rest_element_cannot_have_an_initializer_1186", "A rest element cannot have an initializer."),
        A_parameter_property_may_not_be_declared_using_a_binding_pattern: diag(1187, ts.DiagnosticCategory.Error, "A_parameter_property_may_not_be_declared_using_a_binding_pattern_1187", "A parameter property may not be declared using a binding pattern."),
        Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement: diag(1188, ts.DiagnosticCategory.Error, "Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement_1188", "Only a single variable declaration is allowed in a 'for...of' statement."),
        The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer: diag(1189, ts.DiagnosticCategory.Error, "The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer_1189", "The variable declaration of a 'for...in' statement cannot have an initializer."),
        The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer: diag(1190, ts.DiagnosticCategory.Error, "The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer_1190", "The variable declaration of a 'for...of' statement cannot have an initializer."),
        An_import_declaration_cannot_have_modifiers: diag(1191, ts.DiagnosticCategory.Error, "An_import_declaration_cannot_have_modifiers_1191", "An import declaration cannot have modifiers."),
        Module_0_has_no_default_export: diag(1192, ts.DiagnosticCategory.Error, "Module_0_has_no_default_export_1192", "Module '{0}' has no default export."),
        An_export_declaration_cannot_have_modifiers: diag(1193, ts.DiagnosticCategory.Error, "An_export_declaration_cannot_have_modifiers_1193", "An export declaration cannot have modifiers."),
        Export_declarations_are_not_permitted_in_a_namespace: diag(1194, ts.DiagnosticCategory.Error, "Export_declarations_are_not_permitted_in_a_namespace_1194", "Export declarations are not permitted in a namespace."),
        Catch_clause_variable_cannot_have_a_type_annotation: diag(1196, ts.DiagnosticCategory.Error, "Catch_clause_variable_cannot_have_a_type_annotation_1196", "Catch clause variable cannot have a type annotation."),
        Catch_clause_variable_cannot_have_an_initializer: diag(1197, ts.DiagnosticCategory.Error, "Catch_clause_variable_cannot_have_an_initializer_1197", "Catch clause variable cannot have an initializer."),
        An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive: diag(1198, ts.DiagnosticCategory.Error, "An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive_1198", "An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive."),
        Unterminated_Unicode_escape_sequence: diag(1199, ts.DiagnosticCategory.Error, "Unterminated_Unicode_escape_sequence_1199", "Unterminated Unicode escape sequence."),
        Line_terminator_not_permitted_before_arrow: diag(1200, ts.DiagnosticCategory.Error, "Line_terminator_not_permitted_before_arrow_1200", "Line terminator not permitted before arrow."),
        Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead: diag(1202, ts.DiagnosticCategory.Error, "Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_1202", "Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"', or another module format instead."),
        Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead: diag(1203, ts.DiagnosticCategory.Error, "Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or__1203", "Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead."),
        Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided: diag(1205, ts.DiagnosticCategory.Error, "Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided_1205", "Cannot re-export a type when the '--isolatedModules' flag is provided."),
        Decorators_are_not_valid_here: diag(1206, ts.DiagnosticCategory.Error, "Decorators_are_not_valid_here_1206", "Decorators are not valid here."),
        Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: diag(1207, ts.DiagnosticCategory.Error, "Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name_1207", "Decorators cannot be applied to multiple get/set accessors of the same name."),
        All_files_must_be_modules_when_the_isolatedModules_flag_is_provided: diag(1208, ts.DiagnosticCategory.Error, "All_files_must_be_modules_when_the_isolatedModules_flag_is_provided_1208", "All files must be modules when the '--isolatedModules' flag is provided."),
        Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: diag(1210, ts.DiagnosticCategory.Error, "Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode_1210", "Invalid use of '{0}'. Class definitions are automatically in strict mode."),
        A_class_declaration_without_the_default_modifier_must_have_a_name: diag(1211, ts.DiagnosticCategory.Error, "A_class_declaration_without_the_default_modifier_must_have_a_name_1211", "A class declaration without the 'default' modifier must have a name."),
        Identifier_expected_0_is_a_reserved_word_in_strict_mode: diag(1212, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_1212", "Identifier expected. '{0}' is a reserved word in strict mode."),
        Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: diag(1213, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_stric_1213", "Identifier expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode."),
        Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode: diag(1214, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode_1214", "Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode."),
        Invalid_use_of_0_Modules_are_automatically_in_strict_mode: diag(1215, ts.DiagnosticCategory.Error, "Invalid_use_of_0_Modules_are_automatically_in_strict_mode_1215", "Invalid use of '{0}'. Modules are automatically in strict mode."),
        Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules: diag(1216, ts.DiagnosticCategory.Error, "Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules_1216", "Identifier expected. '__esModule' is reserved as an exported marker when transforming ECMAScript modules."),
        Export_assignment_is_not_supported_when_module_flag_is_system: diag(1218, ts.DiagnosticCategory.Error, "Export_assignment_is_not_supported_when_module_flag_is_system_1218", "Export assignment is not supported when '--module' flag is 'system'."),
        Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning: diag(1219, ts.DiagnosticCategory.Error, "Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_t_1219", "Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning."),
        Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher: diag(1220, ts.DiagnosticCategory.Error, "Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher_1220", "Generators are only available when targeting ECMAScript 2015 or higher."),
        Generators_are_not_allowed_in_an_ambient_context: diag(1221, ts.DiagnosticCategory.Error, "Generators_are_not_allowed_in_an_ambient_context_1221", "Generators are not allowed in an ambient context."),
        An_overload_signature_cannot_be_declared_as_a_generator: diag(1222, ts.DiagnosticCategory.Error, "An_overload_signature_cannot_be_declared_as_a_generator_1222", "An overload signature cannot be declared as a generator."),
        _0_tag_already_specified: diag(1223, ts.DiagnosticCategory.Error, "_0_tag_already_specified_1223", "'{0}' tag already specified."),
        Signature_0_must_be_a_type_predicate: diag(1224, ts.DiagnosticCategory.Error, "Signature_0_must_be_a_type_predicate_1224", "Signature '{0}' must be a type predicate."),
        Cannot_find_parameter_0: diag(1225, ts.DiagnosticCategory.Error, "Cannot_find_parameter_0_1225", "Cannot find parameter '{0}'."),
        Type_predicate_0_is_not_assignable_to_1: diag(1226, ts.DiagnosticCategory.Error, "Type_predicate_0_is_not_assignable_to_1_1226", "Type predicate '{0}' is not assignable to '{1}'."),
        Parameter_0_is_not_in_the_same_position_as_parameter_1: diag(1227, ts.DiagnosticCategory.Error, "Parameter_0_is_not_in_the_same_position_as_parameter_1_1227", "Parameter '{0}' is not in the same position as parameter '{1}'."),
        A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods: diag(1228, ts.DiagnosticCategory.Error, "A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods_1228", "A type predicate is only allowed in return type position for functions and methods."),
        A_type_predicate_cannot_reference_a_rest_parameter: diag(1229, ts.DiagnosticCategory.Error, "A_type_predicate_cannot_reference_a_rest_parameter_1229", "A type predicate cannot reference a rest parameter."),
        A_type_predicate_cannot_reference_element_0_in_a_binding_pattern: diag(1230, ts.DiagnosticCategory.Error, "A_type_predicate_cannot_reference_element_0_in_a_binding_pattern_1230", "A type predicate cannot reference element '{0}' in a binding pattern."),
        An_export_assignment_can_only_be_used_in_a_module: diag(1231, ts.DiagnosticCategory.Error, "An_export_assignment_can_only_be_used_in_a_module_1231", "An export assignment can only be used in a module."),
        An_import_declaration_can_only_be_used_in_a_namespace_or_module: diag(1232, ts.DiagnosticCategory.Error, "An_import_declaration_can_only_be_used_in_a_namespace_or_module_1232", "An import declaration can only be used in a namespace or module."),
        An_export_declaration_can_only_be_used_in_a_module: diag(1233, ts.DiagnosticCategory.Error, "An_export_declaration_can_only_be_used_in_a_module_1233", "An export declaration can only be used in a module."),
        An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file: diag(1234, ts.DiagnosticCategory.Error, "An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file_1234", "An ambient module declaration is only allowed at the top level in a file."),
        A_namespace_declaration_is_only_allowed_in_a_namespace_or_module: diag(1235, ts.DiagnosticCategory.Error, "A_namespace_declaration_is_only_allowed_in_a_namespace_or_module_1235", "A namespace declaration is only allowed in a namespace or module."),
        The_return_type_of_a_property_decorator_function_must_be_either_void_or_any: diag(1236, ts.DiagnosticCategory.Error, "The_return_type_of_a_property_decorator_function_must_be_either_void_or_any_1236", "The return type of a property decorator function must be either 'void' or 'any'."),
        The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any: diag(1237, ts.DiagnosticCategory.Error, "The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any_1237", "The return type of a parameter decorator function must be either 'void' or 'any'."),
        Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression: diag(1238, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression_1238", "Unable to resolve signature of class decorator when called as an expression."),
        Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression: diag(1239, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression_1239", "Unable to resolve signature of parameter decorator when called as an expression."),
        Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression: diag(1240, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression_1240", "Unable to resolve signature of property decorator when called as an expression."),
        Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression: diag(1241, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression_1241", "Unable to resolve signature of method decorator when called as an expression."),
        abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration: diag(1242, ts.DiagnosticCategory.Error, "abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration_1242", "'abstract' modifier can only appear on a class, method, or property declaration."),
        _0_modifier_cannot_be_used_with_1_modifier: diag(1243, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_with_1_modifier_1243", "'{0}' modifier cannot be used with '{1}' modifier."),
        Abstract_methods_can_only_appear_within_an_abstract_class: diag(1244, ts.DiagnosticCategory.Error, "Abstract_methods_can_only_appear_within_an_abstract_class_1244", "Abstract methods can only appear within an abstract class."),
        Method_0_cannot_have_an_implementation_because_it_is_marked_abstract: diag(1245, ts.DiagnosticCategory.Error, "Method_0_cannot_have_an_implementation_because_it_is_marked_abstract_1245", "Method '{0}' cannot have an implementation because it is marked abstract."),
        An_interface_property_cannot_have_an_initializer: diag(1246, ts.DiagnosticCategory.Error, "An_interface_property_cannot_have_an_initializer_1246", "An interface property cannot have an initializer."),
        A_type_literal_property_cannot_have_an_initializer: diag(1247, ts.DiagnosticCategory.Error, "A_type_literal_property_cannot_have_an_initializer_1247", "A type literal property cannot have an initializer."),
        A_class_member_cannot_have_the_0_keyword: diag(1248, ts.DiagnosticCategory.Error, "A_class_member_cannot_have_the_0_keyword_1248", "A class member cannot have the '{0}' keyword."),
        A_decorator_can_only_decorate_a_method_implementation_not_an_overload: diag(1249, ts.DiagnosticCategory.Error, "A_decorator_can_only_decorate_a_method_implementation_not_an_overload_1249", "A decorator can only decorate a method implementation, not an overload."),
        Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5: diag(1250, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'."),
        Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_definitions_are_automatically_in_strict_mode: diag(1251, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_d_1251", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Class definitions are automatically in strict mode."),
        Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_are_automatically_in_strict_mode: diag(1252, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_1252", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Modules are automatically in strict mode."),
        _0_tag_cannot_be_used_independently_as_a_top_level_JSDoc_tag: diag(1253, ts.DiagnosticCategory.Error, "_0_tag_cannot_be_used_independently_as_a_top_level_JSDoc_tag_1253", "'{0}' tag cannot be used independently as a top level JSDoc tag."),
        A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_reference: diag(1254, ts.DiagnosticCategory.Error, "A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_refere_1254", "A 'const' initializer in an ambient context must be a string or numeric literal or literal enum reference."),
        A_definite_assignment_assertion_is_not_permitted_in_this_context: diag(1255, ts.DiagnosticCategory.Error, "A_definite_assignment_assertion_is_not_permitted_in_this_context_1255", "A definite assignment assertion '!' is not permitted in this context."),
        A_rest_element_must_be_last_in_a_tuple_type: diag(1256, ts.DiagnosticCategory.Error, "A_rest_element_must_be_last_in_a_tuple_type_1256", "A rest element must be last in a tuple type."),
        A_required_element_cannot_follow_an_optional_element: diag(1257, ts.DiagnosticCategory.Error, "A_required_element_cannot_follow_an_optional_element_1257", "A required element cannot follow an optional element."),
        Definite_assignment_assertions_can_only_be_used_along_with_a_type_annotation: diag(1258, ts.DiagnosticCategory.Error, "Definite_assignment_assertions_can_only_be_used_along_with_a_type_annotation_1258", "Definite assignment assertions can only be used along with a type annotation."),
        Module_0_can_only_be_default_imported_using_the_1_flag: diag(1259, ts.DiagnosticCategory.Error, "Module_0_can_only_be_default_imported_using_the_1_flag_1259", "Module '{0}' can only be default-imported using the '{1}' flag"),
        with_statements_are_not_allowed_in_an_async_function_block: diag(1300, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_an_async_function_block_1300", "'with' statements are not allowed in an async function block."),
        await_expression_is_only_allowed_within_an_async_function: diag(1308, ts.DiagnosticCategory.Error, "await_expression_is_only_allowed_within_an_async_function_1308", "'await' expression is only allowed within an async function."),
        can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment: diag(1312, ts.DiagnosticCategory.Error, "can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment_1312", "'=' can only be used in an object literal property inside a destructuring assignment."),
        The_body_of_an_if_statement_cannot_be_the_empty_statement: diag(1313, ts.DiagnosticCategory.Error, "The_body_of_an_if_statement_cannot_be_the_empty_statement_1313", "The body of an 'if' statement cannot be the empty statement."),
        Global_module_exports_may_only_appear_in_module_files: diag(1314, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_module_files_1314", "Global module exports may only appear in module files."),
        Global_module_exports_may_only_appear_in_declaration_files: diag(1315, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_declaration_files_1315", "Global module exports may only appear in declaration files."),
        Global_module_exports_may_only_appear_at_top_level: diag(1316, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_at_top_level_1316", "Global module exports may only appear at top level."),
        A_parameter_property_cannot_be_declared_using_a_rest_parameter: diag(1317, ts.DiagnosticCategory.Error, "A_parameter_property_cannot_be_declared_using_a_rest_parameter_1317", "A parameter property cannot be declared using a rest parameter."),
        An_abstract_accessor_cannot_have_an_implementation: diag(1318, ts.DiagnosticCategory.Error, "An_abstract_accessor_cannot_have_an_implementation_1318", "An abstract accessor cannot have an implementation."),
        A_default_export_can_only_be_used_in_an_ECMAScript_style_module: diag(1319, ts.DiagnosticCategory.Error, "A_default_export_can_only_be_used_in_an_ECMAScript_style_module_1319", "A default export can only be used in an ECMAScript-style module."),
        Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1320, ts.DiagnosticCategory.Error, "Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member_1320", "Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member."),
        Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1321, ts.DiagnosticCategory.Error, "Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_cal_1321", "Type of 'yield' operand in an async generator must either be a valid promise or must not contain a callable 'then' member."),
        Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1322, ts.DiagnosticCategory.Error, "Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_con_1322", "Type of iterated elements of a 'yield*' operand must either be a valid promise or must not contain a callable 'then' member."),
        Dynamic_import_is_only_supported_when_module_flag_is_commonjs_or_esNext: diag(1323, ts.DiagnosticCategory.Error, "Dynamic_import_is_only_supported_when_module_flag_is_commonjs_or_esNext_1323", "Dynamic import is only supported when '--module' flag is 'commonjs' or 'esNext'."),
        Dynamic_import_must_have_one_specifier_as_an_argument: diag(1324, ts.DiagnosticCategory.Error, "Dynamic_import_must_have_one_specifier_as_an_argument_1324", "Dynamic import must have one specifier as an argument."),
        Specifier_of_dynamic_import_cannot_be_spread_element: diag(1325, ts.DiagnosticCategory.Error, "Specifier_of_dynamic_import_cannot_be_spread_element_1325", "Specifier of dynamic import cannot be spread element."),
        Dynamic_import_cannot_have_type_arguments: diag(1326, ts.DiagnosticCategory.Error, "Dynamic_import_cannot_have_type_arguments_1326", "Dynamic import cannot have type arguments"),
        String_literal_with_double_quotes_expected: diag(1327, ts.DiagnosticCategory.Error, "String_literal_with_double_quotes_expected_1327", "String literal with double quotes expected."),
        Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_literal: diag(1328, ts.DiagnosticCategory.Error, "Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_li_1328", "Property value can only be string literal, numeric literal, 'true', 'false', 'null', object literal or array literal."),
        _0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0: diag(1329, ts.DiagnosticCategory.Error, "_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329", "'{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?"),
        A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly: diag(1330, ts.DiagnosticCategory.Error, "A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly_1330", "A property of an interface or type literal whose type is a 'unique symbol' type must be 'readonly'."),
        A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly: diag(1331, ts.DiagnosticCategory.Error, "A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly_1331", "A property of a class whose type is a 'unique symbol' type must be both 'static' and 'readonly'."),
        A_variable_whose_type_is_a_unique_symbol_type_must_be_const: diag(1332, ts.DiagnosticCategory.Error, "A_variable_whose_type_is_a_unique_symbol_type_must_be_const_1332", "A variable whose type is a 'unique symbol' type must be 'const'."),
        unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name: diag(1333, ts.DiagnosticCategory.Error, "unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name_1333", "'unique symbol' types may not be used on a variable declaration with a binding name."),
        unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement: diag(1334, ts.DiagnosticCategory.Error, "unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement_1334", "'unique symbol' types are only allowed on variables in a variable statement."),
        unique_symbol_types_are_not_allowed_here: diag(1335, ts.DiagnosticCategory.Error, "unique_symbol_types_are_not_allowed_here_1335", "'unique symbol' types are not allowed here."),
        An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead: diag(1336, ts.DiagnosticCategory.Error, "An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead_1336", "An index signature parameter type cannot be a type alias. Consider writing '[{0}: {1}]: {2}' instead."),
        An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead: diag(1337, ts.DiagnosticCategory.Error, "An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead_1337", "An index signature parameter type cannot be a union type. Consider using a mapped object type instead."),
        infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type: diag(1338, ts.DiagnosticCategory.Error, "infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type_1338", "'infer' declarations are only permitted in the 'extends' clause of a conditional type."),
        Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here: diag(1339, ts.DiagnosticCategory.Error, "Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here_1339", "Module '{0}' does not refer to a value, but is used as a value here."),
        Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0: diag(1340, ts.DiagnosticCategory.Error, "Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0_1340", "Module '{0}' does not refer to a type, but is used as a type here. Did you mean 'typeof import('{0}')'?"),
        Type_arguments_cannot_be_used_here: diag(1342, ts.DiagnosticCategory.Error, "Type_arguments_cannot_be_used_here_1342", "Type arguments cannot be used here."),
        The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_options: diag(1343, ts.DiagnosticCategory.Error, "The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343", "The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options."),
        A_label_is_not_allowed_here: diag(1344, ts.DiagnosticCategory.Error, "A_label_is_not_allowed_here_1344", "'A label is not allowed here."),
        An_expression_of_type_void_cannot_be_tested_for_truthiness: diag(1345, ts.DiagnosticCategory.Error, "An_expression_of_type_void_cannot_be_tested_for_truthiness_1345", "An expression of type 'void' cannot be tested for truthiness"),
        This_parameter_is_not_allowed_with_use_strict_directive: diag(1346, ts.DiagnosticCategory.Error, "This_parameter_is_not_allowed_with_use_strict_directive_1346", "This parameter is not allowed with 'use strict' directive."),
        use_strict_directive_cannot_be_used_with_non_simple_parameter_list: diag(1347, ts.DiagnosticCategory.Error, "use_strict_directive_cannot_be_used_with_non_simple_parameter_list_1347", "'use strict' directive cannot be used with non-simple parameter list."),
        Non_simple_parameter_declared_here: diag(1348, ts.DiagnosticCategory.Error, "Non_simple_parameter_declared_here_1348", "Non-simple parameter declared here."),
        use_strict_directive_used_here: diag(1349, ts.DiagnosticCategory.Error, "use_strict_directive_used_here_1349", "'use strict' directive used here."),
        Print_the_final_configuration_instead_of_building: diag(1350, ts.DiagnosticCategory.Message, "Print_the_final_configuration_instead_of_building_1350", "Print the final configuration instead of building."),
        An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal: diag(1351, ts.DiagnosticCategory.Error, "An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal_1351", "An identifier or keyword cannot immediately follow a numeric literal."),
        A_bigint_literal_cannot_use_exponential_notation: diag(1352, ts.DiagnosticCategory.Error, "A_bigint_literal_cannot_use_exponential_notation_1352", "A bigint literal cannot use exponential notation."),
        A_bigint_literal_must_be_an_integer: diag(1353, ts.DiagnosticCategory.Error, "A_bigint_literal_must_be_an_integer_1353", "A bigint literal must be an integer."),
        readonly_type_modifier_is_only_permitted_on_array_and_tuple_literal_types: diag(1354, ts.DiagnosticCategory.Error, "readonly_type_modifier_is_only_permitted_on_array_and_tuple_literal_types_1354", "'readonly' type modifier is only permitted on array and tuple literal types."),
        A_const_assertions_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array_or_object_literals: diag(1355, ts.DiagnosticCategory.Error, "A_const_assertions_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array__1355", "A 'const' assertions can only be applied to references to enum members, or string, number, boolean, array, or object literals."),
        Did_you_mean_to_mark_this_function_as_async: diag(1356, ts.DiagnosticCategory.Error, "Did_you_mean_to_mark_this_function_as_async_1356", "Did you mean to mark this function as 'async'?"),
        Duplicate_identifier_0: diag(2300, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_2300", "Duplicate identifier '{0}'."),
        Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: diag(2301, ts.DiagnosticCategory.Error, "Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor_2301", "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor."),
        Static_members_cannot_reference_class_type_parameters: diag(2302, ts.DiagnosticCategory.Error, "Static_members_cannot_reference_class_type_parameters_2302", "Static members cannot reference class type parameters."),
        Circular_definition_of_import_alias_0: diag(2303, ts.DiagnosticCategory.Error, "Circular_definition_of_import_alias_0_2303", "Circular definition of import alias '{0}'."),
        Cannot_find_name_0: diag(2304, ts.DiagnosticCategory.Error, "Cannot_find_name_0_2304", "Cannot find name '{0}'."),
        Module_0_has_no_exported_member_1: diag(2305, ts.DiagnosticCategory.Error, "Module_0_has_no_exported_member_1_2305", "Module '{0}' has no exported member '{1}'."),
        File_0_is_not_a_module: diag(2306, ts.DiagnosticCategory.Error, "File_0_is_not_a_module_2306", "File '{0}' is not a module."),
        Cannot_find_module_0: diag(2307, ts.DiagnosticCategory.Error, "Cannot_find_module_0_2307", "Cannot find module '{0}'."),
        Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity: diag(2308, ts.DiagnosticCategory.Error, "Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambig_2308", "Module {0} has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity."),
        An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements: diag(2309, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements_2309", "An export assignment cannot be used in a module with other exported elements."),
        Type_0_recursively_references_itself_as_a_base_type: diag(2310, ts.DiagnosticCategory.Error, "Type_0_recursively_references_itself_as_a_base_type_2310", "Type '{0}' recursively references itself as a base type."),
        A_class_may_only_extend_another_class: diag(2311, ts.DiagnosticCategory.Error, "A_class_may_only_extend_another_class_2311", "A class may only extend another class."),
        An_interface_can_only_extend_an_object_type_or_intersection_of_object_types_with_statically_known_members: diag(2312, ts.DiagnosticCategory.Error, "An_interface_can_only_extend_an_object_type_or_intersection_of_object_types_with_statically_known_me_2312", "An interface can only extend an object type or intersection of object types with statically known members."),
        Type_parameter_0_has_a_circular_constraint: diag(2313, ts.DiagnosticCategory.Error, "Type_parameter_0_has_a_circular_constraint_2313", "Type parameter '{0}' has a circular constraint."),
        Generic_type_0_requires_1_type_argument_s: diag(2314, ts.DiagnosticCategory.Error, "Generic_type_0_requires_1_type_argument_s_2314", "Generic type '{0}' requires {1} type argument(s)."),
        Type_0_is_not_generic: diag(2315, ts.DiagnosticCategory.Error, "Type_0_is_not_generic_2315", "Type '{0}' is not generic."),
        Global_type_0_must_be_a_class_or_interface_type: diag(2316, ts.DiagnosticCategory.Error, "Global_type_0_must_be_a_class_or_interface_type_2316", "Global type '{0}' must be a class or interface type."),
        Global_type_0_must_have_1_type_parameter_s: diag(2317, ts.DiagnosticCategory.Error, "Global_type_0_must_have_1_type_parameter_s_2317", "Global type '{0}' must have {1} type parameter(s)."),
        Cannot_find_global_type_0: diag(2318, ts.DiagnosticCategory.Error, "Cannot_find_global_type_0_2318", "Cannot find global type '{0}'."),
        Named_property_0_of_types_1_and_2_are_not_identical: diag(2319, ts.DiagnosticCategory.Error, "Named_property_0_of_types_1_and_2_are_not_identical_2319", "Named property '{0}' of types '{1}' and '{2}' are not identical."),
        Interface_0_cannot_simultaneously_extend_types_1_and_2: diag(2320, ts.DiagnosticCategory.Error, "Interface_0_cannot_simultaneously_extend_types_1_and_2_2320", "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}'."),
        Excessive_stack_depth_comparing_types_0_and_1: diag(2321, ts.DiagnosticCategory.Error, "Excessive_stack_depth_comparing_types_0_and_1_2321", "Excessive stack depth comparing types '{0}' and '{1}'."),
        Type_0_is_not_assignable_to_type_1: diag(2322, ts.DiagnosticCategory.Error, "Type_0_is_not_assignable_to_type_1_2322", "Type '{0}' is not assignable to type '{1}'."),
        Cannot_redeclare_exported_variable_0: diag(2323, ts.DiagnosticCategory.Error, "Cannot_redeclare_exported_variable_0_2323", "Cannot redeclare exported variable '{0}'."),
        Property_0_is_missing_in_type_1: diag(2324, ts.DiagnosticCategory.Error, "Property_0_is_missing_in_type_1_2324", "Property '{0}' is missing in type '{1}'."),
        Property_0_is_private_in_type_1_but_not_in_type_2: diag(2325, ts.DiagnosticCategory.Error, "Property_0_is_private_in_type_1_but_not_in_type_2_2325", "Property '{0}' is private in type '{1}' but not in type '{2}'."),
        Types_of_property_0_are_incompatible: diag(2326, ts.DiagnosticCategory.Error, "Types_of_property_0_are_incompatible_2326", "Types of property '{0}' are incompatible."),
        Property_0_is_optional_in_type_1_but_required_in_type_2: diag(2327, ts.DiagnosticCategory.Error, "Property_0_is_optional_in_type_1_but_required_in_type_2_2327", "Property '{0}' is optional in type '{1}' but required in type '{2}'."),
        Types_of_parameters_0_and_1_are_incompatible: diag(2328, ts.DiagnosticCategory.Error, "Types_of_parameters_0_and_1_are_incompatible_2328", "Types of parameters '{0}' and '{1}' are incompatible."),
        Index_signature_is_missing_in_type_0: diag(2329, ts.DiagnosticCategory.Error, "Index_signature_is_missing_in_type_0_2329", "Index signature is missing in type '{0}'."),
        Index_signatures_are_incompatible: diag(2330, ts.DiagnosticCategory.Error, "Index_signatures_are_incompatible_2330", "Index signatures are incompatible."),
        this_cannot_be_referenced_in_a_module_or_namespace_body: diag(2331, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_module_or_namespace_body_2331", "'this' cannot be referenced in a module or namespace body."),
        this_cannot_be_referenced_in_current_location: diag(2332, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_current_location_2332", "'this' cannot be referenced in current location."),
        this_cannot_be_referenced_in_constructor_arguments: diag(2333, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_constructor_arguments_2333", "'this' cannot be referenced in constructor arguments."),
        this_cannot_be_referenced_in_a_static_property_initializer: diag(2334, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_static_property_initializer_2334", "'this' cannot be referenced in a static property initializer."),
        super_can_only_be_referenced_in_a_derived_class: diag(2335, ts.DiagnosticCategory.Error, "super_can_only_be_referenced_in_a_derived_class_2335", "'super' can only be referenced in a derived class."),
        super_cannot_be_referenced_in_constructor_arguments: diag(2336, ts.DiagnosticCategory.Error, "super_cannot_be_referenced_in_constructor_arguments_2336", "'super' cannot be referenced in constructor arguments."),
        Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors: diag(2337, ts.DiagnosticCategory.Error, "Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors_2337", "Super calls are not permitted outside constructors or in nested functions inside constructors."),
        super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class: diag(2338, ts.DiagnosticCategory.Error, "super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_der_2338", "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class."),
        Property_0_does_not_exist_on_type_1: diag(2339, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_type_1_2339", "Property '{0}' does not exist on type '{1}'."),
        Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword: diag(2340, ts.DiagnosticCategory.Error, "Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword_2340", "Only public and protected methods of the base class are accessible via the 'super' keyword."),
        Property_0_is_private_and_only_accessible_within_class_1: diag(2341, ts.DiagnosticCategory.Error, "Property_0_is_private_and_only_accessible_within_class_1_2341", "Property '{0}' is private and only accessible within class '{1}'."),
        An_index_expression_argument_must_be_of_type_string_number_symbol_or_any: diag(2342, ts.DiagnosticCategory.Error, "An_index_expression_argument_must_be_of_type_string_number_symbol_or_any_2342", "An index expression argument must be of type 'string', 'number', 'symbol', or 'any'."),
        This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1: diag(2343, ts.DiagnosticCategory.Error, "This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1_2343", "This syntax requires an imported helper named '{1}', but module '{0}' has no exported member '{1}'."),
        Type_0_does_not_satisfy_the_constraint_1: diag(2344, ts.DiagnosticCategory.Error, "Type_0_does_not_satisfy_the_constraint_1_2344", "Type '{0}' does not satisfy the constraint '{1}'."),
        Argument_of_type_0_is_not_assignable_to_parameter_of_type_1: diag(2345, ts.DiagnosticCategory.Error, "Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_2345", "Argument of type '{0}' is not assignable to parameter of type '{1}'."),
        Call_target_does_not_contain_any_signatures: diag(2346, ts.DiagnosticCategory.Error, "Call_target_does_not_contain_any_signatures_2346", "Call target does not contain any signatures."),
        Untyped_function_calls_may_not_accept_type_arguments: diag(2347, ts.DiagnosticCategory.Error, "Untyped_function_calls_may_not_accept_type_arguments_2347", "Untyped function calls may not accept type arguments."),
        Value_of_type_0_is_not_callable_Did_you_mean_to_include_new: diag(2348, ts.DiagnosticCategory.Error, "Value_of_type_0_is_not_callable_Did_you_mean_to_include_new_2348", "Value of type '{0}' is not callable. Did you mean to include 'new'?"),
        Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures: diag(2349, ts.DiagnosticCategory.Error, "Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatur_2349", "Cannot invoke an expression whose type lacks a call signature. Type '{0}' has no compatible call signatures."),
        Only_a_void_function_can_be_called_with_the_new_keyword: diag(2350, ts.DiagnosticCategory.Error, "Only_a_void_function_can_be_called_with_the_new_keyword_2350", "Only a void function can be called with the 'new' keyword."),
        Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature: diag(2351, ts.DiagnosticCategory.Error, "Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature_2351", "Cannot use 'new' with an expression whose type lacks a call or construct signature."),
        Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the_other_If_this_was_intentional_convert_the_expression_to_unknown_first: diag(2352, ts.DiagnosticCategory.Error, "Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the__2352", "Conversion of type '{0}' to type '{1}' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first."),
        Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1: diag(2353, ts.DiagnosticCategory.Error, "Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1_2353", "Object literal may only specify known properties, and '{0}' does not exist in type '{1}'."),
        This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found: diag(2354, ts.DiagnosticCategory.Error, "This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found_2354", "This syntax requires an imported helper but module '{0}' cannot be found."),
        A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value: diag(2355, ts.DiagnosticCategory.Error, "A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value_2355", "A function whose declared type is neither 'void' nor 'any' must return a value."),
        An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type: diag(2356, ts.DiagnosticCategory.Error, "An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type_2356", "An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type."),
        The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access: diag(2357, ts.DiagnosticCategory.Error, "The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access_2357", "The operand of an increment or decrement operator must be a variable or a property access."),
        The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: diag(2358, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_paramete_2358", "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter."),
        The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type: diag(2359, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_F_2359", "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type."),
        The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol: diag(2360, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol_2360", "The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'."),
        The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: diag(2361, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter_2361", "The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter."),
        The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type: diag(2362, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_2362", "The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type."),
        The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type: diag(2363, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_2363", "The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type."),
        The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access: diag(2364, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access_2364", "The left-hand side of an assignment expression must be a variable or a property access."),
        Operator_0_cannot_be_applied_to_types_1_and_2: diag(2365, ts.DiagnosticCategory.Error, "Operator_0_cannot_be_applied_to_types_1_and_2_2365", "Operator '{0}' cannot be applied to types '{1}' and '{2}'."),
        Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined: diag(2366, ts.DiagnosticCategory.Error, "Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined_2366", "Function lacks ending return statement and return type does not include 'undefined'."),
        This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap: diag(2367, ts.DiagnosticCategory.Error, "This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap_2367", "This condition will always return '{0}' since the types '{1}' and '{2}' have no overlap."),
        Type_parameter_name_cannot_be_0: diag(2368, ts.DiagnosticCategory.Error, "Type_parameter_name_cannot_be_0_2368", "Type parameter name cannot be '{0}'."),
        A_parameter_property_is_only_allowed_in_a_constructor_implementation: diag(2369, ts.DiagnosticCategory.Error, "A_parameter_property_is_only_allowed_in_a_constructor_implementation_2369", "A parameter property is only allowed in a constructor implementation."),
        A_rest_parameter_must_be_of_an_array_type: diag(2370, ts.DiagnosticCategory.Error, "A_rest_parameter_must_be_of_an_array_type_2370", "A rest parameter must be of an array type."),
        A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation: diag(2371, ts.DiagnosticCategory.Error, "A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation_2371", "A parameter initializer is only allowed in a function or constructor implementation."),
        Parameter_0_cannot_be_referenced_in_its_initializer: diag(2372, ts.DiagnosticCategory.Error, "Parameter_0_cannot_be_referenced_in_its_initializer_2372", "Parameter '{0}' cannot be referenced in its initializer."),
        Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it: diag(2373, ts.DiagnosticCategory.Error, "Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it_2373", "Initializer of parameter '{0}' cannot reference identifier '{1}' declared after it."),
        Duplicate_string_index_signature: diag(2374, ts.DiagnosticCategory.Error, "Duplicate_string_index_signature_2374", "Duplicate string index signature."),
        Duplicate_number_index_signature: diag(2375, ts.DiagnosticCategory.Error, "Duplicate_number_index_signature_2375", "Duplicate number index signature."),
        A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties: diag(2376, ts.DiagnosticCategory.Error, "A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_proper_2376", "A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties."),
        Constructors_for_derived_classes_must_contain_a_super_call: diag(2377, ts.DiagnosticCategory.Error, "Constructors_for_derived_classes_must_contain_a_super_call_2377", "Constructors for derived classes must contain a 'super' call."),
        A_get_accessor_must_return_a_value: diag(2378, ts.DiagnosticCategory.Error, "A_get_accessor_must_return_a_value_2378", "A 'get' accessor must return a value."),
        Getter_and_setter_accessors_do_not_agree_in_visibility: diag(2379, ts.DiagnosticCategory.Error, "Getter_and_setter_accessors_do_not_agree_in_visibility_2379", "Getter and setter accessors do not agree in visibility."),
        get_and_set_accessor_must_have_the_same_type: diag(2380, ts.DiagnosticCategory.Error, "get_and_set_accessor_must_have_the_same_type_2380", "'get' and 'set' accessor must have the same type."),
        A_signature_with_an_implementation_cannot_use_a_string_literal_type: diag(2381, ts.DiagnosticCategory.Error, "A_signature_with_an_implementation_cannot_use_a_string_literal_type_2381", "A signature with an implementation cannot use a string literal type."),
        Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature: diag(2382, ts.DiagnosticCategory.Error, "Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature_2382", "Specialized overload signature is not assignable to any non-specialized signature."),
        Overload_signatures_must_all_be_exported_or_non_exported: diag(2383, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_exported_or_non_exported_2383", "Overload signatures must all be exported or non-exported."),
        Overload_signatures_must_all_be_ambient_or_non_ambient: diag(2384, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_ambient_or_non_ambient_2384", "Overload signatures must all be ambient or non-ambient."),
        Overload_signatures_must_all_be_public_private_or_protected: diag(2385, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_public_private_or_protected_2385", "Overload signatures must all be public, private or protected."),
        Overload_signatures_must_all_be_optional_or_required: diag(2386, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_optional_or_required_2386", "Overload signatures must all be optional or required."),
        Function_overload_must_be_static: diag(2387, ts.DiagnosticCategory.Error, "Function_overload_must_be_static_2387", "Function overload must be static."),
        Function_overload_must_not_be_static: diag(2388, ts.DiagnosticCategory.Error, "Function_overload_must_not_be_static_2388", "Function overload must not be static."),
        Function_implementation_name_must_be_0: diag(2389, ts.DiagnosticCategory.Error, "Function_implementation_name_must_be_0_2389", "Function implementation name must be '{0}'."),
        Constructor_implementation_is_missing: diag(2390, ts.DiagnosticCategory.Error, "Constructor_implementation_is_missing_2390", "Constructor implementation is missing."),
        Function_implementation_is_missing_or_not_immediately_following_the_declaration: diag(2391, ts.DiagnosticCategory.Error, "Function_implementation_is_missing_or_not_immediately_following_the_declaration_2391", "Function implementation is missing or not immediately following the declaration."),
        Multiple_constructor_implementations_are_not_allowed: diag(2392, ts.DiagnosticCategory.Error, "Multiple_constructor_implementations_are_not_allowed_2392", "Multiple constructor implementations are not allowed."),
        Duplicate_function_implementation: diag(2393, ts.DiagnosticCategory.Error, "Duplicate_function_implementation_2393", "Duplicate function implementation."),
        This_overload_signature_is_not_compatible_with_its_implementation_signature: diag(2394, ts.DiagnosticCategory.Error, "This_overload_signature_is_not_compatible_with_its_implementation_signature_2394", "This overload signature is not compatible with its implementation signature."),
        Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: diag(2395, ts.DiagnosticCategory.Error, "Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local_2395", "Individual declarations in merged declaration '{0}' must be all exported or all local."),
        Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters: diag(2396, ts.DiagnosticCategory.Error, "Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters_2396", "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters."),
        Declaration_name_conflicts_with_built_in_global_identifier_0: diag(2397, ts.DiagnosticCategory.Error, "Declaration_name_conflicts_with_built_in_global_identifier_0_2397", "Declaration name conflicts with built-in global identifier '{0}'."),
        Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference: diag(2399, ts.DiagnosticCategory.Error, "Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference_2399", "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference."),
        Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference: diag(2400, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference_2400", "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference."),
        Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference: diag(2401, ts.DiagnosticCategory.Error, "Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference_2401", "Duplicate identifier '_super'. Compiler uses '_super' to capture base class reference."),
        Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference: diag(2402, ts.DiagnosticCategory.Error, "Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference_2402", "Expression resolves to '_super' that compiler uses to capture base class reference."),
        Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2: diag(2403, ts.DiagnosticCategory.Error, "Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403", "Subsequent variable declarations must have the same type.  Variable '{0}' must be of type '{1}', but here has type '{2}'."),
        The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation: diag(2404, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation_2404", "The left-hand side of a 'for...in' statement cannot use a type annotation."),
        The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any: diag(2405, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any_2405", "The left-hand side of a 'for...in' statement must be of type 'string' or 'any'."),
        The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access: diag(2406, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access_2406", "The left-hand side of a 'for...in' statement must be a variable or a property access."),
        The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_but_here_has_type_0: diag(2407, ts.DiagnosticCategory.Error, "The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_but_2407", "The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type '{0}'."),
        Setters_cannot_return_a_value: diag(2408, ts.DiagnosticCategory.Error, "Setters_cannot_return_a_value_2408", "Setters cannot return a value."),
        Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class: diag(2409, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class_2409", "Return type of constructor signature must be assignable to the instance type of the class."),
        The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any: diag(2410, ts.DiagnosticCategory.Error, "The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any_2410", "The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'."),
        Property_0_of_type_1_is_not_assignable_to_string_index_type_2: diag(2411, ts.DiagnosticCategory.Error, "Property_0_of_type_1_is_not_assignable_to_string_index_type_2_2411", "Property '{0}' of type '{1}' is not assignable to string index type '{2}'."),
        Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2: diag(2412, ts.DiagnosticCategory.Error, "Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2_2412", "Property '{0}' of type '{1}' is not assignable to numeric index type '{2}'."),
        Numeric_index_type_0_is_not_assignable_to_string_index_type_1: diag(2413, ts.DiagnosticCategory.Error, "Numeric_index_type_0_is_not_assignable_to_string_index_type_1_2413", "Numeric index type '{0}' is not assignable to string index type '{1}'."),
        Class_name_cannot_be_0: diag(2414, ts.DiagnosticCategory.Error, "Class_name_cannot_be_0_2414", "Class name cannot be '{0}'."),
        Class_0_incorrectly_extends_base_class_1: diag(2415, ts.DiagnosticCategory.Error, "Class_0_incorrectly_extends_base_class_1_2415", "Class '{0}' incorrectly extends base class '{1}'."),
        Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2: diag(2416, ts.DiagnosticCategory.Error, "Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2_2416", "Property '{0}' in type '{1}' is not assignable to the same property in base type '{2}'."),
        Class_static_side_0_incorrectly_extends_base_class_static_side_1: diag(2417, ts.DiagnosticCategory.Error, "Class_static_side_0_incorrectly_extends_base_class_static_side_1_2417", "Class static side '{0}' incorrectly extends base class static side '{1}'."),
        Type_of_computed_property_s_value_is_0_which_is_not_assignable_to_type_1: diag(2418, ts.DiagnosticCategory.Error, "Type_of_computed_property_s_value_is_0_which_is_not_assignable_to_type_1_2418", "Type of computed property's value is '{0}', which is not assignable to type '{1}'."),
        Class_0_incorrectly_implements_interface_1: diag(2420, ts.DiagnosticCategory.Error, "Class_0_incorrectly_implements_interface_1_2420", "Class '{0}' incorrectly implements interface '{1}'."),
        A_class_can_only_implement_an_object_type_or_intersection_of_object_types_with_statically_known_members: diag(2422, ts.DiagnosticCategory.Error, "A_class_can_only_implement_an_object_type_or_intersection_of_object_types_with_statically_known_memb_2422", "A class can only implement an object type or intersection of object types with statically known members."),
        Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor: diag(2423, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_access_2423", "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member accessor."),
        Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property: diag(2424, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_proper_2424", "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member property."),
        Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function: diag(2425, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_functi_2425", "Class '{0}' defines instance member property '{1}', but extended class '{2}' defines it as instance member function."),
        Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function: diag(2426, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_functi_2426", "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function."),
        Interface_name_cannot_be_0: diag(2427, ts.DiagnosticCategory.Error, "Interface_name_cannot_be_0_2427", "Interface name cannot be '{0}'."),
        All_declarations_of_0_must_have_identical_type_parameters: diag(2428, ts.DiagnosticCategory.Error, "All_declarations_of_0_must_have_identical_type_parameters_2428", "All declarations of '{0}' must have identical type parameters."),
        Interface_0_incorrectly_extends_interface_1: diag(2430, ts.DiagnosticCategory.Error, "Interface_0_incorrectly_extends_interface_1_2430", "Interface '{0}' incorrectly extends interface '{1}'."),
        Enum_name_cannot_be_0: diag(2431, ts.DiagnosticCategory.Error, "Enum_name_cannot_be_0_2431", "Enum name cannot be '{0}'."),
        In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element: diag(2432, ts.DiagnosticCategory.Error, "In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enu_2432", "In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element."),
        A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged: diag(2433, ts.DiagnosticCategory.Error, "A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merg_2433", "A namespace declaration cannot be in a different file from a class or function with which it is merged."),
        A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged: diag(2434, ts.DiagnosticCategory.Error, "A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged_2434", "A namespace declaration cannot be located prior to a class or function with which it is merged."),
        Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces: diag(2435, ts.DiagnosticCategory.Error, "Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces_2435", "Ambient modules cannot be nested in other modules or namespaces."),
        Ambient_module_declaration_cannot_specify_relative_module_name: diag(2436, ts.DiagnosticCategory.Error, "Ambient_module_declaration_cannot_specify_relative_module_name_2436", "Ambient module declaration cannot specify relative module name."),
        Module_0_is_hidden_by_a_local_declaration_with_the_same_name: diag(2437, ts.DiagnosticCategory.Error, "Module_0_is_hidden_by_a_local_declaration_with_the_same_name_2437", "Module '{0}' is hidden by a local declaration with the same name."),
        Import_name_cannot_be_0: diag(2438, ts.DiagnosticCategory.Error, "Import_name_cannot_be_0_2438", "Import name cannot be '{0}'."),
        Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name: diag(2439, ts.DiagnosticCategory.Error, "Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relati_2439", "Import or export declaration in an ambient module declaration cannot reference module through relative module name."),
        Import_declaration_conflicts_with_local_declaration_of_0: diag(2440, ts.DiagnosticCategory.Error, "Import_declaration_conflicts_with_local_declaration_of_0_2440", "Import declaration conflicts with local declaration of '{0}'."),
        Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module: diag(2441, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_2441", "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module."),
        Types_have_separate_declarations_of_a_private_property_0: diag(2442, ts.DiagnosticCategory.Error, "Types_have_separate_declarations_of_a_private_property_0_2442", "Types have separate declarations of a private property '{0}'."),
        Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2: diag(2443, ts.DiagnosticCategory.Error, "Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2_2443", "Property '{0}' is protected but type '{1}' is not a class derived from '{2}'."),
        Property_0_is_protected_in_type_1_but_public_in_type_2: diag(2444, ts.DiagnosticCategory.Error, "Property_0_is_protected_in_type_1_but_public_in_type_2_2444", "Property '{0}' is protected in type '{1}' but public in type '{2}'."),
        Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: diag(2445, ts.DiagnosticCategory.Error, "Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses_2445", "Property '{0}' is protected and only accessible within class '{1}' and its subclasses."),
        Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: diag(2446, ts.DiagnosticCategory.Error, "Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_2446", "Property '{0}' is protected and only accessible through an instance of class '{1}'."),
        The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: diag(2447, ts.DiagnosticCategory.Error, "The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead_2447", "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead."),
        Block_scoped_variable_0_used_before_its_declaration: diag(2448, ts.DiagnosticCategory.Error, "Block_scoped_variable_0_used_before_its_declaration_2448", "Block-scoped variable '{0}' used before its declaration."),
        Class_0_used_before_its_declaration: diag(2449, ts.DiagnosticCategory.Error, "Class_0_used_before_its_declaration_2449", "Class '{0}' used before its declaration."),
        Enum_0_used_before_its_declaration: diag(2450, ts.DiagnosticCategory.Error, "Enum_0_used_before_its_declaration_2450", "Enum '{0}' used before its declaration."),
        Cannot_redeclare_block_scoped_variable_0: diag(2451, ts.DiagnosticCategory.Error, "Cannot_redeclare_block_scoped_variable_0_2451", "Cannot redeclare block-scoped variable '{0}'."),
        An_enum_member_cannot_have_a_numeric_name: diag(2452, ts.DiagnosticCategory.Error, "An_enum_member_cannot_have_a_numeric_name_2452", "An enum member cannot have a numeric name."),
        The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly: diag(2453, ts.DiagnosticCategory.Error, "The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_typ_2453", "The type argument for type parameter '{0}' cannot be inferred from the usage. Consider specifying the type arguments explicitly."),
        Variable_0_is_used_before_being_assigned: diag(2454, ts.DiagnosticCategory.Error, "Variable_0_is_used_before_being_assigned_2454", "Variable '{0}' is used before being assigned."),
        Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0: diag(2455, ts.DiagnosticCategory.Error, "Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0_2455", "Type argument candidate '{1}' is not a valid type argument because it is not a supertype of candidate '{0}'."),
        Type_alias_0_circularly_references_itself: diag(2456, ts.DiagnosticCategory.Error, "Type_alias_0_circularly_references_itself_2456", "Type alias '{0}' circularly references itself."),
        Type_alias_name_cannot_be_0: diag(2457, ts.DiagnosticCategory.Error, "Type_alias_name_cannot_be_0_2457", "Type alias name cannot be '{0}'."),
        An_AMD_module_cannot_have_multiple_name_assignments: diag(2458, ts.DiagnosticCategory.Error, "An_AMD_module_cannot_have_multiple_name_assignments_2458", "An AMD module cannot have multiple name assignments."),
        Type_0_is_not_an_array_type: diag(2461, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_2461", "Type '{0}' is not an array type."),
        A_rest_element_must_be_last_in_a_destructuring_pattern: diag(2462, ts.DiagnosticCategory.Error, "A_rest_element_must_be_last_in_a_destructuring_pattern_2462", "A rest element must be last in a destructuring pattern."),
        A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature: diag(2463, ts.DiagnosticCategory.Error, "A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature_2463", "A binding pattern parameter cannot be optional in an implementation signature."),
        A_computed_property_name_must_be_of_type_string_number_symbol_or_any: diag(2464, ts.DiagnosticCategory.Error, "A_computed_property_name_must_be_of_type_string_number_symbol_or_any_2464", "A computed property name must be of type 'string', 'number', 'symbol', or 'any'."),
        this_cannot_be_referenced_in_a_computed_property_name: diag(2465, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_computed_property_name_2465", "'this' cannot be referenced in a computed property name."),
        super_cannot_be_referenced_in_a_computed_property_name: diag(2466, ts.DiagnosticCategory.Error, "super_cannot_be_referenced_in_a_computed_property_name_2466", "'super' cannot be referenced in a computed property name."),
        A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type: diag(2467, ts.DiagnosticCategory.Error, "A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type_2467", "A computed property name cannot reference a type parameter from its containing type."),
        Cannot_find_global_value_0: diag(2468, ts.DiagnosticCategory.Error, "Cannot_find_global_value_0_2468", "Cannot find global value '{0}'."),
        The_0_operator_cannot_be_applied_to_type_symbol: diag(2469, ts.DiagnosticCategory.Error, "The_0_operator_cannot_be_applied_to_type_symbol_2469", "The '{0}' operator cannot be applied to type 'symbol'."),
        Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object: diag(2470, ts.DiagnosticCategory.Error, "Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object_2470", "'Symbol' reference does not refer to the global Symbol constructor object."),
        A_computed_property_name_of_the_form_0_must_be_of_type_symbol: diag(2471, ts.DiagnosticCategory.Error, "A_computed_property_name_of_the_form_0_must_be_of_type_symbol_2471", "A computed property name of the form '{0}' must be of type 'symbol'."),
        Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher: diag(2472, ts.DiagnosticCategory.Error, "Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher_2472", "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher."),
        Enum_declarations_must_all_be_const_or_non_const: diag(2473, ts.DiagnosticCategory.Error, "Enum_declarations_must_all_be_const_or_non_const_2473", "Enum declarations must all be const or non-const."),
        const_enum_member_initializers_can_only_contain_literal_values_and_other_computed_enum_values: diag(2474, ts.DiagnosticCategory.Error, "const_enum_member_initializers_can_only_contain_literal_values_and_other_computed_enum_values_2474", "const enum member initializers can only contain literal values and other computed enum values."),
        const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query: diag(2475, ts.DiagnosticCategory.Error, "const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_im_2475", "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query."),
        A_const_enum_member_can_only_be_accessed_using_a_string_literal: diag(2476, ts.DiagnosticCategory.Error, "A_const_enum_member_can_only_be_accessed_using_a_string_literal_2476", "A const enum member can only be accessed using a string literal."),
        const_enum_member_initializer_was_evaluated_to_a_non_finite_value: diag(2477, ts.DiagnosticCategory.Error, "const_enum_member_initializer_was_evaluated_to_a_non_finite_value_2477", "'const' enum member initializer was evaluated to a non-finite value."),
        const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN: diag(2478, ts.DiagnosticCategory.Error, "const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN_2478", "'const' enum member initializer was evaluated to disallowed value 'NaN'."),
        Property_0_does_not_exist_on_const_enum_1: diag(2479, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_const_enum_1_2479", "Property '{0}' does not exist on 'const' enum '{1}'."),
        let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations: diag(2480, ts.DiagnosticCategory.Error, "let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations_2480", "'let' is not allowed to be used as a name in 'let' or 'const' declarations."),
        Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1: diag(2481, ts.DiagnosticCategory.Error, "Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1_2481", "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'."),
        The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation: diag(2483, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation_2483", "The left-hand side of a 'for...of' statement cannot use a type annotation."),
        Export_declaration_conflicts_with_exported_declaration_of_0: diag(2484, ts.DiagnosticCategory.Error, "Export_declaration_conflicts_with_exported_declaration_of_0_2484", "Export declaration conflicts with exported declaration of '{0}'."),
        The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access: diag(2487, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access_2487", "The left-hand side of a 'for...of' statement must be a variable or a property access."),
        Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2488, ts.DiagnosticCategory.Error, "Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator_2488", "Type '{0}' must have a '[Symbol.iterator]()' method that returns an iterator."),
        An_iterator_must_have_a_next_method: diag(2489, ts.DiagnosticCategory.Error, "An_iterator_must_have_a_next_method_2489", "An iterator must have a 'next()' method."),
        The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property: diag(2490, ts.DiagnosticCategory.Error, "The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property_2490", "The type returned by the 'next()' method of an iterator must have a 'value' property."),
        The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern: diag(2491, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern_2491", "The left-hand side of a 'for...in' statement cannot be a destructuring pattern."),
        Cannot_redeclare_identifier_0_in_catch_clause: diag(2492, ts.DiagnosticCategory.Error, "Cannot_redeclare_identifier_0_in_catch_clause_2492", "Cannot redeclare identifier '{0}' in catch clause."),
        Tuple_type_0_of_length_1_has_no_element_at_index_2: diag(2493, ts.DiagnosticCategory.Error, "Tuple_type_0_of_length_1_has_no_element_at_index_2_2493", "Tuple type '{0}' of length '{1}' has no element at index '{2}'."),
        Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher: diag(2494, ts.DiagnosticCategory.Error, "Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher_2494", "Using a string in a 'for...of' statement is only supported in ECMAScript 5 and higher."),
        Type_0_is_not_an_array_type_or_a_string_type: diag(2495, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_a_string_type_2495", "Type '{0}' is not an array type or a string type."),
        The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression: diag(2496, ts.DiagnosticCategory.Error, "The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_stand_2496", "The 'arguments' object cannot be referenced in an arrow function in ES3 and ES5. Consider using a standard function expression."),
        This_module_can_only_be_referenced_with_ECMAScript_imports_Slashexports_by_turning_on_the_0_flag_and_referencing_its_default_export: diag(2497, ts.DiagnosticCategory.Error, "This_module_can_only_be_referenced_with_ECMAScript_imports_Slashexports_by_turning_on_the_0_flag_and_2497", "This module can only be referenced with ECMAScript imports/exports by turning on the '{0}' flag and referencing its default export."),
        Module_0_uses_export_and_cannot_be_used_with_export_Asterisk: diag(2498, ts.DiagnosticCategory.Error, "Module_0_uses_export_and_cannot_be_used_with_export_Asterisk_2498", "Module '{0}' uses 'export =' and cannot be used with 'export *'."),
        An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments: diag(2499, ts.DiagnosticCategory.Error, "An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments_2499", "An interface can only extend an identifier/qualified-name with optional type arguments."),
        A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments: diag(2500, ts.DiagnosticCategory.Error, "A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments_2500", "A class can only implement an identifier/qualified-name with optional type arguments."),
        A_rest_element_cannot_contain_a_binding_pattern: diag(2501, ts.DiagnosticCategory.Error, "A_rest_element_cannot_contain_a_binding_pattern_2501", "A rest element cannot contain a binding pattern."),
        _0_is_referenced_directly_or_indirectly_in_its_own_type_annotation: diag(2502, ts.DiagnosticCategory.Error, "_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation_2502", "'{0}' is referenced directly or indirectly in its own type annotation."),
        Cannot_find_namespace_0: diag(2503, ts.DiagnosticCategory.Error, "Cannot_find_namespace_0_2503", "Cannot find namespace '{0}'."),
        Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator: diag(2504, ts.DiagnosticCategory.Error, "Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator_2504", "Type '{0}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator."),
        A_generator_cannot_have_a_void_type_annotation: diag(2505, ts.DiagnosticCategory.Error, "A_generator_cannot_have_a_void_type_annotation_2505", "A generator cannot have a 'void' type annotation."),
        _0_is_referenced_directly_or_indirectly_in_its_own_base_expression: diag(2506, ts.DiagnosticCategory.Error, "_0_is_referenced_directly_or_indirectly_in_its_own_base_expression_2506", "'{0}' is referenced directly or indirectly in its own base expression."),
        Type_0_is_not_a_constructor_function_type: diag(2507, ts.DiagnosticCategory.Error, "Type_0_is_not_a_constructor_function_type_2507", "Type '{0}' is not a constructor function type."),
        No_base_constructor_has_the_specified_number_of_type_arguments: diag(2508, ts.DiagnosticCategory.Error, "No_base_constructor_has_the_specified_number_of_type_arguments_2508", "No base constructor has the specified number of type arguments."),
        Base_constructor_return_type_0_is_not_an_object_type_or_intersection_of_object_types_with_statically_known_members: diag(2509, ts.DiagnosticCategory.Error, "Base_constructor_return_type_0_is_not_an_object_type_or_intersection_of_object_types_with_statically_2509", "Base constructor return type '{0}' is not an object type or intersection of object types with statically known members."),
        Base_constructors_must_all_have_the_same_return_type: diag(2510, ts.DiagnosticCategory.Error, "Base_constructors_must_all_have_the_same_return_type_2510", "Base constructors must all have the same return type."),
        Cannot_create_an_instance_of_an_abstract_class: diag(2511, ts.DiagnosticCategory.Error, "Cannot_create_an_instance_of_an_abstract_class_2511", "Cannot create an instance of an abstract class."),
        Overload_signatures_must_all_be_abstract_or_non_abstract: diag(2512, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_abstract_or_non_abstract_2512", "Overload signatures must all be abstract or non-abstract."),
        Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression: diag(2513, ts.DiagnosticCategory.Error, "Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression_2513", "Abstract method '{0}' in class '{1}' cannot be accessed via super expression."),
        Classes_containing_abstract_methods_must_be_marked_abstract: diag(2514, ts.DiagnosticCategory.Error, "Classes_containing_abstract_methods_must_be_marked_abstract_2514", "Classes containing abstract methods must be marked abstract."),
        Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2: diag(2515, ts.DiagnosticCategory.Error, "Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2_2515", "Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'."),
        All_declarations_of_an_abstract_method_must_be_consecutive: diag(2516, ts.DiagnosticCategory.Error, "All_declarations_of_an_abstract_method_must_be_consecutive_2516", "All declarations of an abstract method must be consecutive."),
        Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type: diag(2517, ts.DiagnosticCategory.Error, "Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type_2517", "Cannot assign an abstract constructor type to a non-abstract constructor type."),
        A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard: diag(2518, ts.DiagnosticCategory.Error, "A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard_2518", "A 'this'-based type guard is not compatible with a parameter-based type guard."),
        An_async_iterator_must_have_a_next_method: diag(2519, ts.DiagnosticCategory.Error, "An_async_iterator_must_have_a_next_method_2519", "An async iterator must have a 'next()' method."),
        Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions: diag(2520, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions_2520", "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions."),
        Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions: diag(2521, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions_2521", "Expression resolves to variable declaration '{0}' that compiler uses to support async functions."),
        The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method: diag(2522, ts.DiagnosticCategory.Error, "The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_usi_2522", "The 'arguments' object cannot be referenced in an async function or method in ES3 and ES5. Consider using a standard function or method."),
        yield_expressions_cannot_be_used_in_a_parameter_initializer: diag(2523, ts.DiagnosticCategory.Error, "yield_expressions_cannot_be_used_in_a_parameter_initializer_2523", "'yield' expressions cannot be used in a parameter initializer."),
        await_expressions_cannot_be_used_in_a_parameter_initializer: diag(2524, ts.DiagnosticCategory.Error, "await_expressions_cannot_be_used_in_a_parameter_initializer_2524", "'await' expressions cannot be used in a parameter initializer."),
        Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value: diag(2525, ts.DiagnosticCategory.Error, "Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value_2525", "Initializer provides no value for this binding element and the binding element has no default value."),
        A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface: diag(2526, ts.DiagnosticCategory.Error, "A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface_2526", "A 'this' type is available only in a non-static member of a class or interface."),
        The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary: diag(2527, ts.DiagnosticCategory.Error, "The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527", "The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary."),
        A_module_cannot_have_multiple_default_exports: diag(2528, ts.DiagnosticCategory.Error, "A_module_cannot_have_multiple_default_exports_2528", "A module cannot have multiple default exports."),
        Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions: diag(2529, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_func_2529", "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module containing async functions."),
        Property_0_is_incompatible_with_index_signature: diag(2530, ts.DiagnosticCategory.Error, "Property_0_is_incompatible_with_index_signature_2530", "Property '{0}' is incompatible with index signature."),
        Object_is_possibly_null: diag(2531, ts.DiagnosticCategory.Error, "Object_is_possibly_null_2531", "Object is possibly 'null'."),
        Object_is_possibly_undefined: diag(2532, ts.DiagnosticCategory.Error, "Object_is_possibly_undefined_2532", "Object is possibly 'undefined'."),
        Object_is_possibly_null_or_undefined: diag(2533, ts.DiagnosticCategory.Error, "Object_is_possibly_null_or_undefined_2533", "Object is possibly 'null' or 'undefined'."),
        A_function_returning_never_cannot_have_a_reachable_end_point: diag(2534, ts.DiagnosticCategory.Error, "A_function_returning_never_cannot_have_a_reachable_end_point_2534", "A function returning 'never' cannot have a reachable end point."),
        Enum_type_0_has_members_with_initializers_that_are_not_literals: diag(2535, ts.DiagnosticCategory.Error, "Enum_type_0_has_members_with_initializers_that_are_not_literals_2535", "Enum type '{0}' has members with initializers that are not literals."),
        Type_0_cannot_be_used_to_index_type_1: diag(2536, ts.DiagnosticCategory.Error, "Type_0_cannot_be_used_to_index_type_1_2536", "Type '{0}' cannot be used to index type '{1}'."),
        Type_0_has_no_matching_index_signature_for_type_1: diag(2537, ts.DiagnosticCategory.Error, "Type_0_has_no_matching_index_signature_for_type_1_2537", "Type '{0}' has no matching index signature for type '{1}'."),
        Type_0_cannot_be_used_as_an_index_type: diag(2538, ts.DiagnosticCategory.Error, "Type_0_cannot_be_used_as_an_index_type_2538", "Type '{0}' cannot be used as an index type."),
        Cannot_assign_to_0_because_it_is_not_a_variable: diag(2539, ts.DiagnosticCategory.Error, "Cannot_assign_to_0_because_it_is_not_a_variable_2539", "Cannot assign to '{0}' because it is not a variable."),
        Cannot_assign_to_0_because_it_is_a_read_only_property: diag(2540, ts.DiagnosticCategory.Error, "Cannot_assign_to_0_because_it_is_a_read_only_property_2540", "Cannot assign to '{0}' because it is a read-only property."),
        The_target_of_an_assignment_must_be_a_variable_or_a_property_access: diag(2541, ts.DiagnosticCategory.Error, "The_target_of_an_assignment_must_be_a_variable_or_a_property_access_2541", "The target of an assignment must be a variable or a property access."),
        Index_signature_in_type_0_only_permits_reading: diag(2542, ts.DiagnosticCategory.Error, "Index_signature_in_type_0_only_permits_reading_2542", "Index signature in type '{0}' only permits reading."),
        Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference: diag(2543, ts.DiagnosticCategory.Error, "Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_me_2543", "Duplicate identifier '_newTarget'. Compiler uses variable declaration '_newTarget' to capture 'new.target' meta-property reference."),
        Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference: diag(2544, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta__2544", "Expression resolves to variable declaration '_newTarget' that compiler uses to capture 'new.target' meta-property reference."),
        A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any: diag(2545, ts.DiagnosticCategory.Error, "A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any_2545", "A mixin class must have a constructor with a single rest parameter of type 'any[]'."),
        Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1: diag(2546, ts.DiagnosticCategory.Error, "Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1_2546", "Property '{0}' has conflicting declarations and is inaccessible in type '{1}'."),
        The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property: diag(2547, ts.DiagnosticCategory.Error, "The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value__2547", "The type returned by the 'next()' method of an async iterator must be a promise for a type with a 'value' property."),
        Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2548, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_2548", "Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator."),
        Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2549, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549", "Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator."),
        Property_0_does_not_exist_on_type_1_Did_you_mean_2: diag(2551, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_type_1_Did_you_mean_2_2551", "Property '{0}' does not exist on type '{1}'. Did you mean '{2}'?"),
        Cannot_find_name_0_Did_you_mean_1: diag(2552, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_1_2552", "Cannot find name '{0}'. Did you mean '{1}'?"),
        Computed_values_are_not_permitted_in_an_enum_with_string_valued_members: diag(2553, ts.DiagnosticCategory.Error, "Computed_values_are_not_permitted_in_an_enum_with_string_valued_members_2553", "Computed values are not permitted in an enum with string valued members."),
        Expected_0_arguments_but_got_1: diag(2554, ts.DiagnosticCategory.Error, "Expected_0_arguments_but_got_1_2554", "Expected {0} arguments, but got {1}."),
        Expected_at_least_0_arguments_but_got_1: diag(2555, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_1_2555", "Expected at least {0} arguments, but got {1}."),
        Expected_0_arguments_but_got_1_or_more: diag(2556, ts.DiagnosticCategory.Error, "Expected_0_arguments_but_got_1_or_more_2556", "Expected {0} arguments, but got {1} or more."),
        Expected_at_least_0_arguments_but_got_1_or_more: diag(2557, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_1_or_more_2557", "Expected at least {0} arguments, but got {1} or more."),
        Expected_0_type_arguments_but_got_1: diag(2558, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_but_got_1_2558", "Expected {0} type arguments, but got {1}."),
        Type_0_has_no_properties_in_common_with_type_1: diag(2559, ts.DiagnosticCategory.Error, "Type_0_has_no_properties_in_common_with_type_1_2559", "Type '{0}' has no properties in common with type '{1}'."),
        Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it: diag(2560, ts.DiagnosticCategory.Error, "Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it_2560", "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?"),
        Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2: diag(2561, ts.DiagnosticCategory.Error, "Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_writ_2561", "Object literal may only specify known properties, but '{0}' does not exist in type '{1}'. Did you mean to write '{2}'?"),
        Base_class_expressions_cannot_reference_class_type_parameters: diag(2562, ts.DiagnosticCategory.Error, "Base_class_expressions_cannot_reference_class_type_parameters_2562", "Base class expressions cannot reference class type parameters."),
        The_containing_function_or_module_body_is_too_large_for_control_flow_analysis: diag(2563, ts.DiagnosticCategory.Error, "The_containing_function_or_module_body_is_too_large_for_control_flow_analysis_2563", "The containing function or module body is too large for control flow analysis."),
        Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor: diag(2564, ts.DiagnosticCategory.Error, "Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor_2564", "Property '{0}' has no initializer and is not definitely assigned in the constructor."),
        Property_0_is_used_before_being_assigned: diag(2565, ts.DiagnosticCategory.Error, "Property_0_is_used_before_being_assigned_2565", "Property '{0}' is used before being assigned."),
        A_rest_element_cannot_have_a_property_name: diag(2566, ts.DiagnosticCategory.Error, "A_rest_element_cannot_have_a_property_name_2566", "A rest element cannot have a property name."),
        Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations: diag(2567, ts.DiagnosticCategory.Error, "Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations_2567", "Enum declarations can only merge with namespace or other enum declarations."),
        Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators: diag(2569, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569", "Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators."),
        Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await: diag(2570, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await_2570", "Property '{0}' does not exist on type '{1}'. Did you forget to use 'await'?"),
        Object_is_of_type_unknown: diag(2571, ts.DiagnosticCategory.Error, "Object_is_of_type_unknown_2571", "Object is of type 'unknown'."),
        Rest_signatures_are_incompatible: diag(2572, ts.DiagnosticCategory.Error, "Rest_signatures_are_incompatible_2572", "Rest signatures are incompatible."),
        Property_0_is_incompatible_with_rest_element_type: diag(2573, ts.DiagnosticCategory.Error, "Property_0_is_incompatible_with_rest_element_type_2573", "Property '{0}' is incompatible with rest element type."),
        A_rest_element_type_must_be_an_array_type: diag(2574, ts.DiagnosticCategory.Error, "A_rest_element_type_must_be_an_array_type_2574", "A rest element type must be an array type."),
        No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments: diag(2575, ts.DiagnosticCategory.Error, "No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments_2575", "No overload expects {0} arguments, but overloads do exist that expect either {1} or {2} arguments."),
        Property_0_is_a_static_member_of_type_1: diag(2576, ts.DiagnosticCategory.Error, "Property_0_is_a_static_member_of_type_1_2576", "Property '{0}' is a static member of type '{1}'"),
        Return_type_annotation_circularly_references_itself: diag(2577, ts.DiagnosticCategory.Error, "Return_type_annotation_circularly_references_itself_2577", "Return type annotation circularly references itself."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode: diag(2580, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode_2580", "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node`."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery: diag(2581, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery_2581", "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i @types/jquery`."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashjest_or_npm_i_types_Slashmocha: diag(2582, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashje_2582", "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha`."),
        Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later: diag(2583, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_2583", "Cannot find name '{0}'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later."),
        Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_include_dom: diag(2584, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_2584", "Cannot find name '{0}'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'."),
        _0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later: diag(2585, ts.DiagnosticCategory.Error, "_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_2585", "'{0}' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later."),
        Enum_type_0_circularly_references_itself: diag(2586, ts.DiagnosticCategory.Error, "Enum_type_0_circularly_references_itself_2586", "Enum type '{0}' circularly references itself."),
        JSDoc_type_0_circularly_references_itself: diag(2587, ts.DiagnosticCategory.Error, "JSDoc_type_0_circularly_references_itself_2587", "JSDoc type '{0}' circularly references itself."),
        Cannot_assign_to_0_because_it_is_a_constant: diag(2588, ts.DiagnosticCategory.Error, "Cannot_assign_to_0_because_it_is_a_constant_2588", "Cannot assign to '{0}' because it is a constant."),
        Type_instantiation_is_excessively_deep_and_possibly_infinite: diag(2589, ts.DiagnosticCategory.Error, "Type_instantiation_is_excessively_deep_and_possibly_infinite_2589", "Type instantiation is excessively deep and possibly infinite."),
        Expression_produces_a_union_type_that_is_too_complex_to_represent: diag(2590, ts.DiagnosticCategory.Error, "Expression_produces_a_union_type_that_is_too_complex_to_represent_2590", "Expression produces a union type that is too complex to represent."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig: diag(2591, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode_and_th_2591", "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig: diag(2592, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery_an_2592", "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i @types/jquery` and then add `jquery` to the types field in your tsconfig."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashjest_or_npm_i_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig: diag(2593, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashje_2593", "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig."),
        This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag: diag(2594, ts.DiagnosticCategory.Error, "This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the__2594", "This module is declared with using 'export =', and can only be used with a default import when using the '{0}' flag."),
        JSX_element_attributes_type_0_may_not_be_a_union_type: diag(2600, ts.DiagnosticCategory.Error, "JSX_element_attributes_type_0_may_not_be_a_union_type_2600", "JSX element attributes type '{0}' may not be a union type."),
        The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: diag(2601, ts.DiagnosticCategory.Error, "The_return_type_of_a_JSX_element_constructor_must_return_an_object_type_2601", "The return type of a JSX element constructor must return an object type."),
        JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: diag(2602, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist_2602", "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist."),
        Property_0_in_type_1_is_not_assignable_to_type_2: diag(2603, ts.DiagnosticCategory.Error, "Property_0_in_type_1_is_not_assignable_to_type_2_2603", "Property '{0}' in type '{1}' is not assignable to type '{2}'."),
        JSX_element_type_0_does_not_have_any_construct_or_call_signatures: diag(2604, ts.DiagnosticCategory.Error, "JSX_element_type_0_does_not_have_any_construct_or_call_signatures_2604", "JSX element type '{0}' does not have any construct or call signatures."),
        JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements: diag(2605, ts.DiagnosticCategory.Error, "JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements_2605", "JSX element type '{0}' is not a constructor function for JSX elements."),
        Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property: diag(2606, ts.DiagnosticCategory.Error, "Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property_2606", "Property '{0}' of JSX spread attribute is not assignable to target property."),
        JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: diag(2607, ts.DiagnosticCategory.Error, "JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property_2607", "JSX element class does not support attributes because it does not have a '{0}' property."),
        The_global_type_JSX_0_may_not_have_more_than_one_property: diag(2608, ts.DiagnosticCategory.Error, "The_global_type_JSX_0_may_not_have_more_than_one_property_2608", "The global type 'JSX.{0}' may not have more than one property."),
        JSX_spread_child_must_be_an_array_type: diag(2609, ts.DiagnosticCategory.Error, "JSX_spread_child_must_be_an_array_type_2609", "JSX spread child must be an array type."),
        Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity: diag(2649, ts.DiagnosticCategory.Error, "Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity_2649", "Cannot augment module '{0}' with value exports because it resolves to a non-module entity."),
        A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums: diag(2651, ts.DiagnosticCategory.Error, "A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_memb_2651", "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums."),
        Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: diag(2652, ts.DiagnosticCategory.Error, "Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_d_2652", "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead."),
        Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1: diag(2653, ts.DiagnosticCategory.Error, "Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1_2653", "Non-abstract class expression does not implement inherited abstract member '{0}' from class '{1}'."),
        Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition: diag(2654, ts.DiagnosticCategory.Error, "Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_pack_2654", "Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition."),
        Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition: diag(2656, ts.DiagnosticCategory.Error, "Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_2656", "Exported external package typings file '{0}' is not a module. Please contact the package author to update the package definition."),
        JSX_expressions_must_have_one_parent_element: diag(2657, ts.DiagnosticCategory.Error, "JSX_expressions_must_have_one_parent_element_2657", "JSX expressions must have one parent element."),
        Type_0_provides_no_match_for_the_signature_1: diag(2658, ts.DiagnosticCategory.Error, "Type_0_provides_no_match_for_the_signature_1_2658", "Type '{0}' provides no match for the signature '{1}'."),
        super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher: diag(2659, ts.DiagnosticCategory.Error, "super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_highe_2659", "'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher."),
        super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions: diag(2660, ts.DiagnosticCategory.Error, "super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions_2660", "'super' can only be referenced in members of derived classes or object literal expressions."),
        Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module: diag(2661, ts.DiagnosticCategory.Error, "Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module_2661", "Cannot export '{0}'. Only local declarations can be exported from a module."),
        Cannot_find_name_0_Did_you_mean_the_static_member_1_0: diag(2662, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_the_static_member_1_0_2662", "Cannot find name '{0}'. Did you mean the static member '{1}.{0}'?"),
        Cannot_find_name_0_Did_you_mean_the_instance_member_this_0: diag(2663, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_the_instance_member_this_0_2663", "Cannot find name '{0}'. Did you mean the instance member 'this.{0}'?"),
        Invalid_module_name_in_augmentation_module_0_cannot_be_found: diag(2664, ts.DiagnosticCategory.Error, "Invalid_module_name_in_augmentation_module_0_cannot_be_found_2664", "Invalid module name in augmentation, module '{0}' cannot be found."),
        Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented: diag(2665, ts.DiagnosticCategory.Error, "Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augm_2665", "Invalid module name in augmentation. Module '{0}' resolves to an untyped module at '{1}', which cannot be augmented."),
        Exports_and_export_assignments_are_not_permitted_in_module_augmentations: diag(2666, ts.DiagnosticCategory.Error, "Exports_and_export_assignments_are_not_permitted_in_module_augmentations_2666", "Exports and export assignments are not permitted in module augmentations."),
        Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module: diag(2667, ts.DiagnosticCategory.Error, "Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_mod_2667", "Imports are not permitted in module augmentations. Consider moving them to the enclosing external module."),
        export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible: diag(2668, ts.DiagnosticCategory.Error, "export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always__2668", "'export' modifier cannot be applied to ambient modules and module augmentations since they are always visible."),
        Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations: diag(2669, ts.DiagnosticCategory.Error, "Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_2669", "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations."),
        Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context: diag(2670, ts.DiagnosticCategory.Error, "Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambien_2670", "Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context."),
        Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity: diag(2671, ts.DiagnosticCategory.Error, "Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity_2671", "Cannot augment module '{0}' because it resolves to a non-module entity."),
        Cannot_assign_a_0_constructor_type_to_a_1_constructor_type: diag(2672, ts.DiagnosticCategory.Error, "Cannot_assign_a_0_constructor_type_to_a_1_constructor_type_2672", "Cannot assign a '{0}' constructor type to a '{1}' constructor type."),
        Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration: diag(2673, ts.DiagnosticCategory.Error, "Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration_2673", "Constructor of class '{0}' is private and only accessible within the class declaration."),
        Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration: diag(2674, ts.DiagnosticCategory.Error, "Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration_2674", "Constructor of class '{0}' is protected and only accessible within the class declaration."),
        Cannot_extend_a_class_0_Class_constructor_is_marked_as_private: diag(2675, ts.DiagnosticCategory.Error, "Cannot_extend_a_class_0_Class_constructor_is_marked_as_private_2675", "Cannot extend a class '{0}'. Class constructor is marked as private."),
        Accessors_must_both_be_abstract_or_non_abstract: diag(2676, ts.DiagnosticCategory.Error, "Accessors_must_both_be_abstract_or_non_abstract_2676", "Accessors must both be abstract or non-abstract."),
        A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type: diag(2677, ts.DiagnosticCategory.Error, "A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type_2677", "A type predicate's type must be assignable to its parameter's type."),
        Type_0_is_not_comparable_to_type_1: diag(2678, ts.DiagnosticCategory.Error, "Type_0_is_not_comparable_to_type_1_2678", "Type '{0}' is not comparable to type '{1}'."),
        A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void: diag(2679, ts.DiagnosticCategory.Error, "A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void_2679", "A function that is called with the 'new' keyword cannot have a 'this' type that is 'void'."),
        A_0_parameter_must_be_the_first_parameter: diag(2680, ts.DiagnosticCategory.Error, "A_0_parameter_must_be_the_first_parameter_2680", "A '{0}' parameter must be the first parameter."),
        A_constructor_cannot_have_a_this_parameter: diag(2681, ts.DiagnosticCategory.Error, "A_constructor_cannot_have_a_this_parameter_2681", "A constructor cannot have a 'this' parameter."),
        get_and_set_accessor_must_have_the_same_this_type: diag(2682, ts.DiagnosticCategory.Error, "get_and_set_accessor_must_have_the_same_this_type_2682", "'get' and 'set' accessor must have the same 'this' type."),
        this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation: diag(2683, ts.DiagnosticCategory.Error, "this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_2683", "'this' implicitly has type 'any' because it does not have a type annotation."),
        The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1: diag(2684, ts.DiagnosticCategory.Error, "The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1_2684", "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'."),
        The_this_types_of_each_signature_are_incompatible: diag(2685, ts.DiagnosticCategory.Error, "The_this_types_of_each_signature_are_incompatible_2685", "The 'this' types of each signature are incompatible."),
        _0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead: diag(2686, ts.DiagnosticCategory.Error, "_0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead_2686", "'{0}' refers to a UMD global, but the current file is a module. Consider adding an import instead."),
        All_declarations_of_0_must_have_identical_modifiers: diag(2687, ts.DiagnosticCategory.Error, "All_declarations_of_0_must_have_identical_modifiers_2687", "All declarations of '{0}' must have identical modifiers."),
        Cannot_find_type_definition_file_for_0: diag(2688, ts.DiagnosticCategory.Error, "Cannot_find_type_definition_file_for_0_2688", "Cannot find type definition file for '{0}'."),
        Cannot_extend_an_interface_0_Did_you_mean_implements: diag(2689, ts.DiagnosticCategory.Error, "Cannot_extend_an_interface_0_Did_you_mean_implements_2689", "Cannot extend an interface '{0}'. Did you mean 'implements'?"),
        An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead: diag(2691, ts.DiagnosticCategory.Error, "An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead_2691", "An import path cannot end with a '{0}' extension. Consider importing '{1}' instead."),
        _0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible: diag(2692, ts.DiagnosticCategory.Error, "_0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible_2692", "'{0}' is a primitive, but '{1}' is a wrapper object. Prefer using '{0}' when possible."),
        _0_only_refers_to_a_type_but_is_being_used_as_a_value_here: diag(2693, ts.DiagnosticCategory.Error, "_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_2693", "'{0}' only refers to a type, but is being used as a value here."),
        Namespace_0_has_no_exported_member_1: diag(2694, ts.DiagnosticCategory.Error, "Namespace_0_has_no_exported_member_1_2694", "Namespace '{0}' has no exported member '{1}'."),
        Left_side_of_comma_operator_is_unused_and_has_no_side_effects: diag(2695, ts.DiagnosticCategory.Error, "Left_side_of_comma_operator_is_unused_and_has_no_side_effects_2695", "Left side of comma operator is unused and has no side effects.", /*reportsUnnecessary*/ true),
        The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead: diag(2696, ts.DiagnosticCategory.Error, "The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead_2696", "The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?"),
        An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option: diag(2697, ts.DiagnosticCategory.Error, "An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_in_2697", "An async function or method must return a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option."),
        Spread_types_may_only_be_created_from_object_types: diag(2698, ts.DiagnosticCategory.Error, "Spread_types_may_only_be_created_from_object_types_2698", "Spread types may only be created from object types."),
        Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1: diag(2699, ts.DiagnosticCategory.Error, "Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1_2699", "Static property '{0}' conflicts with built-in property 'Function.{0}' of constructor function '{1}'."),
        Rest_types_may_only_be_created_from_object_types: diag(2700, ts.DiagnosticCategory.Error, "Rest_types_may_only_be_created_from_object_types_2700", "Rest types may only be created from object types."),
        The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access: diag(2701, ts.DiagnosticCategory.Error, "The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access_2701", "The target of an object rest assignment must be a variable or a property access."),
        _0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here: diag(2702, ts.DiagnosticCategory.Error, "_0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here_2702", "'{0}' only refers to a type, but is being used as a namespace here."),
        The_operand_of_a_delete_operator_must_be_a_property_reference: diag(2703, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_must_be_a_property_reference_2703", "The operand of a delete operator must be a property reference."),
        The_operand_of_a_delete_operator_cannot_be_a_read_only_property: diag(2704, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_cannot_be_a_read_only_property_2704", "The operand of a delete operator cannot be a read-only property."),
        An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option: diag(2705, ts.DiagnosticCategory.Error, "An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_de_2705", "An async function or method in ES5/ES3 requires the 'Promise' constructor.  Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option."),
        Required_type_parameters_may_not_follow_optional_type_parameters: diag(2706, ts.DiagnosticCategory.Error, "Required_type_parameters_may_not_follow_optional_type_parameters_2706", "Required type parameters may not follow optional type parameters."),
        Generic_type_0_requires_between_1_and_2_type_arguments: diag(2707, ts.DiagnosticCategory.Error, "Generic_type_0_requires_between_1_and_2_type_arguments_2707", "Generic type '{0}' requires between {1} and {2} type arguments."),
        Cannot_use_namespace_0_as_a_value: diag(2708, ts.DiagnosticCategory.Error, "Cannot_use_namespace_0_as_a_value_2708", "Cannot use namespace '{0}' as a value."),
        Cannot_use_namespace_0_as_a_type: diag(2709, ts.DiagnosticCategory.Error, "Cannot_use_namespace_0_as_a_type_2709", "Cannot use namespace '{0}' as a type."),
        _0_are_specified_twice_The_attribute_named_0_will_be_overwritten: diag(2710, ts.DiagnosticCategory.Error, "_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710", "'{0}' are specified twice. The attribute named '{0}' will be overwritten."),
        A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option: diag(2711, ts.DiagnosticCategory.Error, "A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES20_2711", "A dynamic import call returns a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option."),
        A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option: diag(2712, ts.DiagnosticCategory.Error, "A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declarat_2712", "A dynamic import call in ES5/ES3 requires the 'Promise' constructor.  Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option."),
        Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1: diag(2713, ts.DiagnosticCategory.Error, "Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_p_2713", "Cannot access '{0}.{1}' because '{0}' is a type, but not a namespace. Did you mean to retrieve the type of the property '{1}' in '{0}' with '{0}[\"{1}\"]'?"),
        The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context: diag(2714, ts.DiagnosticCategory.Error, "The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context_2714", "The expression of an export assignment must be an identifier or qualified name in an ambient context."),
        Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor: diag(2715, ts.DiagnosticCategory.Error, "Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715", "Abstract property '{0}' in class '{1}' cannot be accessed in the constructor."),
        Type_parameter_0_has_a_circular_default: diag(2716, ts.DiagnosticCategory.Error, "Type_parameter_0_has_a_circular_default_2716", "Type parameter '{0}' has a circular default."),
        Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_type_2: diag(2717, ts.DiagnosticCategory.Error, "Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_t_2717", "Subsequent property declarations must have the same type.  Property '{0}' must be of type '{1}', but here has type '{2}'."),
        Duplicate_property_0: diag(2718, ts.DiagnosticCategory.Error, "Duplicate_property_0_2718", "Duplicate property '{0}'."),
        Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated: diag(2719, ts.DiagnosticCategory.Error, "Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated_2719", "Type '{0}' is not assignable to type '{1}'. Two different types with this name exist, but they are unrelated."),
        Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass: diag(2720, ts.DiagnosticCategory.Error, "Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclas_2720", "Class '{0}' incorrectly implements class '{1}'. Did you mean to extend '{1}' and inherit its members as a subclass?"),
        Cannot_invoke_an_object_which_is_possibly_null: diag(2721, ts.DiagnosticCategory.Error, "Cannot_invoke_an_object_which_is_possibly_null_2721", "Cannot invoke an object which is possibly 'null'."),
        Cannot_invoke_an_object_which_is_possibly_undefined: diag(2722, ts.DiagnosticCategory.Error, "Cannot_invoke_an_object_which_is_possibly_undefined_2722", "Cannot invoke an object which is possibly 'undefined'."),
        Cannot_invoke_an_object_which_is_possibly_null_or_undefined: diag(2723, ts.DiagnosticCategory.Error, "Cannot_invoke_an_object_which_is_possibly_null_or_undefined_2723", "Cannot invoke an object which is possibly 'null' or 'undefined'."),
        Module_0_has_no_exported_member_1_Did_you_mean_2: diag(2724, ts.DiagnosticCategory.Error, "Module_0_has_no_exported_member_1_Did_you_mean_2_2724", "Module '{0}' has no exported member '{1}'. Did you mean '{2}'?"),
        Class_name_cannot_be_Object_when_targeting_ES5_with_module_0: diag(2725, ts.DiagnosticCategory.Error, "Class_name_cannot_be_Object_when_targeting_ES5_with_module_0_2725", "Class name cannot be 'Object' when targeting ES5 with module {0}."),
        Cannot_find_lib_definition_for_0: diag(2726, ts.DiagnosticCategory.Error, "Cannot_find_lib_definition_for_0_2726", "Cannot find lib definition for '{0}'."),
        Cannot_find_lib_definition_for_0_Did_you_mean_1: diag(2727, ts.DiagnosticCategory.Error, "Cannot_find_lib_definition_for_0_Did_you_mean_1_2727", "Cannot find lib definition for '{0}'. Did you mean '{1}'?"),
        _0_is_declared_here: diag(2728, ts.DiagnosticCategory.Message, "_0_is_declared_here_2728", "'{0}' is declared here."),
        Property_0_is_used_before_its_initialization: diag(2729, ts.DiagnosticCategory.Error, "Property_0_is_used_before_its_initialization_2729", "Property '{0}' is used before its initialization."),
        An_arrow_function_cannot_have_a_this_parameter: diag(2730, ts.DiagnosticCategory.Error, "An_arrow_function_cannot_have_a_this_parameter_2730", "An arrow function cannot have a 'this' parameter."),
        Implicit_conversion_of_a_symbol_to_a_string_will_fail_at_runtime_Consider_wrapping_this_expression_in_String: diag(2731, ts.DiagnosticCategory.Error, "Implicit_conversion_of_a_symbol_to_a_string_will_fail_at_runtime_Consider_wrapping_this_expression_i_2731", "Implicit conversion of a 'symbol' to a 'string' will fail at runtime. Consider wrapping this expression in 'String(...)'."),
        Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension: diag(2732, ts.DiagnosticCategory.Error, "Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension_2732", "Cannot find module '{0}'. Consider using '--resolveJsonModule' to import module with '.json' extension"),
        Property_0_was_also_declared_here: diag(2733, ts.DiagnosticCategory.Error, "Property_0_was_also_declared_here_2733", "Property '{0}' was also declared here."),
        It_is_highly_likely_that_you_are_missing_a_semicolon: diag(2734, ts.DiagnosticCategory.Error, "It_is_highly_likely_that_you_are_missing_a_semicolon_2734", "It is highly likely that you are missing a semicolon."),
        Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1: diag(2735, ts.DiagnosticCategory.Error, "Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1_2735", "Did you mean for '{0}' to be constrained to type 'new (...args: any[]) => {1}'?"),
        Operator_0_cannot_be_applied_to_type_1: diag(2736, ts.DiagnosticCategory.Error, "Operator_0_cannot_be_applied_to_type_1_2736", "Operator '{0}' cannot be applied to type '{1}'."),
        BigInt_literals_are_not_available_when_targeting_lower_than_ESNext: diag(2737, ts.DiagnosticCategory.Error, "BigInt_literals_are_not_available_when_targeting_lower_than_ESNext_2737", "BigInt literals are not available when targeting lower than ESNext."),
        An_outer_value_of_this_is_shadowed_by_this_container: diag(2738, ts.DiagnosticCategory.Message, "An_outer_value_of_this_is_shadowed_by_this_container_2738", "An outer value of 'this' is shadowed by this container."),
        Type_0_is_missing_the_following_properties_from_type_1_Colon_2: diag(2739, ts.DiagnosticCategory.Error, "Type_0_is_missing_the_following_properties_from_type_1_Colon_2_2739", "Type '{0}' is missing the following properties from type '{1}': {2}"),
        Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more: diag(2740, ts.DiagnosticCategory.Error, "Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more_2740", "Type '{0}' is missing the following properties from type '{1}': {2}, and {3} more."),
        Property_0_is_missing_in_type_1_but_required_in_type_2: diag(2741, ts.DiagnosticCategory.Error, "Property_0_is_missing_in_type_1_but_required_in_type_2_2741", "Property '{0}' is missing in type '{1}' but required in type '{2}'."),
        The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_annotation_is_necessary: diag(2742, ts.DiagnosticCategory.Error, "The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_a_2742", "The inferred type of '{0}' cannot be named without a reference to '{1}'. This is likely not portable. A type annotation is necessary."),
        No_overload_expects_0_type_arguments_but_overloads_do_exist_that_expect_either_1_or_2_type_arguments: diag(2743, ts.DiagnosticCategory.Error, "No_overload_expects_0_type_arguments_but_overloads_do_exist_that_expect_either_1_or_2_type_arguments_2743", "No overload expects {0} type arguments, but overloads do exist that expect either {1} or {2} type arguments."),
        Type_parameter_defaults_can_only_reference_previously_declared_type_parameters: diag(2744, ts.DiagnosticCategory.Error, "Type_parameter_defaults_can_only_reference_previously_declared_type_parameters_2744", "Type parameter defaults can only reference previously declared type parameters."),
        This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_provided: diag(2745, ts.DiagnosticCategory.Error, "This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_pr_2745", "This JSX tag's '{0}' prop expects type '{1}' which requires multiple children, but only a single child was provided."),
        This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided: diag(2746, ts.DiagnosticCategory.Error, "This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided_2746", "This JSX tag's '{0}' prop expects a single child of type '{1}', but multiple children were provided."),
        _0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_type_of_1_is_2: diag(2747, ts.DiagnosticCategory.Error, "_0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_t_2747", "'{0}' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of '{1}' is '{2}'."),
        Cannot_access_ambient_const_enums_when_the_isolatedModules_flag_is_provided: diag(2748, ts.DiagnosticCategory.Error, "Cannot_access_ambient_const_enums_when_the_isolatedModules_flag_is_provided_2748", "Cannot access ambient const enums when the '--isolatedModules' flag is provided."),
        _0_refers_to_a_value_but_is_being_used_as_a_type_here: diag(2749, ts.DiagnosticCategory.Error, "_0_refers_to_a_value_but_is_being_used_as_a_type_here_2749", "'{0}' refers to a value, but is being used as a type here."),
        The_implementation_signature_is_declared_here: diag(2750, ts.DiagnosticCategory.Error, "The_implementation_signature_is_declared_here_2750", "The implementation signature is declared here."),
        Circularity_originates_in_type_at_this_location: diag(2751, ts.DiagnosticCategory.Error, "Circularity_originates_in_type_at_this_location_2751", "Circularity originates in type at this location."),
        The_first_export_default_is_here: diag(2752, ts.DiagnosticCategory.Error, "The_first_export_default_is_here_2752", "The first export default is here."),
        Another_export_default_is_here: diag(2753, ts.DiagnosticCategory.Error, "Another_export_default_is_here_2753", "Another export default is here."),
        super_may_not_use_type_arguments: diag(2754, ts.DiagnosticCategory.Error, "super_may_not_use_type_arguments_2754", "'super' may not use type arguments."),
        Import_declaration_0_is_using_private_name_1: diag(4000, ts.DiagnosticCategory.Error, "Import_declaration_0_is_using_private_name_1_4000", "Import declaration '{0}' is using private name '{1}'."),
        Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: diag(4002, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002", "Type parameter '{0}' of exported class has or is using private name '{1}'."),
        Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: diag(4004, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004", "Type parameter '{0}' of exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4006, ts.DiagnosticCategory.Error, "Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4006", "Type parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4008, ts.DiagnosticCategory.Error, "Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008", "Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: diag(4010, ts.DiagnosticCategory.Error, "Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4010", "Type parameter '{0}' of public static method from exported class has or is using private name '{1}'."),
        Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: diag(4012, ts.DiagnosticCategory.Error, "Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4012", "Type parameter '{0}' of public method from exported class has or is using private name '{1}'."),
        Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: diag(4014, ts.DiagnosticCategory.Error, "Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4014", "Type parameter '{0}' of method from exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_exported_function_has_or_is_using_private_name_1: diag(4016, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_function_has_or_is_using_private_name_1_4016", "Type parameter '{0}' of exported function has or is using private name '{1}'."),
        Implements_clause_of_exported_class_0_has_or_is_using_private_name_1: diag(4019, ts.DiagnosticCategory.Error, "Implements_clause_of_exported_class_0_has_or_is_using_private_name_1_4019", "Implements clause of exported class '{0}' has or is using private name '{1}'."),
        extends_clause_of_exported_class_0_has_or_is_using_private_name_1: diag(4020, ts.DiagnosticCategory.Error, "extends_clause_of_exported_class_0_has_or_is_using_private_name_1_4020", "'extends' clause of exported class '{0}' has or is using private name '{1}'."),
        extends_clause_of_exported_interface_0_has_or_is_using_private_name_1: diag(4022, ts.DiagnosticCategory.Error, "extends_clause_of_exported_interface_0_has_or_is_using_private_name_1_4022", "'extends' clause of exported interface '{0}' has or is using private name '{1}'."),
        Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4023, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4023", "Exported variable '{0}' has or is using name '{1}' from external module {2} but cannot be named."),
        Exported_variable_0_has_or_is_using_name_1_from_private_module_2: diag(4024, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_name_1_from_private_module_2_4024", "Exported variable '{0}' has or is using name '{1}' from private module '{2}'."),
        Exported_variable_0_has_or_is_using_private_name_1: diag(4025, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_private_name_1_4025", "Exported variable '{0}' has or is using private name '{1}'."),
        Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4026, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot__4026", "Public static property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4027, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4027", "Public static property '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
        Public_static_property_0_of_exported_class_has_or_is_using_private_name_1: diag(4028, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_private_name_1_4028", "Public static property '{0}' of exported class has or is using private name '{1}'."),
        Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4029, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_name_4029", "Public property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4030, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4030", "Public property '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
        Public_property_0_of_exported_class_has_or_is_using_private_name_1: diag(4031, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_private_name_1_4031", "Public property '{0}' of exported class has or is using private name '{1}'."),
        Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4032, ts.DiagnosticCategory.Error, "Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4032", "Property '{0}' of exported interface has or is using name '{1}' from private module '{2}'."),
        Property_0_of_exported_interface_has_or_is_using_private_name_1: diag(4033, ts.DiagnosticCategory.Error, "Property_0_of_exported_interface_has_or_is_using_private_name_1_4033", "Property '{0}' of exported interface has or is using private name '{1}'."),
        Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4034, ts.DiagnosticCategory.Error, "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_mod_4034", "Parameter type of public static setter '{0}' from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1: diag(4035, ts.DiagnosticCategory.Error, "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1_4035", "Parameter type of public static setter '{0}' from exported class has or is using private name '{1}'."),
        Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4036, ts.DiagnosticCategory.Error, "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4036", "Parameter type of public setter '{0}' from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1: diag(4037, ts.DiagnosticCategory.Error, "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1_4037", "Parameter type of public setter '{0}' from exported class has or is using private name '{1}'."),
        Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4038, ts.DiagnosticCategory.Error, "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_modul_4038", "Return type of public static getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4039, ts.DiagnosticCategory.Error, "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_4039", "Return type of public static getter '{0}' from exported class has or is using name '{1}' from private module '{2}'."),
        Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1: diag(4040, ts.DiagnosticCategory.Error, "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1_4040", "Return type of public static getter '{0}' from exported class has or is using private name '{1}'."),
        Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4041, ts.DiagnosticCategory.Error, "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_4041", "Return type of public getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4042, ts.DiagnosticCategory.Error, "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4042", "Return type of public getter '{0}' from exported class has or is using name '{1}' from private module '{2}'."),
        Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1: diag(4043, ts.DiagnosticCategory.Error, "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1_4043", "Return type of public getter '{0}' from exported class has or is using private name '{1}'."),
        Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4044, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_mod_4044", "Return type of constructor signature from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4045, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0_4045", "Return type of constructor signature from exported interface has or is using private name '{0}'."),
        Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4046, ts.DiagnosticCategory.Error, "Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4046", "Return type of call signature from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4047, ts.DiagnosticCategory.Error, "Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0_4047", "Return type of call signature from exported interface has or is using private name '{0}'."),
        Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4048, ts.DiagnosticCategory.Error, "Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4048", "Return type of index signature from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4049, ts.DiagnosticCategory.Error, "Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0_4049", "Return type of index signature from exported interface has or is using private name '{0}'."),
        Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4050, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module__4050", "Return type of public static method from exported class has or is using name '{0}' from external module {1} but cannot be named."),
        Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4051, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4051", "Return type of public static method from exported class has or is using name '{0}' from private module '{1}'."),
        Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0: diag(4052, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0_4052", "Return type of public static method from exported class has or is using private name '{0}'."),
        Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4053, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_c_4053", "Return type of public method from exported class has or is using name '{0}' from external module {1} but cannot be named."),
        Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4054, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4054", "Return type of public method from exported class has or is using name '{0}' from private module '{1}'."),
        Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0: diag(4055, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0_4055", "Return type of public method from exported class has or is using private name '{0}'."),
        Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4056, ts.DiagnosticCategory.Error, "Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4056", "Return type of method from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0: diag(4057, ts.DiagnosticCategory.Error, "Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0_4057", "Return type of method from exported interface has or is using private name '{0}'."),
        Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4058, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named_4058", "Return type of exported function has or is using name '{0}' from external module {1} but cannot be named."),
        Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1: diag(4059, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1_4059", "Return type of exported function has or is using name '{0}' from private module '{1}'."),
        Return_type_of_exported_function_has_or_is_using_private_name_0: diag(4060, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_private_name_0_4060", "Return type of exported function has or is using private name '{0}'."),
        Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4061, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_can_4061", "Parameter '{0}' of constructor from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4062, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2_4062", "Parameter '{0}' of constructor from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1: diag(4063, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1_4063", "Parameter '{0}' of constructor from exported class has or is using private name '{1}'."),
        Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4064, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_mod_4064", "Parameter '{0}' of constructor signature from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4065, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4065", "Parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'."),
        Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4066, ts.DiagnosticCategory.Error, "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4066", "Parameter '{0}' of call signature from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4067, ts.DiagnosticCategory.Error, "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4067", "Parameter '{0}' of call signature from exported interface has or is using private name '{1}'."),
        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4068, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module__4068", "Parameter '{0}' of public static method from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4069, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4069", "Parameter '{0}' of public static method from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: diag(4070, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4070", "Parameter '{0}' of public static method from exported class has or is using private name '{1}'."),
        Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4071, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_c_4071", "Parameter '{0}' of public method from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4072, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4072", "Parameter '{0}' of public method from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: diag(4073, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4073", "Parameter '{0}' of public method from exported class has or is using private name '{1}'."),
        Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4074, ts.DiagnosticCategory.Error, "Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4074", "Parameter '{0}' of method from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: diag(4075, ts.DiagnosticCategory.Error, "Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4075", "Parameter '{0}' of method from exported interface has or is using private name '{1}'."),
        Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4076, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4076", "Parameter '{0}' of exported function has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2: diag(4077, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2_4077", "Parameter '{0}' of exported function has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_exported_function_has_or_is_using_private_name_1: diag(4078, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_private_name_1_4078", "Parameter '{0}' of exported function has or is using private name '{1}'."),
        Exported_type_alias_0_has_or_is_using_private_name_1: diag(4081, ts.DiagnosticCategory.Error, "Exported_type_alias_0_has_or_is_using_private_name_1_4081", "Exported type alias '{0}' has or is using private name '{1}'."),
        Default_export_of_the_module_has_or_is_using_private_name_0: diag(4082, ts.DiagnosticCategory.Error, "Default_export_of_the_module_has_or_is_using_private_name_0_4082", "Default export of the module has or is using private name '{0}'."),
        Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1: diag(4083, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1_4083", "Type parameter '{0}' of exported type alias has or is using private name '{1}'."),
        Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict: diag(4090, ts.DiagnosticCategory.Error, "Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_librar_4090", "Conflicting definitions for '{0}' found at '{1}' and '{2}'. Consider installing a specific version of this library to resolve the conflict."),
        Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4091, ts.DiagnosticCategory.Error, "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4091", "Parameter '{0}' of index signature from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4092, ts.DiagnosticCategory.Error, "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1_4092", "Parameter '{0}' of index signature from exported interface has or is using private name '{1}'."),
        Property_0_of_exported_class_expression_may_not_be_private_or_protected: diag(4094, ts.DiagnosticCategory.Error, "Property_0_of_exported_class_expression_may_not_be_private_or_protected_4094", "Property '{0}' of exported class expression may not be private or protected."),
        Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4095, ts.DiagnosticCategory.Error, "Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_4095", "Public static method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4096, ts.DiagnosticCategory.Error, "Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4096", "Public static method '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
        Public_static_method_0_of_exported_class_has_or_is_using_private_name_1: diag(4097, ts.DiagnosticCategory.Error, "Public_static_method_0_of_exported_class_has_or_is_using_private_name_1_4097", "Public static method '{0}' of exported class has or is using private name '{1}'."),
        Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4098, ts.DiagnosticCategory.Error, "Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4098", "Public method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4099, ts.DiagnosticCategory.Error, "Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4099", "Public method '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
        Public_method_0_of_exported_class_has_or_is_using_private_name_1: diag(4100, ts.DiagnosticCategory.Error, "Public_method_0_of_exported_class_has_or_is_using_private_name_1_4100", "Public method '{0}' of exported class has or is using private name '{1}'."),
        Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4101, ts.DiagnosticCategory.Error, "Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4101", "Method '{0}' of exported interface has or is using name '{1}' from private module '{2}'."),
        Method_0_of_exported_interface_has_or_is_using_private_name_1: diag(4102, ts.DiagnosticCategory.Error, "Method_0_of_exported_interface_has_or_is_using_private_name_1_4102", "Method '{0}' of exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1: diag(4103, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1_4103", "Type parameter '{0}' of exported mapped object type is using private name '{1}'."),
        The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1: diag(4104, ts.DiagnosticCategory.Error, "The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1_4104", "The type '{0}' is 'readonly' and cannot be assigned to the mutable type '{1}'."),
        The_current_host_does_not_support_the_0_option: diag(5001, ts.DiagnosticCategory.Error, "The_current_host_does_not_support_the_0_option_5001", "The current host does not support the '{0}' option."),
        Cannot_find_the_common_subdirectory_path_for_the_input_files: diag(5009, ts.DiagnosticCategory.Error, "Cannot_find_the_common_subdirectory_path_for_the_input_files_5009", "Cannot find the common subdirectory path for the input files."),
        File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0: diag(5010, ts.DiagnosticCategory.Error, "File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0_5010", "File specification cannot end in a recursive directory wildcard ('**'): '{0}'."),
        Cannot_read_file_0_Colon_1: diag(5012, ts.DiagnosticCategory.Error, "Cannot_read_file_0_Colon_1_5012", "Cannot read file '{0}': {1}."),
        Failed_to_parse_file_0_Colon_1: diag(5014, ts.DiagnosticCategory.Error, "Failed_to_parse_file_0_Colon_1_5014", "Failed to parse file '{0}': {1}."),
        Unknown_compiler_option_0: diag(5023, ts.DiagnosticCategory.Error, "Unknown_compiler_option_0_5023", "Unknown compiler option '{0}'."),
        Compiler_option_0_requires_a_value_of_type_1: diag(5024, ts.DiagnosticCategory.Error, "Compiler_option_0_requires_a_value_of_type_1_5024", "Compiler option '{0}' requires a value of type {1}."),
        Could_not_write_file_0_Colon_1: diag(5033, ts.DiagnosticCategory.Error, "Could_not_write_file_0_Colon_1_5033", "Could not write file '{0}': {1}."),
        Option_project_cannot_be_mixed_with_source_files_on_a_command_line: diag(5042, ts.DiagnosticCategory.Error, "Option_project_cannot_be_mixed_with_source_files_on_a_command_line_5042", "Option 'project' cannot be mixed with source files on a command line."),
        Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher: diag(5047, ts.DiagnosticCategory.Error, "Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES_5047", "Option 'isolatedModules' can only be used when either option '--module' is provided or option 'target' is 'ES2015' or higher."),
        Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided: diag(5051, ts.DiagnosticCategory.Error, "Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided_5051", "Option '{0} can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided."),
        Option_0_cannot_be_specified_without_specifying_option_1: diag(5052, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_without_specifying_option_1_5052", "Option '{0}' cannot be specified without specifying option '{1}'."),
        Option_0_cannot_be_specified_with_option_1: diag(5053, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_with_option_1_5053", "Option '{0}' cannot be specified with option '{1}'."),
        A_tsconfig_json_file_is_already_defined_at_Colon_0: diag(5054, ts.DiagnosticCategory.Error, "A_tsconfig_json_file_is_already_defined_at_Colon_0_5054", "A 'tsconfig.json' file is already defined at: '{0}'."),
        Cannot_write_file_0_because_it_would_overwrite_input_file: diag(5055, ts.DiagnosticCategory.Error, "Cannot_write_file_0_because_it_would_overwrite_input_file_5055", "Cannot write file '{0}' because it would overwrite input file."),
        Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files: diag(5056, ts.DiagnosticCategory.Error, "Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files_5056", "Cannot write file '{0}' because it would be overwritten by multiple input files."),
        Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0: diag(5057, ts.DiagnosticCategory.Error, "Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0_5057", "Cannot find a tsconfig.json file at the specified directory: '{0}'."),
        The_specified_path_does_not_exist_Colon_0: diag(5058, ts.DiagnosticCategory.Error, "The_specified_path_does_not_exist_Colon_0_5058", "The specified path does not exist: '{0}'."),
        Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier: diag(5059, ts.DiagnosticCategory.Error, "Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier_5059", "Invalid value for '--reactNamespace'. '{0}' is not a valid identifier."),
        Option_paths_cannot_be_used_without_specifying_baseUrl_option: diag(5060, ts.DiagnosticCategory.Error, "Option_paths_cannot_be_used_without_specifying_baseUrl_option_5060", "Option 'paths' cannot be used without specifying '--baseUrl' option."),
        Pattern_0_can_have_at_most_one_Asterisk_character: diag(5061, ts.DiagnosticCategory.Error, "Pattern_0_can_have_at_most_one_Asterisk_character_5061", "Pattern '{0}' can have at most one '*' character."),
        Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character: diag(5062, ts.DiagnosticCategory.Error, "Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character_5062", "Substitution '{0}' in pattern '{1}' in can have at most one '*' character."),
        Substitutions_for_pattern_0_should_be_an_array: diag(5063, ts.DiagnosticCategory.Error, "Substitutions_for_pattern_0_should_be_an_array_5063", "Substitutions for pattern '{0}' should be an array."),
        Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2: diag(5064, ts.DiagnosticCategory.Error, "Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2_5064", "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'."),
        File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0: diag(5065, ts.DiagnosticCategory.Error, "File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildca_5065", "File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'."),
        Substitutions_for_pattern_0_shouldn_t_be_an_empty_array: diag(5066, ts.DiagnosticCategory.Error, "Substitutions_for_pattern_0_shouldn_t_be_an_empty_array_5066", "Substitutions for pattern '{0}' shouldn't be an empty array."),
        Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name: diag(5067, ts.DiagnosticCategory.Error, "Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name_5067", "Invalid value for 'jsxFactory'. '{0}' is not a valid identifier or qualified-name."),
        Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig: diag(5068, ts.DiagnosticCategory.Error, "Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript__5068", "Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig."),
        Option_0_cannot_be_specified_without_specifying_option_1_or_option_2: diag(5069, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_without_specifying_option_1_or_option_2_5069", "Option '{0}' cannot be specified without specifying option '{1}' or option '{2}'."),
        Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy: diag(5070, ts.DiagnosticCategory.Error, "Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070", "Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy."),
        Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_esNext: diag(5071, ts.DiagnosticCategory.Error, "Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_5071", "Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'."),
        Unknown_build_option_0: diag(5072, ts.DiagnosticCategory.Error, "Unknown_build_option_0_5072", "Unknown build option '{0}'."),
        Build_option_0_requires_a_value_of_type_1: diag(5073, ts.DiagnosticCategory.Error, "Build_option_0_requires_a_value_of_type_1_5073", "Build option '{0}' requires a value of type {1}."),
        Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBuildInfoFile_is_specified: diag(5074, ts.DiagnosticCategory.Error, "Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBui_5074", "Option '--incremental' can only be specified using tsconfig, emitting to single file or when option `--tsBuildInfoFile` is specified."),
        _0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_constraint_2: diag(5075, ts.DiagnosticCategory.Error, "_0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_5075", "'{0}' is assignable to the constraint of type '{1}', but '{1}' could be instantiated with a different subtype of constraint '{2}'."),
        Generates_a_sourcemap_for_each_corresponding_d_ts_file: diag(6000, ts.DiagnosticCategory.Message, "Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000", "Generates a sourcemap for each corresponding '.d.ts' file."),
        Concatenate_and_emit_output_to_single_file: diag(6001, ts.DiagnosticCategory.Message, "Concatenate_and_emit_output_to_single_file_6001", "Concatenate and emit output to single file."),
        Generates_corresponding_d_ts_file: diag(6002, ts.DiagnosticCategory.Message, "Generates_corresponding_d_ts_file_6002", "Generates corresponding '.d.ts' file."),
        Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: diag(6003, ts.DiagnosticCategory.Message, "Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations_6003", "Specify the location where debugger should locate map files instead of generated locations."),
        Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations: diag(6004, ts.DiagnosticCategory.Message, "Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations_6004", "Specify the location where debugger should locate TypeScript files instead of source locations."),
        Watch_input_files: diag(6005, ts.DiagnosticCategory.Message, "Watch_input_files_6005", "Watch input files."),
        Redirect_output_structure_to_the_directory: diag(6006, ts.DiagnosticCategory.Message, "Redirect_output_structure_to_the_directory_6006", "Redirect output structure to the directory."),
        Do_not_erase_const_enum_declarations_in_generated_code: diag(6007, ts.DiagnosticCategory.Message, "Do_not_erase_const_enum_declarations_in_generated_code_6007", "Do not erase const enum declarations in generated code."),
        Do_not_emit_outputs_if_any_errors_were_reported: diag(6008, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_if_any_errors_were_reported_6008", "Do not emit outputs if any errors were reported."),
        Do_not_emit_comments_to_output: diag(6009, ts.DiagnosticCategory.Message, "Do_not_emit_comments_to_output_6009", "Do not emit comments to output."),
        Do_not_emit_outputs: diag(6010, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_6010", "Do not emit outputs."),
        Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: diag(6011, ts.DiagnosticCategory.Message, "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", "Allow default imports from modules with no default export. This does not affect code emit, just typechecking."),
        Skip_type_checking_of_declaration_files: diag(6012, ts.DiagnosticCategory.Message, "Skip_type_checking_of_declaration_files_6012", "Skip type checking of declaration files."),
        Do_not_resolve_the_real_path_of_symlinks: diag(6013, ts.DiagnosticCategory.Message, "Do_not_resolve_the_real_path_of_symlinks_6013", "Do not resolve the real path of symlinks."),
        Only_emit_d_ts_declaration_files: diag(6014, ts.DiagnosticCategory.Message, "Only_emit_d_ts_declaration_files_6014", "Only emit '.d.ts' declaration files."),
        Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_ES2018_ES2019_or_ESNEXT: diag(6015, ts.DiagnosticCategory.Message, "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_ES2018_ES2019_or_ESNEXT_6015", "Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'."),
        Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext: diag(6016, ts.DiagnosticCategory.Message, "Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext_6016", "Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'."),
        Print_this_message: diag(6017, ts.DiagnosticCategory.Message, "Print_this_message_6017", "Print this message."),
        Print_the_compiler_s_version: diag(6019, ts.DiagnosticCategory.Message, "Print_the_compiler_s_version_6019", "Print the compiler's version."),
        Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json: diag(6020, ts.DiagnosticCategory.Message, "Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020", "Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'."),
        Syntax_Colon_0: diag(6023, ts.DiagnosticCategory.Message, "Syntax_Colon_0_6023", "Syntax: {0}"),
        options: diag(6024, ts.DiagnosticCategory.Message, "options_6024", "options"),
        file: diag(6025, ts.DiagnosticCategory.Message, "file_6025", "file"),
        Examples_Colon_0: diag(6026, ts.DiagnosticCategory.Message, "Examples_Colon_0_6026", "Examples: {0}"),
        Options_Colon: diag(6027, ts.DiagnosticCategory.Message, "Options_Colon_6027", "Options:"),
        Version_0: diag(6029, ts.DiagnosticCategory.Message, "Version_0_6029", "Version {0}"),
        Insert_command_line_options_and_files_from_a_file: diag(6030, ts.DiagnosticCategory.Message, "Insert_command_line_options_and_files_from_a_file_6030", "Insert command line options and files from a file."),
        Starting_compilation_in_watch_mode: diag(6031, ts.DiagnosticCategory.Message, "Starting_compilation_in_watch_mode_6031", "Starting compilation in watch mode..."),
        File_change_detected_Starting_incremental_compilation: diag(6032, ts.DiagnosticCategory.Message, "File_change_detected_Starting_incremental_compilation_6032", "File change detected. Starting incremental compilation..."),
        KIND: diag(6034, ts.DiagnosticCategory.Message, "KIND_6034", "KIND"),
        FILE: diag(6035, ts.DiagnosticCategory.Message, "FILE_6035", "FILE"),
        VERSION: diag(6036, ts.DiagnosticCategory.Message, "VERSION_6036", "VERSION"),
        LOCATION: diag(6037, ts.DiagnosticCategory.Message, "LOCATION_6037", "LOCATION"),
        DIRECTORY: diag(6038, ts.DiagnosticCategory.Message, "DIRECTORY_6038", "DIRECTORY"),
        STRATEGY: diag(6039, ts.DiagnosticCategory.Message, "STRATEGY_6039", "STRATEGY"),
        FILE_OR_DIRECTORY: diag(6040, ts.DiagnosticCategory.Message, "FILE_OR_DIRECTORY_6040", "FILE OR DIRECTORY"),
        Generates_corresponding_map_file: diag(6043, ts.DiagnosticCategory.Message, "Generates_corresponding_map_file_6043", "Generates corresponding '.map' file."),
        Compiler_option_0_expects_an_argument: diag(6044, ts.DiagnosticCategory.Error, "Compiler_option_0_expects_an_argument_6044", "Compiler option '{0}' expects an argument."),
        Unterminated_quoted_string_in_response_file_0: diag(6045, ts.DiagnosticCategory.Error, "Unterminated_quoted_string_in_response_file_0_6045", "Unterminated quoted string in response file '{0}'."),
        Argument_for_0_option_must_be_Colon_1: diag(6046, ts.DiagnosticCategory.Error, "Argument_for_0_option_must_be_Colon_1_6046", "Argument for '{0}' option must be: {1}."),
        Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1: diag(6048, ts.DiagnosticCategory.Error, "Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1_6048", "Locale must be of the form <language> or <language>-<territory>. For example '{0}' or '{1}'."),
        Unsupported_locale_0: diag(6049, ts.DiagnosticCategory.Error, "Unsupported_locale_0_6049", "Unsupported locale '{0}'."),
        Unable_to_open_file_0: diag(6050, ts.DiagnosticCategory.Error, "Unable_to_open_file_0_6050", "Unable to open file '{0}'."),
        Corrupted_locale_file_0: diag(6051, ts.DiagnosticCategory.Error, "Corrupted_locale_file_0_6051", "Corrupted locale file {0}."),
        Raise_error_on_expressions_and_declarations_with_an_implied_any_type: diag(6052, ts.DiagnosticCategory.Message, "Raise_error_on_expressions_and_declarations_with_an_implied_any_type_6052", "Raise error on expressions and declarations with an implied 'any' type."),
        File_0_not_found: diag(6053, ts.DiagnosticCategory.Error, "File_0_not_found_6053", "File '{0}' not found."),
        File_0_has_unsupported_extension_The_only_supported_extensions_are_1: diag(6054, ts.DiagnosticCategory.Error, "File_0_has_unsupported_extension_The_only_supported_extensions_are_1_6054", "File '{0}' has unsupported extension. The only supported extensions are {1}."),
        Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures: diag(6055, ts.DiagnosticCategory.Message, "Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures_6055", "Suppress noImplicitAny errors for indexing objects lacking index signatures."),
        Do_not_emit_declarations_for_code_that_has_an_internal_annotation: diag(6056, ts.DiagnosticCategory.Message, "Do_not_emit_declarations_for_code_that_has_an_internal_annotation_6056", "Do not emit declarations for code that has an '@internal' annotation."),
        Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir: diag(6058, ts.DiagnosticCategory.Message, "Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir_6058", "Specify the root directory of input files. Use to control the output directory structure with --outDir."),
        File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files: diag(6059, ts.DiagnosticCategory.Error, "File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files_6059", "File '{0}' is not under 'rootDir' '{1}'. 'rootDir' is expected to contain all source files."),
        Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix: diag(6060, ts.DiagnosticCategory.Message, "Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix_6060", "Specify the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix)."),
        NEWLINE: diag(6061, ts.DiagnosticCategory.Message, "NEWLINE_6061", "NEWLINE"),
        Option_0_can_only_be_specified_in_tsconfig_json_file: diag(6064, ts.DiagnosticCategory.Error, "Option_0_can_only_be_specified_in_tsconfig_json_file_6064", "Option '{0}' can only be specified in 'tsconfig.json' file."),
        Enables_experimental_support_for_ES7_decorators: diag(6065, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_ES7_decorators_6065", "Enables experimental support for ES7 decorators."),
        Enables_experimental_support_for_emitting_type_metadata_for_decorators: diag(6066, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_emitting_type_metadata_for_decorators_6066", "Enables experimental support for emitting type metadata for decorators."),
        Enables_experimental_support_for_ES7_async_functions: diag(6068, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_ES7_async_functions_6068", "Enables experimental support for ES7 async functions."),
        Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6: diag(6069, ts.DiagnosticCategory.Message, "Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6_6069", "Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)."),
        Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: diag(6070, ts.DiagnosticCategory.Message, "Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file_6070", "Initializes a TypeScript project and creates a tsconfig.json file."),
        Successfully_created_a_tsconfig_json_file: diag(6071, ts.DiagnosticCategory.Message, "Successfully_created_a_tsconfig_json_file_6071", "Successfully created a tsconfig.json file."),
        Suppress_excess_property_checks_for_object_literals: diag(6072, ts.DiagnosticCategory.Message, "Suppress_excess_property_checks_for_object_literals_6072", "Suppress excess property checks for object literals."),
        Stylize_errors_and_messages_using_color_and_context_experimental: diag(6073, ts.DiagnosticCategory.Message, "Stylize_errors_and_messages_using_color_and_context_experimental_6073", "Stylize errors and messages using color and context (experimental)."),
        Do_not_report_errors_on_unused_labels: diag(6074, ts.DiagnosticCategory.Message, "Do_not_report_errors_on_unused_labels_6074", "Do not report errors on unused labels."),
        Report_error_when_not_all_code_paths_in_function_return_a_value: diag(6075, ts.DiagnosticCategory.Message, "Report_error_when_not_all_code_paths_in_function_return_a_value_6075", "Report error when not all code paths in function return a value."),
        Report_errors_for_fallthrough_cases_in_switch_statement: diag(6076, ts.DiagnosticCategory.Message, "Report_errors_for_fallthrough_cases_in_switch_statement_6076", "Report errors for fallthrough cases in switch statement."),
        Do_not_report_errors_on_unreachable_code: diag(6077, ts.DiagnosticCategory.Message, "Do_not_report_errors_on_unreachable_code_6077", "Do not report errors on unreachable code."),
        Disallow_inconsistently_cased_references_to_the_same_file: diag(6078, ts.DiagnosticCategory.Message, "Disallow_inconsistently_cased_references_to_the_same_file_6078", "Disallow inconsistently-cased references to the same file."),
        Specify_library_files_to_be_included_in_the_compilation: diag(6079, ts.DiagnosticCategory.Message, "Specify_library_files_to_be_included_in_the_compilation_6079", "Specify library files to be included in the compilation."),
        Specify_JSX_code_generation_Colon_preserve_react_native_or_react: diag(6080, ts.DiagnosticCategory.Message, "Specify_JSX_code_generation_Colon_preserve_react_native_or_react_6080", "Specify JSX code generation: 'preserve', 'react-native', or 'react'."),
        File_0_has_an_unsupported_extension_so_skipping_it: diag(6081, ts.DiagnosticCategory.Message, "File_0_has_an_unsupported_extension_so_skipping_it_6081", "File '{0}' has an unsupported extension, so skipping it."),
        Only_amd_and_system_modules_are_supported_alongside_0: diag(6082, ts.DiagnosticCategory.Error, "Only_amd_and_system_modules_are_supported_alongside_0_6082", "Only 'amd' and 'system' modules are supported alongside --{0}."),
        Base_directory_to_resolve_non_absolute_module_names: diag(6083, ts.DiagnosticCategory.Message, "Base_directory_to_resolve_non_absolute_module_names_6083", "Base directory to resolve non-absolute module names."),
        Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit: diag(6084, ts.DiagnosticCategory.Message, "Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react__6084", "[Deprecated] Use '--jsxFactory' instead. Specify the object invoked for createElement when targeting 'react' JSX emit"),
        Enable_tracing_of_the_name_resolution_process: diag(6085, ts.DiagnosticCategory.Message, "Enable_tracing_of_the_name_resolution_process_6085", "Enable tracing of the name resolution process."),
        Resolving_module_0_from_1: diag(6086, ts.DiagnosticCategory.Message, "Resolving_module_0_from_1_6086", "======== Resolving module '{0}' from '{1}'. ========"),
        Explicitly_specified_module_resolution_kind_Colon_0: diag(6087, ts.DiagnosticCategory.Message, "Explicitly_specified_module_resolution_kind_Colon_0_6087", "Explicitly specified module resolution kind: '{0}'."),
        Module_resolution_kind_is_not_specified_using_0: diag(6088, ts.DiagnosticCategory.Message, "Module_resolution_kind_is_not_specified_using_0_6088", "Module resolution kind is not specified, using '{0}'."),
        Module_name_0_was_successfully_resolved_to_1: diag(6089, ts.DiagnosticCategory.Message, "Module_name_0_was_successfully_resolved_to_1_6089", "======== Module name '{0}' was successfully resolved to '{1}'. ========"),
        Module_name_0_was_not_resolved: diag(6090, ts.DiagnosticCategory.Message, "Module_name_0_was_not_resolved_6090", "======== Module name '{0}' was not resolved. ========"),
        paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0: diag(6091, ts.DiagnosticCategory.Message, "paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0_6091", "'paths' option is specified, looking for a pattern to match module name '{0}'."),
        Module_name_0_matched_pattern_1: diag(6092, ts.DiagnosticCategory.Message, "Module_name_0_matched_pattern_1_6092", "Module name '{0}', matched pattern '{1}'."),
        Trying_substitution_0_candidate_module_location_Colon_1: diag(6093, ts.DiagnosticCategory.Message, "Trying_substitution_0_candidate_module_location_Colon_1_6093", "Trying substitution '{0}', candidate module location: '{1}'."),
        Resolving_module_name_0_relative_to_base_url_1_2: diag(6094, ts.DiagnosticCategory.Message, "Resolving_module_name_0_relative_to_base_url_1_2_6094", "Resolving module name '{0}' relative to base url '{1}' - '{2}'."),
        Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1: diag(6095, ts.DiagnosticCategory.Message, "Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1_6095", "Loading module as file / folder, candidate module location '{0}', target file type '{1}'."),
        File_0_does_not_exist: diag(6096, ts.DiagnosticCategory.Message, "File_0_does_not_exist_6096", "File '{0}' does not exist."),
        File_0_exist_use_it_as_a_name_resolution_result: diag(6097, ts.DiagnosticCategory.Message, "File_0_exist_use_it_as_a_name_resolution_result_6097", "File '{0}' exist - use it as a name resolution result."),
        Loading_module_0_from_node_modules_folder_target_file_type_1: diag(6098, ts.DiagnosticCategory.Message, "Loading_module_0_from_node_modules_folder_target_file_type_1_6098", "Loading module '{0}' from 'node_modules' folder, target file type '{1}'."),
        Found_package_json_at_0: diag(6099, ts.DiagnosticCategory.Message, "Found_package_json_at_0_6099", "Found 'package.json' at '{0}'."),
        package_json_does_not_have_a_0_field: diag(6100, ts.DiagnosticCategory.Message, "package_json_does_not_have_a_0_field_6100", "'package.json' does not have a '{0}' field."),
        package_json_has_0_field_1_that_references_2: diag(6101, ts.DiagnosticCategory.Message, "package_json_has_0_field_1_that_references_2_6101", "'package.json' has '{0}' field '{1}' that references '{2}'."),
        Allow_javascript_files_to_be_compiled: diag(6102, ts.DiagnosticCategory.Message, "Allow_javascript_files_to_be_compiled_6102", "Allow javascript files to be compiled."),
        Option_0_should_have_array_of_strings_as_a_value: diag(6103, ts.DiagnosticCategory.Error, "Option_0_should_have_array_of_strings_as_a_value_6103", "Option '{0}' should have array of strings as a value."),
        Checking_if_0_is_the_longest_matching_prefix_for_1_2: diag(6104, ts.DiagnosticCategory.Message, "Checking_if_0_is_the_longest_matching_prefix_for_1_2_6104", "Checking if '{0}' is the longest matching prefix for '{1}' - '{2}'."),
        Expected_type_of_0_field_in_package_json_to_be_1_got_2: diag(6105, ts.DiagnosticCategory.Message, "Expected_type_of_0_field_in_package_json_to_be_1_got_2_6105", "Expected type of '{0}' field in 'package.json' to be '{1}', got '{2}'."),
        baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1: diag(6106, ts.DiagnosticCategory.Message, "baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1_6106", "'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'."),
        rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0: diag(6107, ts.DiagnosticCategory.Message, "rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107", "'rootDirs' option is set, using it to resolve relative module name '{0}'."),
        Longest_matching_prefix_for_0_is_1: diag(6108, ts.DiagnosticCategory.Message, "Longest_matching_prefix_for_0_is_1_6108", "Longest matching prefix for '{0}' is '{1}'."),
        Loading_0_from_the_root_dir_1_candidate_location_2: diag(6109, ts.DiagnosticCategory.Message, "Loading_0_from_the_root_dir_1_candidate_location_2_6109", "Loading '{0}' from the root dir '{1}', candidate location '{2}'."),
        Trying_other_entries_in_rootDirs: diag(6110, ts.DiagnosticCategory.Message, "Trying_other_entries_in_rootDirs_6110", "Trying other entries in 'rootDirs'."),
        Module_resolution_using_rootDirs_has_failed: diag(6111, ts.DiagnosticCategory.Message, "Module_resolution_using_rootDirs_has_failed_6111", "Module resolution using 'rootDirs' has failed."),
        Do_not_emit_use_strict_directives_in_module_output: diag(6112, ts.DiagnosticCategory.Message, "Do_not_emit_use_strict_directives_in_module_output_6112", "Do not emit 'use strict' directives in module output."),
        Enable_strict_null_checks: diag(6113, ts.DiagnosticCategory.Message, "Enable_strict_null_checks_6113", "Enable strict null checks."),
        Unknown_option_excludes_Did_you_mean_exclude: diag(6114, ts.DiagnosticCategory.Error, "Unknown_option_excludes_Did_you_mean_exclude_6114", "Unknown option 'excludes'. Did you mean 'exclude'?"),
        Raise_error_on_this_expressions_with_an_implied_any_type: diag(6115, ts.DiagnosticCategory.Message, "Raise_error_on_this_expressions_with_an_implied_any_type_6115", "Raise error on 'this' expressions with an implied 'any' type."),
        Resolving_type_reference_directive_0_containing_file_1_root_directory_2: diag(6116, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_1_root_directory_2_6116", "======== Resolving type reference directive '{0}', containing file '{1}', root directory '{2}'. ========"),
        Resolving_using_primary_search_paths: diag(6117, ts.DiagnosticCategory.Message, "Resolving_using_primary_search_paths_6117", "Resolving using primary search paths..."),
        Resolving_from_node_modules_folder: diag(6118, ts.DiagnosticCategory.Message, "Resolving_from_node_modules_folder_6118", "Resolving from node_modules folder..."),
        Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2: diag(6119, ts.DiagnosticCategory.Message, "Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2_6119", "======== Type reference directive '{0}' was successfully resolved to '{1}', primary: {2}. ========"),
        Type_reference_directive_0_was_not_resolved: diag(6120, ts.DiagnosticCategory.Message, "Type_reference_directive_0_was_not_resolved_6120", "======== Type reference directive '{0}' was not resolved. ========"),
        Resolving_with_primary_search_path_0: diag(6121, ts.DiagnosticCategory.Message, "Resolving_with_primary_search_path_0_6121", "Resolving with primary search path '{0}'."),
        Root_directory_cannot_be_determined_skipping_primary_search_paths: diag(6122, ts.DiagnosticCategory.Message, "Root_directory_cannot_be_determined_skipping_primary_search_paths_6122", "Root directory cannot be determined, skipping primary search paths."),
        Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set: diag(6123, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set_6123", "======== Resolving type reference directive '{0}', containing file '{1}', root directory not set. ========"),
        Type_declaration_files_to_be_included_in_compilation: diag(6124, ts.DiagnosticCategory.Message, "Type_declaration_files_to_be_included_in_compilation_6124", "Type declaration files to be included in compilation."),
        Looking_up_in_node_modules_folder_initial_location_0: diag(6125, ts.DiagnosticCategory.Message, "Looking_up_in_node_modules_folder_initial_location_0_6125", "Looking up in 'node_modules' folder, initial location '{0}'."),
        Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder: diag(6126, ts.DiagnosticCategory.Message, "Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_mod_6126", "Containing file is not specified and root directory cannot be determined, skipping lookup in 'node_modules' folder."),
        Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1: diag(6127, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1_6127", "======== Resolving type reference directive '{0}', containing file not set, root directory '{1}'. ========"),
        Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set: diag(6128, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set_6128", "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========"),
        Resolving_real_path_for_0_result_1: diag(6130, ts.DiagnosticCategory.Message, "Resolving_real_path_for_0_result_1_6130", "Resolving real path for '{0}', result '{1}'."),
        Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: diag(6131, ts.DiagnosticCategory.Error, "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'."),
        File_name_0_has_a_1_extension_stripping_it: diag(6132, ts.DiagnosticCategory.Message, "File_name_0_has_a_1_extension_stripping_it_6132", "File name '{0}' has a '{1}' extension - stripping it."),
        _0_is_declared_but_its_value_is_never_read: diag(6133, ts.DiagnosticCategory.Error, "_0_is_declared_but_its_value_is_never_read_6133", "'{0}' is declared but its value is never read.", /*reportsUnnecessary*/ true),
        Report_errors_on_unused_locals: diag(6134, ts.DiagnosticCategory.Message, "Report_errors_on_unused_locals_6134", "Report errors on unused locals."),
        Report_errors_on_unused_parameters: diag(6135, ts.DiagnosticCategory.Message, "Report_errors_on_unused_parameters_6135", "Report errors on unused parameters."),
        The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files: diag(6136, ts.DiagnosticCategory.Message, "The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files_6136", "The maximum dependency depth to search under node_modules and load JavaScript files."),
        Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1: diag(6137, ts.DiagnosticCategory.Error, "Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1_6137", "Cannot import type declaration files. Consider importing '{0}' instead of '{1}'."),
        Property_0_is_declared_but_its_value_is_never_read: diag(6138, ts.DiagnosticCategory.Error, "Property_0_is_declared_but_its_value_is_never_read_6138", "Property '{0}' is declared but its value is never read.", /*reportsUnnecessary*/ true),
        Import_emit_helpers_from_tslib: diag(6139, ts.DiagnosticCategory.Message, "Import_emit_helpers_from_tslib_6139", "Import emit helpers from 'tslib'."),
        Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2: diag(6140, ts.DiagnosticCategory.Error, "Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using__6140", "Auto discovery for typings is enabled in project '{0}'. Running extra resolution pass for module '{1}' using cache location '{2}'."),
        Parse_in_strict_mode_and_emit_use_strict_for_each_source_file: diag(6141, ts.DiagnosticCategory.Message, "Parse_in_strict_mode_and_emit_use_strict_for_each_source_file_6141", "Parse in strict mode and emit \"use strict\" for each source file."),
        Module_0_was_resolved_to_1_but_jsx_is_not_set: diag(6142, ts.DiagnosticCategory.Error, "Module_0_was_resolved_to_1_but_jsx_is_not_set_6142", "Module '{0}' was resolved to '{1}', but '--jsx' is not set."),
        Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1: diag(6144, ts.DiagnosticCategory.Message, "Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1_6144", "Module '{0}' was resolved as locally declared ambient module in file '{1}'."),
        Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified: diag(6145, ts.DiagnosticCategory.Message, "Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified_6145", "Module '{0}' was resolved as ambient module declared in '{1}' since this file was not modified."),
        Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h: diag(6146, ts.DiagnosticCategory.Message, "Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h_6146", "Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'."),
        Resolution_for_module_0_was_found_in_cache_from_location_1: diag(6147, ts.DiagnosticCategory.Message, "Resolution_for_module_0_was_found_in_cache_from_location_1_6147", "Resolution for module '{0}' was found in cache from location '{1}'."),
        Directory_0_does_not_exist_skipping_all_lookups_in_it: diag(6148, ts.DiagnosticCategory.Message, "Directory_0_does_not_exist_skipping_all_lookups_in_it_6148", "Directory '{0}' does not exist, skipping all lookups in it."),
        Show_diagnostic_information: diag(6149, ts.DiagnosticCategory.Message, "Show_diagnostic_information_6149", "Show diagnostic information."),
        Show_verbose_diagnostic_information: diag(6150, ts.DiagnosticCategory.Message, "Show_verbose_diagnostic_information_6150", "Show verbose diagnostic information."),
        Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file: diag(6151, ts.DiagnosticCategory.Message, "Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file_6151", "Emit a single file with source maps instead of having a separate file."),
        Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set: diag(6152, ts.DiagnosticCategory.Message, "Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap__6152", "Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set."),
        Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule: diag(6153, ts.DiagnosticCategory.Message, "Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule_6153", "Transpile each file as a separate module (similar to 'ts.transpileModule')."),
        Print_names_of_generated_files_part_of_the_compilation: diag(6154, ts.DiagnosticCategory.Message, "Print_names_of_generated_files_part_of_the_compilation_6154", "Print names of generated files part of the compilation."),
        Print_names_of_files_part_of_the_compilation: diag(6155, ts.DiagnosticCategory.Message, "Print_names_of_files_part_of_the_compilation_6155", "Print names of files part of the compilation."),
        The_locale_used_when_displaying_messages_to_the_user_e_g_en_us: diag(6156, ts.DiagnosticCategory.Message, "The_locale_used_when_displaying_messages_to_the_user_e_g_en_us_6156", "The locale used when displaying messages to the user (e.g. 'en-us')"),
        Do_not_generate_custom_helper_functions_like_extends_in_compiled_output: diag(6157, ts.DiagnosticCategory.Message, "Do_not_generate_custom_helper_functions_like_extends_in_compiled_output_6157", "Do not generate custom helper functions like '__extends' in compiled output."),
        Do_not_include_the_default_library_file_lib_d_ts: diag(6158, ts.DiagnosticCategory.Message, "Do_not_include_the_default_library_file_lib_d_ts_6158", "Do not include the default library file (lib.d.ts)."),
        Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files: diag(6159, ts.DiagnosticCategory.Message, "Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files_6159", "Do not add triple-slash references or imported modules to the list of compiled files."),
        Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files: diag(6160, ts.DiagnosticCategory.Message, "Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files_6160", "[Deprecated] Use '--skipLibCheck' instead. Skip type checking of default library declaration files."),
        List_of_folders_to_include_type_definitions_from: diag(6161, ts.DiagnosticCategory.Message, "List_of_folders_to_include_type_definitions_from_6161", "List of folders to include type definitions from."),
        Disable_size_limitations_on_JavaScript_projects: diag(6162, ts.DiagnosticCategory.Message, "Disable_size_limitations_on_JavaScript_projects_6162", "Disable size limitations on JavaScript projects."),
        The_character_set_of_the_input_files: diag(6163, ts.DiagnosticCategory.Message, "The_character_set_of_the_input_files_6163", "The character set of the input files."),
        Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files: diag(6164, ts.DiagnosticCategory.Message, "Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files_6164", "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files."),
        Do_not_truncate_error_messages: diag(6165, ts.DiagnosticCategory.Message, "Do_not_truncate_error_messages_6165", "Do not truncate error messages."),
        Output_directory_for_generated_declaration_files: diag(6166, ts.DiagnosticCategory.Message, "Output_directory_for_generated_declaration_files_6166", "Output directory for generated declaration files."),
        A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl: diag(6167, ts.DiagnosticCategory.Message, "A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl_6167", "A series of entries which re-map imports to lookup locations relative to the 'baseUrl'."),
        List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime: diag(6168, ts.DiagnosticCategory.Message, "List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime_6168", "List of root folders whose combined content represents the structure of the project at runtime."),
        Show_all_compiler_options: diag(6169, ts.DiagnosticCategory.Message, "Show_all_compiler_options_6169", "Show all compiler options."),
        Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file: diag(6170, ts.DiagnosticCategory.Message, "Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file_6170", "[Deprecated] Use '--outFile' instead. Concatenate and emit output to single file"),
        Command_line_Options: diag(6171, ts.DiagnosticCategory.Message, "Command_line_Options_6171", "Command-line Options"),
        Basic_Options: diag(6172, ts.DiagnosticCategory.Message, "Basic_Options_6172", "Basic Options"),
        Strict_Type_Checking_Options: diag(6173, ts.DiagnosticCategory.Message, "Strict_Type_Checking_Options_6173", "Strict Type-Checking Options"),
        Module_Resolution_Options: diag(6174, ts.DiagnosticCategory.Message, "Module_Resolution_Options_6174", "Module Resolution Options"),
        Source_Map_Options: diag(6175, ts.DiagnosticCategory.Message, "Source_Map_Options_6175", "Source Map Options"),
        Additional_Checks: diag(6176, ts.DiagnosticCategory.Message, "Additional_Checks_6176", "Additional Checks"),
        Experimental_Options: diag(6177, ts.DiagnosticCategory.Message, "Experimental_Options_6177", "Experimental Options"),
        Advanced_Options: diag(6178, ts.DiagnosticCategory.Message, "Advanced_Options_6178", "Advanced Options"),
        Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3: diag(6179, ts.DiagnosticCategory.Message, "Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3_6179", "Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'."),
        Enable_all_strict_type_checking_options: diag(6180, ts.DiagnosticCategory.Message, "Enable_all_strict_type_checking_options_6180", "Enable all strict type-checking options."),
        List_of_language_service_plugins: diag(6181, ts.DiagnosticCategory.Message, "List_of_language_service_plugins_6181", "List of language service plugins."),
        Scoped_package_detected_looking_in_0: diag(6182, ts.DiagnosticCategory.Message, "Scoped_package_detected_looking_in_0_6182", "Scoped package detected, looking in '{0}'"),
        Reusing_resolution_of_module_0_to_file_1_from_old_program: diag(6183, ts.DiagnosticCategory.Message, "Reusing_resolution_of_module_0_to_file_1_from_old_program_6183", "Reusing resolution of module '{0}' to file '{1}' from old program."),
        Reusing_module_resolutions_originating_in_0_since_resolutions_are_unchanged_from_old_program: diag(6184, ts.DiagnosticCategory.Message, "Reusing_module_resolutions_originating_in_0_since_resolutions_are_unchanged_from_old_program_6184", "Reusing module resolutions originating in '{0}' since resolutions are unchanged from old program."),
        Disable_strict_checking_of_generic_signatures_in_function_types: diag(6185, ts.DiagnosticCategory.Message, "Disable_strict_checking_of_generic_signatures_in_function_types_6185", "Disable strict checking of generic signatures in function types."),
        Enable_strict_checking_of_function_types: diag(6186, ts.DiagnosticCategory.Message, "Enable_strict_checking_of_function_types_6186", "Enable strict checking of function types."),
        Enable_strict_checking_of_property_initialization_in_classes: diag(6187, ts.DiagnosticCategory.Message, "Enable_strict_checking_of_property_initialization_in_classes_6187", "Enable strict checking of property initialization in classes."),
        Numeric_separators_are_not_allowed_here: diag(6188, ts.DiagnosticCategory.Error, "Numeric_separators_are_not_allowed_here_6188", "Numeric separators are not allowed here."),
        Multiple_consecutive_numeric_separators_are_not_permitted: diag(6189, ts.DiagnosticCategory.Error, "Multiple_consecutive_numeric_separators_are_not_permitted_6189", "Multiple consecutive numeric separators are not permitted."),
        Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen: diag(6191, ts.DiagnosticCategory.Message, "Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen_6191", "Whether to keep outdated console output in watch mode instead of clearing the screen."),
        All_imports_in_import_declaration_are_unused: diag(6192, ts.DiagnosticCategory.Error, "All_imports_in_import_declaration_are_unused_6192", "All imports in import declaration are unused.", /*reportsUnnecessary*/ true),
        Found_1_error_Watching_for_file_changes: diag(6193, ts.DiagnosticCategory.Message, "Found_1_error_Watching_for_file_changes_6193", "Found 1 error. Watching for file changes."),
        Found_0_errors_Watching_for_file_changes: diag(6194, ts.DiagnosticCategory.Message, "Found_0_errors_Watching_for_file_changes_6194", "Found {0} errors. Watching for file changes."),
        Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols: diag(6195, ts.DiagnosticCategory.Message, "Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195", "Resolve 'keyof' to string valued property names only (no numbers or symbols)."),
        _0_is_declared_but_never_used: diag(6196, ts.DiagnosticCategory.Error, "_0_is_declared_but_never_used_6196", "'{0}' is declared but never used.", /*reportsUnnecessary*/ true),
        Include_modules_imported_with_json_extension: diag(6197, ts.DiagnosticCategory.Message, "Include_modules_imported_with_json_extension_6197", "Include modules imported with '.json' extension"),
        All_destructured_elements_are_unused: diag(6198, ts.DiagnosticCategory.Error, "All_destructured_elements_are_unused_6198", "All destructured elements are unused.", /*reportsUnnecessary*/ true),
        All_variables_are_unused: diag(6199, ts.DiagnosticCategory.Error, "All_variables_are_unused_6199", "All variables are unused.", /*reportsUnnecessary*/ true),
        Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0: diag(6200, ts.DiagnosticCategory.Error, "Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0_6200", "Definitions of the following identifiers conflict with those in another file: {0}"),
        Conflicts_are_in_this_file: diag(6201, ts.DiagnosticCategory.Message, "Conflicts_are_in_this_file_6201", "Conflicts are in this file."),
        _0_was_also_declared_here: diag(6203, ts.DiagnosticCategory.Message, "_0_was_also_declared_here_6203", "'{0}' was also declared here."),
        and_here: diag(6204, ts.DiagnosticCategory.Message, "and_here_6204", "and here."),
        All_type_parameters_are_unused: diag(6205, ts.DiagnosticCategory.Error, "All_type_parameters_are_unused_6205", "All type parameters are unused"),
        package_json_has_a_typesVersions_field_with_version_specific_path_mappings: diag(6206, ts.DiagnosticCategory.Message, "package_json_has_a_typesVersions_field_with_version_specific_path_mappings_6206", "'package.json' has a 'typesVersions' field with version-specific path mappings."),
        package_json_does_not_have_a_typesVersions_entry_that_matches_version_0: diag(6207, ts.DiagnosticCategory.Message, "package_json_does_not_have_a_typesVersions_entry_that_matches_version_0_6207", "'package.json' does not have a 'typesVersions' entry that matches version '{0}'."),
        package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2: diag(6208, ts.DiagnosticCategory.Message, "package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_ma_6208", "'package.json' has a 'typesVersions' entry '{0}' that matches compiler version '{1}', looking for a pattern to match module name '{2}'."),
        package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range: diag(6209, ts.DiagnosticCategory.Message, "package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range_6209", "'package.json' has a 'typesVersions' entry '{0}' that is not a valid semver range."),
        An_argument_for_0_was_not_provided: diag(6210, ts.DiagnosticCategory.Message, "An_argument_for_0_was_not_provided_6210", "An argument for '{0}' was not provided."),
        An_argument_matching_this_binding_pattern_was_not_provided: diag(6211, ts.DiagnosticCategory.Message, "An_argument_matching_this_binding_pattern_was_not_provided_6211", "An argument matching this binding pattern was not provided."),
        Did_you_mean_to_call_this_expression: diag(6212, ts.DiagnosticCategory.Message, "Did_you_mean_to_call_this_expression_6212", "Did you mean to call this expression?"),
        Did_you_mean_to_use_new_with_this_expression: diag(6213, ts.DiagnosticCategory.Message, "Did_you_mean_to_use_new_with_this_expression_6213", "Did you mean to use 'new' with this expression?"),
        Enable_strict_bind_call_and_apply_methods_on_functions: diag(6214, ts.DiagnosticCategory.Message, "Enable_strict_bind_call_and_apply_methods_on_functions_6214", "Enable strict 'bind', 'call', and 'apply' methods on functions."),
        Using_compiler_options_of_project_reference_redirect_0: diag(6215, ts.DiagnosticCategory.Message, "Using_compiler_options_of_project_reference_redirect_0_6215", "Using compiler options of project reference redirect '{0}'."),
        Found_1_error: diag(6216, ts.DiagnosticCategory.Message, "Found_1_error_6216", "Found 1 error."),
        Found_0_errors: diag(6217, ts.DiagnosticCategory.Message, "Found_0_errors_6217", "Found {0} errors."),
        Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2: diag(6218, ts.DiagnosticCategory.Message, "Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2_6218", "======== Module name '{0}' was successfully resolved to '{1}' with Package ID '{2}'. ========"),
        Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3: diag(6219, ts.DiagnosticCategory.Message, "Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3_6219", "======== Type reference directive '{0}' was successfully resolved to '{1}' with Package ID '{2}', primary: {3}. ========"),
        package_json_had_a_falsy_0_field: diag(6220, ts.DiagnosticCategory.Message, "package_json_had_a_falsy_0_field_6220", "'package.json' had a falsy '{0}' field."),
        Projects_to_reference: diag(6300, ts.DiagnosticCategory.Message, "Projects_to_reference_6300", "Projects to reference"),
        Enable_project_compilation: diag(6302, ts.DiagnosticCategory.Message, "Enable_project_compilation_6302", "Enable project compilation"),
        Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0: diag(6202, ts.DiagnosticCategory.Error, "Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0_6202", "Project references may not form a circular graph. Cycle detected: {0}"),
        Composite_projects_may_not_disable_declaration_emit: diag(6304, ts.DiagnosticCategory.Error, "Composite_projects_may_not_disable_declaration_emit_6304", "Composite projects may not disable declaration emit."),
        Output_file_0_has_not_been_built_from_source_file_1: diag(6305, ts.DiagnosticCategory.Error, "Output_file_0_has_not_been_built_from_source_file_1_6305", "Output file '{0}' has not been built from source file '{1}'."),
        Referenced_project_0_must_have_setting_composite_Colon_true: diag(6306, ts.DiagnosticCategory.Error, "Referenced_project_0_must_have_setting_composite_Colon_true_6306", "Referenced project '{0}' must have setting \"composite\": true."),
        File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern: diag(6307, ts.DiagnosticCategory.Error, "File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern_6307", "File '{0}' is not in project file list. Projects must list all files or use an 'include' pattern."),
        Cannot_prepend_project_0_because_it_does_not_have_outFile_set: diag(6308, ts.DiagnosticCategory.Error, "Cannot_prepend_project_0_because_it_does_not_have_outFile_set_6308", "Cannot prepend project '{0}' because it does not have 'outFile' set"),
        Output_file_0_from_project_1_does_not_exist: diag(6309, ts.DiagnosticCategory.Error, "Output_file_0_from_project_1_does_not_exist_6309", "Output file '{0}' from project '{1}' does not exist"),
        Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2: diag(6350, ts.DiagnosticCategory.Message, "Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2_6350", "Project '{0}' is out of date because oldest output '{1}' is older than newest input '{2}'"),
        Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2: diag(6351, ts.DiagnosticCategory.Message, "Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2_6351", "Project '{0}' is up to date because newest input '{1}' is older than oldest output '{2}'"),
        Project_0_is_out_of_date_because_output_file_1_does_not_exist: diag(6352, ts.DiagnosticCategory.Message, "Project_0_is_out_of_date_because_output_file_1_does_not_exist_6352", "Project '{0}' is out of date because output file '{1}' does not exist"),
        Project_0_is_out_of_date_because_its_dependency_1_is_out_of_date: diag(6353, ts.DiagnosticCategory.Message, "Project_0_is_out_of_date_because_its_dependency_1_is_out_of_date_6353", "Project '{0}' is out of date because its dependency '{1}' is out of date"),
        Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies: diag(6354, ts.DiagnosticCategory.Message, "Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies_6354", "Project '{0}' is up to date with .d.ts files from its dependencies"),
        Projects_in_this_build_Colon_0: diag(6355, ts.DiagnosticCategory.Message, "Projects_in_this_build_Colon_0_6355", "Projects in this build: {0}"),
        A_non_dry_build_would_delete_the_following_files_Colon_0: diag(6356, ts.DiagnosticCategory.Message, "A_non_dry_build_would_delete_the_following_files_Colon_0_6356", "A non-dry build would delete the following files: {0}"),
        A_non_dry_build_would_build_project_0: diag(6357, ts.DiagnosticCategory.Message, "A_non_dry_build_would_build_project_0_6357", "A non-dry build would build project '{0}'"),
        Building_project_0: diag(6358, ts.DiagnosticCategory.Message, "Building_project_0_6358", "Building project '{0}'..."),
        Updating_output_timestamps_of_project_0: diag(6359, ts.DiagnosticCategory.Message, "Updating_output_timestamps_of_project_0_6359", "Updating output timestamps of project '{0}'..."),
        delete_this_Project_0_is_up_to_date_because_it_was_previously_built: diag(6360, ts.DiagnosticCategory.Message, "delete_this_Project_0_is_up_to_date_because_it_was_previously_built_6360", "delete this - Project '{0}' is up to date because it was previously built"),
        Project_0_is_up_to_date: diag(6361, ts.DiagnosticCategory.Message, "Project_0_is_up_to_date_6361", "Project '{0}' is up to date"),
        Skipping_build_of_project_0_because_its_dependency_1_has_errors: diag(6362, ts.DiagnosticCategory.Message, "Skipping_build_of_project_0_because_its_dependency_1_has_errors_6362", "Skipping build of project '{0}' because its dependency '{1}' has errors"),
        Project_0_can_t_be_built_because_its_dependency_1_has_errors: diag(6363, ts.DiagnosticCategory.Message, "Project_0_can_t_be_built_because_its_dependency_1_has_errors_6363", "Project '{0}' can't be built because its dependency '{1}' has errors"),
        Build_one_or_more_projects_and_their_dependencies_if_out_of_date: diag(6364, ts.DiagnosticCategory.Message, "Build_one_or_more_projects_and_their_dependencies_if_out_of_date_6364", "Build one or more projects and their dependencies, if out of date"),
        Delete_the_outputs_of_all_projects: diag(6365, ts.DiagnosticCategory.Message, "Delete_the_outputs_of_all_projects_6365", "Delete the outputs of all projects"),
        Enable_verbose_logging: diag(6366, ts.DiagnosticCategory.Message, "Enable_verbose_logging_6366", "Enable verbose logging"),
        Show_what_would_be_built_or_deleted_if_specified_with_clean: diag(6367, ts.DiagnosticCategory.Message, "Show_what_would_be_built_or_deleted_if_specified_with_clean_6367", "Show what would be built (or deleted, if specified with '--clean')"),
        Build_all_projects_including_those_that_appear_to_be_up_to_date: diag(6368, ts.DiagnosticCategory.Message, "Build_all_projects_including_those_that_appear_to_be_up_to_date_6368", "Build all projects, including those that appear to be up to date"),
        Option_build_must_be_the_first_command_line_argument: diag(6369, ts.DiagnosticCategory.Error, "Option_build_must_be_the_first_command_line_argument_6369", "Option '--build' must be the first command line argument."),
        Options_0_and_1_cannot_be_combined: diag(6370, ts.DiagnosticCategory.Error, "Options_0_and_1_cannot_be_combined_6370", "Options '{0}' and '{1}' cannot be combined."),
        Updating_unchanged_output_timestamps_of_project_0: diag(6371, ts.DiagnosticCategory.Message, "Updating_unchanged_output_timestamps_of_project_0_6371", "Updating unchanged output timestamps of project '{0}'..."),
        Project_0_is_out_of_date_because_output_of_its_dependency_1_has_changed: diag(6372, ts.DiagnosticCategory.Message, "Project_0_is_out_of_date_because_output_of_its_dependency_1_has_changed_6372", "Project '{0}' is out of date because output of its dependency '{1}' has changed"),
        Updating_output_of_project_0: diag(6373, ts.DiagnosticCategory.Message, "Updating_output_of_project_0_6373", "Updating output of project '{0}'..."),
        A_non_dry_build_would_update_timestamps_for_output_of_project_0: diag(6374, ts.DiagnosticCategory.Message, "A_non_dry_build_would_update_timestamps_for_output_of_project_0_6374", "A non-dry build would update timestamps for output of project '{0}'"),
        A_non_dry_build_would_update_output_of_project_0: diag(6375, ts.DiagnosticCategory.Message, "A_non_dry_build_would_update_output_of_project_0_6375", "A non-dry build would update output of project '{0}'"),
        Cannot_update_output_of_project_0_because_there_was_error_reading_file_1: diag(6376, ts.DiagnosticCategory.Message, "Cannot_update_output_of_project_0_because_there_was_error_reading_file_1_6376", "Cannot update output of project '{0}' because there was error reading file '{1}'"),
        Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1: diag(6377, ts.DiagnosticCategory.Error, "Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1_6377", "Cannot write file '{0}' because it will overwrite '.tsbuildinfo' file generated by referenced project '{1}'"),
        Enable_incremental_compilation: diag(6378, ts.DiagnosticCategory.Message, "Enable_incremental_compilation_6378", "Enable incremental compilation"),
        Composite_projects_may_not_disable_incremental_compilation: diag(6379, ts.DiagnosticCategory.Error, "Composite_projects_may_not_disable_incremental_compilation_6379", "Composite projects may not disable incremental compilation."),
        Specify_file_to_store_incremental_compilation_information: diag(6380, ts.DiagnosticCategory.Message, "Specify_file_to_store_incremental_compilation_information_6380", "Specify file to store incremental compilation information"),
        Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2: diag(6381, ts.DiagnosticCategory.Message, "Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_curren_6381", "Project '{0}' is out of date because output for it was generated with version '{1}' that differs with current version '{2}'"),
        The_expected_type_comes_from_property_0_which_is_declared_here_on_type_1: diag(6500, ts.DiagnosticCategory.Message, "The_expected_type_comes_from_property_0_which_is_declared_here_on_type_1_6500", "The expected type comes from property '{0}' which is declared here on type '{1}'"),
        The_expected_type_comes_from_this_index_signature: diag(6501, ts.DiagnosticCategory.Message, "The_expected_type_comes_from_this_index_signature_6501", "The expected type comes from this index signature."),
        The_expected_type_comes_from_the_return_type_of_this_signature: diag(6502, ts.DiagnosticCategory.Message, "The_expected_type_comes_from_the_return_type_of_this_signature_6502", "The expected type comes from the return type of this signature."),
        Variable_0_implicitly_has_an_1_type: diag(7005, ts.DiagnosticCategory.Error, "Variable_0_implicitly_has_an_1_type_7005", "Variable '{0}' implicitly has an '{1}' type."),
        Parameter_0_implicitly_has_an_1_type: diag(7006, ts.DiagnosticCategory.Error, "Parameter_0_implicitly_has_an_1_type_7006", "Parameter '{0}' implicitly has an '{1}' type."),
        Member_0_implicitly_has_an_1_type: diag(7008, ts.DiagnosticCategory.Error, "Member_0_implicitly_has_an_1_type_7008", "Member '{0}' implicitly has an '{1}' type."),
        new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type: diag(7009, ts.DiagnosticCategory.Error, "new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type_7009", "'new' expression, whose target lacks a construct signature, implicitly has an 'any' type."),
        _0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type: diag(7010, ts.DiagnosticCategory.Error, "_0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type_7010", "'{0}', which lacks return-type annotation, implicitly has an '{1}' return type."),
        Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type: diag(7011, ts.DiagnosticCategory.Error, "Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type_7011", "Function expression, which lacks return-type annotation, implicitly has an '{0}' return type."),
        Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: diag(7013, ts.DiagnosticCategory.Error, "Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7013", "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type."),
        Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type: diag(7014, ts.DiagnosticCategory.Error, "Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type_7014", "Function type, which lacks return-type annotation, implicitly has an '{0}' return type."),
        Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number: diag(7015, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number_7015", "Element implicitly has an 'any' type because index expression is not of type 'number'."),
        Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type: diag(7016, ts.DiagnosticCategory.Error, "Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type_7016", "Could not find a declaration file for module '{0}'. '{1}' implicitly has an 'any' type."),
        Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature: diag(7017, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_7017", "Element implicitly has an 'any' type because type '{0}' has no index signature."),
        Object_literal_s_property_0_implicitly_has_an_1_type: diag(7018, ts.DiagnosticCategory.Error, "Object_literal_s_property_0_implicitly_has_an_1_type_7018", "Object literal's property '{0}' implicitly has an '{1}' type."),
        Rest_parameter_0_implicitly_has_an_any_type: diag(7019, ts.DiagnosticCategory.Error, "Rest_parameter_0_implicitly_has_an_any_type_7019", "Rest parameter '{0}' implicitly has an 'any[]' type."),
        Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: diag(7020, ts.DiagnosticCategory.Error, "Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020", "Call signature, which lacks return-type annotation, implicitly has an 'any' return type."),
        _0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: diag(7022, ts.DiagnosticCategory.Error, "_0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or__7022", "'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer."),
        _0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: diag(7023, ts.DiagnosticCategory.Error, "_0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_reference_7023", "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions."),
        Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: diag(7024, ts.DiagnosticCategory.Error, "Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_ref_7024", "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions."),
        Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: diag(7025, ts.DiagnosticCategory.Error, "Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_typ_7025", "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type."),
        JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists: diag(7026, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists_7026", "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists."),
        Unreachable_code_detected: diag(7027, ts.DiagnosticCategory.Error, "Unreachable_code_detected_7027", "Unreachable code detected.", /*reportsUnnecessary*/ true),
        Unused_label: diag(7028, ts.DiagnosticCategory.Error, "Unused_label_7028", "Unused label.", /*reportsUnnecessary*/ true),
        Fallthrough_case_in_switch: diag(7029, ts.DiagnosticCategory.Error, "Fallthrough_case_in_switch_7029", "Fallthrough case in switch."),
        Not_all_code_paths_return_a_value: diag(7030, ts.DiagnosticCategory.Error, "Not_all_code_paths_return_a_value_7030", "Not all code paths return a value."),
        Binding_element_0_implicitly_has_an_1_type: diag(7031, ts.DiagnosticCategory.Error, "Binding_element_0_implicitly_has_an_1_type_7031", "Binding element '{0}' implicitly has an '{1}' type."),
        Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation: diag(7032, ts.DiagnosticCategory.Error, "Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation_7032", "Property '{0}' implicitly has type 'any', because its set accessor lacks a parameter type annotation."),
        Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation: diag(7033, ts.DiagnosticCategory.Error, "Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation_7033", "Property '{0}' implicitly has type 'any', because its get accessor lacks a return type annotation."),
        Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined: diag(7034, ts.DiagnosticCategory.Error, "Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined_7034", "Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined."),
        Try_npm_install_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0: diag(7035, ts.DiagnosticCategory.Error, "Try_npm_install_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_mod_7035", "Try `npm install @types/{1}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`"),
        Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0: diag(7036, ts.DiagnosticCategory.Error, "Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036", "Dynamic import's specifier must be of type 'string', but here has type '{0}'."),
        Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for_all_imports_Implies_allowSyntheticDefaultImports: diag(7037, ts.DiagnosticCategory.Message, "Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for__7037", "Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'."),
        Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead: diag(7038, ts.DiagnosticCategory.Message, "Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cau_7038", "Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead."),
        Mapped_object_type_implicitly_has_an_any_template_type: diag(7039, ts.DiagnosticCategory.Error, "Mapped_object_type_implicitly_has_an_any_template_type_7039", "Mapped object type implicitly has an 'any' template type."),
        If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1: diag(7040, ts.DiagnosticCategory.Error, "If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_S_7040", "If the '{0}' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/{1}`"),
        The_containing_arrow_function_captures_the_global_value_of_this: diag(7041, ts.DiagnosticCategory.Error, "The_containing_arrow_function_captures_the_global_value_of_this_7041", "The containing arrow function captures the global value of 'this'."),
        Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used: diag(7042, ts.DiagnosticCategory.Error, "Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used_7042", "Module '{0}' was resolved to '{1}', but '--resolveJsonModule' is not used."),
        Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage: diag(7043, ts.DiagnosticCategory.Suggestion, "Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7043", "Variable '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage."),
        Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage: diag(7044, ts.DiagnosticCategory.Suggestion, "Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7044", "Parameter '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage."),
        Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage: diag(7045, ts.DiagnosticCategory.Suggestion, "Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7045", "Member '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage."),
        Variable_0_implicitly_has_type_1_in_some_locations_but_a_better_type_may_be_inferred_from_usage: diag(7046, ts.DiagnosticCategory.Suggestion, "Variable_0_implicitly_has_type_1_in_some_locations_but_a_better_type_may_be_inferred_from_usage_7046", "Variable '{0}' implicitly has type '{1}' in some locations, but a better type may be inferred from usage."),
        Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage: diag(7047, ts.DiagnosticCategory.Suggestion, "Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage_7047", "Rest parameter '{0}' implicitly has an 'any[]' type, but a better type may be inferred from usage."),
        Property_0_implicitly_has_type_any_but_a_better_type_for_its_get_accessor_may_be_inferred_from_usage: diag(7048, ts.DiagnosticCategory.Suggestion, "Property_0_implicitly_has_type_any_but_a_better_type_for_its_get_accessor_may_be_inferred_from_usage_7048", "Property '{0}' implicitly has type 'any', but a better type for its get accessor may be inferred from usage."),
        Property_0_implicitly_has_type_any_but_a_better_type_for_its_set_accessor_may_be_inferred_from_usage: diag(7049, ts.DiagnosticCategory.Suggestion, "Property_0_implicitly_has_type_any_but_a_better_type_for_its_set_accessor_may_be_inferred_from_usage_7049", "Property '{0}' implicitly has type 'any', but a better type for its set accessor may be inferred from usage."),
        _0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage: diag(7050, ts.DiagnosticCategory.Suggestion, "_0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage_7050", "'{0}' implicitly has an '{1}' return type, but a better type may be inferred from usage."),
        Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1: diag(7051, ts.DiagnosticCategory.Error, "Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1_7051", "Parameter has a name but no type. Did you mean '{0}: {1}'?"),
        Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1: diag(7052, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1_7052", "Element implicitly has an 'any' type because type '{0}' has no index signature. Did you mean to call '{1}' ?"),
        Element_implicitly_has_an_any_type_because_expression_of_type_0_can_t_be_used_to_index_type_1: diag(7053, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_expression_of_type_0_can_t_be_used_to_index_type_1_7053", "Element implicitly has an 'any' type because expression of type '{0}' can't be used to index type '{1}'."),
        No_index_signature_with_a_parameter_of_type_0_was_found_on_type_1: diag(7054, ts.DiagnosticCategory.Error, "No_index_signature_with_a_parameter_of_type_0_was_found_on_type_1_7054", "No index signature with a parameter of type '{0}' was found on type '{1}'."),
        You_cannot_rename_this_element: diag(8000, ts.DiagnosticCategory.Error, "You_cannot_rename_this_element_8000", "You cannot rename this element."),
        You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: diag(8001, ts.DiagnosticCategory.Error, "You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library_8001", "You cannot rename elements that are defined in the standard TypeScript library."),
        import_can_only_be_used_in_a_ts_file: diag(8002, ts.DiagnosticCategory.Error, "import_can_only_be_used_in_a_ts_file_8002", "'import ... =' can only be used in a .ts file."),
        export_can_only_be_used_in_a_ts_file: diag(8003, ts.DiagnosticCategory.Error, "export_can_only_be_used_in_a_ts_file_8003", "'export=' can only be used in a .ts file."),
        type_parameter_declarations_can_only_be_used_in_a_ts_file: diag(8004, ts.DiagnosticCategory.Error, "type_parameter_declarations_can_only_be_used_in_a_ts_file_8004", "'type parameter declarations' can only be used in a .ts file."),
        implements_clauses_can_only_be_used_in_a_ts_file: diag(8005, ts.DiagnosticCategory.Error, "implements_clauses_can_only_be_used_in_a_ts_file_8005", "'implements clauses' can only be used in a .ts file."),
        interface_declarations_can_only_be_used_in_a_ts_file: diag(8006, ts.DiagnosticCategory.Error, "interface_declarations_can_only_be_used_in_a_ts_file_8006", "'interface declarations' can only be used in a .ts file."),
        module_declarations_can_only_be_used_in_a_ts_file: diag(8007, ts.DiagnosticCategory.Error, "module_declarations_can_only_be_used_in_a_ts_file_8007", "'module declarations' can only be used in a .ts file."),
        type_aliases_can_only_be_used_in_a_ts_file: diag(8008, ts.DiagnosticCategory.Error, "type_aliases_can_only_be_used_in_a_ts_file_8008", "'type aliases' can only be used in a .ts file."),
        _0_can_only_be_used_in_a_ts_file: diag(8009, ts.DiagnosticCategory.Error, "_0_can_only_be_used_in_a_ts_file_8009", "'{0}' can only be used in a .ts file."),
        types_can_only_be_used_in_a_ts_file: diag(8010, ts.DiagnosticCategory.Error, "types_can_only_be_used_in_a_ts_file_8010", "'types' can only be used in a .ts file."),
        type_arguments_can_only_be_used_in_a_ts_file: diag(8011, ts.DiagnosticCategory.Error, "type_arguments_can_only_be_used_in_a_ts_file_8011", "'type arguments' can only be used in a .ts file."),
        parameter_modifiers_can_only_be_used_in_a_ts_file: diag(8012, ts.DiagnosticCategory.Error, "parameter_modifiers_can_only_be_used_in_a_ts_file_8012", "'parameter modifiers' can only be used in a .ts file."),
        non_null_assertions_can_only_be_used_in_a_ts_file: diag(8013, ts.DiagnosticCategory.Error, "non_null_assertions_can_only_be_used_in_a_ts_file_8013", "'non-null assertions' can only be used in a .ts file."),
        enum_declarations_can_only_be_used_in_a_ts_file: diag(8015, ts.DiagnosticCategory.Error, "enum_declarations_can_only_be_used_in_a_ts_file_8015", "'enum declarations' can only be used in a .ts file."),
        type_assertion_expressions_can_only_be_used_in_a_ts_file: diag(8016, ts.DiagnosticCategory.Error, "type_assertion_expressions_can_only_be_used_in_a_ts_file_8016", "'type assertion expressions' can only be used in a .ts file."),
        Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0: diag(8017, ts.DiagnosticCategory.Error, "Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0_8017", "Octal literal types must use ES2015 syntax. Use the syntax '{0}'."),
        Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0: diag(8018, ts.DiagnosticCategory.Error, "Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0_8018", "Octal literals are not allowed in enums members initializer. Use the syntax '{0}'."),
        Report_errors_in_js_files: diag(8019, ts.DiagnosticCategory.Message, "Report_errors_in_js_files_8019", "Report errors in .js files."),
        JSDoc_types_can_only_be_used_inside_documentation_comments: diag(8020, ts.DiagnosticCategory.Error, "JSDoc_types_can_only_be_used_inside_documentation_comments_8020", "JSDoc types can only be used inside documentation comments."),
        JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags: diag(8021, ts.DiagnosticCategory.Error, "JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags_8021", "JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags."),
        JSDoc_0_is_not_attached_to_a_class: diag(8022, ts.DiagnosticCategory.Error, "JSDoc_0_is_not_attached_to_a_class_8022", "JSDoc '@{0}' is not attached to a class."),
        JSDoc_0_1_does_not_match_the_extends_2_clause: diag(8023, ts.DiagnosticCategory.Error, "JSDoc_0_1_does_not_match_the_extends_2_clause_8023", "JSDoc '@{0} {1}' does not match the 'extends {2}' clause."),
        JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name: diag(8024, ts.DiagnosticCategory.Error, "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_8024", "JSDoc '@param' tag has name '{0}', but there is no parameter with that name."),
        Class_declarations_cannot_have_more_than_one_augments_or_extends_tag: diag(8025, ts.DiagnosticCategory.Error, "Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025", "Class declarations cannot have more than one `@augments` or `@extends` tag."),
        Expected_0_type_arguments_provide_these_with_an_extends_tag: diag(8026, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_provide_these_with_an_extends_tag_8026", "Expected {0} type arguments; provide these with an '@extends' tag."),
        Expected_0_1_type_arguments_provide_these_with_an_extends_tag: diag(8027, ts.DiagnosticCategory.Error, "Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027", "Expected {0}-{1} type arguments; provide these with an '@extends' tag."),
        JSDoc_may_only_appear_in_the_last_parameter_of_a_signature: diag(8028, ts.DiagnosticCategory.Error, "JSDoc_may_only_appear_in_the_last_parameter_of_a_signature_8028", "JSDoc '...' may only appear in the last parameter of a signature."),
        JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type: diag(8029, ts.DiagnosticCategory.Error, "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_h_8029", "JSDoc '@param' tag has name '{0}', but there is no parameter with that name. It would match 'arguments' if it had an array type."),
        The_type_of_a_function_declaration_must_match_the_function_s_signature: diag(8030, ts.DiagnosticCategory.Error, "The_type_of_a_function_declaration_must_match_the_function_s_signature_8030", "The type of a function declaration must match the function's signature."),
        You_cannot_rename_a_module_via_a_global_import: diag(8031, ts.DiagnosticCategory.Error, "You_cannot_rename_a_module_via_a_global_import_8031", "You cannot rename a module via a global import."),
        Qualified_name_0_is_not_allowed_without_a_leading_param_object_1: diag(8032, ts.DiagnosticCategory.Error, "Qualified_name_0_is_not_allowed_without_a_leading_param_object_1_8032", "Qualified name '{0}' is not allowed without a leading '@param {object} {1}'."),
        Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clause: diag(9002, ts.DiagnosticCategory.Error, "Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002", "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause."),
        class_expressions_are_not_currently_supported: diag(9003, ts.DiagnosticCategory.Error, "class_expressions_are_not_currently_supported_9003", "'class' expressions are not currently supported."),
        Language_service_is_disabled: diag(9004, ts.DiagnosticCategory.Error, "Language_service_is_disabled_9004", "Language service is disabled."),
        JSX_attributes_must_only_be_assigned_a_non_empty_expression: diag(17000, ts.DiagnosticCategory.Error, "JSX_attributes_must_only_be_assigned_a_non_empty_expression_17000", "JSX attributes must only be assigned a non-empty 'expression'."),
        JSX_elements_cannot_have_multiple_attributes_with_the_same_name: diag(17001, ts.DiagnosticCategory.Error, "JSX_elements_cannot_have_multiple_attributes_with_the_same_name_17001", "JSX elements cannot have multiple attributes with the same name."),
        Expected_corresponding_JSX_closing_tag_for_0: diag(17002, ts.DiagnosticCategory.Error, "Expected_corresponding_JSX_closing_tag_for_0_17002", "Expected corresponding JSX closing tag for '{0}'."),
        JSX_attribute_expected: diag(17003, ts.DiagnosticCategory.Error, "JSX_attribute_expected_17003", "JSX attribute expected."),
        Cannot_use_JSX_unless_the_jsx_flag_is_provided: diag(17004, ts.DiagnosticCategory.Error, "Cannot_use_JSX_unless_the_jsx_flag_is_provided_17004", "Cannot use JSX unless the '--jsx' flag is provided."),
        A_constructor_cannot_contain_a_super_call_when_its_class_extends_null: diag(17005, ts.DiagnosticCategory.Error, "A_constructor_cannot_contain_a_super_call_when_its_class_extends_null_17005", "A constructor cannot contain a 'super' call when its class extends 'null'."),
        An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses: diag(17006, ts.DiagnosticCategory.Error, "An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_ex_17006", "An unary expression with the '{0}' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses."),
        A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses: diag(17007, ts.DiagnosticCategory.Error, "A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Con_17007", "A type assertion expression is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses."),
        JSX_element_0_has_no_corresponding_closing_tag: diag(17008, ts.DiagnosticCategory.Error, "JSX_element_0_has_no_corresponding_closing_tag_17008", "JSX element '{0}' has no corresponding closing tag."),
        super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class: diag(17009, ts.DiagnosticCategory.Error, "super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class_17009", "'super' must be called before accessing 'this' in the constructor of a derived class."),
        Unknown_type_acquisition_option_0: diag(17010, ts.DiagnosticCategory.Error, "Unknown_type_acquisition_option_0_17010", "Unknown type acquisition option '{0}'."),
        super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class: diag(17011, ts.DiagnosticCategory.Error, "super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class_17011", "'super' must be called before accessing a property of 'super' in the constructor of a derived class."),
        _0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2: diag(17012, ts.DiagnosticCategory.Error, "_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012", "'{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?"),
        Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor: diag(17013, ts.DiagnosticCategory.Error, "Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constru_17013", "Meta-property '{0}' is only allowed in the body of a function declaration, function expression, or constructor."),
        JSX_fragment_has_no_corresponding_closing_tag: diag(17014, ts.DiagnosticCategory.Error, "JSX_fragment_has_no_corresponding_closing_tag_17014", "JSX fragment has no corresponding closing tag."),
        Expected_corresponding_closing_tag_for_JSX_fragment: diag(17015, ts.DiagnosticCategory.Error, "Expected_corresponding_closing_tag_for_JSX_fragment_17015", "Expected corresponding closing tag for JSX fragment."),
        JSX_fragment_is_not_supported_when_using_jsxFactory: diag(17016, ts.DiagnosticCategory.Error, "JSX_fragment_is_not_supported_when_using_jsxFactory_17016", "JSX fragment is not supported when using --jsxFactory"),
        JSX_fragment_is_not_supported_when_using_an_inline_JSX_factory_pragma: diag(17017, ts.DiagnosticCategory.Error, "JSX_fragment_is_not_supported_when_using_an_inline_JSX_factory_pragma_17017", "JSX fragment is not supported when using an inline JSX factory pragma"),
        Circularity_detected_while_resolving_configuration_Colon_0: diag(18000, ts.DiagnosticCategory.Error, "Circularity_detected_while_resolving_configuration_Colon_0_18000", "Circularity detected while resolving configuration: {0}"),
        A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not: diag(18001, ts.DiagnosticCategory.Error, "A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not_18001", "A path in an 'extends' option must be relative or rooted, but '{0}' is not."),
        The_files_list_in_config_file_0_is_empty: diag(18002, ts.DiagnosticCategory.Error, "The_files_list_in_config_file_0_is_empty_18002", "The 'files' list in config file '{0}' is empty."),
        No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2: diag(18003, ts.DiagnosticCategory.Error, "No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2_18003", "No inputs were found in config file '{0}'. Specified 'include' paths were '{1}' and 'exclude' paths were '{2}'."),
        File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module: diag(80001, ts.DiagnosticCategory.Suggestion, "File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module_80001", "File is a CommonJS module; it may be converted to an ES6 module."),
        This_constructor_function_may_be_converted_to_a_class_declaration: diag(80002, ts.DiagnosticCategory.Suggestion, "This_constructor_function_may_be_converted_to_a_class_declaration_80002", "This constructor function may be converted to a class declaration."),
        Import_may_be_converted_to_a_default_import: diag(80003, ts.DiagnosticCategory.Suggestion, "Import_may_be_converted_to_a_default_import_80003", "Import may be converted to a default import."),
        JSDoc_types_may_be_moved_to_TypeScript_types: diag(80004, ts.DiagnosticCategory.Suggestion, "JSDoc_types_may_be_moved_to_TypeScript_types_80004", "JSDoc types may be moved to TypeScript types."),
        require_call_may_be_converted_to_an_import: diag(80005, ts.DiagnosticCategory.Suggestion, "require_call_may_be_converted_to_an_import_80005", "'require' call may be converted to an import."),
        This_may_be_converted_to_an_async_function: diag(80006, ts.DiagnosticCategory.Suggestion, "This_may_be_converted_to_an_async_function_80006", "This may be converted to an async function."),
        Add_missing_super_call: diag(90001, ts.DiagnosticCategory.Message, "Add_missing_super_call_90001", "Add missing 'super()' call"),
        Make_super_call_the_first_statement_in_the_constructor: diag(90002, ts.DiagnosticCategory.Message, "Make_super_call_the_first_statement_in_the_constructor_90002", "Make 'super()' call the first statement in the constructor"),
        Change_extends_to_implements: diag(90003, ts.DiagnosticCategory.Message, "Change_extends_to_implements_90003", "Change 'extends' to 'implements'"),
        Remove_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_declaration_for_Colon_0_90004", "Remove declaration for: '{0}'"),
        Remove_import_from_0: diag(90005, ts.DiagnosticCategory.Message, "Remove_import_from_0_90005", "Remove import from '{0}'"),
        Implement_interface_0: diag(90006, ts.DiagnosticCategory.Message, "Implement_interface_0_90006", "Implement interface '{0}'"),
        Implement_inherited_abstract_class: diag(90007, ts.DiagnosticCategory.Message, "Implement_inherited_abstract_class_90007", "Implement inherited abstract class"),
        Add_0_to_unresolved_variable: diag(90008, ts.DiagnosticCategory.Message, "Add_0_to_unresolved_variable_90008", "Add '{0}.' to unresolved variable"),
        Remove_destructuring: diag(90009, ts.DiagnosticCategory.Message, "Remove_destructuring_90009", "Remove destructuring"),
        Remove_variable_statement: diag(90010, ts.DiagnosticCategory.Message, "Remove_variable_statement_90010", "Remove variable statement"),
        Remove_template_tag: diag(90011, ts.DiagnosticCategory.Message, "Remove_template_tag_90011", "Remove template tag"),
        Remove_type_parameters: diag(90012, ts.DiagnosticCategory.Message, "Remove_type_parameters_90012", "Remove type parameters"),
        Import_0_from_module_1: diag(90013, ts.DiagnosticCategory.Message, "Import_0_from_module_1_90013", "Import '{0}' from module \"{1}\""),
        Change_0_to_1: diag(90014, ts.DiagnosticCategory.Message, "Change_0_to_1_90014", "Change '{0}' to '{1}'"),
        Add_0_to_existing_import_declaration_from_1: diag(90015, ts.DiagnosticCategory.Message, "Add_0_to_existing_import_declaration_from_1_90015", "Add '{0}' to existing import declaration from \"{1}\""),
        Declare_property_0: diag(90016, ts.DiagnosticCategory.Message, "Declare_property_0_90016", "Declare property '{0}'"),
        Add_index_signature_for_property_0: diag(90017, ts.DiagnosticCategory.Message, "Add_index_signature_for_property_0_90017", "Add index signature for property '{0}'"),
        Disable_checking_for_this_file: diag(90018, ts.DiagnosticCategory.Message, "Disable_checking_for_this_file_90018", "Disable checking for this file"),
        Ignore_this_error_message: diag(90019, ts.DiagnosticCategory.Message, "Ignore_this_error_message_90019", "Ignore this error message"),
        Initialize_property_0_in_the_constructor: diag(90020, ts.DiagnosticCategory.Message, "Initialize_property_0_in_the_constructor_90020", "Initialize property '{0}' in the constructor"),
        Initialize_static_property_0: diag(90021, ts.DiagnosticCategory.Message, "Initialize_static_property_0_90021", "Initialize static property '{0}'"),
        Change_spelling_to_0: diag(90022, ts.DiagnosticCategory.Message, "Change_spelling_to_0_90022", "Change spelling to '{0}'"),
        Declare_method_0: diag(90023, ts.DiagnosticCategory.Message, "Declare_method_0_90023", "Declare method '{0}'"),
        Declare_static_method_0: diag(90024, ts.DiagnosticCategory.Message, "Declare_static_method_0_90024", "Declare static method '{0}'"),
        Prefix_0_with_an_underscore: diag(90025, ts.DiagnosticCategory.Message, "Prefix_0_with_an_underscore_90025", "Prefix '{0}' with an underscore"),
        Rewrite_as_the_indexed_access_type_0: diag(90026, ts.DiagnosticCategory.Message, "Rewrite_as_the_indexed_access_type_0_90026", "Rewrite as the indexed access type '{0}'"),
        Declare_static_property_0: diag(90027, ts.DiagnosticCategory.Message, "Declare_static_property_0_90027", "Declare static property '{0}'"),
        Call_decorator_expression: diag(90028, ts.DiagnosticCategory.Message, "Call_decorator_expression_90028", "Call decorator expression"),
        Add_async_modifier_to_containing_function: diag(90029, ts.DiagnosticCategory.Message, "Add_async_modifier_to_containing_function_90029", "Add async modifier to containing function"),
        Replace_infer_0_with_unknown: diag(90030, ts.DiagnosticCategory.Message, "Replace_infer_0_with_unknown_90030", "Replace 'infer {0}' with 'unknown'"),
        Replace_all_unused_infer_with_unknown: diag(90031, ts.DiagnosticCategory.Message, "Replace_all_unused_infer_with_unknown_90031", "Replace all unused 'infer' with 'unknown'"),
        Import_default_0_from_module_1: diag(90032, ts.DiagnosticCategory.Message, "Import_default_0_from_module_1_90032", "Import default '{0}' from module \"{1}\""),
        Add_default_import_0_to_existing_import_declaration_from_1: diag(90033, ts.DiagnosticCategory.Message, "Add_default_import_0_to_existing_import_declaration_from_1_90033", "Add default import '{0}' to existing import declaration from \"{1}\""),
        Add_parameter_name: diag(90034, ts.DiagnosticCategory.Message, "Add_parameter_name_90034", "Add parameter name"),
        Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"),
        Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"),
        Extract_to_0_in_1: diag(95004, ts.DiagnosticCategory.Message, "Extract_to_0_in_1_95004", "Extract to {0} in {1}"),
        Extract_function: diag(95005, ts.DiagnosticCategory.Message, "Extract_function_95005", "Extract function"),
        Extract_constant: diag(95006, ts.DiagnosticCategory.Message, "Extract_constant_95006", "Extract constant"),
        Extract_to_0_in_enclosing_scope: diag(95007, ts.DiagnosticCategory.Message, "Extract_to_0_in_enclosing_scope_95007", "Extract to {0} in enclosing scope"),
        Extract_to_0_in_1_scope: diag(95008, ts.DiagnosticCategory.Message, "Extract_to_0_in_1_scope_95008", "Extract to {0} in {1} scope"),
        Annotate_with_type_from_JSDoc: diag(95009, ts.DiagnosticCategory.Message, "Annotate_with_type_from_JSDoc_95009", "Annotate with type from JSDoc"),
        Annotate_with_types_from_JSDoc: diag(95010, ts.DiagnosticCategory.Message, "Annotate_with_types_from_JSDoc_95010", "Annotate with types from JSDoc"),
        Infer_type_of_0_from_usage: diag(95011, ts.DiagnosticCategory.Message, "Infer_type_of_0_from_usage_95011", "Infer type of '{0}' from usage"),
        Infer_parameter_types_from_usage: diag(95012, ts.DiagnosticCategory.Message, "Infer_parameter_types_from_usage_95012", "Infer parameter types from usage"),
        Convert_to_default_import: diag(95013, ts.DiagnosticCategory.Message, "Convert_to_default_import_95013", "Convert to default import"),
        Install_0: diag(95014, ts.DiagnosticCategory.Message, "Install_0_95014", "Install '{0}'"),
        Replace_import_with_0: diag(95015, ts.DiagnosticCategory.Message, "Replace_import_with_0_95015", "Replace import with '{0}'."),
        Use_synthetic_default_member: diag(95016, ts.DiagnosticCategory.Message, "Use_synthetic_default_member_95016", "Use synthetic 'default' member."),
        Convert_to_ES6_module: diag(95017, ts.DiagnosticCategory.Message, "Convert_to_ES6_module_95017", "Convert to ES6 module"),
        Add_undefined_type_to_property_0: diag(95018, ts.DiagnosticCategory.Message, "Add_undefined_type_to_property_0_95018", "Add 'undefined' type to property '{0}'"),
        Add_initializer_to_property_0: diag(95019, ts.DiagnosticCategory.Message, "Add_initializer_to_property_0_95019", "Add initializer to property '{0}'"),
        Add_definite_assignment_assertion_to_property_0: diag(95020, ts.DiagnosticCategory.Message, "Add_definite_assignment_assertion_to_property_0_95020", "Add definite assignment assertion to property '{0}'"),
        Add_all_missing_members: diag(95022, ts.DiagnosticCategory.Message, "Add_all_missing_members_95022", "Add all missing members"),
        Infer_all_types_from_usage: diag(95023, ts.DiagnosticCategory.Message, "Infer_all_types_from_usage_95023", "Infer all types from usage"),
        Delete_all_unused_declarations: diag(95024, ts.DiagnosticCategory.Message, "Delete_all_unused_declarations_95024", "Delete all unused declarations"),
        Prefix_all_unused_declarations_with_where_possible: diag(95025, ts.DiagnosticCategory.Message, "Prefix_all_unused_declarations_with_where_possible_95025", "Prefix all unused declarations with '_' where possible"),
        Fix_all_detected_spelling_errors: diag(95026, ts.DiagnosticCategory.Message, "Fix_all_detected_spelling_errors_95026", "Fix all detected spelling errors"),
        Add_initializers_to_all_uninitialized_properties: diag(95027, ts.DiagnosticCategory.Message, "Add_initializers_to_all_uninitialized_properties_95027", "Add initializers to all uninitialized properties"),
        Add_definite_assignment_assertions_to_all_uninitialized_properties: diag(95028, ts.DiagnosticCategory.Message, "Add_definite_assignment_assertions_to_all_uninitialized_properties_95028", "Add definite assignment assertions to all uninitialized properties"),
        Add_undefined_type_to_all_uninitialized_properties: diag(95029, ts.DiagnosticCategory.Message, "Add_undefined_type_to_all_uninitialized_properties_95029", "Add undefined type to all uninitialized properties"),
        Change_all_jsdoc_style_types_to_TypeScript: diag(95030, ts.DiagnosticCategory.Message, "Change_all_jsdoc_style_types_to_TypeScript_95030", "Change all jsdoc-style types to TypeScript"),
        Change_all_jsdoc_style_types_to_TypeScript_and_add_undefined_to_nullable_types: diag(95031, ts.DiagnosticCategory.Message, "Change_all_jsdoc_style_types_to_TypeScript_and_add_undefined_to_nullable_types_95031", "Change all jsdoc-style types to TypeScript (and add '| undefined' to nullable types)"),
        Implement_all_unimplemented_interfaces: diag(95032, ts.DiagnosticCategory.Message, "Implement_all_unimplemented_interfaces_95032", "Implement all unimplemented interfaces"),
        Install_all_missing_types_packages: diag(95033, ts.DiagnosticCategory.Message, "Install_all_missing_types_packages_95033", "Install all missing types packages"),
        Rewrite_all_as_indexed_access_types: diag(95034, ts.DiagnosticCategory.Message, "Rewrite_all_as_indexed_access_types_95034", "Rewrite all as indexed access types"),
        Convert_all_to_default_imports: diag(95035, ts.DiagnosticCategory.Message, "Convert_all_to_default_imports_95035", "Convert all to default imports"),
        Make_all_super_calls_the_first_statement_in_their_constructor: diag(95036, ts.DiagnosticCategory.Message, "Make_all_super_calls_the_first_statement_in_their_constructor_95036", "Make all 'super()' calls the first statement in their constructor"),
        Add_qualifier_to_all_unresolved_variables_matching_a_member_name: diag(95037, ts.DiagnosticCategory.Message, "Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037", "Add qualifier to all unresolved variables matching a member name"),
        Change_all_extended_interfaces_to_implements: diag(95038, ts.DiagnosticCategory.Message, "Change_all_extended_interfaces_to_implements_95038", "Change all extended interfaces to 'implements'"),
        Add_all_missing_super_calls: diag(95039, ts.DiagnosticCategory.Message, "Add_all_missing_super_calls_95039", "Add all missing super calls"),
        Implement_all_inherited_abstract_classes: diag(95040, ts.DiagnosticCategory.Message, "Implement_all_inherited_abstract_classes_95040", "Implement all inherited abstract classes"),
        Add_all_missing_async_modifiers: diag(95041, ts.DiagnosticCategory.Message, "Add_all_missing_async_modifiers_95041", "Add all missing 'async' modifiers"),
        Add_ts_ignore_to_all_error_messages: diag(95042, ts.DiagnosticCategory.Message, "Add_ts_ignore_to_all_error_messages_95042", "Add '@ts-ignore' to all error messages"),
        Annotate_everything_with_types_from_JSDoc: diag(95043, ts.DiagnosticCategory.Message, "Annotate_everything_with_types_from_JSDoc_95043", "Annotate everything with types from JSDoc"),
        Add_to_all_uncalled_decorators: diag(95044, ts.DiagnosticCategory.Message, "Add_to_all_uncalled_decorators_95044", "Add '()' to all uncalled decorators"),
        Convert_all_constructor_functions_to_classes: diag(95045, ts.DiagnosticCategory.Message, "Convert_all_constructor_functions_to_classes_95045", "Convert all constructor functions to classes"),
        Generate_get_and_set_accessors: diag(95046, ts.DiagnosticCategory.Message, "Generate_get_and_set_accessors_95046", "Generate 'get' and 'set' accessors"),
        Convert_require_to_import: diag(95047, ts.DiagnosticCategory.Message, "Convert_require_to_import_95047", "Convert 'require' to 'import'"),
        Convert_all_require_to_import: diag(95048, ts.DiagnosticCategory.Message, "Convert_all_require_to_import_95048", "Convert all 'require' to 'import'"),
        Move_to_a_new_file: diag(95049, ts.DiagnosticCategory.Message, "Move_to_a_new_file_95049", "Move to a new file"),
        Remove_unreachable_code: diag(95050, ts.DiagnosticCategory.Message, "Remove_unreachable_code_95050", "Remove unreachable code"),
        Remove_all_unreachable_code: diag(95051, ts.DiagnosticCategory.Message, "Remove_all_unreachable_code_95051", "Remove all unreachable code"),
        Add_missing_typeof: diag(95052, ts.DiagnosticCategory.Message, "Add_missing_typeof_95052", "Add missing 'typeof'"),
        Remove_unused_label: diag(95053, ts.DiagnosticCategory.Message, "Remove_unused_label_95053", "Remove unused label"),
        Remove_all_unused_labels: diag(95054, ts.DiagnosticCategory.Message, "Remove_all_unused_labels_95054", "Remove all unused labels"),
        Convert_0_to_mapped_object_type: diag(95055, ts.DiagnosticCategory.Message, "Convert_0_to_mapped_object_type_95055", "Convert '{0}' to mapped object type"),
        Convert_namespace_import_to_named_imports: diag(95056, ts.DiagnosticCategory.Message, "Convert_namespace_import_to_named_imports_95056", "Convert namespace import to named imports"),
        Convert_named_imports_to_namespace_import: diag(95057, ts.DiagnosticCategory.Message, "Convert_named_imports_to_namespace_import_95057", "Convert named imports to namespace import"),
        Add_or_remove_braces_in_an_arrow_function: diag(95058, ts.DiagnosticCategory.Message, "Add_or_remove_braces_in_an_arrow_function_95058", "Add or remove braces in an arrow function"),
        Add_braces_to_arrow_function: diag(95059, ts.DiagnosticCategory.Message, "Add_braces_to_arrow_function_95059", "Add braces to arrow function"),
        Remove_braces_from_arrow_function: diag(95060, ts.DiagnosticCategory.Message, "Remove_braces_from_arrow_function_95060", "Remove braces from arrow function"),
        Convert_default_export_to_named_export: diag(95061, ts.DiagnosticCategory.Message, "Convert_default_export_to_named_export_95061", "Convert default export to named export"),
        Convert_named_export_to_default_export: diag(95062, ts.DiagnosticCategory.Message, "Convert_named_export_to_default_export_95062", "Convert named export to default export"),
        Add_missing_enum_member_0: diag(95063, ts.DiagnosticCategory.Message, "Add_missing_enum_member_0_95063", "Add missing enum member '{0}'"),
        Add_all_missing_imports: diag(95064, ts.DiagnosticCategory.Message, "Add_all_missing_imports_95064", "Add all missing imports"),
        Convert_to_async_function: diag(95065, ts.DiagnosticCategory.Message, "Convert_to_async_function_95065", "Convert to async function"),
        Convert_all_to_async_functions: diag(95066, ts.DiagnosticCategory.Message, "Convert_all_to_async_functions_95066", "Convert all to async functions"),
        Add_unknown_conversion_for_non_overlapping_types: diag(95069, ts.DiagnosticCategory.Message, "Add_unknown_conversion_for_non_overlapping_types_95069", "Add 'unknown' conversion for non-overlapping types"),
        Add_unknown_to_all_conversions_of_non_overlapping_types: diag(95070, ts.DiagnosticCategory.Message, "Add_unknown_to_all_conversions_of_non_overlapping_types_95070", "Add 'unknown' to all conversions of non-overlapping types"),
        Add_missing_new_operator_to_call: diag(95071, ts.DiagnosticCategory.Message, "Add_missing_new_operator_to_call_95071", "Add missing 'new' operator to call"),
        Add_missing_new_operator_to_all_calls: diag(95072, ts.DiagnosticCategory.Message, "Add_missing_new_operator_to_all_calls_95072", "Add missing 'new' operator to all calls"),
        Add_names_to_all_parameters_without_names: diag(95073, ts.DiagnosticCategory.Message, "Add_names_to_all_parameters_without_names_95073", "Add names to all parameters without names"),
        Enable_the_experimentalDecorators_option_in_your_configuration_file: diag(95074, ts.DiagnosticCategory.Message, "Enable_the_experimentalDecorators_option_in_your_configuration_file_95074", "Enable the 'experimentalDecorators' option in your configuration file"),
        Convert_parameters_to_destructured_object: diag(95075, ts.DiagnosticCategory.Message, "Convert_parameters_to_destructured_object_95075", "Convert parameters to destructured object"),
        Allow_accessing_UMD_globals_from_modules: diag(95076, ts.DiagnosticCategory.Message, "Allow_accessing_UMD_globals_from_modules_95076", "Allow accessing UMD globals from modules."),
        Extract_type: diag(95077, ts.DiagnosticCategory.Message, "Extract_type_95077", "Extract type"),
        Extract_to_type_alias: diag(95078, ts.DiagnosticCategory.Message, "Extract_to_type_alias_95078", "Extract to type alias"),
        Extract_to_typedef: diag(95079, ts.DiagnosticCategory.Message, "Extract_to_typedef_95079", "Extract to typedef"),
        No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer: diag(18004, ts.DiagnosticCategory.Error, "No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer_18004", "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer."),
        Quoted_constructors_have_previously_been_interpreted_as_methods_which_is_incorrect_In_TypeScript_3_6_they_will_be_correctly_parsed_as_constructors_In_the_meantime_consider_using_constructor_to_write_a_constructor_or_constructor_to_write_a_method: diag(18005, ts.DiagnosticCategory.Error, "Quoted_constructors_have_previously_been_interpreted_as_methods_which_is_incorrect_In_TypeScript_3_6_18005", "Quoted constructors have previously been interpreted as methods, which is incorrect. In TypeScript 3.6, they will be correctly parsed as constructors. In the meantime, consider using 'constructor()' to write a constructor, or '[\"constructor\"]()' to write a method."),
        Classes_may_not_have_a_field_named_constructor: diag(18006, ts.DiagnosticCategory.Error, "Classes_may_not_have_a_field_named_constructor_18006", "Classes may not have a field named 'constructor'."),
    };
})(ts || (ts = {}));
var ts;
(function (ts) {
    var _a;
    /* @internal */
    function tokenIsIdentifierOrKeyword(token) {
        return token >= 73 /* Identifier */;
    }
    ts.tokenIsIdentifierOrKeyword = tokenIsIdentifierOrKeyword;
    /* @internal */
    function tokenIsIdentifierOrKeywordOrGreaterThan(token) {
        return token === 30 /* GreaterThanToken */ || tokenIsIdentifierOrKeyword(token);
    }
    ts.tokenIsIdentifierOrKeywordOrGreaterThan = tokenIsIdentifierOrKeywordOrGreaterThan;
    var textToKeywordObj = (_a = {
            abstract: 119 /* AbstractKeyword */,
            any: 121 /* AnyKeyword */,
            as: 120 /* AsKeyword */,
            bigint: 147 /* BigIntKeyword */,
            boolean: 124 /* BooleanKeyword */,
            break: 74 /* BreakKeyword */,
            case: 75 /* CaseKeyword */,
            catch: 76 /* CatchKeyword */,
            class: 77 /* ClassKeyword */,
            continue: 79 /* ContinueKeyword */,
            const: 78 /* ConstKeyword */
        },
        _a["" + "constructor"] = 125 /* ConstructorKeyword */,
        _a.debugger = 80 /* DebuggerKeyword */,
        _a.declare = 126 /* DeclareKeyword */,
        _a.default = 81 /* DefaultKeyword */,
        _a.delete = 82 /* DeleteKeyword */,
        _a.do = 83 /* DoKeyword */,
        _a.else = 84 /* ElseKeyword */,
        _a.enum = 85 /* EnumKeyword */,
        _a.export = 86 /* ExportKeyword */,
        _a.extends = 87 /* ExtendsKeyword */,
        _a.false = 88 /* FalseKeyword */,
        _a.finally = 89 /* FinallyKeyword */,
        _a.for = 90 /* ForKeyword */,
        _a.from = 145 /* FromKeyword */,
        _a.function = 91 /* FunctionKeyword */,
        _a.get = 127 /* GetKeyword */,
        _a.if = 92 /* IfKeyword */,
        _a.implements = 110 /* ImplementsKeyword */,
        _a.import = 93 /* ImportKeyword */,
        _a.in = 94 /* InKeyword */,
        _a.infer = 128 /* InferKeyword */,
        _a.instanceof = 95 /* InstanceOfKeyword */,
        _a.interface = 111 /* InterfaceKeyword */,
        _a.is = 129 /* IsKeyword */,
        _a.keyof = 130 /* KeyOfKeyword */,
        _a.let = 112 /* LetKeyword */,
        _a.module = 131 /* ModuleKeyword */,
        _a.namespace = 132 /* NamespaceKeyword */,
        _a.never = 133 /* NeverKeyword */,
        _a.new = 96 /* NewKeyword */,
        _a.null = 97 /* NullKeyword */,
        _a.number = 136 /* NumberKeyword */,
        _a.object = 137 /* ObjectKeyword */,
        _a.package = 113 /* PackageKeyword */,
        _a.private = 114 /* PrivateKeyword */,
        _a.protected = 115 /* ProtectedKeyword */,
        _a.public = 116 /* PublicKeyword */,
        _a.readonly = 134 /* ReadonlyKeyword */,
        _a.require = 135 /* RequireKeyword */,
        _a.global = 146 /* GlobalKeyword */,
        _a.return = 98 /* ReturnKeyword */,
        _a.set = 138 /* SetKeyword */,
        _a.static = 117 /* StaticKeyword */,
        _a.string = 139 /* StringKeyword */,
        _a.super = 99 /* SuperKeyword */,
        _a.switch = 100 /* SwitchKeyword */,
        _a.symbol = 140 /* SymbolKeyword */,
        _a.this = 101 /* ThisKeyword */,
        _a.throw = 102 /* ThrowKeyword */,
        _a.true = 103 /* TrueKeyword */,
        _a.try = 104 /* TryKeyword */,
        _a.type = 141 /* TypeKeyword */,
        _a.typeof = 105 /* TypeOfKeyword */,
        _a.undefined = 142 /* UndefinedKeyword */,
        _a.unique = 143 /* UniqueKeyword */,
        _a.unknown = 144 /* UnknownKeyword */,
        _a.var = 106 /* VarKeyword */,
        _a.void = 107 /* VoidKeyword */,
        _a.while = 108 /* WhileKeyword */,
        _a.with = 109 /* WithKeyword */,
        _a.yield = 118 /* YieldKeyword */,
        _a.async = 122 /* AsyncKeyword */,
        _a.await = 123 /* AwaitKeyword */,
        _a.of = 148 /* OfKeyword */,
        _a);
    var textToKeyword = ts.createMapFromTemplate(textToKeywordObj);
    var textToToken = ts.createMapFromTemplate(__assign({}, textToKeywordObj, { "{": 18 /* OpenBraceToken */, "}": 19 /* CloseBraceToken */, "(": 20 /* OpenParenToken */, ")": 21 /* CloseParenToken */, "[": 22 /* OpenBracketToken */, "]": 23 /* CloseBracketToken */, ".": 24 /* DotToken */, "...": 25 /* DotDotDotToken */, ";": 26 /* SemicolonToken */, ",": 27 /* CommaToken */, "<": 28 /* LessThanToken */, ">": 30 /* GreaterThanToken */, "<=": 31 /* LessThanEqualsToken */, ">=": 32 /* GreaterThanEqualsToken */, "==": 33 /* EqualsEqualsToken */, "!=": 34 /* ExclamationEqualsToken */, "===": 35 /* EqualsEqualsEqualsToken */, "!==": 36 /* ExclamationEqualsEqualsToken */, "=>": 37 /* EqualsGreaterThanToken */, "+": 38 /* PlusToken */, "-": 39 /* MinusToken */, "**": 41 /* AsteriskAsteriskToken */, "*": 40 /* AsteriskToken */, "/": 42 /* SlashToken */, "%": 43 /* PercentToken */, "++": 44 /* PlusPlusToken */, "--": 45 /* MinusMinusToken */, "<<": 46 /* LessThanLessThanToken */, "</": 29 /* LessThanSlashToken */, ">>": 47 /* GreaterThanGreaterThanToken */, ">>>": 48 /* GreaterThanGreaterThanGreaterThanToken */, "&": 49 /* AmpersandToken */, "|": 50 /* BarToken */, "^": 51 /* CaretToken */, "!": 52 /* ExclamationToken */, "~": 53 /* TildeToken */, "&&": 54 /* AmpersandAmpersandToken */, "||": 55 /* BarBarToken */, "?": 56 /* QuestionToken */, ":": 57 /* ColonToken */, "=": 60 /* EqualsToken */, "+=": 61 /* PlusEqualsToken */, "-=": 62 /* MinusEqualsToken */, "*=": 63 /* AsteriskEqualsToken */, "**=": 64 /* AsteriskAsteriskEqualsToken */, "/=": 65 /* SlashEqualsToken */, "%=": 66 /* PercentEqualsToken */, "<<=": 67 /* LessThanLessThanEqualsToken */, ">>=": 68 /* GreaterThanGreaterThanEqualsToken */, ">>>=": 69 /* GreaterThanGreaterThanGreaterThanEqualsToken */, "&=": 70 /* AmpersandEqualsToken */, "|=": 71 /* BarEqualsToken */, "^=": 72 /* CaretEqualsToken */, "@": 58 /* AtToken */ }));
    /*
        As per ECMAScript Language Specification 3th Edition, Section 7.6: Identifiers
        IdentifierStart ::
            Can contain Unicode 3.0.0 categories:
            Uppercase letter (Lu),
            Lowercase letter (Ll),
            Titlecase letter (Lt),
            Modifier letter (Lm),
            Other letter (Lo), or
            Letter number (Nl).
        IdentifierPart :: =
            Can contain IdentifierStart + Unicode 3.0.0 categories:
            Non-spacing mark (Mn),
            Combining spacing mark (Mc),
            Decimal number (Nd), or
            Connector punctuation (Pc).

        Codepoint ranges for ES3 Identifiers are extracted from the Unicode 3.0.0 specification at:
        http://www.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.txt
    */
    var unicodeES3IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1610, 1649, 1747, 1749, 1749, 1765, 1766, 1786, 1788, 1808, 1808, 1810, 1836, 1920, 1957, 2309, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2784, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3294, 3294, 3296, 3297, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3424, 3425, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805, 3840, 3840, 3904, 3911, 3913, 3946, 3976, 3979, 4096, 4129, 4131, 4135, 4137, 4138, 4176, 4181, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6067, 6176, 6263, 6272, 6312, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8319, 8319, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12346, 12353, 12436, 12445, 12446, 12449, 12538, 12540, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65138, 65140, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    var unicodeES3IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 768, 846, 864, 866, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1155, 1158, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1441, 1443, 1465, 1467, 1469, 1471, 1471, 1473, 1474, 1476, 1476, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1621, 1632, 1641, 1648, 1747, 1749, 1756, 1759, 1768, 1770, 1773, 1776, 1788, 1808, 1836, 1840, 1866, 1920, 1968, 2305, 2307, 2309, 2361, 2364, 2381, 2384, 2388, 2392, 2403, 2406, 2415, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2492, 2494, 2500, 2503, 2504, 2507, 2509, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2562, 2562, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2649, 2652, 2654, 2654, 2662, 2676, 2689, 2691, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2784, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2876, 2883, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2913, 2918, 2927, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3031, 3031, 3047, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3134, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3168, 3169, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3262, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3297, 3302, 3311, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3390, 3395, 3398, 3400, 3402, 3405, 3415, 3415, 3424, 3425, 3430, 3439, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3805, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3946, 3953, 3972, 3974, 3979, 3984, 3991, 3993, 4028, 4038, 4038, 4096, 4129, 4131, 4135, 4137, 4138, 4140, 4146, 4150, 4153, 4160, 4169, 4176, 4185, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 4969, 4977, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6099, 6112, 6121, 6160, 6169, 6176, 6263, 6272, 6313, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8255, 8256, 8319, 8319, 8400, 8412, 8417, 8417, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12346, 12353, 12436, 12441, 12442, 12445, 12446, 12449, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65056, 65059, 65075, 65076, 65101, 65103, 65136, 65138, 65140, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65381, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    /*
        As per ECMAScript Language Specification 5th Edition, Section 7.6: ISyntaxToken Names and Identifiers
        IdentifierStart ::
            Can contain Unicode 6.2 categories:
            Uppercase letter (Lu),
            Lowercase letter (Ll),
            Titlecase letter (Lt),
            Modifier letter (Lm),
            Other letter (Lo), or
            Letter number (Nl).
        IdentifierPart ::
            Can contain IdentifierStart + Unicode 6.2 categories:
            Non-spacing mark (Mn),
            Combining spacing mark (Mc),
            Decimal number (Nd),
            Connector punctuation (Pc),
            <ZWNJ>, or
            <ZWJ>.

        Codepoint ranges for ES5 Identifiers are extracted from the Unicode 6.2 specification at:
        http://www.unicode.org/Public/6.2.0/ucd/UnicodeData.txt
    */
    var unicodeES5IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2208, 2208, 2210, 2220, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2423, 2425, 2431, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3133, 3160, 3161, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3424, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3807, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6263, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6428, 6480, 6509, 6512, 6516, 6528, 6571, 6593, 6599, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7098, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7401, 7404, 7406, 7409, 7413, 7414, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11502, 11506, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11823, 11823, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42647, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43648, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43744, 43754, 43762, 43764, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44002, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    var unicodeES5IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1520, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2048, 2093, 2112, 2139, 2208, 2208, 2210, 2220, 2276, 2302, 2304, 2403, 2406, 2415, 2417, 2423, 2425, 2431, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3161, 3168, 3171, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3299, 3302, 3311, 3313, 3314, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3396, 3398, 3400, 3402, 3406, 3415, 3415, 3424, 3427, 3430, 3439, 3450, 3455, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5908, 5920, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6160, 6169, 6176, 6263, 6272, 6314, 6320, 6389, 6400, 6428, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6617, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6912, 6987, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7376, 7378, 7380, 7414, 7424, 7654, 7676, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8204, 8205, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 11823, 11823, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12442, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42647, 42655, 42737, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43047, 43072, 43123, 43136, 43204, 43216, 43225, 43232, 43255, 43259, 43259, 43264, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43643, 43648, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65062, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    function lookupInUnicodeMap(code, map) {
        // Bail out quickly if it couldn't possibly be in the map.
        if (code < map[0]) {
            return false;
        }
        // Perform binary search in one of the Unicode range maps
        var lo = 0;
        var hi = map.length;
        var mid;
        while (lo + 1 < hi) {
            mid = lo + (hi - lo) / 2;
            // mid has to be even to catch a range's beginning
            mid -= mid % 2;
            if (map[mid] <= code && code <= map[mid + 1]) {
                return true;
            }
            if (code < map[mid]) {
                hi = mid;
            }
            else {
                lo = mid + 2;
            }
        }
        return false;
    }
    /* @internal */ function isUnicodeIdentifierStart(code, languageVersion) {
        return languageVersion >= 1 /* ES5 */ ?
            lookupInUnicodeMap(code, unicodeES5IdentifierStart) :
            lookupInUnicodeMap(code, unicodeES3IdentifierStart);
    }
    ts.isUnicodeIdentifierStart = isUnicodeIdentifierStart;
    function isUnicodeIdentifierPart(code, languageVersion) {
        return languageVersion >= 1 /* ES5 */ ?
            lookupInUnicodeMap(code, unicodeES5IdentifierPart) :
            lookupInUnicodeMap(code, unicodeES3IdentifierPart);
    }
    function makeReverseMap(source) {
        var result = [];
        source.forEach(function (value, name) {
            result[value] = name;
        });
        return result;
    }
    var tokenStrings = makeReverseMap(textToToken);
    function tokenToString(t) {
        return tokenStrings[t];
    }
    ts.tokenToString = tokenToString;
    /* @internal */
    function stringToToken(s) {
        return textToToken.get(s);
    }
    ts.stringToToken = stringToToken;
    /* @internal */
    function computeLineStarts(text) {
        var result = new Array();
        var pos = 0;
        var lineStart = 0;
        while (pos < text.length) {
            var ch = text.charCodeAt(pos);
            pos++;
            switch (ch) {
                case 13 /* carriageReturn */:
                    if (text.charCodeAt(pos) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                    result.push(lineStart);
                    lineStart = pos;
                    break;
                default:
                    if (ch > 127 /* maxAsciiCharacter */ && isLineBreak(ch)) {
                        result.push(lineStart);
                        lineStart = pos;
                    }
                    break;
            }
        }
        result.push(lineStart);
        return result;
    }
    ts.computeLineStarts = computeLineStarts;
    function getPositionOfLineAndCharacter(sourceFile, line, character, allowEdits) {
        return sourceFile.getPositionOfLineAndCharacter ?
            sourceFile.getPositionOfLineAndCharacter(line, character, allowEdits) :
            computePositionOfLineAndCharacter(getLineStarts(sourceFile), line, character, sourceFile.text, allowEdits);
    }
    ts.getPositionOfLineAndCharacter = getPositionOfLineAndCharacter;
    /* @internal */
    function computePositionOfLineAndCharacter(lineStarts, line, character, debugText, allowEdits) {
        if (line < 0 || line >= lineStarts.length) {
            if (allowEdits) {
                // Clamp line to nearest allowable value
                line = line < 0 ? 0 : line >= lineStarts.length ? lineStarts.length - 1 : line;
            }
            else {
                ts.Debug.fail("Bad line number. Line: " + line + ", lineStarts.length: " + lineStarts.length + " , line map is correct? " + (debugText !== undefined ? ts.arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"));
            }
        }
        var res = lineStarts[line] + character;
        if (allowEdits) {
            // Clamp to nearest allowable values to allow the underlying to be edited without crashing (accuracy is lost, instead)
            // TODO: Somehow track edits between file as it was during the creation of sourcemap we have and the current file and
            // apply them to the computed position to improve accuracy
            return res > lineStarts[line + 1] ? lineStarts[line + 1] : typeof debugText === "string" && res > debugText.length ? debugText.length : res;
        }
        if (line < lineStarts.length - 1) {
            ts.Debug.assert(res < lineStarts[line + 1]);
        }
        else if (debugText !== undefined) {
            ts.Debug.assert(res <= debugText.length); // Allow single character overflow for trailing newline
        }
        return res;
    }
    ts.computePositionOfLineAndCharacter = computePositionOfLineAndCharacter;
    /* @internal */
    function getLineStarts(sourceFile) {
        return sourceFile.lineMap || (sourceFile.lineMap = computeLineStarts(sourceFile.text));
    }
    ts.getLineStarts = getLineStarts;
    /* @internal */
    /**
     * We assume the first line starts at position 0 and 'position' is non-negative.
     */
    function computeLineAndCharacterOfPosition(lineStarts, position) {
        var lineNumber = ts.binarySearch(lineStarts, position, ts.identity, ts.compareValues);
        if (lineNumber < 0) {
            // If the actual position was not found,
            // the binary search returns the 2's-complement of the next line start
            // e.g. if the line starts at [5, 10, 23, 80] and the position requested was 20
            // then the search will return -2.
            //
            // We want the index of the previous line start, so we subtract 1.
            // Review 2's-complement if this is confusing.
            lineNumber = ~lineNumber - 1;
            ts.Debug.assert(lineNumber !== -1, "position cannot precede the beginning of the file");
        }
        return {
            line: lineNumber,
            character: position - lineStarts[lineNumber]
        };
    }
    ts.computeLineAndCharacterOfPosition = computeLineAndCharacterOfPosition;
    function getLineAndCharacterOfPosition(sourceFile, position) {
        return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position);
    }
    ts.getLineAndCharacterOfPosition = getLineAndCharacterOfPosition;
    function isWhiteSpaceLike(ch) {
        return isWhiteSpaceSingleLine(ch) || isLineBreak(ch);
    }
    ts.isWhiteSpaceLike = isWhiteSpaceLike;
    /** Does not include line breaks. For that, see isWhiteSpaceLike. */
    function isWhiteSpaceSingleLine(ch) {
        // Note: nextLine is in the Zs space, and should be considered to be a whitespace.
        // It is explicitly not a line-break as it isn't in the exact set specified by EcmaScript.
        return ch === 32 /* space */ ||
            ch === 9 /* tab */ ||
            ch === 11 /* verticalTab */ ||
            ch === 12 /* formFeed */ ||
            ch === 160 /* nonBreakingSpace */ ||
            ch === 133 /* nextLine */ ||
            ch === 5760 /* ogham */ ||
            ch >= 8192 /* enQuad */ && ch <= 8203 /* zeroWidthSpace */ ||
            ch === 8239 /* narrowNoBreakSpace */ ||
            ch === 8287 /* mathematicalSpace */ ||
            ch === 12288 /* ideographicSpace */ ||
            ch === 65279 /* byteOrderMark */;
    }
    ts.isWhiteSpaceSingleLine = isWhiteSpaceSingleLine;
    function isLineBreak(ch) {
        // ES5 7.3:
        // The ECMAScript line terminator characters are listed in Table 3.
        //     Table 3: Line Terminator Characters
        //     Code Unit Value     Name                    Formal Name
        //     \u000A              Line Feed               <LF>
        //     \u000D              Carriage Return         <CR>
        //     \u2028              Line separator          <LS>
        //     \u2029              Paragraph separator     <PS>
        // Only the characters in Table 3 are treated as line terminators. Other new line or line
        // breaking characters are treated as white space but not as line terminators.
        return ch === 10 /* lineFeed */ ||
            ch === 13 /* carriageReturn */ ||
            ch === 8232 /* lineSeparator */ ||
            ch === 8233 /* paragraphSeparator */;
    }
    ts.isLineBreak = isLineBreak;
    function isDigit(ch) {
        return ch >= 48 /* _0 */ && ch <= 57 /* _9 */;
    }
    /* @internal */
    function isOctalDigit(ch) {
        return ch >= 48 /* _0 */ && ch <= 55 /* _7 */;
    }
    ts.isOctalDigit = isOctalDigit;
    function couldStartTrivia(text, pos) {
        // Keep in sync with skipTrivia
        var ch = text.charCodeAt(pos);
        switch (ch) {
            case 13 /* carriageReturn */:
            case 10 /* lineFeed */:
            case 9 /* tab */:
            case 11 /* verticalTab */:
            case 12 /* formFeed */:
            case 32 /* space */:
            case 47 /* slash */:
            // starts of normal trivia
            case 60 /* lessThan */:
            case 124 /* bar */:
            case 61 /* equals */:
            case 62 /* greaterThan */:
                // Starts of conflict marker trivia
                return true;
            case 35 /* hash */:
                // Only if its the beginning can we have #! trivia
                return pos === 0;
            default:
                return ch > 127 /* maxAsciiCharacter */;
        }
    }
    ts.couldStartTrivia = couldStartTrivia;
    /* @internal */
    function skipTrivia(text, pos, stopAfterLineBreak, stopAtComments) {
        if (stopAtComments === void 0) { stopAtComments = false; }
        if (ts.positionIsSynthesized(pos)) {
            return pos;
        }
        // Keep in sync with couldStartTrivia
        while (true) {
            var ch = text.charCodeAt(pos);
            switch (ch) {
                case 13 /* carriageReturn */:
                    if (text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                    pos++;
                    if (stopAfterLineBreak) {
                        return pos;
                    }
                    continue;
                case 9 /* tab */:
                case 11 /* verticalTab */:
                case 12 /* formFeed */:
                case 32 /* space */:
                    pos++;
                    continue;
                case 47 /* slash */:
                    if (stopAtComments) {
                        break;
                    }
                    if (text.charCodeAt(pos + 1) === 47 /* slash */) {
                        pos += 2;
                        while (pos < text.length) {
                            if (isLineBreak(text.charCodeAt(pos))) {
                                break;
                            }
                            pos++;
                        }
                        continue;
                    }
                    if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
                        pos += 2;
                        while (pos < text.length) {
                            if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                pos += 2;
                                break;
                            }
                            pos++;
                        }
                        continue;
                    }
                    break;
                case 60 /* lessThan */:
                case 124 /* bar */:
                case 61 /* equals */:
                case 62 /* greaterThan */:
                    if (isConflictMarkerTrivia(text, pos)) {
                        pos = scanConflictMarkerTrivia(text, pos);
                        continue;
                    }
                    break;
                case 35 /* hash */:
                    if (pos === 0 && isShebangTrivia(text, pos)) {
                        pos = scanShebangTrivia(text, pos);
                        continue;
                    }
                    break;
                default:
                    if (ch > 127 /* maxAsciiCharacter */ && (isWhiteSpaceLike(ch))) {
                        pos++;
                        continue;
                    }
                    break;
            }
            return pos;
        }
    }
    ts.skipTrivia = skipTrivia;
    // All conflict markers consist of the same character repeated seven times.  If it is
    // a <<<<<<< or >>>>>>> marker then it is also followed by a space.
    var mergeConflictMarkerLength = "<<<<<<<".length;
    function isConflictMarkerTrivia(text, pos) {
        ts.Debug.assert(pos >= 0);
        // Conflict markers must be at the start of a line.
        if (pos === 0 || isLineBreak(text.charCodeAt(pos - 1))) {
            var ch = text.charCodeAt(pos);
            if ((pos + mergeConflictMarkerLength) < text.length) {
                for (var i = 0; i < mergeConflictMarkerLength; i++) {
                    if (text.charCodeAt(pos + i) !== ch) {
                        return false;
                    }
                }
                return ch === 61 /* equals */ ||
                    text.charCodeAt(pos + mergeConflictMarkerLength) === 32 /* space */;
            }
        }
        return false;
    }
    function scanConflictMarkerTrivia(text, pos, error) {
        if (error) {
            error(ts.Diagnostics.Merge_conflict_marker_encountered, pos, mergeConflictMarkerLength);
        }
        var ch = text.charCodeAt(pos);
        var len = text.length;
        if (ch === 60 /* lessThan */ || ch === 62 /* greaterThan */) {
            while (pos < len && !isLineBreak(text.charCodeAt(pos))) {
                pos++;
            }
        }
        else {
            ts.Debug.assert(ch === 124 /* bar */ || ch === 61 /* equals */);
            // Consume everything from the start of a ||||||| or ======= marker to the start
            // of the next ======= or >>>>>>> marker.
            while (pos < len) {
                var currentChar = text.charCodeAt(pos);
                if ((currentChar === 61 /* equals */ || currentChar === 62 /* greaterThan */) && currentChar !== ch && isConflictMarkerTrivia(text, pos)) {
                    break;
                }
                pos++;
            }
        }
        return pos;
    }
    var shebangTriviaRegex = /^#!.*/;
    /*@internal*/
    function isShebangTrivia(text, pos) {
        // Shebangs check must only be done at the start of the file
        ts.Debug.assert(pos === 0);
        return shebangTriviaRegex.test(text);
    }
    ts.isShebangTrivia = isShebangTrivia;
    /*@internal*/
    function scanShebangTrivia(text, pos) {
        var shebang = shebangTriviaRegex.exec(text)[0];
        pos = pos + shebang.length;
        return pos;
    }
    ts.scanShebangTrivia = scanShebangTrivia;
    /**
     * Invokes a callback for each comment range following the provided position.
     *
     * Single-line comment ranges include the leading double-slash characters but not the ending
     * line break. Multi-line comment ranges include the leading slash-asterisk and trailing
     * asterisk-slash characters.
     *
     * @param reduce If true, accumulates the result of calling the callback in a fashion similar
     *      to reduceLeft. If false, iteration stops when the callback returns a truthy value.
     * @param text The source text to scan.
     * @param pos The position at which to start scanning.
     * @param trailing If false, whitespace is skipped until the first line break and comments
     *      between that location and the next token are returned. If true, comments occurring
     *      between the given position and the next line break are returned.
     * @param cb The callback to execute as each comment range is encountered.
     * @param state A state value to pass to each iteration of the callback.
     * @param initial An initial value to pass when accumulating results (when "reduce" is true).
     * @returns If "reduce" is true, the accumulated value. If "reduce" is false, the first truthy
     *      return value of the callback.
     */
    function iterateCommentRanges(reduce, text, pos, trailing, cb, state, initial) {
        var pendingPos;
        var pendingEnd;
        var pendingKind;
        var pendingHasTrailingNewLine;
        var hasPendingCommentRange = false;
        var collecting = trailing;
        var accumulator = initial;
        if (pos === 0) {
            collecting = true;
            var shebang = getShebang(text);
            if (shebang) {
                pos = shebang.length;
            }
        }
        scan: while (pos >= 0 && pos < text.length) {
            var ch = text.charCodeAt(pos);
            switch (ch) {
                case 13 /* carriageReturn */:
                    if (text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                    pos++;
                    if (trailing) {
                        break scan;
                    }
                    collecting = true;
                    if (hasPendingCommentRange) {
                        pendingHasTrailingNewLine = true;
                    }
                    continue;
                case 9 /* tab */:
                case 11 /* verticalTab */:
                case 12 /* formFeed */:
                case 32 /* space */:
                    pos++;
                    continue;
                case 47 /* slash */:
                    var nextChar = text.charCodeAt(pos + 1);
                    var hasTrailingNewLine = false;
                    if (nextChar === 47 /* slash */ || nextChar === 42 /* asterisk */) {
                        var kind = nextChar === 47 /* slash */ ? 2 /* SingleLineCommentTrivia */ : 3 /* MultiLineCommentTrivia */;
                        var startPos = pos;
                        pos += 2;
                        if (nextChar === 47 /* slash */) {
                            while (pos < text.length) {
                                if (isLineBreak(text.charCodeAt(pos))) {
                                    hasTrailingNewLine = true;
                                    break;
                                }
                                pos++;
                            }
                        }
                        else {
                            while (pos < text.length) {
                                if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                    pos += 2;
                                    break;
                                }
                                pos++;
                            }
                        }
                        if (collecting) {
                            if (hasPendingCommentRange) {
                                accumulator = cb(pendingPos, pendingEnd, pendingKind, pendingHasTrailingNewLine, state, accumulator);
                                if (!reduce && accumulator) {
                                    // If we are not reducing and we have a truthy result, return it.
                                    return accumulator;
                                }
                            }
                            pendingPos = startPos;
                            pendingEnd = pos;
                            pendingKind = kind;
                            pendingHasTrailingNewLine = hasTrailingNewLine;
                            hasPendingCommentRange = true;
                        }
                        continue;
                    }
                    break scan;
                default:
                    if (ch > 127 /* maxAsciiCharacter */ && (isWhiteSpaceLike(ch))) {
                        if (hasPendingCommentRange && isLineBreak(ch)) {
                            pendingHasTrailingNewLine = true;
                        }
                        pos++;
                        continue;
                    }
                    break scan;
            }
        }
        if (hasPendingCommentRange) {
            accumulator = cb(pendingPos, pendingEnd, pendingKind, pendingHasTrailingNewLine, state, accumulator);
        }
        return accumulator;
    }
    function forEachLeadingCommentRange(text, pos, cb, state) {
        return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state);
    }
    ts.forEachLeadingCommentRange = forEachLeadingCommentRange;
    function forEachTrailingCommentRange(text, pos, cb, state) {
        return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state);
    }
    ts.forEachTrailingCommentRange = forEachTrailingCommentRange;
    function reduceEachLeadingCommentRange(text, pos, cb, state, initial) {
        return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ false, cb, state, initial);
    }
    ts.reduceEachLeadingCommentRange = reduceEachLeadingCommentRange;
    function reduceEachTrailingCommentRange(text, pos, cb, state, initial) {
        return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial);
    }
    ts.reduceEachTrailingCommentRange = reduceEachTrailingCommentRange;
    function appendCommentRange(pos, end, kind, hasTrailingNewLine, _state, comments) {
        if (!comments) {
            comments = [];
        }
        comments.push({ kind: kind, pos: pos, end: end, hasTrailingNewLine: hasTrailingNewLine });
        return comments;
    }
    function getLeadingCommentRanges(text, pos) {
        return reduceEachLeadingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined);
    }
    ts.getLeadingCommentRanges = getLeadingCommentRanges;
    function getTrailingCommentRanges(text, pos) {
        return reduceEachTrailingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined);
    }
    ts.getTrailingCommentRanges = getTrailingCommentRanges;
    /** Optionally, get the shebang */
    function getShebang(text) {
        var match = shebangTriviaRegex.exec(text);
        if (match) {
            return match[0];
        }
    }
    ts.getShebang = getShebang;
    function isIdentifierStart(ch, languageVersion) {
        return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ ||
            ch === 36 /* $ */ || ch === 95 /* _ */ ||
            ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierStart(ch, languageVersion);
    }
    ts.isIdentifierStart = isIdentifierStart;
    function isIdentifierPart(ch, languageVersion) {
        return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ ||
            ch >= 48 /* _0 */ && ch <= 57 /* _9 */ || ch === 36 /* $ */ || ch === 95 /* _ */ ||
            ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierPart(ch, languageVersion);
    }
    ts.isIdentifierPart = isIdentifierPart;
    /* @internal */
    function isIdentifierText(name, languageVersion) {
        if (!isIdentifierStart(name.charCodeAt(0), languageVersion)) {
            return false;
        }
        for (var i = 1; i < name.length; i++) {
            if (!isIdentifierPart(name.charCodeAt(i), languageVersion)) {
                return false;
            }
        }
        return true;
    }
    ts.isIdentifierText = isIdentifierText;
    // Creates a scanner over a (possibly unspecified) range of a piece of text.
    function createScanner(languageVersion, skipTrivia, languageVariant, textInitial, onError, start, length) {
        if (languageVariant === void 0) { languageVariant = 0 /* Standard */; }
        var text = textInitial;
        // Current position (end position of text of current token)
        var pos;
        // end of text
        var end;
        // Start position of whitespace before current token
        var startPos;
        // Start position of text of current token
        var tokenPos;
        var token;
        var tokenValue;
        var tokenFlags;
        var inJSDocType = 0;
        setText(text, start, length);
        return {
            getStartPos: function () { return startPos; },
            getTextPos: function () { return pos; },
            getToken: function () { return token; },
            getTokenPos: function () { return tokenPos; },
            getTokenText: function () { return text.substring(tokenPos, pos); },
            getTokenValue: function () { return tokenValue; },
            hasExtendedUnicodeEscape: function () { return (tokenFlags & 8 /* ExtendedUnicodeEscape */) !== 0; },
            hasPrecedingLineBreak: function () { return (tokenFlags & 1 /* PrecedingLineBreak */) !== 0; },
            isIdentifier: function () { return token === 73 /* Identifier */ || token > 109 /* LastReservedWord */; },
            isReservedWord: function () { return token >= 74 /* FirstReservedWord */ && token <= 109 /* LastReservedWord */; },
            isUnterminated: function () { return (tokenFlags & 4 /* Unterminated */) !== 0; },
            getTokenFlags: function () { return tokenFlags; },
            reScanGreaterToken: reScanGreaterToken,
            reScanSlashToken: reScanSlashToken,
            reScanTemplateToken: reScanTemplateToken,
            scanJsxIdentifier: scanJsxIdentifier,
            scanJsxAttributeValue: scanJsxAttributeValue,
            reScanJsxToken: reScanJsxToken,
            reScanLessThanToken: reScanLessThanToken,
            scanJsxToken: scanJsxToken,
            scanJsDocToken: scanJsDocToken,
            scan: scan,
            getText: getText,
            setText: setText,
            setScriptTarget: setScriptTarget,
            setLanguageVariant: setLanguageVariant,
            setOnError: setOnError,
            setTextPos: setTextPos,
            setInJSDocType: setInJSDocType,
            tryScan: tryScan,
            lookAhead: lookAhead,
            scanRange: scanRange,
        };
        function error(message, errPos, length) {
            if (errPos === void 0) { errPos = pos; }
            if (onError) {
                var oldPos = pos;
                pos = errPos;
                onError(message, length || 0);
                pos = oldPos;
            }
        }
        function scanNumberFragment() {
            var start = pos;
            var allowSeparator = false;
            var isPreviousTokenSeparator = false;
            var result = "";
            while (true) {
                var ch = text.charCodeAt(pos);
                if (ch === 95 /* _ */) {
                    tokenFlags |= 512 /* ContainsSeparator */;
                    if (allowSeparator) {
                        allowSeparator = false;
                        isPreviousTokenSeparator = true;
                        result += text.substring(start, pos);
                    }
                    else if (isPreviousTokenSeparator) {
                        error(ts.Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1);
                    }
                    else {
                        error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1);
                    }
                    pos++;
                    start = pos;
                    continue;
                }
                if (isDigit(ch)) {
                    allowSeparator = true;
                    isPreviousTokenSeparator = false;
                    pos++;
                    continue;
                }
                break;
            }
            if (text.charCodeAt(pos - 1) === 95 /* _ */) {
                error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
            }
            return result + text.substring(start, pos);
        }
        function scanNumber() {
            var start = pos;
            var mainFragment = scanNumberFragment();
            var decimalFragment;
            var scientificFragment;
            if (text.charCodeAt(pos) === 46 /* dot */) {
                pos++;
                decimalFragment = scanNumberFragment();
            }
            var end = pos;
            if (text.charCodeAt(pos) === 69 /* E */ || text.charCodeAt(pos) === 101 /* e */) {
                pos++;
                tokenFlags |= 16 /* Scientific */;
                if (text.charCodeAt(pos) === 43 /* plus */ || text.charCodeAt(pos) === 45 /* minus */)
                    pos++;
                var preNumericPart = pos;
                var finalFragment = scanNumberFragment();
                if (!finalFragment) {
                    error(ts.Diagnostics.Digit_expected);
                }
                else {
                    scientificFragment = text.substring(end, preNumericPart) + finalFragment;
                    end = pos;
                }
            }
            var result;
            if (tokenFlags & 512 /* ContainsSeparator */) {
                result = mainFragment;
                if (decimalFragment) {
                    result += "." + decimalFragment;
                }
                if (scientificFragment) {
                    result += scientificFragment;
                }
            }
            else {
                result = text.substring(start, end); // No need to use all the fragments; no _ removal needed
            }
            if (decimalFragment !== undefined || tokenFlags & 16 /* Scientific */) {
                checkForIdentifierStartAfterNumericLiteral(start, decimalFragment === undefined && !!(tokenFlags & 16 /* Scientific */));
                return {
                    type: 8 /* NumericLiteral */,
                    value: "" + +result // if value is not an integer, it can be safely coerced to a number
                };
            }
            else {
                tokenValue = result;
                var type = checkBigIntSuffix(); // if value is an integer, check whether it is a bigint
                checkForIdentifierStartAfterNumericLiteral(start);
                return { type: type, value: tokenValue };
            }
        }
        function checkForIdentifierStartAfterNumericLiteral(numericStart, isScientific) {
            if (!isIdentifierStart(text.charCodeAt(pos), languageVersion)) {
                return;
            }
            var identifierStart = pos;
            var length = scanIdentifierParts().length;
            if (length === 1 && text[identifierStart] === "n") {
                if (isScientific) {
                    error(ts.Diagnostics.A_bigint_literal_cannot_use_exponential_notation, numericStart, identifierStart - numericStart + 1);
                }
                else {
                    error(ts.Diagnostics.A_bigint_literal_must_be_an_integer, numericStart, identifierStart - numericStart + 1);
                }
            }
            else {
                error(ts.Diagnostics.An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal, identifierStart, length);
                pos = identifierStart;
            }
        }
        function scanOctalDigits() {
            var start = pos;
            while (isOctalDigit(text.charCodeAt(pos))) {
                pos++;
            }
            return +(text.substring(start, pos));
        }
        /**
         * Scans the given number of hexadecimal digits in the text,
         * returning -1 if the given number is unavailable.
         */
        function scanExactNumberOfHexDigits(count, canHaveSeparators) {
            var valueString = scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ false, canHaveSeparators);
            return valueString ? parseInt(valueString, 16) : -1;
        }
        /**
         * Scans as many hexadecimal digits as are available in the text,
         * returning "" if the given number of digits was unavailable.
         */
        function scanMinimumNumberOfHexDigits(count, canHaveSeparators) {
            return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ true, canHaveSeparators);
        }
        function scanHexDigits(minCount, scanAsManyAsPossible, canHaveSeparators) {
            var valueChars = [];
            var allowSeparator = false;
            var isPreviousTokenSeparator = false;
            while (valueChars.length < minCount || scanAsManyAsPossible) {
                var ch = text.charCodeAt(pos);
                if (canHaveSeparators && ch === 95 /* _ */) {
                    tokenFlags |= 512 /* ContainsSeparator */;
                    if (allowSeparator) {
                        allowSeparator = false;
                        isPreviousTokenSeparator = true;
                    }
                    else if (isPreviousTokenSeparator) {
                        error(ts.Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1);
                    }
                    else {
                        error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1);
                    }
                    pos++;
                    continue;
                }
                allowSeparator = canHaveSeparators;
                if (ch >= 65 /* A */ && ch <= 70 /* F */) {
                    ch += 97 /* a */ - 65 /* A */; // standardize hex literals to lowercase
                }
                else if (!((ch >= 48 /* _0 */ && ch <= 57 /* _9 */) ||
                    (ch >= 97 /* a */ && ch <= 102 /* f */))) {
                    break;
                }
                valueChars.push(ch);
                pos++;
                isPreviousTokenSeparator = false;
            }
            if (valueChars.length < minCount) {
                valueChars = [];
            }
            if (text.charCodeAt(pos - 1) === 95 /* _ */) {
                error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
            }
            return String.fromCharCode.apply(String, valueChars);
        }
        function scanString(jsxAttributeString) {
            if (jsxAttributeString === void 0) { jsxAttributeString = false; }
            var quote = text.charCodeAt(pos);
            pos++;
            var result = "";
            var start = pos;
            while (true) {
                if (pos >= end) {
                    result += text.substring(start, pos);
                    tokenFlags |= 4 /* Unterminated */;
                    error(ts.Diagnostics.Unterminated_string_literal);
                    break;
                }
                var ch = text.charCodeAt(pos);
                if (ch === quote) {
                    result += text.substring(start, pos);
                    pos++;
                    break;
                }
                if (ch === 92 /* backslash */ && !jsxAttributeString) {
                    result += text.substring(start, pos);
                    result += scanEscapeSequence();
                    start = pos;
                    continue;
                }
                if (isLineBreak(ch) && !jsxAttributeString) {
                    result += text.substring(start, pos);
                    tokenFlags |= 4 /* Unterminated */;
                    error(ts.Diagnostics.Unterminated_string_literal);
                    break;
                }
                pos++;
            }
            return result;
        }
        /**
         * Sets the current 'tokenValue' and returns a NoSubstitutionTemplateLiteral or
         * a literal component of a TemplateExpression.
         */
        function scanTemplateAndSetTokenValue() {
            var startedWithBacktick = text.charCodeAt(pos) === 96 /* backtick */;
            pos++;
            var start = pos;
            var contents = "";
            var resultingToken;
            while (true) {
                if (pos >= end) {
                    contents += text.substring(start, pos);
                    tokenFlags |= 4 /* Unterminated */;
                    error(ts.Diagnostics.Unterminated_template_literal);
                    resultingToken = startedWithBacktick ? 14 /* NoSubstitutionTemplateLiteral */ : 17 /* TemplateTail */;
                    break;
                }
                var currChar = text.charCodeAt(pos);
                // '`'
                if (currChar === 96 /* backtick */) {
                    contents += text.substring(start, pos);
                    pos++;
                    resultingToken = startedWithBacktick ? 14 /* NoSubstitutionTemplateLiteral */ : 17 /* TemplateTail */;
                    break;
                }
                // '${'
                if (currChar === 36 /* $ */ && pos + 1 < end && text.charCodeAt(pos + 1) === 123 /* openBrace */) {
                    contents += text.substring(start, pos);
                    pos += 2;
                    resultingToken = startedWithBacktick ? 15 /* TemplateHead */ : 16 /* TemplateMiddle */;
                    break;
                }
                // Escape character
                if (currChar === 92 /* backslash */) {
                    contents += text.substring(start, pos);
                    contents += scanEscapeSequence();
                    start = pos;
                    continue;
                }
                // Speculated ECMAScript 6 Spec 11.8.6.1:
                // <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for Template Values
                if (currChar === 13 /* carriageReturn */) {
                    contents += text.substring(start, pos);
                    pos++;
                    if (pos < end && text.charCodeAt(pos) === 10 /* lineFeed */) {
                        pos++;
                    }
                    contents += "\n";
                    start = pos;
                    continue;
                }
                pos++;
            }
            ts.Debug.assert(resultingToken !== undefined);
            tokenValue = contents;
            return resultingToken;
        }
        function scanEscapeSequence() {
            pos++;
            if (pos >= end) {
                error(ts.Diagnostics.Unexpected_end_of_text);
                return "";
            }
            var ch = text.charCodeAt(pos);
            pos++;
            switch (ch) {
                case 48 /* _0 */:
                    return "\0";
                case 98 /* b */:
                    return "\b";
                case 116 /* t */:
                    return "\t";
                case 110 /* n */:
                    return "\n";
                case 118 /* v */:
                    return "\v";
                case 102 /* f */:
                    return "\f";
                case 114 /* r */:
                    return "\r";
                case 39 /* singleQuote */:
                    return "\'";
                case 34 /* doubleQuote */:
                    return "\"";
                case 117 /* u */:
                    // '\u{DDDDDDDD}'
                    if (pos < end && text.charCodeAt(pos) === 123 /* openBrace */) {
                        tokenFlags |= 8 /* ExtendedUnicodeEscape */;
                        pos++;
                        return scanExtendedUnicodeEscape();
                    }
                    // '\uDDDD'
                    return scanHexadecimalEscape(/*numDigits*/ 4);
                case 120 /* x */:
                    // '\xDD'
                    return scanHexadecimalEscape(/*numDigits*/ 2);
                // when encountering a LineContinuation (i.e. a backslash and a line terminator sequence),
                // the line terminator is interpreted to be "the empty code unit sequence".
                case 13 /* carriageReturn */:
                    if (pos < end && text.charCodeAt(pos) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                case 8232 /* lineSeparator */:
                case 8233 /* paragraphSeparator */:
                    return "";
                default:
                    return String.fromCharCode(ch);
            }
        }
        function scanHexadecimalEscape(numDigits) {
            var escapedValue = scanExactNumberOfHexDigits(numDigits, /*canHaveSeparators*/ false);
            if (escapedValue >= 0) {
                return String.fromCharCode(escapedValue);
            }
            else {
                error(ts.Diagnostics.Hexadecimal_digit_expected);
                return "";
            }
        }
        function scanExtendedUnicodeEscape() {
            var escapedValueString = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false);
            var escapedValue = escapedValueString ? parseInt(escapedValueString, 16) : -1;
            var isInvalidExtendedEscape = false;
            // Validate the value of the digit
            if (escapedValue < 0) {
                error(ts.Diagnostics.Hexadecimal_digit_expected);
                isInvalidExtendedEscape = true;
            }
            else if (escapedValue > 0x10FFFF) {
                error(ts.Diagnostics.An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive);
                isInvalidExtendedEscape = true;
            }
            if (pos >= end) {
                error(ts.Diagnostics.Unexpected_end_of_text);
                isInvalidExtendedEscape = true;
            }
            else if (text.charCodeAt(pos) === 125 /* closeBrace */) {
                // Only swallow the following character up if it's a '}'.
                pos++;
            }
            else {
                error(ts.Diagnostics.Unterminated_Unicode_escape_sequence);
                isInvalidExtendedEscape = true;
            }
            if (isInvalidExtendedEscape) {
                return "";
            }
            return utf16EncodeAsString(escapedValue);
        }
        // Derived from the 10.1.1 UTF16Encoding of the ES6 Spec.
        function utf16EncodeAsString(codePoint) {
            ts.Debug.assert(0x0 <= codePoint && codePoint <= 0x10FFFF);
            if (codePoint <= 65535) {
                return String.fromCharCode(codePoint);
            }
            var codeUnit1 = Math.floor((codePoint - 65536) / 1024) + 0xD800;
            var codeUnit2 = ((codePoint - 65536) % 1024) + 0xDC00;
            return String.fromCharCode(codeUnit1, codeUnit2);
        }
        // Current character is known to be a backslash. Check for Unicode escape of the form '\uXXXX'
        // and return code point value if valid Unicode escape is found. Otherwise return -1.
        function peekUnicodeEscape() {
            if (pos + 5 < end && text.charCodeAt(pos + 1) === 117 /* u */) {
                var start_1 = pos;
                pos += 2;
                var value = scanExactNumberOfHexDigits(4, /*canHaveSeparators*/ false);
                pos = start_1;
                return value;
            }
            return -1;
        }
        function scanIdentifierParts() {
            var result = "";
            var start = pos;
            while (pos < end) {
                var ch = text.charCodeAt(pos);
                if (isIdentifierPart(ch, languageVersion)) {
                    pos++;
                }
                else if (ch === 92 /* backslash */) {
                    ch = peekUnicodeEscape();
                    if (!(ch >= 0 && isIdentifierPart(ch, languageVersion))) {
                        break;
                    }
                    result += text.substring(start, pos);
                    result += String.fromCharCode(ch);
                    // Valid Unicode escape is always six characters
                    pos += 6;
                    start = pos;
                }
                else {
                    break;
                }
            }
            result += text.substring(start, pos);
            return result;
        }
        function getIdentifierToken() {
            // Reserved words are between 2 and 11 characters long and start with a lowercase letter
            var len = tokenValue.length;
            if (len >= 2 && len <= 11) {
                var ch = tokenValue.charCodeAt(0);
                if (ch >= 97 /* a */ && ch <= 122 /* z */) {
                    var keyword = textToKeyword.get(tokenValue);
                    if (keyword !== undefined) {
                        return token = keyword;
                    }
                }
            }
            return token = 73 /* Identifier */;
        }
        function scanBinaryOrOctalDigits(base) {
            var value = "";
            // For counting number of digits; Valid binaryIntegerLiteral must have at least one binary digit following B or b.
            // Similarly valid octalIntegerLiteral must have at least one octal digit following o or O.
            var separatorAllowed = false;
            var isPreviousTokenSeparator = false;
            while (true) {
                var ch = text.charCodeAt(pos);
                // Numeric separators are allowed anywhere within a numeric literal, except not at the beginning, or following another separator
                if (ch === 95 /* _ */) {
                    tokenFlags |= 512 /* ContainsSeparator */;
                    if (separatorAllowed) {
                        separatorAllowed = false;
                        isPreviousTokenSeparator = true;
                    }
                    else if (isPreviousTokenSeparator) {
                        error(ts.Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1);
                    }
                    else {
                        error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1);
                    }
                    pos++;
                    continue;
                }
                separatorAllowed = true;
                if (!isDigit(ch) || ch - 48 /* _0 */ >= base) {
                    break;
                }
                value += text[pos];
                pos++;
                isPreviousTokenSeparator = false;
            }
            if (text.charCodeAt(pos - 1) === 95 /* _ */) {
                // Literal ends with underscore - not allowed
                error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
            }
            return value;
        }
        function checkBigIntSuffix() {
            if (text.charCodeAt(pos) === 110 /* n */) {
                tokenValue += "n";
                // Use base 10 instead of base 2 or base 8 for shorter literals
                if (tokenFlags & 384 /* BinaryOrOctalSpecifier */) {
                    tokenValue = ts.parsePseudoBigInt(tokenValue) + "n";
                }
                pos++;
                return 9 /* BigIntLiteral */;
            }
            else { // not a bigint, so can convert to number in simplified form
                // Number() may not support 0b or 0o, so use parseInt() instead
                var numericValue = tokenFlags & 128 /* BinarySpecifier */
                    ? parseInt(tokenValue.slice(2), 2) // skip "0b"
                    : tokenFlags & 256 /* OctalSpecifier */
                        ? parseInt(tokenValue.slice(2), 8) // skip "0o"
                        : +tokenValue;
                tokenValue = "" + numericValue;
                return 8 /* NumericLiteral */;
            }
        }
        function scan() {
            var _a;
            startPos = pos;
            tokenFlags = 0;
            var asteriskSeen = false;
            while (true) {
                tokenPos = pos;
                if (pos >= end) {
                    return token = 1 /* EndOfFileToken */;
                }
                var ch = text.charCodeAt(pos);
                // Special handling for shebang
                if (ch === 35 /* hash */ && pos === 0 && isShebangTrivia(text, pos)) {
                    pos = scanShebangTrivia(text, pos);
                    if (skipTrivia) {
                        continue;
                    }
                    else {
                        return token = 6 /* ShebangTrivia */;
                    }
                }
                switch (ch) {
                    case 10 /* lineFeed */:
                    case 13 /* carriageReturn */:
                        tokenFlags |= 1 /* PrecedingLineBreak */;
                        if (skipTrivia) {
                            pos++;
                            continue;
                        }
                        else {
                            if (ch === 13 /* carriageReturn */ && pos + 1 < end && text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
                                // consume both CR and LF
                                pos += 2;
                            }
                            else {
                                pos++;
                            }
                            return token = 4 /* NewLineTrivia */;
                        }
                    case 9 /* tab */:
                    case 11 /* verticalTab */:
                    case 12 /* formFeed */:
                    case 32 /* space */:
                    case 160 /* nonBreakingSpace */:
                    case 5760 /* ogham */:
                    case 8192 /* enQuad */:
                    case 8193 /* emQuad */:
                    case 8194 /* enSpace */:
                    case 8195 /* emSpace */:
                    case 8196 /* threePerEmSpace */:
                    case 8197 /* fourPerEmSpace */:
                    case 8198 /* sixPerEmSpace */:
                    case 8199 /* figureSpace */:
                    case 8200 /* punctuationSpace */:
                    case 8201 /* thinSpace */:
                    case 8202 /* hairSpace */:
                    case 8203 /* zeroWidthSpace */:
                    case 8239 /* narrowNoBreakSpace */:
                    case 8287 /* mathematicalSpace */:
                    case 12288 /* ideographicSpace */:
                    case 65279 /* byteOrderMark */:
                        if (skipTrivia) {
                            pos++;
                            continue;
                        }
                        else {
                            while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) {
                                pos++;
                            }
                            return token = 5 /* WhitespaceTrivia */;
                        }
                    case 33 /* exclamation */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 36 /* ExclamationEqualsEqualsToken */;
                            }
                            return pos += 2, token = 34 /* ExclamationEqualsToken */;
                        }
                        pos++;
                        return token = 52 /* ExclamationToken */;
                    case 34 /* doubleQuote */:
                    case 39 /* singleQuote */:
                        tokenValue = scanString();
                        return token = 10 /* StringLiteral */;
                    case 96 /* backtick */:
                        return token = scanTemplateAndSetTokenValue();
                    case 37 /* percent */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 66 /* PercentEqualsToken */;
                        }
                        pos++;
                        return token = 43 /* PercentToken */;
                    case 38 /* ampersand */:
                        if (text.charCodeAt(pos + 1) === 38 /* ampersand */) {
                            return pos += 2, token = 54 /* AmpersandAmpersandToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 70 /* AmpersandEqualsToken */;
                        }
                        pos++;
                        return token = 49 /* AmpersandToken */;
                    case 40 /* openParen */:
                        pos++;
                        return token = 20 /* OpenParenToken */;
                    case 41 /* closeParen */:
                        pos++;
                        return token = 21 /* CloseParenToken */;
                    case 42 /* asterisk */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 63 /* AsteriskEqualsToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 64 /* AsteriskAsteriskEqualsToken */;
                            }
                            return pos += 2, token = 41 /* AsteriskAsteriskToken */;
                        }
                        pos++;
                        if (inJSDocType && !asteriskSeen && (tokenFlags & 1 /* PrecedingLineBreak */)) {
                            // decoration at the start of a JSDoc comment line
                            asteriskSeen = true;
                            continue;
                        }
                        return token = 40 /* AsteriskToken */;
                    case 43 /* plus */:
                        if (text.charCodeAt(pos + 1) === 43 /* plus */) {
                            return pos += 2, token = 44 /* PlusPlusToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 61 /* PlusEqualsToken */;
                        }
                        pos++;
                        return token = 38 /* PlusToken */;
                    case 44 /* comma */:
                        pos++;
                        return token = 27 /* CommaToken */;
                    case 45 /* minus */:
                        if (text.charCodeAt(pos + 1) === 45 /* minus */) {
                            return pos += 2, token = 45 /* MinusMinusToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 62 /* MinusEqualsToken */;
                        }
                        pos++;
                        return token = 39 /* MinusToken */;
                    case 46 /* dot */:
                        if (isDigit(text.charCodeAt(pos + 1))) {
                            tokenValue = scanNumber().value;
                            return token = 8 /* NumericLiteral */;
                        }
                        if (text.charCodeAt(pos + 1) === 46 /* dot */ && text.charCodeAt(pos + 2) === 46 /* dot */) {
                            return pos += 3, token = 25 /* DotDotDotToken */;
                        }
                        pos++;
                        return token = 24 /* DotToken */;
                    case 47 /* slash */:
                        // Single-line comment
                        if (text.charCodeAt(pos + 1) === 47 /* slash */) {
                            pos += 2;
                            while (pos < end) {
                                if (isLineBreak(text.charCodeAt(pos))) {
                                    break;
                                }
                                pos++;
                            }
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 2 /* SingleLineCommentTrivia */;
                            }
                        }
                        // Multi-line comment
                        if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
                            pos += 2;
                            if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) !== 47 /* slash */) {
                                tokenFlags |= 2 /* PrecedingJSDocComment */;
                            }
                            var commentClosed = false;
                            while (pos < end) {
                                var ch_1 = text.charCodeAt(pos);
                                if (ch_1 === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                    pos += 2;
                                    commentClosed = true;
                                    break;
                                }
                                if (isLineBreak(ch_1)) {
                                    tokenFlags |= 1 /* PrecedingLineBreak */;
                                }
                                pos++;
                            }
                            if (!commentClosed) {
                                error(ts.Diagnostics.Asterisk_Slash_expected);
                            }
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                if (!commentClosed) {
                                    tokenFlags |= 4 /* Unterminated */;
                                }
                                return token = 3 /* MultiLineCommentTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 65 /* SlashEqualsToken */;
                        }
                        pos++;
                        return token = 42 /* SlashToken */;
                    case 48 /* _0 */:
                        if (pos + 2 < end && (text.charCodeAt(pos + 1) === 88 /* X */ || text.charCodeAt(pos + 1) === 120 /* x */)) {
                            pos += 2;
                            tokenValue = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ true);
                            if (!tokenValue) {
                                error(ts.Diagnostics.Hexadecimal_digit_expected);
                                tokenValue = "0";
                            }
                            tokenValue = "0x" + tokenValue;
                            tokenFlags |= 64 /* HexSpecifier */;
                            return token = checkBigIntSuffix();
                        }
                        else if (pos + 2 < end && (text.charCodeAt(pos + 1) === 66 /* B */ || text.charCodeAt(pos + 1) === 98 /* b */)) {
                            pos += 2;
                            tokenValue = scanBinaryOrOctalDigits(/* base */ 2);
                            if (!tokenValue) {
                                error(ts.Diagnostics.Binary_digit_expected);
                                tokenValue = "0";
                            }
                            tokenValue = "0b" + tokenValue;
                            tokenFlags |= 128 /* BinarySpecifier */;
                            return token = checkBigIntSuffix();
                        }
                        else if (pos + 2 < end && (text.charCodeAt(pos + 1) === 79 /* O */ || text.charCodeAt(pos + 1) === 111 /* o */)) {
                            pos += 2;
                            tokenValue = scanBinaryOrOctalDigits(/* base */ 8);
                            if (!tokenValue) {
                                error(ts.Diagnostics.Octal_digit_expected);
                                tokenValue = "0";
                            }
                            tokenValue = "0o" + tokenValue;
                            tokenFlags |= 256 /* OctalSpecifier */;
                            return token = checkBigIntSuffix();
                        }
                        // Try to parse as an octal
                        if (pos + 1 < end && isOctalDigit(text.charCodeAt(pos + 1))) {
                            tokenValue = "" + scanOctalDigits();
                            tokenFlags |= 32 /* Octal */;
                            return token = 8 /* NumericLiteral */;
                        }
                    // This fall-through is a deviation from the EcmaScript grammar. The grammar says that a leading zero
                    // can only be followed by an octal digit, a dot, or the end of the number literal. However, we are being
                    // permissive and allowing decimal digits of the form 08* and 09* (which many browsers also do).
                    // falls through
                    case 49 /* _1 */:
                    case 50 /* _2 */:
                    case 51 /* _3 */:
                    case 52 /* _4 */:
                    case 53 /* _5 */:
                    case 54 /* _6 */:
                    case 55 /* _7 */:
                    case 56 /* _8 */:
                    case 57 /* _9 */:
                        (_a = scanNumber(), token = _a.type, tokenValue = _a.value);
                        return token;
                    case 58 /* colon */:
                        pos++;
                        return token = 57 /* ColonToken */;
                    case 59 /* semicolon */:
                        pos++;
                        return token = 26 /* SemicolonToken */;
                    case 60 /* lessThan */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 60 /* lessThan */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 67 /* LessThanLessThanEqualsToken */;
                            }
                            return pos += 2, token = 46 /* LessThanLessThanToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 31 /* LessThanEqualsToken */;
                        }
                        if (languageVariant === 1 /* JSX */ &&
                            text.charCodeAt(pos + 1) === 47 /* slash */ &&
                            text.charCodeAt(pos + 2) !== 42 /* asterisk */) {
                            return pos += 2, token = 29 /* LessThanSlashToken */;
                        }
                        pos++;
                        return token = 28 /* LessThanToken */;
                    case 61 /* equals */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 35 /* EqualsEqualsEqualsToken */;
                            }
                            return pos += 2, token = 33 /* EqualsEqualsToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 62 /* greaterThan */) {
                            return pos += 2, token = 37 /* EqualsGreaterThanToken */;
                        }
                        pos++;
                        return token = 60 /* EqualsToken */;
                    case 62 /* greaterThan */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        pos++;
                        return token = 30 /* GreaterThanToken */;
                    case 63 /* question */:
                        pos++;
                        return token = 56 /* QuestionToken */;
                    case 91 /* openBracket */:
                        pos++;
                        return token = 22 /* OpenBracketToken */;
                    case 93 /* closeBracket */:
                        pos++;
                        return token = 23 /* CloseBracketToken */;
                    case 94 /* caret */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 72 /* CaretEqualsToken */;
                        }
                        pos++;
                        return token = 51 /* CaretToken */;
                    case 123 /* openBrace */:
                        pos++;
                        return token = 18 /* OpenBraceToken */;
                    case 124 /* bar */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 124 /* bar */) {
                            return pos += 2, token = 55 /* BarBarToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 71 /* BarEqualsToken */;
                        }
                        pos++;
                        return token = 50 /* BarToken */;
                    case 125 /* closeBrace */:
                        pos++;
                        return token = 19 /* CloseBraceToken */;
                    case 126 /* tilde */:
                        pos++;
                        return token = 53 /* TildeToken */;
                    case 64 /* at */:
                        pos++;
                        return token = 58 /* AtToken */;
                    case 92 /* backslash */:
                        var cookedChar = peekUnicodeEscape();
                        if (cookedChar >= 0 && isIdentifierStart(cookedChar, languageVersion)) {
                            pos += 6;
                            tokenValue = String.fromCharCode(cookedChar) + scanIdentifierParts();
                            return token = getIdentifierToken();
                        }
                        error(ts.Diagnostics.Invalid_character);
                        pos++;
                        return token = 0 /* Unknown */;
                    default:
                        if (isIdentifierStart(ch, languageVersion)) {
                            pos++;
                            while (pos < end && isIdentifierPart(ch = text.charCodeAt(pos), languageVersion))
                                pos++;
                            tokenValue = text.substring(tokenPos, pos);
                            if (ch === 92 /* backslash */) {
                                tokenValue += scanIdentifierParts();
                            }
                            return token = getIdentifierToken();
                        }
                        else if (isWhiteSpaceSingleLine(ch)) {
                            pos++;
                            continue;
                        }
                        else if (isLineBreak(ch)) {
                            tokenFlags |= 1 /* PrecedingLineBreak */;
                            pos++;
                            continue;
                        }
                        error(ts.Diagnostics.Invalid_character);
                        pos++;
                        return token = 0 /* Unknown */;
                }
            }
        }
        function reScanGreaterToken() {
            if (token === 30 /* GreaterThanToken */) {
                if (text.charCodeAt(pos) === 62 /* greaterThan */) {
                    if (text.charCodeAt(pos + 1) === 62 /* greaterThan */) {
                        if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                            return pos += 3, token = 69 /* GreaterThanGreaterThanGreaterThanEqualsToken */;
                        }
                        return pos += 2, token = 48 /* GreaterThanGreaterThanGreaterThanToken */;
                    }
                    if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                        return pos += 2, token = 68 /* GreaterThanGreaterThanEqualsToken */;
                    }
                    pos++;
                    return token = 47 /* GreaterThanGreaterThanToken */;
                }
                if (text.charCodeAt(pos) === 61 /* equals */) {
                    pos++;
                    return token = 32 /* GreaterThanEqualsToken */;
                }
            }
            return token;
        }
        function reScanSlashToken() {
            if (token === 42 /* SlashToken */ || token === 65 /* SlashEqualsToken */) {
                var p = tokenPos + 1;
                var inEscape = false;
                var inCharacterClass = false;
                while (true) {
                    // If we reach the end of a file, or hit a newline, then this is an unterminated
                    // regex.  Report error and return what we have so far.
                    if (p >= end) {
                        tokenFlags |= 4 /* Unterminated */;
                        error(ts.Diagnostics.Unterminated_regular_expression_literal);
                        break;
                    }
                    var ch = text.charCodeAt(p);
                    if (isLineBreak(ch)) {
                        tokenFlags |= 4 /* Unterminated */;
                        error(ts.Diagnostics.Unterminated_regular_expression_literal);
                        break;
                    }
                    if (inEscape) {
                        // Parsing an escape character;
                        // reset the flag and just advance to the next char.
                        inEscape = false;
                    }
                    else if (ch === 47 /* slash */ && !inCharacterClass) {
                        // A slash within a character class is permissible,
                        // but in general it signals the end of the regexp literal.
                        p++;
                        break;
                    }
                    else if (ch === 91 /* openBracket */) {
                        inCharacterClass = true;
                    }
                    else if (ch === 92 /* backslash */) {
                        inEscape = true;
                    }
                    else if (ch === 93 /* closeBracket */) {
                        inCharacterClass = false;
                    }
                    p++;
                }
                while (p < end && isIdentifierPart(text.charCodeAt(p), languageVersion)) {
                    p++;
                }
                pos = p;
                tokenValue = text.substring(tokenPos, pos);
                token = 13 /* RegularExpressionLiteral */;
            }
            return token;
        }
        /**
         * Unconditionally back up and scan a template expression portion.
         */
        function reScanTemplateToken() {
            ts.Debug.assert(token === 19 /* CloseBraceToken */, "'reScanTemplateToken' should only be called on a '}'");
            pos = tokenPos;
            return token = scanTemplateAndSetTokenValue();
        }
        function reScanJsxToken() {
            pos = tokenPos = startPos;
            return token = scanJsxToken();
        }
        function reScanLessThanToken() {
            if (token === 46 /* LessThanLessThanToken */) {
                pos = tokenPos + 1;
                return token = 28 /* LessThanToken */;
            }
            return token;
        }
        function scanJsxToken() {
            startPos = tokenPos = pos;
            if (pos >= end) {
                return token = 1 /* EndOfFileToken */;
            }
            var char = text.charCodeAt(pos);
            if (char === 60 /* lessThan */) {
                if (text.charCodeAt(pos + 1) === 47 /* slash */) {
                    pos += 2;
                    return token = 29 /* LessThanSlashToken */;
                }
                pos++;
                return token = 28 /* LessThanToken */;
            }
            if (char === 123 /* openBrace */) {
                pos++;
                return token = 18 /* OpenBraceToken */;
            }
            // First non-whitespace character on this line.
            var firstNonWhitespace = 0;
            // These initial values are special because the first line is:
            // firstNonWhitespace = 0 to indicate that we want leading whitspace,
            while (pos < end) {
                char = text.charCodeAt(pos);
                if (char === 123 /* openBrace */) {
                    break;
                }
                if (char === 60 /* lessThan */) {
                    if (isConflictMarkerTrivia(text, pos)) {
                        pos = scanConflictMarkerTrivia(text, pos, error);
                        return token = 7 /* ConflictMarkerTrivia */;
                    }
                    break;
                }
                // FirstNonWhitespace is 0, then we only see whitespaces so far. If we see a linebreak, we want to ignore that whitespaces.
                // i.e (- : whitespace)
                //      <div>----
                //      </div> becomes <div></div>
                //
                //      <div>----</div> becomes <div>----</div>
                if (isLineBreak(char) && firstNonWhitespace === 0) {
                    firstNonWhitespace = -1;
                }
                else if (!isWhiteSpaceLike(char)) {
                    firstNonWhitespace = pos;
                }
                pos++;
            }
            tokenValue = text.substring(startPos, pos);
            return firstNonWhitespace === -1 ? 12 /* JsxTextAllWhiteSpaces */ : 11 /* JsxText */;
        }
        // Scans a JSX identifier; these differ from normal identifiers in that
        // they allow dashes
        function scanJsxIdentifier() {
            if (tokenIsIdentifierOrKeyword(token)) {
                var firstCharPosition = pos;
                while (pos < end) {
                    var ch = text.charCodeAt(pos);
                    if (ch === 45 /* minus */ || ((firstCharPosition === pos) ? isIdentifierStart(ch, languageVersion) : isIdentifierPart(ch, languageVersion))) {
                        pos++;
                    }
                    else {
                        break;
                    }
                }
                tokenValue += text.substring(firstCharPosition, pos);
            }
            return token;
        }
        function scanJsxAttributeValue() {
            startPos = pos;
            switch (text.charCodeAt(pos)) {
                case 34 /* doubleQuote */:
                case 39 /* singleQuote */:
                    tokenValue = scanString(/*jsxAttributeString*/ true);
                    return token = 10 /* StringLiteral */;
                default:
                    // If this scans anything other than `{`, it's a parse error.
                    return scan();
            }
        }
        function scanJsDocToken() {
            startPos = tokenPos = pos;
            tokenFlags = 0;
            if (pos >= end) {
                return token = 1 /* EndOfFileToken */;
            }
            var ch = text.charCodeAt(pos);
            pos++;
            switch (ch) {
                case 9 /* tab */:
                case 11 /* verticalTab */:
                case 12 /* formFeed */:
                case 32 /* space */:
                    while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) {
                        pos++;
                    }
                    return token = 5 /* WhitespaceTrivia */;
                case 64 /* at */:
                    return token = 58 /* AtToken */;
                case 10 /* lineFeed */:
                case 13 /* carriageReturn */:
                    tokenFlags |= 1 /* PrecedingLineBreak */;
                    return token = 4 /* NewLineTrivia */;
                case 42 /* asterisk */:
                    return token = 40 /* AsteriskToken */;
                case 123 /* openBrace */:
                    return token = 18 /* OpenBraceToken */;
                case 125 /* closeBrace */:
                    return token = 19 /* CloseBraceToken */;
                case 91 /* openBracket */:
                    return token = 22 /* OpenBracketToken */;
                case 93 /* closeBracket */:
                    return token = 23 /* CloseBracketToken */;
                case 60 /* lessThan */:
                    return token = 28 /* LessThanToken */;
                case 61 /* equals */:
                    return token = 60 /* EqualsToken */;
                case 44 /* comma */:
                    return token = 27 /* CommaToken */;
                case 46 /* dot */:
                    return token = 24 /* DotToken */;
                case 96 /* backtick */:
                    return token = 59 /* BacktickToken */;
            }
            if (isIdentifierStart(ch, 8 /* Latest */)) {
                while (isIdentifierPart(text.charCodeAt(pos), 8 /* Latest */) && pos < end) {
                    pos++;
                }
                tokenValue = text.substring(tokenPos, pos);
                return token = getIdentifierToken();
            }
            else {
                return token = 0 /* Unknown */;
            }
        }
        function speculationHelper(callback, isLookahead) {
            var savePos = pos;
            var saveStartPos = startPos;
            var saveTokenPos = tokenPos;
            var saveToken = token;
            var saveTokenValue = tokenValue;
            var saveTokenFlags = tokenFlags;
            var result = callback();
            // If our callback returned something 'falsy' or we're just looking ahead,
            // then unconditionally restore us to where we were.
            if (!result || isLookahead) {
                pos = savePos;
                startPos = saveStartPos;
                tokenPos = saveTokenPos;
                token = saveToken;
                tokenValue = saveTokenValue;
                tokenFlags = saveTokenFlags;
            }
            return result;
        }
        function scanRange(start, length, callback) {
            var saveEnd = end;
            var savePos = pos;
            var saveStartPos = startPos;
            var saveTokenPos = tokenPos;
            var saveToken = token;
            var saveTokenValue = tokenValue;
            var saveTokenFlags = tokenFlags;
            setText(text, start, length);
            var result = callback();
            end = saveEnd;
            pos = savePos;
            startPos = saveStartPos;
            tokenPos = saveTokenPos;
            token = saveToken;
            tokenValue = saveTokenValue;
            tokenFlags = saveTokenFlags;
            return result;
        }
        function lookAhead(callback) {
            return speculationHelper(callback, /*isLookahead*/ true);
        }
        function tryScan(callback) {
            return speculationHelper(callback, /*isLookahead*/ false);
        }
        function getText() {
            return text;
        }
        function setText(newText, start, length) {
            text = newText || "";
            end = length === undefined ? text.length : start + length;
            setTextPos(start || 0);
        }
        function setOnError(errorCallback) {
            onError = errorCallback;
        }
        function setScriptTarget(scriptTarget) {
            languageVersion = scriptTarget;
        }
        function setLanguageVariant(variant) {
            languageVariant = variant;
        }
        function setTextPos(textPos) {
            ts.Debug.assert(textPos >= 0);
            pos = textPos;
            startPos = textPos;
            tokenPos = textPos;
            token = 0 /* Unknown */;
            tokenValue = undefined;
            tokenFlags = 0;
        }
        function setInJSDocType(inType) {
            inJSDocType += inType ? 1 : -1;
        }
    }
    ts.createScanner = createScanner;
})(ts || (ts = {}));
var ts;
(function (ts) {
    function isExternalModuleNameRelative(moduleName) {
        // TypeScript 1.0 spec (April 2014): 11.2.1
        // An external module name is "relative" if the first term is "." or "..".
        // Update: We also consider a path like `C:\foo.ts` "relative" because we do not search for it in `node_modules` or treat it as an ambient module.
        return ts.pathIsRelative(moduleName) || ts.isRootedDiskPath(moduleName);
    }
    ts.isExternalModuleNameRelative = isExternalModuleNameRelative;
    function sortAndDeduplicateDiagnostics(diagnostics) {
        return ts.sortAndDeduplicate(diagnostics, ts.compareDiagnostics);
    }
    ts.sortAndDeduplicateDiagnostics = sortAndDeduplicateDiagnostics;
})(ts || (ts = {}));
/* @internal */
(function (ts) {
    ts.resolvingEmptyArray = [];
    ts.emptyMap = ts.createMap();
    ts.emptyUnderscoreEscapedMap = ts.emptyMap;
    ts.externalHelpersModuleNameText = "tslib";
    ts.defaultMaximumTruncationLength = 160;
    function getDeclarationOfKind(symbol, kind) {
        var declarations = symbol.declarations;
        if (declarations) {
            for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) {
                var declaration = declarations_1[_i];
                if (declaration.kind === kind) {
                    return declaration;
                }
            }
        }
        return undefined;
    }
    ts.getDeclarationOfKind = getDeclarationOfKind;
    /** Create a new escaped identifier map. */
    function createUnderscoreEscapedMap() {
        return new ts.MapCtr();
    }
    ts.createUnderscoreEscapedMap = createUnderscoreEscapedMap;
    function hasEntries(map) {
        return !!map && !!map.size;
    }
    ts.hasEntries = hasEntries;
    function createSymbolTable(symbols) {
        var result = ts.createMap();
        if (symbols) {
            for (var _i = 0, symbols_1 = symbols; _i < symbols_1.length; _i++) {
                var symbol = symbols_1[_i];
                result.set(symbol.escapedName, symbol);
            }
        }
        return result;
    }
    ts.createSymbolTable = createSymbolTable;
    var stringWriter = createSingleLineStringWriter();
    function createSingleLineStringWriter() {
        var str = "";
        var writeText = function (text) { return str += text; };
        return {
            getText: function () { return str; },
            write: writeText,
            rawWrite: writeText,
            writeKeyword: writeText,
            writeOperator: writeText,
            writePunctuation: writeText,
            writeSpace: writeText,
            writeStringLiteral: writeText,
            writeLiteral: writeText,
            writeParameter: writeText,
            writeProperty: writeText,
            writeSymbol: function (s, _) { return writeText(s); },
            writeTrailingSemicolon: writeText,
            writeComment: writeText,
            getTextPos: function () { return str.length; },
            getLine: function () { return 0; },
            getColumn: function () { return 0; },
            getIndent: function () { return 0; },
            isAtStartOfLine: function () { return false; },
            // Completely ignore indentation for string writers.  And map newlines to
            // a single space.
            writeLine: function () { return str += " "; },
            increaseIndent: ts.noop,
            decreaseIndent: ts.noop,
            clear: function () { return str = ""; },
            trackSymbol: ts.noop,
            reportInaccessibleThisError: ts.noop,
            reportInaccessibleUniqueSymbolError: ts.noop,
            reportPrivateInBaseOfClassExpression: ts.noop,
        };
    }
    function toPath(fileName, basePath, getCanonicalFileName) {
        var nonCanonicalizedPath = ts.isRootedDiskPath(fileName)
            ? ts.normalizePath(fileName)
            : ts.getNormalizedAbsolutePath(fileName, basePath);
        return getCanonicalFileName(nonCanonicalizedPath);
    }
    ts.toPath = toPath;
    function changesAffectModuleResolution(oldOptions, newOptions) {
        return oldOptions.configFilePath !== newOptions.configFilePath ||
            optionsHaveModuleResolutionChanges(oldOptions, newOptions);
    }
    ts.changesAffectModuleResolution = changesAffectModuleResolution;
    function optionsHaveModuleResolutionChanges(oldOptions, newOptions) {
        return ts.moduleResolutionOptionDeclarations.some(function (o) {
            return !ts.isJsonEqual(ts.getCompilerOptionValue(oldOptions, o), ts.getCompilerOptionValue(newOptions, o));
        });
    }
    ts.optionsHaveModuleResolutionChanges = optionsHaveModuleResolutionChanges;
    function findAncestor(node, callback) {
        while (node) {
            var result = callback(node);
            if (result === "quit") {
                return undefined;
            }
            else if (result) {
                return node;
            }
            node = node.parent;
        }
        return undefined;
    }
    ts.findAncestor = findAncestor;
    function forEachAncestor(node, callback) {
        while (true) {
            var res = callback(node);
            if (res === "quit")
                return undefined;
            if (res !== undefined)
                return res;
            if (ts.isSourceFile(node))
                return undefined;
            node = node.parent;
        }
    }
    ts.forEachAncestor = forEachAncestor;
    function forEachEntry(map, callback) {
        var _a;
        var iterator = map.entries();
        for (var _b = iterator.next(), pair = _b.value, done = _b.done; !done; _a = iterator.next(), pair = _a.value, done = _a.done, _a) {
            var key = pair[0], value = pair[1];
            var result = callback(value, key);
            if (result) {
                return result;
            }
        }
        return undefined;
    }
    ts.forEachEntry = forEachEntry;
    function forEachKey(map, callback) {
        var _a;
        var iterator = map.keys();
        for (var _b = iterator.next(), key = _b.value, done = _b.done; !done; _a = iterator.next(), key = _a.value, done = _a.done, _a) {
            var result = callback(key);
            if (result) {
                return result;
            }
        }
        return undefined;
    }
    ts.forEachKey = forEachKey;
    function copyEntries(source, target) {
        source.forEach(function (value, key) {
            target.set(key, value);
        });
    }
    ts.copyEntries = copyEntries;
    function arrayToSet(array, makeKey) {
        return ts.arrayToMap(array, makeKey || (function (s) { return s; }), function () { return true; });
    }
    ts.arrayToSet = arrayToSet;
    function cloneMap(map) {
        var clone = ts.createMap();
        copyEntries(map, clone);
        return clone;
    }
    ts.cloneMap = cloneMap;
    function usingSingleLineStringWriter(action) {
        var oldString = stringWriter.getText();
        try {
            action(stringWriter);
            return stringWriter.getText();
        }
        finally {
            stringWriter.clear();
            stringWriter.writeKeyword(oldString);
        }
    }
    ts.usingSingleLineStringWriter = usingSingleLineStringWriter;
    function getFullWidth(node) {
        return node.end - node.pos;
    }
    ts.getFullWidth = getFullWidth;
    function getResolvedModule(sourceFile, moduleNameText) {
        return sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules.get(moduleNameText);
    }
    ts.getResolvedModule = getResolvedModule;
    function setResolvedModule(sourceFile, moduleNameText, resolvedModule) {
        if (!sourceFile.resolvedModules) {
            sourceFile.resolvedModules = ts.createMap();
        }
        sourceFile.resolvedModules.set(moduleNameText, resolvedModule);
    }
    ts.setResolvedModule = setResolvedModule;
    function setResolvedTypeReferenceDirective(sourceFile, typeReferenceDirectiveName, resolvedTypeReferenceDirective) {
        if (!sourceFile.resolvedTypeReferenceDirectiveNames) {
            sourceFile.resolvedTypeReferenceDirectiveNames = ts.createMap();
        }
        sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, resolvedTypeReferenceDirective);
    }
    ts.setResolvedTypeReferenceDirective = setResolvedTypeReferenceDirective;
    function projectReferenceIsEqualTo(oldRef, newRef) {
        return oldRef.path === newRef.path &&
            !oldRef.prepend === !newRef.prepend &&
            !oldRef.circular === !newRef.circular;
    }
    ts.projectReferenceIsEqualTo = projectReferenceIsEqualTo;
    function moduleResolutionIsEqualTo(oldResolution, newResolution) {
        return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport &&
            oldResolution.extension === newResolution.extension &&
            oldResolution.resolvedFileName === newResolution.resolvedFileName &&
            oldResolution.originalPath === newResolution.originalPath &&
            packageIdIsEqual(oldResolution.packageId, newResolution.packageId);
    }
    ts.moduleResolutionIsEqualTo = moduleResolutionIsEqualTo;
    function packageIdIsEqual(a, b) {
        return a === b || !!a && !!b && a.name === b.name && a.subModuleName === b.subModuleName && a.version === b.version;
    }
    function packageIdToString(_a) {
        var name = _a.name, subModuleName = _a.subModuleName, version = _a.version;
        var fullName = subModuleName ? name + "/" + subModuleName : name;
        return fullName + "@" + version;
    }
    ts.packageIdToString = packageIdToString;
    function typeDirectiveIsEqualTo(oldResolution, newResolution) {
        return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary;
    }
    ts.typeDirectiveIsEqualTo = typeDirectiveIsEqualTo;
    function hasChangesInResolutions(names, newResolutions, oldResolutions, comparer) {
        ts.Debug.assert(names.length === newResolutions.length);
        for (var i = 0; i < names.length; i++) {
            var newResolution = newResolutions[i];
            var oldResolution = oldResolutions && oldResolutions.get(names[i]);
            var changed = oldResolution
                ? !newResolution || !comparer(oldResolution, newResolution)
                : newResolution;
            if (changed) {
                return true;
            }
        }
        return false;
    }
    ts.hasChangesInResolutions = hasChangesInResolutions;
    // Returns true if this node contains a parse error anywhere underneath it.
    function containsParseError(node) {
        aggregateChildData(node);
        return (node.flags & 131072 /* ThisNodeOrAnySubNodesHasError */) !== 0;
    }
    ts.containsParseError = containsParseError;
    function aggregateChildData(node) {
        if (!(node.flags & 262144 /* HasAggregatedChildData */)) {
            // A node is considered to contain a parse error if:
            //  a) the parser explicitly marked that it had an error
            //  b) any of it's children reported that it had an error.
            var thisNodeOrAnySubNodesHasError = ((node.flags & 32768 /* ThisNodeHasError */) !== 0) ||
                ts.forEachChild(node, containsParseError);
            // If so, mark ourselves accordingly.
            if (thisNodeOrAnySubNodesHasError) {
                node.flags |= 131072 /* ThisNodeOrAnySubNodesHasError */;
            }
            // Also mark that we've propagated the child information to this node.  This way we can
            // always consult the bit directly on this node without needing to check its children
            // again.
            node.flags |= 262144 /* HasAggregatedChildData */;
        }
    }
    function getSourceFileOfNode(node) {
        while (node && node.kind !== 285 /* SourceFile */) {
            node = node.parent;
        }
        return node;
    }
    ts.getSourceFileOfNode = getSourceFileOfNode;
    function isStatementWithLocals(node) {
        switch (node.kind) {
            case 219 /* Block */:
            case 247 /* CaseBlock */:
            case 226 /* ForStatement */:
            case 227 /* ForInStatement */:
            case 228 /* ForOfStatement */:
                return true;
        }
        return false;
    }
    ts.isStatementWithLocals = isStatementWithLocals;
    function getStartPositionOfLine(line, sourceFile) {
        ts.Debug.assert(line >= 0);
        return ts.getLineStarts(sourceFile)[line];
    }
    ts.getStartPositionOfLine = getStartPositionOfLine;
    // This is a useful function for debugging purposes.
    function nodePosToString(node) {
        var file = getSourceFileOfNode(node);
        var loc = ts.getLineAndCharacterOfPosition(file, node.pos);
        return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")";
    }
    ts.nodePosToString = nodePosToString;
    function getEndLinePosition(line, sourceFile) {
        ts.Debug.assert(line >= 0);
        var lineStarts = ts.getLineStarts(sourceFile);
        var lineIndex = line;
        var sourceText = sourceFile.text;
        if (lineIndex + 1 === lineStarts.length) {
            // last line - return EOF
            return sourceText.length - 1;
        }
        else {
            // current line start
            var start = lineStarts[lineIndex];
            // take the start position of the next line - 1 = it should be some line break
            var pos = lineStarts[lineIndex + 1] - 1;
            ts.Debug.assert(ts.isLineBreak(sourceText.charCodeAt(pos)));
            // walk backwards skipping line breaks, stop the the beginning of current line.
            // i.e:
            // <some text>
            // $ <- end of line for this position should match the start position
            while (start <= pos && ts.isLineBreak(sourceText.charCodeAt(pos))) {
                pos--;
            }
            return pos;
        }
    }
    ts.getEndLinePosition = getEndLinePosition;
    /**
     * Returns a value indicating whether a name is unique globally or within the current file.
     * Note: This does not consider whether a name appears as a free identifier or not, so at the expression `x.y` this includes both `x` and `y`.
     */
    function isFileLevelUniqueName(sourceFile, name, hasGlobalName) {
        return !(hasGlobalName && hasGlobalName(name)) && !sourceFile.identifiers.has(name);
    }
    ts.isFileLevelUniqueName = isFileLevelUniqueName;
    // Returns true if this node is missing from the actual source code. A 'missing' node is different
    // from 'undefined/defined'. When a node is undefined (which can happen for optional nodes
    // in the tree), it is definitely missing. However, a node may be defined, but still be
    // missing.  This happens whenever the parser knows it needs to parse something, but can't
    // get anything in the source code that it expects at that location. For example:
    //
    //          let a: ;
    //
    // Here, the Type in the Type-Annotation is not-optional (as there is a colon in the source
    // code). So the parser will attempt to parse out a type, and will create an actual node.
    // However, this node will be 'missing' in the sense that no actual source-code/tokens are
    // contained within it.
    function nodeIsMissing(node) {
        if (node === undefined) {
            return true;
        }
        return node.pos === node.end && node.pos >= 0 && node.kind !== 1 /* EndOfFileToken */;
    }
    ts.nodeIsMissing = nodeIsMissing;
    function nodeIsPresent(node) {
        return !nodeIsMissing(node);
    }
    ts.nodeIsPresent = nodeIsPresent;
    function insertStatementsAfterPrologue(to, from, isPrologueDirective) {
        if (from === undefined || from.length === 0)
            return to;
        var statementIndex = 0;
        // skip all prologue directives to insert at the correct position
        for (; statementIndex < to.length; ++statementIndex) {
            if (!isPrologueDirective(to[statementIndex])) {
                break;
            }
        }
        to.splice.apply(to, [statementIndex, 0].concat(from));
        return to;
    }
    function insertStatementAfterPrologue(to, statement, isPrologueDirective) {
        if (statement === undefined)
            return to;
        var statementIndex = 0;
        // skip all prologue directives to insert at the correct position
        for (; statementIndex < to.length; ++statementIndex) {
            if (!isPrologueDirective(to[statementIndex])) {
                break;
            }
        }
        to.splice(statementIndex, 0, statement);
        return to;
    }
    function isAnyPrologueDirective(node) {
        return isPrologueDirective(node) || !!(getEmitFlags(node) & 1048576 /* CustomPrologue */);
    }
    /**
     * Prepends statements to an array while taking care of prologue directives.
     */
    function insertStatementsAfterStandardPrologue(to, from) {
        return insertStatementsAfterPrologue(to, from, isPrologueDirective);
    }
    ts.insertStatementsAfterStandardPrologue = insertStatementsAfterStandardPrologue;
    function insertStatementsAfterCustomPrologue(to, from) {
        return insertStatementsAfterPrologue(to, from, isAnyPrologueDirective);
    }
    ts.insertStatementsAfterCustomPrologue = insertStatementsAfterCustomPrologue;
    /**
     * Prepends statements to an array while taking care of prologue directives.
     */
    function insertStatementAfterStandardPrologue(to, statement) {
        return insertStatementAfterPrologue(to, statement, isPrologueDirective);
    }
    ts.insertStatementAfterStandardPrologue = insertStatementAfterStandardPrologue;
    function insertStatementAfterCustomPrologue(to, statement) {
        return insertStatementAfterPrologue(to, statement, isAnyPrologueDirective);
    }
    ts.insertStatementAfterCustomPrologue = insertStatementAfterCustomPrologue;
    /**
     * Determine if the given comment is a triple-slash
     *
     * @return true if the comment is a triple-slash comment else false
     */
    function isRecognizedTripleSlashComment(text, commentPos, commentEnd) {
        // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text
        // so that we don't end up computing comment string and doing match for all // comments
        if (text.charCodeAt(commentPos + 1) === 47 /* slash */ &&
            commentPos + 2 < commentEnd &&
            text.charCodeAt(commentPos + 2) === 47 /* slash */) {
            var textSubStr = text.substring(commentPos, commentEnd);
            return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) ||
                textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) ||
                textSubStr.match(fullTripleSlashReferenceTypeReferenceDirectiveRegEx) ||
                textSubStr.match(defaultLibReferenceRegEx) ?
                true : false;
        }
        return false;
    }
    ts.isRecognizedTripleSlashComment = isRecognizedTripleSlashComment;
    function isPinnedComment(text, start) {
        return text.charCodeAt(start + 1) === 42 /* asterisk */ &&
            text.charCodeAt(start + 2) === 33 /* exclamation */;
    }
    ts.isPinnedComment = isPinnedComment;
    function getTokenPosOfNode(node, sourceFile, includeJsDoc) {
        // With nodes that have no width (i.e. 'Missing' nodes), we actually *don't*
        // want to skip trivia because this will launch us forward to the next token.
        if (nodeIsMissing(node)) {
            return node.pos;
        }
        if (ts.isJSDocNode(node)) {
            return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
        }
        if (includeJsDoc && ts.hasJSDocNodes(node)) {
            return getTokenPosOfNode(node.jsDoc[0]);
        }
        // For a syntax list, it is possible that one of its children has JSDocComment nodes, while
        // the syntax list itself considers them as normal trivia. Therefore if we simply skip
        // trivia for the list, we may have skipped the JSDocComment as well. So we should process its
        // first child to determine the actual position of its first token.
        if (node.kind === 312 /* SyntaxList */ && node._children.length > 0) {
            return getTokenPosOfNode(node._children[0], sourceFile, includeJsDoc);
        }
        return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
    }
    ts.getTokenPosOfNode = getTokenPosOfNode;
    function getNonDecoratorTokenPosOfNode(node, sourceFile) {
        if (nodeIsMissing(node) || !node.decorators) {
            return getTokenPosOfNode(node, sourceFile);
        }
        return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.decorators.end);
    }
    ts.getNonDecoratorTokenPosOfNode = getNonDecoratorTokenPosOfNode;
    function getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia) {
        if (includeTrivia === void 0) { includeTrivia = false; }
        return getTextOfNodeFromSourceText(sourceFile.text, node, includeTrivia);
    }
    ts.getSourceTextOfNodeFromSourceFile = getSourceTextOfNodeFromSourceFile;
    function isJSDocTypeExpressionOrChild(node) {
        return node.kind === 289 /* JSDocTypeExpression */ || (node.parent && isJSDocTypeExpressionOrChild(node.parent));
    }
    function getTextOfNodeFromSourceText(sourceText, node, includeTrivia) {
        if (includeTrivia === void 0) { includeTrivia = false; }
        if (nodeIsMissing(node)) {
            return "";
        }
        var text = sourceText.substring(includeTrivia ? node.pos : ts.skipTrivia(sourceText, node.pos), node.end);
        if (isJSDocTypeExpressionOrChild(node)) {
            // strip space + asterisk at line start
            text = text.replace(/(^|\r?\n|\r)\s*\*\s*/g, "$1");
        }
        return text;
    }
    ts.getTextOfNodeFromSourceText = getTextOfNodeFromSourceText;
    function getTextOfNode(node, includeTrivia) {
        if (includeTrivia === void 0) { includeTrivia = false; }
        return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia);
    }
    ts.getTextOfNode = getTextOfNode;
    function getPos(range) {
        return range.pos;
    }
    /**
     * Note: it is expected that the `nodeArray` and the `node` are within the same file.
     * For example, searching for a `SourceFile` in a `SourceFile[]` wouldn't work.
     */
    function indexOfNode(nodeArray, node) {
        return ts.binarySearch(nodeArray, node, getPos, ts.compareValues);
    }
    ts.indexOfNode = indexOfNode;
    /**
     * Gets flags that control emit behavior of a node.
     */
    function getEmitFlags(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.flags || 0;
    }
    ts.getEmitFlags = getEmitFlags;
    function getLiteralText(node, sourceFile, neverAsciiEscape) {
        // If we don't need to downlevel and we can reach the original source text using
        // the node's parent reference, then simply get the text as it was originally written.
        if (!nodeIsSynthesized(node) && node.parent && !((ts.isNumericLiteral(node) && node.numericLiteralFlags & 512 /* ContainsSeparator */) ||
            ts.isBigIntLiteral(node))) {
            return getSourceTextOfNodeFromSourceFile(sourceFile, node);
        }
        var escapeText = neverAsciiEscape || (getEmitFlags(node) & 16777216 /* NoAsciiEscaping */) ? escapeString : escapeNonAsciiString;
        // If we can't reach the original source text, use the canonical form if it's a number,
        // or a (possibly escaped) quoted form of the original text if it's string-like.
        switch (node.kind) {
            case 10 /* StringLiteral */:
                if (node.singleQuote) {
                    return "'" + escapeText(node.text, 39 /* singleQuote */) + "'";
                }
                else {
                    return '"' + escapeText(node.text, 34 /* doubleQuote */) + '"';
                }
            case 14 /* NoSubstitutionTemplateLiteral */:
                return "`" + escapeText(node.text, 96 /* backtick */) + "`";
            case 15 /* TemplateHead */:
                // tslint:disable-next-line no-invalid-template-strings
                return "`" + escapeText(node.text, 96 /* backtick */) + "${";
            case 16 /* TemplateMiddle */:
                // tslint:disable-next-line no-invalid-template-strings
                return "}" + escapeText(node.text, 96 /* backtick */) + "${";
            case 17 /* TemplateTail */:
                return "}" + escapeText(node.text, 96 /* backtick */) + "`";
            case 8 /* NumericLiteral */:
            case 9 /* BigIntLiteral */:
            case 13 /* RegularExpressionLiteral */:
                return node.text;
        }
        return ts.Debug.fail("Literal kind '" + node.kind + "' not accounted for.");
    }
    ts.getLiteralText = getLiteralText;
    function getTextOfConstantValue(value) {
        return ts.isString(value) ? '"' + escapeNonAsciiString(value) + '"' : "" + value;
    }
    ts.getTextOfConstantValue = getTextOfConstantValue;
    // Make an identifier from an external module name by extracting the string after the last "/" and replacing
    // all non-alphanumeric characters with underscores
    function makeIdentifierFromModuleName(moduleName) {
        return ts.getBaseFileName(moduleName).replace(/^(\d)/, "_$1").replace(/\W/g, "_");
    }
    ts.makeIdentifierFromModuleName = makeIdentifierFromModuleName;
    function isBlockOrCatchScoped(declaration) {
        return (ts.getCombinedNodeFlags(declaration) & 3 /* BlockScoped */) !== 0 ||
            isCatchClauseVariableDeclarationOrBindingElement(declaration);
    }
    ts.isBlockOrCatchScoped = isBlockOrCatchScoped;
    function isCatchClauseVariableDeclarationOrBindingElement(declaration) {
        var node = getRootDeclaration(declaration);
        return node.kind === 238 /* VariableDeclaration */ && node.parent.kind === 275 /* CatchClause */;
    }
    ts.isCatchClauseVariableDeclarationOrBindingElement = isCatchClauseVariableDeclarationOrBindingElement;
    function isAmbientModule(node) {
        return ts.isModuleDeclaration(node) && (node.name.kind === 10 /* StringLiteral */ || isGlobalScopeAugmentation(node));
    }
    ts.isAmbientModule = isAmbientModule;
    function isModuleWithStringLiteralName(node) {
        return ts.isModuleDeclaration(node) && node.name.kind === 10 /* StringLiteral */;
    }
    ts.isModuleWithStringLiteralName = isModuleWithStringLiteralName;
    function isNonGlobalAmbientModule(node) {
        return ts.isModuleDeclaration(node) && ts.isStringLiteral(node.name);
    }
    ts.isNonGlobalAmbientModule = isNonGlobalAmbientModule;
    /**
     * An effective module (namespace) declaration is either
     * 1. An actual declaration: namespace X { ... }
     * 2. A Javascript declaration, which is:
     *    An identifier in a nested property access expression: Y in `X.Y.Z = { ... }`
     */
    function isEffectiveModuleDeclaration(node) {
        return ts.isModuleDeclaration(node) || ts.isIdentifier(node);
    }
    ts.isEffectiveModuleDeclaration = isEffectiveModuleDeclaration;
    /** Given a symbol for a module, checks that it is a shorthand ambient module. */
    function isShorthandAmbientModuleSymbol(moduleSymbol) {
        return isShorthandAmbientModule(moduleSymbol.valueDeclaration);
    }
    ts.isShorthandAmbientModuleSymbol = isShorthandAmbientModuleSymbol;
    function isShorthandAmbientModule(node) {
        // The only kind of module that can be missing a body is a shorthand ambient module.
        return node && node.kind === 245 /* ModuleDeclaration */ && (!node.body);
    }
    function isBlockScopedContainerTopLevel(node) {
        return node.kind === 285 /* SourceFile */ ||
            node.kind === 245 /* ModuleDeclaration */ ||
            ts.isFunctionLike(node);
    }
    ts.isBlockScopedContainerTopLevel = isBlockScopedContainerTopLevel;
    function isGlobalScopeAugmentation(module) {
        return !!(module.flags & 512 /* GlobalAugmentation */);
    }
    ts.isGlobalScopeAugmentation = isGlobalScopeAugmentation;
    function isExternalModuleAugmentation(node) {
        return isAmbientModule(node) && isModuleAugmentationExternal(node);
    }
    ts.isExternalModuleAugmentation = isExternalModuleAugmentation;
    function isModuleAugmentationExternal(node) {
        // external module augmentation is a ambient module declaration that is either:
        // - defined in the top level scope and source file is an external module
        // - defined inside ambient module declaration located in the top level scope and source file not an external module
        switch (node.parent.kind) {
            case 285 /* SourceFile */:
                return ts.isExternalModule(node.parent);
            case 246 /* ModuleBlock */:
                return isAmbientModule(node.parent.parent) && ts.isSourceFile(node.parent.parent.parent) && !ts.isExternalModule(node.parent.parent.parent);
        }
        return false;
    }
    ts.isModuleAugmentationExternal = isModuleAugmentationExternal;
    function getNonAugmentationDeclaration(symbol) {
        return ts.find(symbol.declarations, function (d) { return !isExternalModuleAugmentation(d) && !(ts.isModuleDeclaration(d) && isGlobalScopeAugmentation(d)); });
    }
    ts.getNonAugmentationDeclaration = getNonAugmentationDeclaration;
    function isEffectiveExternalModule(node, compilerOptions) {
        return ts.isExternalModule(node) || compilerOptions.isolatedModules || ((ts.getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS) && !!node.commonJsModuleIndicator);
    }
    ts.isEffectiveExternalModule = isEffectiveExternalModule;
    function isBlockScope(node, parentNode) {
        switch (node.kind) {
            case 285 /* SourceFile */:
            case 247 /* CaseBlock */:
            case 275 /* CatchClause */:
            case 245 /* ModuleDeclaration */:
            case 226 /* ForStatement */:
            case 227 /* ForInStatement */:
            case 228 /* ForOfStatement */:
            case 158 /* Constructor */:
            case 157 /* MethodDeclaration */:
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
            case 240 /* FunctionDeclaration */:
            case 197 /* FunctionExpression */:
            case 198 /* ArrowFunction */:
                return true;
            case 219 /* Block */:
                // function block is not considered block-scope container
                // see comment in binder.ts: bind(...), case for SyntaxKind.Block
                return !ts.isFunctionLike(parentNode);
        }
        return false;
    }
    ts.isBlockScope = isBlockScope;
    function isDeclarationWithTypeParameters(node) {
        switch (node.kind) {
            case 303 /* JSDocCallbackTag */:
            case 310 /* JSDocTypedefTag */:
            case 299 /* JSDocSignature */:
                return true;
            default:
                ts.assertType(node);
                return isDeclarationWithTypeParameterChildren(node);
        }
    }
    ts.isDeclarationWithTypeParameters = isDeclarationWithTypeParameters;
    function isDeclarationWithTypeParameterChildren(node) {
        switch (node.kind) {
            case 161 /* CallSignature */:
            case 162 /* ConstructSignature */:
            case 156 /* MethodSignature */:
            case 163 /* IndexSignature */:
            case 166 /* FunctionType */:
            case 167 /* ConstructorType */:
            case 295 /* JSDocFunctionType */:
            case 241 /* ClassDeclaration */:
            case 210 /* ClassExpression */:
            case 242 /* InterfaceDeclaration */:
            case 243 /* TypeAliasDeclaration */:
            case 309 /* JSDocTemplateTag */:
            case 240 /* FunctionDeclaration */:
            case 157 /* MethodDeclaration */:
            case 158 /* Constructor */:
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
            case 197 /* FunctionExpression */:
            case 198 /* ArrowFunction */:
                return true;
            default:
                ts.assertType(node);
                return false;
        }
    }
    ts.isDeclarationWithTypeParameterChildren = isDeclarationWithTypeParameterChildren;
    function isAnyImportSyntax(node) {
        switch (node.kind) {
            case 250 /* ImportDeclaration */:
            case 249 /* ImportEqualsDeclaration */:
                return true;
            default:
                return false;
        }
    }
    ts.isAnyImportSyntax = isAnyImportSyntax;
    function isLateVisibilityPaintedStatement(node) {
        switch (node.kind) {
            case 250 /* ImportDeclaration */:
            case 249 /* ImportEqualsDeclaration */:
            case 220 /* VariableStatement */:
            case 241 /* ClassDeclaration */:
            case 240 /* FunctionDeclaration */:
            case 245 /* ModuleDeclaration */:
            case 243 /* TypeAliasDeclaration */:
            case 242 /* InterfaceDeclaration */:
            case 244 /* EnumDeclaration */:
                return true;
            default:
                return false;
        }
    }
    ts.isLateVisibilityPaintedStatement = isLateVisibilityPaintedStatement;
    function isAnyImportOrReExport(node) {
        return isAnyImportSyntax(node) || ts.isExportDeclaration(node);
    }
    ts.isAnyImportOrReExport = isAnyImportOrReExport;
    // Gets the nearest enclosing block scope container that has the provided node
    // as a descendant, that is not the provided node.
    function getEnclosingBlockScopeContainer(node) {
        return findAncestor(node.parent, function (current) { return isBlockScope(current, current.parent); });
    }
    ts.getEnclosingBlockScopeContainer = getEnclosingBlockScopeContainer;
    // Return display name of an identifier
    // Computed property names will just be emitted as "[<expr>]", where <expr> is the source
    // text of the expression in the computed property.
    function declarationNameToString(name) {
        return !name || getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name);
    }
    ts.declarationNameToString = declarationNameToString;
    function getNameFromIndexInfo(info) {
        return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : undefined;
    }
    ts.getNameFromIndexInfo = getNameFromIndexInfo;
    function getTextOfPropertyName(name) {
        switch (name.kind) {
            case 73 /* Identifier */:
                return name.escapedText;
            case 10 /* StringLiteral */:
            case 8 /* NumericLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
                return ts.escapeLeadingUnderscores(name.text);
            case 150 /* ComputedPropertyName */:
                if (isStringOrNumericLiteralLike(name.expression))
                    return ts.escapeLeadingUnderscores(name.expression.text);
                return ts.Debug.fail("Text of property name cannot be read from non-literal-valued ComputedPropertyNames");
            default:
                return ts.Debug.assertNever(name);
        }
    }
    ts.getTextOfPropertyName = getTextOfPropertyName;
    function entityNameToString(name) {
        switch (name.kind) {
            case 73 /* Identifier */:
                return getFullWidth(name) === 0 ? ts.idText(name) : getTextOfNode(name);
            case 149 /* QualifiedName */:
                return entityNameToString(name.left) + "." + entityNameToString(name.right);
            case 190 /* PropertyAccessExpression */:
                return entityNameToString(name.expression) + "." + entityNameToString(name.name);
            default:
                throw ts.Debug.assertNever(name);
        }
    }
    ts.entityNameToString = entityNameToString;
    function createDiagnosticForNode(node, message, arg0, arg1, arg2, arg3) {
        var sourceFile = getSourceFileOfNode(node);
        return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3);
    }
    ts.createDiagnosticForNode = createDiagnosticForNode;
    function createDiagnosticForNodeArray(sourceFile, nodes, message, arg0, arg1, arg2, arg3) {
        var start = ts.skipTrivia(sourceFile.text, nodes.pos);
        return ts.createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2, arg3);
    }
    ts.createDiagnosticForNodeArray = createDiagnosticForNodeArray;
    function createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3) {
        var span = getErrorSpanForNode(sourceFile, node);
        return ts.createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2, arg3);
    }
    ts.createDiagnosticForNodeInSourceFile = createDiagnosticForNodeInSourceFile;
    function createDiagnosticForNodeFromMessageChain(node, messageChain, relatedInformation) {
        var sourceFile = getSourceFileOfNode(node);
        var span = getErrorSpanForNode(sourceFile, node);
        return {
            file: sourceFile,
            start: span.start,
            length: span.length,
            code: messageChain.code,
            category: messageChain.category,
            messageText: messageChain.next ? messageChain : messageChain.messageText,
            relatedInformation: relatedInformation
        };
    }
    ts.createDiagnosticForNodeFromMessageChain = createDiagnosticForNodeFromMessageChain;
    function getSpanOfTokenAtPosition(sourceFile, pos) {
        var scanner = ts.createScanner(sourceFile.languageVersion, /*skipTrivia*/ true, sourceFile.languageVariant, sourceFile.text, /*onError:*/ undefined, pos);
        scanner.scan();
        var start = scanner.getTokenPos();
        return ts.createTextSpanFromBounds(start, scanner.getTextPos());
    }
    ts.getSpanOfTokenAtPosition = getSpanOfTokenAtPosition;
    function getErrorSpanForArrowFunction(sourceFile, node) {
        var pos = ts.skipTrivia(sourceFile.text, node.pos);
        if (node.body && node.body.kind === 219 /* Block */) {
            var startLine = ts.getLineAndCharacterOfPosition(sourceFile, node.body.pos).line;
            var endLine = ts.getLineAndCharacterOfPosition(sourceFile, node.body.end).line;
            if (startLine < endLine) {
                // The arrow function spans multiple lines,
                // make the error span be the first line, inclusive.
                return ts.createTextSpan(pos, getEndLinePosition(startLine, sourceFile) - pos + 1);
            }
        }
        return ts.createTextSpanFromBounds(pos, node.end);
    }
    function getErrorSpanForNode(sourceFile, node) {
        var errorNode = node;
        switch (node.kind) {
            case 285 /* SourceFile */:
                var pos_1 = ts.skipTrivia(sourceFile.text, 0, /*stopAfterLineBreak*/ false);
                if (pos_1 === sourceFile.text.length) {
                    // file is empty - return span for the beginning of the file
                    return ts.createTextSpan(0, 0);
                }
                return getSpanOfTokenAtPosition(sourceFile, pos_1);
            // This list is a work in progress. Add missing node kinds to improve their error
            // spans.
            case 238 /* VariableDeclaration */:
            case 187 /* BindingElement */:
            case 241 /* ClassDeclaration */:
            case 210 /* ClassExpression */:
            case 242 /* InterfaceDeclaration */:
            case 245 /* ModuleDeclaration */:
            case 244 /* EnumDeclaration */:
            case 279 /* EnumMember */:
            case 240 /* FunctionDeclaration */:
            case 197 /* FunctionExpression */:
            case 157 /* MethodDeclaration */:
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
            case 243 /* TypeAliasDeclaration */:
            case 155 /* PropertyDeclaration */:
            case 154 /* PropertySignature */:
                errorNode = node.name;
                break;
            case 198 /* ArrowFunction */:
                return getErrorSpanForArrowFunction(sourceFile, node);
        }
        if (errorNode === undefined) {
            // If we don't have a better node, then just set the error on the first token of
            // construct.
            return getSpanOfTokenAtPosition(sourceFile, node.pos);
        }
        var isMissing = nodeIsMissing(errorNode);
        var pos = isMissing || ts.isJsxText(node)
            ? errorNode.pos
            : ts.skipTrivia(sourceFile.text, errorNode.pos);
        // These asserts should all be satisfied for a properly constructed `errorNode`.
        if (isMissing) {
            ts.Debug.assert(pos === errorNode.pos, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
            ts.Debug.assert(pos === errorNode.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
        }
        else {
            ts.Debug.assert(pos >= errorNode.pos, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
            ts.Debug.assert(pos <= errorNode.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
        }
        return ts.createTextSpanFromBounds(pos, errorNode.end);
    }
    ts.getErrorSpanForNode = getErrorSpanForNode;
    function isExternalOrCommonJsModule(file) {
        return (file.externalModuleIndicator || file.commonJsModuleIndicator) !== undefined;
    }
    ts.isExternalOrCommonJsModule = isExternalOrCommonJsModule;
    function isJsonSourceFile(file) {
        return file.scriptKind === 6 /* JSON */;
    }
    ts.isJsonSourceFile = isJsonSourceFile;
    function isEnumConst(node) {
        return !!(ts.getCombinedModifierFlags(node) & 2048 /* Const */);
    }
    ts.isEnumConst = isEnumConst;
    function isDeclarationReadonly(declaration) {
        return !!(ts.getCombinedModifierFlags(declaration) & 64 /* Readonly */ && !ts.isParameterPropertyDeclaration(declaration));
    }
    ts.isDeclarationReadonly = isDeclarationReadonly;
    function isVarConst(node) {
        return !!(ts.getCombinedNodeFlags(node) & 2 /* Const */);
    }
    ts.isVarConst = isVarConst;
    function isLet(node) {
        return !!(ts.getCombinedNodeFlags(node) & 1 /* Let */);
    }
    ts.isLet = isLet;
    function isSuperCall(n) {
        return n.kind === 192 /* CallExpression */ && n.expression.kind === 99 /* SuperKeyword */;
    }
    ts.isSuperCall = isSuperCall;
    function isImportCall(n) {
        return n.kind === 192 /* CallExpression */ && n.expression.kind === 93 /* ImportKeyword */;
    }
    ts.isImportCall = isImportCall;
    function isLiteralImportTypeNode(n) {
        return ts.isImportTypeNode(n) && ts.isLiteralTypeNode(n.argument) && ts.isStringLiteral(n.argument.literal);
    }
    ts.isLiteralImportTypeNode = isLiteralImportTypeNode;
    function isPrologueDirective(node) {
        return node.kind === 222 /* ExpressionStatement */
            && node.expression.kind === 10 /* StringLiteral */;
    }
    ts.isPrologueDirective = isPrologueDirective;
    function getLeadingCommentRangesOfNode(node, sourceFileOfNode) {
        return node.kind !== 11 /* JsxText */ ? ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos) : undefined;
    }
    ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode;
    function getJSDocCommentRanges(node, text) {
        var commentRanges = (node.kind === 152 /* Parameter */ ||
            node.kind === 151 /* TypeParameter */ ||
            node.kind === 197 /* FunctionExpression */ ||
            node.kind === 198 /* ArrowFunction */ ||
            node.kind === 196 /* ParenthesizedExpression */) ?
            ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) :
            ts.getLeadingCommentRanges(text, node.pos);
        // True if the comment starts with '/**' but not if it is '/**/'
        return ts.filter(commentRanges, function (comment) {
            return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
                text.charCodeAt(comment.pos + 2) === 42 /* asterisk */ &&
                text.charCodeAt(comment.pos + 3) !== 47 /* slash */;
        });
    }
    ts.getJSDocCommentRanges = getJSDocCommentRanges;
    ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*<reference\s+path\s*=\s*)('|")(.+?)\2.*?\/>/;
    var fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*<reference\s+types\s*=\s*)('|")(.+?)\2.*?\/>/;
    ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*<amd-dependency\s+path\s*=\s*)('|")(.+?)\2.*?\/>/;
    var defaultLibReferenceRegEx = /^(\/\/\/\s*<reference\s+no-default-lib\s*=\s*)('|")(.+?)\2\s*\/>/;
    function isPartOfTypeNode(node) {
        if (164 /* FirstTypeNode */ <= node.kind && node.kind <= 184 /* LastTypeNode */) {
            return true;
        }
        switch (node.kind) {
            case 121 /* AnyKeyword */:
            case 144 /* UnknownKeyword */:
            case 136 /* NumberKeyword */:
            case 147 /* BigIntKeyword */:
            case 139 /* StringKeyword */:
            case 124 /* BooleanKeyword */:
            case 140 /* SymbolKeyword */:
            case 137 /* ObjectKeyword */:
            case 142 /* UndefinedKeyword */:
            case 133 /* NeverKeyword */:
                return true;
            case 107 /* VoidKeyword */:
                return node.parent.kind !== 201 /* VoidExpression */;
            case 212 /* ExpressionWithTypeArguments */:
                return !isExpressionWithTypeArgumentsInClassExtendsClause(node);
            case 151 /* TypeParameter */:
                return node.parent.kind === 182 /* MappedType */ || node.parent.kind === 177 /* InferType */;
            // Identifiers and qualified names may be type nodes, depending on their context. Climb
            // above them to find the lowest container
            case 73 /* Identifier */:
                // If the identifier is the RHS of a qualified name, then it's a type iff its parent is.
                if (node.parent.kind === 149 /* QualifiedName */ && node.parent.right === node) {
                    node = node.parent;
                }
                else if (node.parent.kind === 190 /* PropertyAccessExpression */ && node.parent.name === node) {
                    node = node.parent;
                }
                // At this point, node is either a qualified name or an identifier
                ts.Debug.assert(node.kind === 73 /* Identifier */ || node.kind === 149 /* QualifiedName */ || node.kind === 190 /* PropertyAccessExpression */, "'node' was expected to be a qualified name, identifier or property access in 'isPartOfTypeNode'.");
            // falls through
            case 149 /* QualifiedName */:
            case 190 /* PropertyAccessExpression */:
            case 101 /* ThisKeyword */: {
                var parent = node.parent;
                if (parent.kind === 168 /* TypeQuery */) {
                    return false;
                }
                if (parent.kind === 184 /* ImportType */) {
                    return !parent.isTypeOf;
                }
                // Do not recursively call isPartOfTypeNode on the parent. In the example:
                //
                //     let a: A.B.C;
                //
                // Calling isPartOfTypeNode would consider the qualified name A.B a type node.
                // Only C and A.B.C are type nodes.
                if (164 /* FirstTypeNode */ <= parent.kind && parent.kind <= 184 /* LastTypeNode */) {
                    return true;
                }
                switch (parent.kind) {
                    case 212 /* ExpressionWithTypeArguments */:
                        return !isExpressionWithTypeArgumentsInClassExtendsClause(parent);
                    case 151 /* TypeParameter */:
                        return node === parent.constraint;
                    case 309 /* JSDocTemplateTag */:
                        return node === parent.constraint;
                    case 155 /* PropertyDeclaration */:
                    case 154 /* PropertySignature */:
                    case 152 /* Parameter */:
                    case 238 /* VariableDeclaration */:
                        return node === parent.type;
                    case 240 /* FunctionDeclaration */:
                    case 197 /* FunctionExpression */:
                    case 198 /* ArrowFunction */:
                    case 158 /* Constructor */:
                    case 157 /* MethodDeclaration */:
                    case 156 /* MethodSignature */:
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                        return node === parent.type;
                    case 161 /* CallSignature */:
                    case 162 /* ConstructSignature */:
                    case 163 /* IndexSignature */:
                        return node === parent.type;
                    case 195 /* TypeAssertionExpression */:
                        return node === parent.type;
                    case 192 /* CallExpression */:
                    case 193 /* NewExpression */:
                        return ts.contains(parent.typeArguments, node);
                    case 194 /* TaggedTemplateExpression */:
                        // TODO (drosen): TaggedTemplateExpressions may eventually support type arguments.
                        return false;
                }
            }
        }
        return false;
    }
    ts.isPartOfTypeNode = isPartOfTypeNode;
    function isChildOfNodeWithKind(node, kind) {
        while (node) {
            if (node.kind === kind) {
                return true;
            }
            node = node.parent;
        }
        return false;
    }
    ts.isChildOfNodeWithKind = isChildOfNodeWithKind;
    // Warning: This has the same semantics as the forEach family of functions,
    //          in that traversal terminates in the event that 'visitor' supplies a truthy value.
    function forEachReturnStatement(body, visitor) {
        return traverse(body);
        function traverse(node) {
            switch (node.kind) {
                case 231 /* ReturnStatement */:
                    return visitor(node);
                case 247 /* CaseBlock */:
                case 219 /* Block */:
                case 223 /* IfStatement */:
                case 224 /* DoStatement */:
                case 225 /* WhileStatement */:
                case 226 /* ForStatement */:
                case 227 /* ForInStatement */:
                case 228 /* ForOfStatement */:
                case 232 /* WithStatement */:
                case 233 /* SwitchStatement */:
                case 272 /* CaseClause */:
                case 273 /* DefaultClause */:
                case 234 /* LabeledStatement */:
                case 236 /* TryStatement */:
                case 275 /* CatchClause */:
                    return ts.forEachChild(node, traverse);
            }
        }
    }
    ts.forEachReturnStatement = forEachReturnStatement;
    function forEachYieldExpression(body, visitor) {
        return traverse(body);
        function traverse(node) {
            switch (node.kind) {
                case 208 /* YieldExpression */:
                    visitor(node);
                    var operand = node.expression;
                    if (operand) {
                        traverse(operand);
                    }
                    return;
                case 244 /* EnumDeclaration */:
                case 242 /* InterfaceDeclaration */:
                case 245 /* ModuleDeclaration */:
                case 243 /* TypeAliasDeclaration */:
                case 241 /* ClassDeclaration */:
                case 210 /* ClassExpression */:
                    // These are not allowed inside a generator now, but eventually they may be allowed
                    // as local types. Regardless, any yield statements contained within them should be
                    // skipped in this traversal.
                    return;
                default:
                    if (ts.isFunctionLike(node)) {
                        if (node.name && node.name.kind === 150 /* ComputedPropertyName */) {
                            // Note that we will not include methods/accessors of a class because they would require
                            // first descending into the class. This is by design.
                            traverse(node.name.expression);
                            return;
                        }
                    }
                    else if (!isPartOfTypeNode(node)) {
                        // This is the general case, which should include mostly expressions and statements.
                        // Also includes NodeArrays.
                        ts.forEachChild(node, traverse);
                    }
            }
        }
    }
    ts.forEachYieldExpression = forEachYieldExpression;
    /**
     * Gets the most likely element type for a TypeNode. This is not an exhaustive test
     * as it assumes a rest argument can only be an array type (either T[], or Array<T>).
     *
     * @param node The type node.
     */
    function getRestParameterElementType(node) {
        if (node && node.kind === 170 /* ArrayType */) {
            return node.elementType;
        }
        else if (node && node.kind === 165 /* TypeReference */) {
            return ts.singleOrUndefined(node.typeArguments);
        }
        else {
            return undefined;
        }
    }
    ts.getRestParameterElementType = getRestParameterElementType;
    function getMembersOfDeclaration(node) {
        switch (node.kind) {
            case 242 /* InterfaceDeclaration */:
            case 241 /* ClassDeclaration */:
            case 210 /* ClassExpression */:
            case 169 /* TypeLiteral */:
                return node.members;
            case 189 /* ObjectLiteralExpression */:
                return node.properties;
        }
    }
    ts.getMembersOfDeclaration = getMembersOfDeclaration;
    function isVariableLike(node) {
        if (node) {
            switch (node.kind) {
                case 187 /* BindingElement */:
                case 279 /* EnumMember */:
                case 152 /* Parameter */:
                case 276 /* PropertyAssignment */:
                case 155 /* PropertyDeclaration */:
                case 154 /* PropertySignature */:
                case 277 /* ShorthandPropertyAssignment */:
                case 238 /* VariableDeclaration */:
                    return true;
            }
        }
        return false;
    }
    ts.isVariableLike = isVariableLike;
    function isVariableLikeOrAccessor(node) {
        return isVariableLike(node) || ts.isAccessor(node);
    }
    ts.isVariableLikeOrAccessor = isVariableLikeOrAccessor;
    function isVariableDeclarationInVariableStatement(node) {
        return node.parent.kind === 239 /* VariableDeclarationList */
            && node.parent.parent.kind === 220 /* VariableStatement */;
    }
    ts.isVariableDeclarationInVariableStatement = isVariableDeclarationInVariableStatement;
    function isValidESSymbolDeclaration(node) {
        return ts.isVariableDeclaration(node) ? isVarConst(node) && ts.isIdentifier(node.name) && isVariableDeclarationInVariableStatement(node) :
            ts.isPropertyDeclaration(node) ? hasReadonlyModifier(node) && hasStaticModifier(node) :
                ts.isPropertySignature(node) && hasReadonlyModifier(node);
    }
    ts.isValidESSymbolDeclaration = isValidESSymbolDeclaration;
    function introducesArgumentsExoticObject(node) {
        switch (node.kind) {
            case 157 /* MethodDeclaration */:
            case 156 /* MethodSignature */:
            case 158 /* Constructor */:
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
            case 240 /* FunctionDeclaration */:
            case 197 /* FunctionExpression */:
                return true;
        }
        return false;
    }
    ts.introducesArgumentsExoticObject = introducesArgumentsExoticObject;
    function unwrapInnermostStatementOfLabel(node, beforeUnwrapLabelCallback) {
        while (true) {
            if (beforeUnwrapLabelCallback) {
                beforeUnwrapLabelCallback(node);
            }
            if (node.statement.kind !== 234 /* LabeledStatement */) {
                return node.statement;
            }
            node = node.statement;
        }
    }
    ts.unwrapInnermostStatementOfLabel = unwrapInnermostStatementOfLabel;
    function isFunctionBlock(node) {
        return node && node.kind === 219 /* Block */ && ts.isFunctionLike(node.parent);
    }
    ts.isFunctionBlock = isFunctionBlock;
    function isObjectLiteralMethod(node) {
        return node && node.kind === 157 /* MethodDeclaration */ && node.parent.kind === 189 /* ObjectLiteralExpression */;
    }
    ts.isObjectLiteralMethod = isObjectLiteralMethod;
    function isObjectLiteralOrClassExpressionMethod(node) {
        return node.kind === 157 /* MethodDeclaration */ &&
            (node.parent.kind === 189 /* ObjectLiteralExpression */ ||
                node.parent.kind === 210 /* ClassExpression */);
    }
    ts.isObjectLiteralOrClassExpressionMethod = isObjectLiteralOrClassExpressionMethod;
    function isIdentifierTypePredicate(predicate) {
        return predicate && predicate.kind === 1 /* Identifier */;
    }
    ts.isIdentifierTypePredicate = isIdentifierTypePredicate;
    function isThisTypePredicate(predicate) {
        return predicate && predicate.kind === 0 /* This */;
    }
    ts.isThisTypePredicate = isThisTypePredicate;
    function getPropertyAssignment(objectLiteral, key, key2) {
        return objectLiteral.properties.filter(function (property) {
            if (property.kind === 276 /* PropertyAssignment */) {
                var propName = getTextOfPropertyName(property.name);
                return key === propName || (!!key2 && key2 === propName);
            }
            return false;
        });
    }
    ts.getPropertyAssignment = getPropertyAssignment;
    function getTsConfigObjectLiteralExpression(tsConfigSourceFile) {
        if (tsConfigSourceFile && tsConfigSourceFile.statements.length) {
            var expression = tsConfigSourceFile.statements[0].expression;
            return ts.tryCast(expression, ts.isObjectLiteralExpression);
        }
    }
    ts.getTsConfigObjectLiteralExpression = getTsConfigObjectLiteralExpression;
    function getTsConfigPropArrayElementValue(tsConfigSourceFile, propKey, elementValue) {
        return ts.firstDefined(getTsConfigPropArray(tsConfigSourceFile, propKey), function (property) {
            return ts.isArrayLiteralExpression(property.initializer) ?
                ts.find(property.initializer.elements, function (element) { return ts.isStringLiteral(element) && element.text === elementValue; }) :
                undefined;
        });
    }
    ts.getTsConfigPropArrayElementValue = getTsConfigPropArrayElementValue;
    function getTsConfigPropArray(tsConfigSourceFile, propKey) {
        var jsonObjectLiteral = getTsConfigObjectLiteralExpression(tsConfigSourceFile);
        return jsonObjectLiteral ? getPropertyAssignment(jsonObjectLiteral, propKey) : ts.emptyArray;
    }
    ts.getTsConfigPropArray = getTsConfigPropArray;
    function getContainingFunction(node) {
        return findAncestor(node.parent, ts.isFunctionLike);
    }
    ts.getContainingFunction = getContainingFunction;
    function getContainingFunctionDeclaration(node) {
        return findAncestor(node.parent, ts.isFunctionLikeDeclaration);
    }
    ts.getContainingFunctionDeclaration = getContainingFunctionDeclaration;
    function getContainingClass(node) {
        return findAncestor(node.parent, ts.isClassLike);
    }
    ts.getContainingClass = getContainingClass;
    function getThisContainer(node, includeArrowFunctions) {
        ts.Debug.assert(node.kind !== 285 /* SourceFile */);
        while (true) {
            node = node.parent;
            if (!node) {
                return ts.Debug.fail(); // If we never pass in a SourceFile, this should be unreachable, since we'll stop when we reach that.
            }
            switch (node.kind) {
                case 150 /* ComputedPropertyName */:
                    // If the grandparent node is an object literal (as opposed to a class),
                    // then the computed property is not a 'this' container.
                    // A computed property name in a class needs to be a this container
                    // so that we can error on it.
                    if (ts.isClassLike(node.parent.parent)) {
                        return node;
                    }
                    // If this is a computed property, then the parent should not
                    // make it a this container. The parent might be a property
                    // in an object literal, like a method or accessor. But in order for
                    // such a parent to be a this container, the reference must be in
                    // the *body* of the container.
                    node = node.parent;
                    break;
                case 153 /* Decorator */:
                    // Decorators are always applied outside of the body of a class or method.
                    if (node.parent.kind === 152 /* Parameter */ && ts.isClassElement(node.parent.parent)) {
                        // If the decorator's parent is a Parameter, we resolve the this container from
                        // the grandparent class declaration.
                        node = node.parent.parent;
                    }
                    else if (ts.isClassElement(node.parent)) {
                        // If the decorator's parent is a class element, we resolve the 'this' container
                        // from the parent class declaration.
                        node = node.parent;
                    }
                    break;
                case 198 /* ArrowFunction */:
                    if (!includeArrowFunctions) {
                        continue;
                    }
                // falls through
                case 240 /* FunctionDeclaration */:
                case 197 /* FunctionExpression */:
                case 245 /* ModuleDeclaration */:
                case 155 /* PropertyDeclaration */:
                case 154 /* PropertySignature */:
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                case 158 /* Constructor */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                case 161 /* CallSignature */:
                case 162 /* ConstructSignature */:
                case 163 /* IndexSignature */:
                case 244 /* EnumDeclaration */:
                case 285 /* SourceFile */:
                    return node;
            }
        }
    }
    ts.getThisContainer = getThisContainer;
    function getNewTargetContainer(node) {
        var container = getThisContainer(node, /*includeArrowFunctions*/ false);
        if (container) {
            switch (container.kind) {
                case 158 /* Constructor */:
                case 240 /* FunctionDeclaration */:
                case 197 /* FunctionExpression */:
                    return container;
            }
        }
        return undefined;
    }
    ts.getNewTargetContainer = getNewTargetContainer;
    /**
     * Given an super call/property node, returns the closest node where
     * - a super call/property access is legal in the node and not legal in the parent node the node.
     *   i.e. super call is legal in constructor but not legal in the class body.
     * - the container is an arrow function (so caller might need to call getSuperContainer again in case it needs to climb higher)
     * - a super call/property is definitely illegal in the container (but might be legal in some subnode)
     *   i.e. super property access is illegal in function declaration but can be legal in the statement list
     */
    function getSuperContainer(node, stopOnFunctions) {
        while (true) {
            node = node.parent;
            if (!node) {
                return node;
            }
            switch (node.kind) {
                case 150 /* ComputedPropertyName */:
                    node = node.parent;
                    break;
                case 240 /* FunctionDeclaration */:
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */:
                    if (!stopOnFunctions) {
                        continue;
                    }
                // falls through
                case 155 /* PropertyDeclaration */:
                case 154 /* PropertySignature */:
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                case 158 /* Constructor */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    return node;
                case 153 /* Decorator */:
                    // Decorators are always applied outside of the body of a class or method.
                    if (node.parent.kind === 152 /* Parameter */ && ts.isClassElement(node.parent.parent)) {
                        // If the decorator's parent is a Parameter, we resolve the this container from
                        // the grandparent class declaration.
                        node = node.parent.parent;
                    }
                    else if (ts.isClassElement(node.parent)) {
                        // If the decorator's parent is a class element, we resolve the 'this' container
                        // from the parent class declaration.
                        node = node.parent;
                    }
                    break;
            }
        }
    }
    ts.getSuperContainer = getSuperContainer;
    function getImmediatelyInvokedFunctionExpression(func) {
        if (func.kind === 197 /* FunctionExpression */ || func.kind === 198 /* ArrowFunction */) {
            var prev = func;
            var parent = func.parent;
            while (parent.kind === 196 /* ParenthesizedExpression */) {
                prev = parent;
                parent = parent.parent;
            }
            if (parent.kind === 192 /* CallExpression */ && parent.expression === prev) {
                return parent;
            }
        }
    }
    ts.getImmediatelyInvokedFunctionExpression = getImmediatelyInvokedFunctionExpression;
    function isSuperOrSuperProperty(node) {
        return node.kind === 99 /* SuperKeyword */
            || isSuperProperty(node);
    }
    ts.isSuperOrSuperProperty = isSuperOrSuperProperty;
    /**
     * Determines whether a node is a property or element access expression for `super`.
     */
    function isSuperProperty(node) {
        var kind = node.kind;
        return (kind === 190 /* PropertyAccessExpression */ || kind === 191 /* ElementAccessExpression */)
            && node.expression.kind === 99 /* SuperKeyword */;
    }
    ts.isSuperProperty = isSuperProperty;
    /**
     * Determines whether a node is a property or element access expression for `this`.
     */
    function isThisProperty(node) {
        var kind = node.kind;
        return (kind === 190 /* PropertyAccessExpression */ || kind === 191 /* ElementAccessExpression */)
            && node.expression.kind === 101 /* ThisKeyword */;
    }
    ts.isThisProperty = isThisProperty;
    function getEntityNameFromTypeNode(node) {
        switch (node.kind) {
            case 165 /* TypeReference */:
                return node.typeName;
            case 212 /* ExpressionWithTypeArguments */:
                return isEntityNameExpression(node.expression)
                    ? node.expression
                    : undefined;
            case 73 /* Identifier */:
            case 149 /* QualifiedName */:
                return node;
        }
        return undefined;
    }
    ts.getEntityNameFromTypeNode = getEntityNameFromTypeNode;
    function getInvokedExpression(node) {
        switch (node.kind) {
            case 194 /* TaggedTemplateExpression */:
                return node.tag;
            case 263 /* JsxOpeningElement */:
            case 262 /* JsxSelfClosingElement */:
                return node.tagName;
            default:
                return node.expression;
        }
    }
    ts.getInvokedExpression = getInvokedExpression;
    function nodeCanBeDecorated(node, parent, grandparent) {
        switch (node.kind) {
            case 241 /* ClassDeclaration */:
                // classes are valid targets
                return true;
            case 155 /* PropertyDeclaration */:
                // property declarations are valid if their parent is a class declaration.
                return parent.kind === 241 /* ClassDeclaration */;
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
            case 157 /* MethodDeclaration */:
                // if this method has a body and its parent is a class declaration, this is a valid target.
                return node.body !== undefined
                    && parent.kind === 241 /* ClassDeclaration */;
            case 152 /* Parameter */:
                // if the parameter's parent has a body and its grandparent is a class declaration, this is a valid target;
                return parent.body !== undefined
                    && (parent.kind === 158 /* Constructor */
                        || parent.kind === 157 /* MethodDeclaration */
                        || parent.kind === 160 /* SetAccessor */)
                    && grandparent.kind === 241 /* ClassDeclaration */;
        }
        return false;
    }
    ts.nodeCanBeDecorated = nodeCanBeDecorated;
    function nodeIsDecorated(node, parent, grandparent) {
        return node.decorators !== undefined
            && nodeCanBeDecorated(node, parent, grandparent); // TODO: GH#18217
    }
    ts.nodeIsDecorated = nodeIsDecorated;
    function nodeOrChildIsDecorated(node, parent, grandparent) {
        return nodeIsDecorated(node, parent, grandparent) || childIsDecorated(node, parent); // TODO: GH#18217
    }
    ts.nodeOrChildIsDecorated = nodeOrChildIsDecorated;
    function childIsDecorated(node, parent) {
        switch (node.kind) {
            case 241 /* ClassDeclaration */:
                return ts.some(node.members, function (m) { return nodeOrChildIsDecorated(m, node, parent); }); // TODO: GH#18217
            case 157 /* MethodDeclaration */:
            case 160 /* SetAccessor */:
                return ts.some(node.parameters, function (p) { return nodeIsDecorated(p, node, parent); }); // TODO: GH#18217
            default:
                return false;
        }
    }
    ts.childIsDecorated = childIsDecorated;
    function isJSXTagName(node) {
        var parent = node.parent;
        if (parent.kind === 263 /* JsxOpeningElement */ ||
            parent.kind === 262 /* JsxSelfClosingElement */ ||
            parent.kind === 264 /* JsxClosingElement */) {
            return parent.tagName === node;
        }
        return false;
    }
    ts.isJSXTagName = isJSXTagName;
    function isExpressionNode(node) {
        switch (node.kind) {
            case 99 /* SuperKeyword */:
            case 97 /* NullKeyword */:
            case 103 /* TrueKeyword */:
            case 88 /* FalseKeyword */:
            case 13 /* RegularExpressionLiteral */:
            case 188 /* ArrayLiteralExpression */:
            case 189 /* ObjectLiteralExpression */:
            case 190 /* PropertyAccessExpression */:
            case 191 /* ElementAccessExpression */:
            case 192 /* CallExpression */:
            case 193 /* NewExpression */:
            case 194 /* TaggedTemplateExpression */:
            case 213 /* AsExpression */:
            case 195 /* TypeAssertionExpression */:
            case 214 /* NonNullExpression */:
            case 196 /* ParenthesizedExpression */:
            case 197 /* FunctionExpression */:
            case 210 /* ClassExpression */:
            case 198 /* ArrowFunction */:
            case 201 /* VoidExpression */:
            case 199 /* DeleteExpression */:
            case 200 /* TypeOfExpression */:
            case 203 /* PrefixUnaryExpression */:
            case 204 /* PostfixUnaryExpression */:
            case 205 /* BinaryExpression */:
            case 206 /* ConditionalExpression */:
            case 209 /* SpreadElement */:
            case 207 /* TemplateExpression */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 211 /* OmittedExpression */:
            case 261 /* JsxElement */:
            case 262 /* JsxSelfClosingElement */:
            case 265 /* JsxFragment */:
            case 208 /* YieldExpression */:
            case 202 /* AwaitExpression */:
            case 215 /* MetaProperty */:
                return true;
            case 149 /* QualifiedName */:
                while (node.parent.kind === 149 /* QualifiedName */) {
                    node = node.parent;
                }
                return node.parent.kind === 168 /* TypeQuery */ || isJSXTagName(node);
            case 73 /* Identifier */:
                if (node.parent.kind === 168 /* TypeQuery */ || isJSXTagName(node)) {
                    return true;
                }
            // falls through
            case 8 /* NumericLiteral */:
            case 9 /* BigIntLiteral */:
            case 10 /* StringLiteral */:
            case 101 /* ThisKeyword */:
                return isInExpressionContext(node);
            default:
                return false;
        }
    }
    ts.isExpressionNode = isExpressionNode;
    function isInExpressionContext(node) {
        var parent = node.parent;
        switch (parent.kind) {
            case 238 /* VariableDeclaration */:
            case 152 /* Parameter */:
            case 155 /* PropertyDeclaration */:
            case 154 /* PropertySignature */:
            case 279 /* EnumMember */:
            case 276 /* PropertyAssignment */:
            case 187 /* BindingElement */:
                return parent.initializer === node;
            case 222 /* ExpressionStatement */:
            case 223 /* IfStatement */:
            case 224 /* DoStatement */:
            case 225 /* WhileStatement */:
            case 231 /* ReturnStatement */:
            case 232 /* WithStatement */:
            case 233 /* SwitchStatement */:
            case 272 /* CaseClause */:
            case 235 /* ThrowStatement */:
                return parent.expression === node;
            case 226 /* ForStatement */:
                var forStatement = parent;
                return (forStatement.initializer === node && forStatement.initializer.kind !== 239 /* VariableDeclarationList */) ||
                    forStatement.condition === node ||
                    forStatement.incrementor === node;
            case 227 /* ForInStatement */:
            case 228 /* ForOfStatement */:
                var forInStatement = parent;
                return (forInStatement.initializer === node && forInStatement.initializer.kind !== 239 /* VariableDeclarationList */) ||
                    forInStatement.expression === node;
            case 195 /* TypeAssertionExpression */:
            case 213 /* AsExpression */:
                return node === parent.expression;
            case 217 /* TemplateSpan */:
                return node === parent.expression;
            case 150 /* ComputedPropertyName */:
                return node === parent.expression;
            case 153 /* Decorator */:
            case 271 /* JsxExpression */:
            case 270 /* JsxSpreadAttribute */:
            case 278 /* SpreadAssignment */:
                return true;
            case 212 /* ExpressionWithTypeArguments */:
                return parent.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent);
            case 277 /* ShorthandPropertyAssignment */:
                return parent.objectAssignmentInitializer === node;
            default:
                return isExpressionNode(parent);
        }
    }
    ts.isInExpressionContext = isInExpressionContext;
    function isExternalModuleImportEqualsDeclaration(node) {
        return node.kind === 249 /* ImportEqualsDeclaration */ && node.moduleReference.kind === 260 /* ExternalModuleReference */;
    }
    ts.isExternalModuleImportEqualsDeclaration = isExternalModuleImportEqualsDeclaration;
    function getExternalModuleImportEqualsDeclarationExpression(node) {
        ts.Debug.assert(isExternalModuleImportEqualsDeclaration(node));
        return node.moduleReference.expression;
    }
    ts.getExternalModuleImportEqualsDeclarationExpression = getExternalModuleImportEqualsDeclarationExpression;
    function isInternalModuleImportEqualsDeclaration(node) {
        return node.kind === 249 /* ImportEqualsDeclaration */ && node.moduleReference.kind !== 260 /* ExternalModuleReference */;
    }
    ts.isInternalModuleImportEqualsDeclaration = isInternalModuleImportEqualsDeclaration;
    function isSourceFileJS(file) {
        return isInJSFile(file);
    }
    ts.isSourceFileJS = isSourceFileJS;
    function isSourceFileNotJS(file) {
        return !isInJSFile(file);
    }
    ts.isSourceFileNotJS = isSourceFileNotJS;
    function isInJSFile(node) {
        return !!node && !!(node.flags & 65536 /* JavaScriptFile */);
    }
    ts.isInJSFile = isInJSFile;
    function isInJsonFile(node) {
        return !!node && !!(node.flags & 16777216 /* JsonFile */);
    }
    ts.isInJsonFile = isInJsonFile;
    function isInJSDoc(node) {
        return !!node && !!(node.flags & 2097152 /* JSDoc */);
    }
    ts.isInJSDoc = isInJSDoc;
    function isJSDocIndexSignature(node) {
        return ts.isTypeReferenceNode(node) &&
            ts.isIdentifier(node.typeName) &&
            node.typeName.escapedText === "Object" &&
            node.typeArguments && node.typeArguments.length === 2 &&
            (node.typeArguments[0].kind === 139 /* StringKeyword */ || node.typeArguments[0].kind === 136 /* NumberKeyword */);
    }
    ts.isJSDocIndexSignature = isJSDocIndexSignature;
    function isRequireCall(callExpression, checkArgumentIsStringLiteralLike) {
        if (callExpression.kind !== 192 /* CallExpression */) {
            return false;
        }
        var _a = callExpression, expression = _a.expression, args = _a.arguments;
        if (expression.kind !== 73 /* Identifier */ || expression.escapedText !== "require") {
            return false;
        }
        if (args.length !== 1) {
            return false;
        }
        var arg = args[0];
        return !checkArgumentIsStringLiteralLike || ts.isStringLiteralLike(arg);
    }
    ts.isRequireCall = isRequireCall;
    function isSingleOrDoubleQuote(charCode) {
        return charCode === 39 /* singleQuote */ || charCode === 34 /* doubleQuote */;
    }
    ts.isSingleOrDoubleQuote = isSingleOrDoubleQuote;
    function isStringDoubleQuoted(str, sourceFile) {
        return getSourceTextOfNodeFromSourceFile(sourceFile, str).charCodeAt(0) === 34 /* doubleQuote */;
    }
    ts.isStringDoubleQuoted = isStringDoubleQuoted;
    function getDeclarationOfExpando(node) {
        if (!node.parent) {
            return undefined;
        }
        var name;
        var decl;
        if (ts.isVariableDeclaration(node.parent) && node.parent.initializer === node) {
            if (!isInJSFile(node) && !isVarConst(node.parent)) {
                return undefined;
            }
            name = node.parent.name;
            decl = node.parent;
        }
        else if (ts.isBinaryExpression(node.parent) && node.parent.operatorToken.kind === 60 /* EqualsToken */ && node.parent.right === node) {
            name = node.parent.left;
            decl = name;
        }
        else if (ts.isBinaryExpression(node.parent) && node.parent.operatorToken.kind === 55 /* BarBarToken */) {
            if (ts.isVariableDeclaration(node.parent.parent) && node.parent.parent.initializer === node.parent) {
                name = node.parent.parent.name;
                decl = node.parent.parent;
            }
            else if (ts.isBinaryExpression(node.parent.parent) && node.parent.parent.operatorToken.kind === 60 /* EqualsToken */ && node.parent.parent.right === node.parent) {
                name = node.parent.parent.left;
                decl = name;
            }
            if (!name || !isEntityNameExpression(name) || !isSameEntityName(name, node.parent.left)) {
                return undefined;
            }
        }
        if (!name || !getExpandoInitializer(node, isPrototypeAccess(name))) {
            return undefined;
        }
        return decl;
    }
    ts.getDeclarationOfExpando = getDeclarationOfExpando;
    function isAssignmentDeclaration(decl) {
        return ts.isBinaryExpression(decl) || ts.isPropertyAccessExpression(decl) || ts.isIdentifier(decl) || ts.isCallExpression(decl);
    }
    ts.isAssignmentDeclaration = isAssignmentDeclaration;
    /** Get the initializer, taking into account defaulted Javascript initializers */
    function getEffectiveInitializer(node) {
        if (isInJSFile(node) && node.initializer &&
            ts.isBinaryExpression(node.initializer) && node.initializer.operatorToken.kind === 55 /* BarBarToken */ &&
            node.name && isEntityNameExpression(node.name) && isSameEntityName(node.name, node.initializer.left)) {
            return node.initializer.right;
        }
        return node.initializer;
    }
    ts.getEffectiveInitializer = getEffectiveInitializer;
    /** Get the declaration initializer when it is container-like (See getExpandoInitializer). */
    function getDeclaredExpandoInitializer(node) {
        var init = getEffectiveInitializer(node);
        return init && getExpandoInitializer(init, isPrototypeAccess(node.name));
    }
    ts.getDeclaredExpandoInitializer = getDeclaredExpandoInitializer;
    function hasExpandoValueProperty(node, isPrototypeAssignment) {
        return ts.forEach(node.properties, function (p) { return ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.escapedText === "value" && p.initializer && getExpandoInitializer(p.initializer, isPrototypeAssignment); });
    }
    /**
     * Get the assignment 'initializer' -- the righthand side-- when the initializer is container-like (See getExpandoInitializer).
     * We treat the right hand side of assignments with container-like initalizers as declarations.
     */
    function getAssignedExpandoInitializer(node) {
        if (node && node.parent && ts.isBinaryExpression(node.parent) && node.parent.operatorToken.kind === 60 /* EqualsToken */) {
            var isPrototypeAssignment = isPrototypeAccess(node.parent.left);
            return getExpandoInitializer(node.parent.right, isPrototypeAssignment) ||
                getDefaultedExpandoInitializer(node.parent.left, node.parent.right, isPrototypeAssignment);
        }
        if (node && ts.isCallExpression(node) && isBindableObjectDefinePropertyCall(node)) {
            var result = hasExpandoValueProperty(node.arguments[2], node.arguments[1].text === "prototype");
            if (result) {
                return result;
            }
        }
    }
    ts.getAssignedExpandoInitializer = getAssignedExpandoInitializer;
    /**
     * Recognized expando initializers are:
     * 1. (function() {})() -- IIFEs
     * 2. function() { } -- Function expressions
     * 3. class { } -- Class expressions
     * 4. {} -- Empty object literals
     * 5. { ... } -- Non-empty object literals, when used to initialize a prototype, like `C.prototype = { m() { } }`
     *
     * This function returns the provided initializer, or undefined if it is not valid.
     */
    function getExpandoInitializer(initializer, isPrototypeAssignment) {
        if (ts.isCallExpression(initializer)) {
            var e = skipParentheses(initializer.expression);
            return e.kind === 197 /* FunctionExpression */ || e.kind === 198 /* ArrowFunction */ ? initializer : undefined;
        }
        if (initializer.kind === 197 /* FunctionExpression */ ||
            initializer.kind === 210 /* ClassExpression */ ||
            initializer.kind === 198 /* ArrowFunction */) {
            return initializer;
        }
        if (ts.isObjectLiteralExpression(initializer) && (initializer.properties.length === 0 || isPrototypeAssignment)) {
            return initializer;
        }
    }
    ts.getExpandoInitializer = getExpandoInitializer;
    /**
     * A defaulted expando initializer matches the pattern
     * `Lhs = Lhs || ExpandoInitializer`
     * or `var Lhs = Lhs || ExpandoInitializer`
     *
     * The second Lhs is required to be the same as the first except that it may be prefixed with
     * 'window.', 'global.' or 'self.' The second Lhs is otherwise ignored by the binder and checker.
     */
    function getDefaultedExpandoInitializer(name, initializer, isPrototypeAssignment) {
        var e = ts.isBinaryExpression(initializer) && initializer.operatorToken.kind === 55 /* BarBarToken */ && getExpandoInitializer(initializer.right, isPrototypeAssignment);
        if (e && isSameEntityName(name, initializer.left)) {
            return e;
        }
    }
    function isDefaultedExpandoInitializer(node) {
        var name = ts.isVariableDeclaration(node.parent) ? node.parent.name :
            ts.isBinaryExpression(node.parent) && node.parent.operatorToken.kind === 60 /* EqualsToken */ ? node.parent.left :
                undefined;
        return name && getExpandoInitializer(node.right, isPrototypeAccess(name)) && isEntityNameExpression(name) && isSameEntityName(name, node.left);
    }
    ts.isDefaultedExpandoInitializer = isDefaultedExpandoInitializer;
    /** Given an expando initializer, return its declaration name, or the left-hand side of the assignment if it's part of an assignment declaration. */
    function getNameOfExpando(node) {
        if (ts.isBinaryExpression(node.parent)) {
            var parent = (node.parent.operatorToken.kind === 55 /* BarBarToken */ && ts.isBinaryExpression(node.parent.parent)) ? node.parent.parent : node.parent;
            if (parent.operatorToken.kind === 60 /* EqualsToken */ && ts.isIdentifier(parent.left)) {
                return parent.left;
            }
        }
        else if (ts.isVariableDeclaration(node.parent)) {
            return node.parent.name;
        }
    }
    ts.getNameOfExpando = getNameOfExpando;
    /**
     * Is the 'declared' name the same as the one in the initializer?
     * @return true for identical entity names, as well as ones where the initializer is prefixed with
     * 'window', 'self' or 'global'. For example:
     *
     * var my = my || {}
     * var min = window.min || {}
     * my.app = self.my.app || class { }
     */
    function isSameEntityName(name, initializer) {
        if (ts.isIdentifier(name) && ts.isIdentifier(initializer)) {
            return name.escapedText === initializer.escapedText;
        }
        if (ts.isIdentifier(name) && ts.isPropertyAccessExpression(initializer)) {
            return (initializer.expression.kind === 101 /* ThisKeyword */ ||
                ts.isIdentifier(initializer.expression) &&
                    (initializer.expression.escapedText === "window" ||
                        initializer.expression.escapedText === "self" ||
                        initializer.expression.escapedText === "global")) &&
                isSameEntityName(name, initializer.name);
        }
        if (ts.isPropertyAccessExpression(name) && ts.isPropertyAccessExpression(initializer)) {
            return name.name.escapedText === initializer.name.escapedText && isSameEntityName(name.expression, initializer.expression);
        }
        return false;
    }
    function getRightMostAssignedExpression(node) {
        while (isAssignmentExpression(node, /*excludeCompoundAssignments*/ true)) {
            node = node.right;
        }
        return node;
    }
    ts.getRightMostAssignedExpression = getRightMostAssignedExpression;
    function isExportsIdentifier(node) {
        return ts.isIdentifier(node) && node.escapedText === "exports";
    }
    ts.isExportsIdentifier = isExportsIdentifier;
    function isModuleExportsPropertyAccessExpression(node) {
        return ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.expression) && node.expression.escapedText === "module" && node.name.escapedText === "exports";
    }
    ts.isModuleExportsPropertyAccessExpression = isModuleExportsPropertyAccessExpression;
    /// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
    /// assignments we treat as special in the binder
    function getAssignmentDeclarationKind(expr) {
        var special = getAssignmentDeclarationKindWorker(expr);
        return special === 5 /* Property */ || isInJSFile(expr) ? special : 0 /* None */;
    }
    ts.getAssignmentDeclarationKind = getAssignmentDeclarationKind;
    function isBindableObjectDefinePropertyCall(expr) {
        return ts.length(expr.arguments) === 3 &&
            ts.isPropertyAccessExpression(expr.expression) &&
            ts.isIdentifier(expr.expression.expression) &&
            ts.idText(expr.expression.expression) === "Object" &&
            ts.idText(expr.expression.name) === "defineProperty" &&
            isStringOrNumericLiteralLike(expr.arguments[1]) &&
            isEntityNameExpression(expr.arguments[0]);
    }
    ts.isBindableObjectDefinePropertyCall = isBindableObjectDefinePropertyCall;
    function getAssignmentDeclarationKindWorker(expr) {
        if (ts.isCallExpression(expr)) {
            if (!isBindableObjectDefinePropertyCall(expr)) {
                return 0 /* None */;
            }
            var entityName = expr.arguments[0];
            if (isExportsIdentifier(entityName) || isModuleExportsPropertyAccessExpression(entityName)) {
                return 8 /* ObjectDefinePropertyExports */;
            }
            if (ts.isPropertyAccessExpression(entityName) && entityName.name.escapedText === "prototype" && isEntityNameExpression(entityName.expression)) {
                return 9 /* ObjectDefinePrototypeProperty */;
            }
            return 7 /* ObjectDefinePropertyValue */;
        }
        if (expr.operatorToken.kind !== 60 /* EqualsToken */ ||
            !ts.isPropertyAccessExpression(expr.left)) {
            return 0 /* None */;
        }
        var lhs = expr.left;
        if (isEntityNameExpression(lhs.expression) && lhs.name.escapedText === "prototype" && ts.isObjectLiteralExpression(getInitializerOfBinaryExpression(expr))) {
            // F.prototype = { ... }
            return 6 /* Prototype */;
        }
        return getAssignmentDeclarationPropertyAccessKind(lhs);
    }
    function getAssignmentDeclarationPropertyAccessKind(lhs) {
        if (lhs.expression.kind === 101 /* ThisKeyword */) {
            return 4 /* ThisProperty */;
        }
        else if (isModuleExportsPropertyAccessExpression(lhs)) {
            // module.exports = expr
            return 2 /* ModuleExports */;
        }
        else if (isEntityNameExpression(lhs.expression)) {
            if (isPrototypeAccess(lhs.expression)) {
                // F.G....prototype.x = expr
                return 3 /* PrototypeProperty */;
            }
            var nextToLast = lhs;
            while (ts.isPropertyAccessExpression(nextToLast.expression)) {
                nextToLast = nextToLast.expression;
            }
            ts.Debug.assert(ts.isIdentifier(nextToLast.expression));
            var id = nextToLast.expression;
            if (id.escapedText === "exports" ||
                id.escapedText === "module" && nextToLast.name.escapedText === "exports") {
                // exports.name = expr OR module.exports.name = expr
                return 1 /* ExportsProperty */;
            }
            // F.G...x = expr
            return 5 /* Property */;
        }
        return 0 /* None */;
    }
    ts.getAssignmentDeclarationPropertyAccessKind = getAssignmentDeclarationPropertyAccessKind;
    function getInitializerOfBinaryExpression(expr) {
        while (ts.isBinaryExpression(expr.right)) {
            expr = expr.right;
        }
        return expr.right;
    }
    ts.getInitializerOfBinaryExpression = getInitializerOfBinaryExpression;
    function isPrototypePropertyAssignment(node) {
        return ts.isBinaryExpression(node) && getAssignmentDeclarationKind(node) === 3 /* PrototypeProperty */;
    }
    ts.isPrototypePropertyAssignment = isPrototypePropertyAssignment;
    function isSpecialPropertyDeclaration(expr) {
        return isInJSFile(expr) &&
            expr.parent && expr.parent.kind === 222 /* ExpressionStatement */ &&
            !!ts.getJSDocTypeTag(expr.parent);
    }
    ts.isSpecialPropertyDeclaration = isSpecialPropertyDeclaration;
    function isFunctionSymbol(symbol) {
        if (!symbol || !symbol.valueDeclaration) {
            return false;
        }
        var decl = symbol.valueDeclaration;
        return decl.kind === 240 /* FunctionDeclaration */ || ts.isVariableDeclaration(decl) && decl.initializer && ts.isFunctionLike(decl.initializer);
    }
    ts.isFunctionSymbol = isFunctionSymbol;
    function importFromModuleSpecifier(node) {
        return tryGetImportFromModuleSpecifier(node) || ts.Debug.failBadSyntaxKind(node.parent);
    }
    ts.importFromModuleSpecifier = importFromModuleSpecifier;
    function tryGetImportFromModuleSpecifier(node) {
        switch (node.parent.kind) {
            case 250 /* ImportDeclaration */:
            case 256 /* ExportDeclaration */:
                return node.parent;
            case 260 /* ExternalModuleReference */:
                return node.parent.parent;
            case 192 /* CallExpression */:
                return isImportCall(node.parent) || isRequireCall(node.parent, /*checkArg*/ false) ? node.parent : undefined;
            case 183 /* LiteralType */:
                ts.Debug.assert(ts.isStringLiteral(node));
                return ts.tryCast(node.parent.parent, ts.isImportTypeNode);
            default:
                return undefined;
        }
    }
    ts.tryGetImportFromModuleSpecifier = tryGetImportFromModuleSpecifier;
    function getExternalModuleName(node) {
        switch (node.kind) {
            case 250 /* ImportDeclaration */:
            case 256 /* ExportDeclaration */:
                return node.moduleSpecifier;
            case 249 /* ImportEqualsDeclaration */:
                return node.moduleReference.kind === 260 /* ExternalModuleReference */ ? node.moduleReference.expression : undefined;
            case 184 /* ImportType */:
                return isLiteralImportTypeNode(node) ? node.argument.literal : undefined;
            default:
                return ts.Debug.assertNever(node);
        }
    }
    ts.getExternalModuleName = getExternalModuleName;
    function getNamespaceDeclarationNode(node) {
        switch (node.kind) {
            case 250 /* ImportDeclaration */:
                return node.importClause && ts.tryCast(node.importClause.namedBindings, ts.isNamespaceImport);
            case 249 /* ImportEqualsDeclaration */:
                return node;
            case 256 /* ExportDeclaration */:
                return undefined;
            default:
                return ts.Debug.assertNever(node);
        }
    }
    ts.getNamespaceDeclarationNode = getNamespaceDeclarationNode;
    function isDefaultImport(node) {
        return node.kind === 250 /* ImportDeclaration */ && !!node.importClause && !!node.importClause.name;
    }
    ts.isDefaultImport = isDefaultImport;
    function hasQuestionToken(node) {
        if (node) {
            switch (node.kind) {
                case 152 /* Parameter */:
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                case 277 /* ShorthandPropertyAssignment */:
                case 276 /* PropertyAssignment */:
                case 155 /* PropertyDeclaration */:
                case 154 /* PropertySignature */:
                    return node.questionToken !== undefined;
            }
        }
        return false;
    }
    ts.hasQuestionToken = hasQuestionToken;
    function isJSDocConstructSignature(node) {
        var param = ts.isJSDocFunctionType(node) ? ts.firstOrUndefined(node.parameters) : undefined;
        var name = ts.tryCast(param && param.name, ts.isIdentifier);
        return !!name && name.escapedText === "new";
    }
    ts.isJSDocConstructSignature = isJSDocConstructSignature;
    function isJSDocTypeAlias(node) {
        return node.kind === 310 /* JSDocTypedefTag */ || node.kind === 303 /* JSDocCallbackTag */;
    }
    ts.isJSDocTypeAlias = isJSDocTypeAlias;
    function isTypeAlias(node) {
        return isJSDocTypeAlias(node) || ts.isTypeAliasDeclaration(node);
    }
    ts.isTypeAlias = isTypeAlias;
    function getSourceOfAssignment(node) {
        return ts.isExpressionStatement(node) &&
            node.expression && ts.isBinaryExpression(node.expression) &&
            node.expression.operatorToken.kind === 60 /* EqualsToken */
            ? node.expression.right
            : undefined;
    }
    function getSourceOfDefaultedAssignment(node) {
        return ts.isExpressionStatement(node) &&
            ts.isBinaryExpression(node.expression) &&
            getAssignmentDeclarationKind(node.expression) !== 0 /* None */ &&
            ts.isBinaryExpression(node.expression.right) &&
            node.expression.right.operatorToken.kind === 55 /* BarBarToken */
            ? node.expression.right.right
            : undefined;
    }
    function getSingleInitializerOfVariableStatementOrPropertyDeclaration(node) {
        switch (node.kind) {
            case 220 /* VariableStatement */:
                var v = getSingleVariableOfVariableStatement(node);
                return v && v.initializer;
            case 155 /* PropertyDeclaration */:
                return node.initializer;
            case 276 /* PropertyAssignment */:
                return node.initializer;
        }
    }
    ts.getSingleInitializerOfVariableStatementOrPropertyDeclaration = getSingleInitializerOfVariableStatementOrPropertyDeclaration;
    function getSingleVariableOfVariableStatement(node) {
        return ts.isVariableStatement(node) ? ts.firstOrUndefined(node.declarationList.declarations) : undefined;
    }
    function getNestedModuleDeclaration(node) {
        return ts.isModuleDeclaration(node) &&
            node.body &&
            node.body.kind === 245 /* ModuleDeclaration */
            ? node.body
            : undefined;
    }
    function getJSDocCommentsAndTags(hostNode) {
        var result;
        // Pull parameter comments from declaring function as well
        if (isVariableLike(hostNode) && ts.hasInitializer(hostNode) && ts.hasJSDocNodes(hostNode.initializer)) {
            result = ts.addRange(result, hostNode.initializer.jsDoc);
        }
        var node = hostNode;
        while (node && node.parent) {
            if (ts.hasJSDocNodes(node)) {
                result = ts.addRange(result, node.jsDoc);
            }
            if (node.kind === 152 /* Parameter */) {
                result = ts.addRange(result, ts.getJSDocParameterTags(node));
                break;
            }
            if (node.kind === 151 /* TypeParameter */) {
                result = ts.addRange(result, ts.getJSDocTypeParameterTags(node));
                break;
            }
            node = getNextJSDocCommentLocation(node);
        }
        return result || ts.emptyArray;
    }
    ts.getJSDocCommentsAndTags = getJSDocCommentsAndTags;
    function getNextJSDocCommentLocation(node) {
        var parent = node.parent;
        if (parent.kind === 276 /* PropertyAssignment */ ||
            parent.kind === 255 /* ExportAssignment */ ||
            parent.kind === 155 /* PropertyDeclaration */ ||
            parent.kind === 222 /* ExpressionStatement */ && node.kind === 190 /* PropertyAccessExpression */ ||
            getNestedModuleDeclaration(parent) ||
            ts.isBinaryExpression(node) && node.operatorToken.kind === 60 /* EqualsToken */) {
            return parent;
        }
        // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement.
        // /**
        //   * @param {number} name
        //   * @returns {number}
        //   */
        // var x = function(name) { return name.length; }
        else if (parent.parent &&
            (getSingleVariableOfVariableStatement(parent.parent) === node ||
                ts.isBinaryExpression(parent) && parent.operatorToken.kind === 60 /* EqualsToken */)) {
            return parent.parent;
        }
        else if (parent.parent && parent.parent.parent &&
            (getSingleVariableOfVariableStatement(parent.parent.parent) ||
                getSingleInitializerOfVariableStatementOrPropertyDeclaration(parent.parent.parent) === node ||
                getSourceOfDefaultedAssignment(parent.parent.parent))) {
            return parent.parent.parent;
        }
    }
    /** Does the opposite of `getJSDocParameterTags`: given a JSDoc parameter, finds the parameter corresponding to it. */
    function getParameterSymbolFromJSDoc(node) {
        if (node.symbol) {
            return node.symbol;
        }
        if (!ts.isIdentifier(node.name)) {
            return undefined;
        }
        var name = node.name.escapedText;
        var decl = getHostSignatureFromJSDoc(node);
        if (!decl) {
            return undefined;
        }
        var parameter = ts.find(decl.parameters, function (p) { return p.name.kind === 73 /* Identifier */ && p.name.escapedText === name; });
        return parameter && parameter.symbol;
    }
    ts.getParameterSymbolFromJSDoc = getParameterSymbolFromJSDoc;
    function getHostSignatureFromJSDoc(node) {
        return getHostSignatureFromJSDocHost(getJSDocHost(node));
    }
    ts.getHostSignatureFromJSDoc = getHostSignatureFromJSDoc;
    function getHostSignatureFromJSDocHost(host) {
        var decl = getSourceOfDefaultedAssignment(host) ||
            getSourceOfAssignment(host) ||
            getSingleInitializerOfVariableStatementOrPropertyDeclaration(host) ||
            getSingleVariableOfVariableStatement(host) ||
            getNestedModuleDeclaration(host) ||
            host;
        return decl && ts.isFunctionLike(decl) ? decl : undefined;
    }
    ts.getHostSignatureFromJSDocHost = getHostSignatureFromJSDocHost;
    function getJSDocHost(node) {
        return ts.Debug.assertDefined(findAncestor(node.parent, ts.isJSDoc)).parent;
    }
    ts.getJSDocHost = getJSDocHost;
    function getTypeParameterFromJsDoc(node) {
        var name = node.name.escapedText;
        var typeParameters = node.parent.parent.parent.typeParameters;
        return ts.find(typeParameters, function (p) { return p.name.escapedText === name; });
    }
    ts.getTypeParameterFromJsDoc = getTypeParameterFromJsDoc;
    function hasRestParameter(s) {
        var last = ts.lastOrUndefined(s.parameters);
        return !!last && isRestParameter(last);
    }
    ts.hasRestParameter = hasRestParameter;
    function isRestParameter(node) {
        var type = ts.isJSDocParameterTag(node) ? (node.typeExpression && node.typeExpression.type) : node.type;
        return node.dotDotDotToken !== undefined || !!type && type.kind === 296 /* JSDocVariadicType */;
    }
    ts.isRestParameter = isRestParameter;
    var AssignmentKind;
    (function (AssignmentKind) {
        AssignmentKind[AssignmentKind["None"] = 0] = "None";
        AssignmentKind[AssignmentKind["Definite"] = 1] = "Definite";
        AssignmentKind[AssignmentKind["Compound"] = 2] = "Compound";
    })(AssignmentKind = ts.AssignmentKind || (ts.AssignmentKind = {}));
    function getAssignmentTargetKind(node) {
        var parent = node.parent;
        while (true) {
            switch (parent.kind) {
                case 205 /* BinaryExpression */:
                    var binaryOperator = parent.operatorToken.kind;
                    return isAssignmentOperator(binaryOperator) && parent.left === node ?
                        binaryOperator === 60 /* EqualsToken */ ? 1 /* Definite */ : 2 /* Compound */ :
                        0 /* None */;
                case 203 /* PrefixUnaryExpression */:
                case 204 /* PostfixUnaryExpression */:
                    var unaryOperator = parent.operator;
                    return unaryOperator === 44 /* PlusPlusToken */ || unaryOperator === 45 /* MinusMinusToken */ ? 2 /* Compound */ : 0 /* None */;
                case 227 /* ForInStatement */:
                case 228 /* ForOfStatement */:
                    return parent.initializer === node ? 1 /* Definite */ : 0 /* None */;
                case 196 /* ParenthesizedExpression */:
                case 188 /* ArrayLiteralExpression */:
                case 209 /* SpreadElement */:
                case 214 /* NonNullExpression */:
                    node = parent;
                    break;
                case 277 /* ShorthandPropertyAssignment */:
                    if (parent.name !== node) {
                        return 0 /* None */;
                    }
                    node = parent.parent;
                    break;
                case 276 /* PropertyAssignment */:
                    if (parent.name === node) {
                        return 0 /* None */;
                    }
                    node = parent.parent;
                    break;
                default:
                    return 0 /* None */;
            }
            parent = node.parent;
        }
    }
    ts.getAssignmentTargetKind = getAssignmentTargetKind;
    // A node is an assignment target if it is on the left hand side of an '=' token, if it is parented by a property
    // assignment in an object literal that is an assignment target, or if it is parented by an array literal that is
    // an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ a }] = xxx'.
    // (Note that `p` is not a target in the above examples, only `a`.)
    function isAssignmentTarget(node) {
        return getAssignmentTargetKind(node) !== 0 /* None */;
    }
    ts.isAssignmentTarget = isAssignmentTarget;
    /**
     * Indicates whether a node could contain a `var` VariableDeclarationList that contributes to
     * the same `var` declaration scope as the node's parent.
     */
    function isNodeWithPossibleHoistedDeclaration(node) {
        switch (node.kind) {
            case 219 /* Block */:
            case 220 /* VariableStatement */:
            case 232 /* WithStatement */:
            case 223 /* IfStatement */:
            case 233 /* SwitchStatement */:
            case 247 /* CaseBlock */:
            case 272 /* CaseClause */:
            case 273 /* DefaultClause */:
            case 234 /* LabeledStatement */:
            case 226 /* ForStatement */:
            case 227 /* ForInStatement */:
            case 228 /* ForOfStatement */:
            case 224 /* DoStatement */:
            case 225 /* WhileStatement */:
            case 236 /* TryStatement */:
            case 275 /* CatchClause */:
                return true;
        }
        return false;
    }
    ts.isNodeWithPossibleHoistedDeclaration = isNodeWithPossibleHoistedDeclaration;
    function isValueSignatureDeclaration(node) {
        return ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isMethodOrAccessor(node) || ts.isFunctionDeclaration(node) || ts.isConstructorDeclaration(node);
    }
    ts.isValueSignatureDeclaration = isValueSignatureDeclaration;
    function walkUp(node, kind) {
        while (node && node.kind === kind) {
            node = node.parent;
        }
        return node;
    }
    function walkUpParenthesizedTypes(node) {
        return walkUp(node, 178 /* ParenthesizedType */);
    }
    ts.walkUpParenthesizedTypes = walkUpParenthesizedTypes;
    function walkUpParenthesizedExpressions(node) {
        return walkUp(node, 196 /* ParenthesizedExpression */);
    }
    ts.walkUpParenthesizedExpressions = walkUpParenthesizedExpressions;
    function skipParentheses(node) {
        while (node.kind === 196 /* ParenthesizedExpression */) {
            node = node.expression;
        }
        return node;
    }
    ts.skipParentheses = skipParentheses;
    function skipParenthesesUp(node) {
        while (node.kind === 196 /* ParenthesizedExpression */) {
            node = node.parent;
        }
        return node;
    }
    // a node is delete target iff. it is PropertyAccessExpression/ElementAccessExpression with parentheses skipped
    function isDeleteTarget(node) {
        if (node.kind !== 190 /* PropertyAccessExpression */ && node.kind !== 191 /* ElementAccessExpression */) {
            return false;
        }
        node = walkUpParenthesizedExpressions(node.parent);
        return node && node.kind === 199 /* DeleteExpression */;
    }
    ts.isDeleteTarget = isDeleteTarget;
    function isNodeDescendantOf(node, ancestor) {
        while (node) {
            if (node === ancestor)
                return true;
            node = node.parent;
        }
        return false;
    }
    ts.isNodeDescendantOf = isNodeDescendantOf;
    // True if `name` is the name of a declaration node
    function isDeclarationName(name) {
        return !ts.isSourceFile(name) && !ts.isBindingPattern(name) && ts.isDeclaration(name.parent) && name.parent.name === name;
    }
    ts.isDeclarationName = isDeclarationName;
    // See GH#16030
    function getDeclarationFromName(name) {
        var parent = name.parent;
        switch (name.kind) {
            case 10 /* StringLiteral */:
            case 8 /* NumericLiteral */:
                if (ts.isComputedPropertyName(parent))
                    return parent.parent;
            // falls through
            case 73 /* Identifier */:
                if (ts.isDeclaration(parent)) {
                    return parent.name === name ? parent : undefined;
                }
                else if (ts.isQualifiedName(parent)) {
                    var tag = parent.parent;
                    return ts.isJSDocParameterTag(tag) && tag.name === parent ? tag : undefined;
                }
                else {
                    var binExp = parent.parent;
                    return ts.isBinaryExpression(binExp) &&
                        getAssignmentDeclarationKind(binExp) !== 0 /* None */ &&
                        (binExp.left.symbol || binExp.symbol) &&
                        ts.getNameOfDeclaration(binExp) === name
                        ? binExp
                        : undefined;
                }
            default:
                return undefined;
        }
    }
    ts.getDeclarationFromName = getDeclarationFromName;
    function isLiteralComputedPropertyDeclarationName(node) {
        return (node.kind === 10 /* StringLiteral */ || node.kind === 8 /* NumericLiteral */) &&
            node.parent.kind === 150 /* ComputedPropertyName */ &&
            ts.isDeclaration(node.parent.parent);
    }
    ts.isLiteralComputedPropertyDeclarationName = isLiteralComputedPropertyDeclarationName;
    // Return true if the given identifier is classified as an IdentifierName
    function isIdentifierName(node) {
        var parent = node.parent;
        switch (parent.kind) {
            case 155 /* PropertyDeclaration */:
            case 154 /* PropertySignature */:
            case 157 /* MethodDeclaration */:
            case 156 /* MethodSignature */:
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
            case 279 /* EnumMember */:
            case 276 /* PropertyAssignment */:
            case 190 /* PropertyAccessExpression */:
                // Name in member declaration or property name in property access
                return parent.name === node;
            case 149 /* QualifiedName */:
                // Name on right hand side of dot in a type query or type reference
                if (parent.right === node) {
                    while (parent.kind === 149 /* QualifiedName */) {
                        parent = parent.parent;
                    }
                    return parent.kind === 168 /* TypeQuery */ || parent.kind === 165 /* TypeReference */;
                }
                return false;
            case 187 /* BindingElement */:
            case 254 /* ImportSpecifier */:
                // Property name in binding element or import specifier
                return parent.propertyName === node;
            case 258 /* ExportSpecifier */:
            case 268 /* JsxAttribute */:
                // Any name in an export specifier or JSX Attribute
                return true;
        }
        return false;
    }
    ts.isIdentifierName = isIdentifierName;
    // An alias symbol is created by one of the following declarations:
    // import <symbol> = ...
    // import <symbol> from ...
    // import * as <symbol> from ...
    // import { x as <symbol> } from ...
    // export { x as <symbol> } from ...
    // export = <EntityNameExpression>
    // export default <EntityNameExpression>
    // module.exports = <EntityNameExpression>
    function isAliasSymbolDeclaration(node) {
        return node.kind === 249 /* ImportEqualsDeclaration */ ||
            node.kind === 248 /* NamespaceExportDeclaration */ ||
            node.kind === 251 /* ImportClause */ && !!node.name ||
            node.kind === 252 /* NamespaceImport */ ||
            node.kind === 254 /* ImportSpecifier */ ||
            node.kind === 258 /* ExportSpecifier */ ||
            node.kind === 255 /* ExportAssignment */ && exportAssignmentIsAlias(node) ||
            ts.isBinaryExpression(node) && getAssignmentDeclarationKind(node) === 2 /* ModuleExports */ && exportAssignmentIsAlias(node);
    }
    ts.isAliasSymbolDeclaration = isAliasSymbolDeclaration;
    function exportAssignmentIsAlias(node) {
        var e = ts.isExportAssignment(node) ? node.expression : node.right;
        return isEntityNameExpression(e) || ts.isClassExpression(e);
    }
    ts.exportAssignmentIsAlias = exportAssignmentIsAlias;
    function getEffectiveBaseTypeNode(node) {
        var baseType = getClassExtendsHeritageElement(node);
        if (baseType && isInJSFile(node)) {
            // Prefer an @augments tag because it may have type parameters.
            var tag = ts.getJSDocAugmentsTag(node);
            if (tag) {
                return tag.class;
            }
        }
        return baseType;
    }
    ts.getEffectiveBaseTypeNode = getEffectiveBaseTypeNode;
    function getClassExtendsHeritageElement(node) {
        var heritageClause = getHeritageClause(node.heritageClauses, 87 /* ExtendsKeyword */);
        return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined;
    }
    ts.getClassExtendsHeritageElement = getClassExtendsHeritageElement;
    function getClassImplementsHeritageClauseElements(node) {
        var heritageClause = getHeritageClause(node.heritageClauses, 110 /* ImplementsKeyword */);
        return heritageClause ? heritageClause.types : undefined;
    }
    ts.getClassImplementsHeritageClauseElements = getClassImplementsHeritageClauseElements;
    /** Returns the node in an `extends` or `implements` clause of a class or interface. */
    function getAllSuperTypeNodes(node) {
        return ts.isInterfaceDeclaration(node) ? getInterfaceBaseTypeNodes(node) || ts.emptyArray
            : ts.isClassLike(node) ? ts.concatenate(ts.singleElementArray(getEffectiveBaseTypeNode(node)), getClassImplementsHeritageClauseElements(node)) || ts.emptyArray
                : ts.emptyArray;
    }
    ts.getAllSuperTypeNodes = getAllSuperTypeNodes;
    function getInterfaceBaseTypeNodes(node) {
        var heritageClause = getHeritageClause(node.heritageClauses, 87 /* ExtendsKeyword */);
        return heritageClause ? heritageClause.types : undefined;
    }
    ts.getInterfaceBaseTypeNodes = getInterfaceBaseTypeNodes;
    function getHeritageClause(clauses, kind) {
        if (clauses) {
            for (var _i = 0, clauses_1 = clauses; _i < clauses_1.length; _i++) {
                var clause = clauses_1[_i];
                if (clause.token === kind) {
                    return clause;
                }
            }
        }
        return undefined;
    }
    ts.getHeritageClause = getHeritageClause;
    function tryResolveScriptReference(host, sourceFile, reference) {
        if (!host.getCompilerOptions().noResolve) {
            var referenceFileName = ts.isRootedDiskPath(reference.fileName) ? reference.fileName : ts.combinePaths(ts.getDirectoryPath(sourceFile.fileName), reference.fileName);
            return host.getSourceFile(referenceFileName);
        }
    }
    ts.tryResolveScriptReference = tryResolveScriptReference;
    function getAncestor(node, kind) {
        while (node) {
            if (node.kind === kind) {
                return node;
            }
            node = node.parent;
        }
        return undefined;
    }
    ts.getAncestor = getAncestor;
    function isKeyword(token) {
        return 74 /* FirstKeyword */ <= token && token <= 148 /* LastKeyword */;
    }
    ts.isKeyword = isKeyword;
    function isContextualKeyword(token) {
        return 119 /* FirstContextualKeyword */ <= token && token <= 148 /* LastContextualKeyword */;
    }
    ts.isContextualKeyword = isContextualKeyword;
    function isNonContextualKeyword(token) {
        return isKeyword(token) && !isContextualKeyword(token);
    }
    ts.isNonContextualKeyword = isNonContextualKeyword;
    function isStringANonContextualKeyword(name) {
        var token = ts.stringToToken(name);
        return token !== undefined && isNonContextualKeyword(token);
    }
    ts.isStringANonContextualKeyword = isStringANonContextualKeyword;
    function isIdentifierANonContextualKeyword(_a) {
        var originalKeywordKind = _a.originalKeywordKind;
        return !!originalKeywordKind && !isContextualKeyword(originalKeywordKind);
    }
    ts.isIdentifierANonContextualKeyword = isIdentifierANonContextualKeyword;
    function isTrivia(token) {
        return 2 /* FirstTriviaToken */ <= token && token <= 7 /* LastTriviaToken */;
    }
    ts.isTrivia = isTrivia;
    var FunctionFlags;
    (function (FunctionFlags) {
        FunctionFlags[FunctionFlags["Normal"] = 0] = "Normal";
        FunctionFlags[FunctionFlags["Generator"] = 1] = "Generator";
        FunctionFlags[FunctionFlags["Async"] = 2] = "Async";
        FunctionFlags[FunctionFlags["Invalid"] = 4] = "Invalid";
        FunctionFlags[FunctionFlags["AsyncGenerator"] = 3] = "AsyncGenerator";
    })(FunctionFlags = ts.FunctionFlags || (ts.FunctionFlags = {}));
    function getFunctionFlags(node) {
        if (!node) {
            return 4 /* Invalid */;
        }
        var flags = 0 /* Normal */;
        switch (node.kind) {
            case 240 /* FunctionDeclaration */:
            case 197 /* FunctionExpression */:
            case 157 /* MethodDeclaration */:
                if (node.asteriskToken) {
                    flags |= 1 /* Generator */;
                }
            // falls through
            case 198 /* ArrowFunction */:
                if (hasModifier(node, 256 /* Async */)) {
                    flags |= 2 /* Async */;
                }
                break;
        }
        if (!node.body) {
            flags |= 4 /* Invalid */;
        }
        return flags;
    }
    ts.getFunctionFlags = getFunctionFlags;
    function isAsyncFunction(node) {
        switch (node.kind) {
            case 240 /* FunctionDeclaration */:
            case 197 /* FunctionExpression */:
            case 198 /* ArrowFunction */:
            case 157 /* MethodDeclaration */:
                return node.body !== undefined
                    && node.asteriskToken === undefined
                    && hasModifier(node, 256 /* Async */);
        }
        return false;
    }
    ts.isAsyncFunction = isAsyncFunction;
    function isStringOrNumericLiteralLike(node) {
        return ts.isStringLiteralLike(node) || ts.isNumericLiteral(node);
    }
    ts.isStringOrNumericLiteralLike = isStringOrNumericLiteralLike;
    /**
     * A declaration has a dynamic name if both of the following are true:
     *   1. The declaration has a computed property name
     *   2. The computed name is *not* expressed as Symbol.<name>, where name
     *      is a property of the Symbol constructor that denotes a built in
     *      Symbol.
     */
    function hasDynamicName(declaration) {
        var name = ts.getNameOfDeclaration(declaration);
        return !!name && isDynamicName(name);
    }
    ts.hasDynamicName = hasDynamicName;
    function isDynamicName(name) {
        return name.kind === 150 /* ComputedPropertyName */ &&
            !isStringOrNumericLiteralLike(name.expression) &&
            !isWellKnownSymbolSyntactically(name.expression);
    }
    ts.isDynamicName = isDynamicName;
    /**
     * Checks if the expression is of the form:
     *    Symbol.name
     * where Symbol is literally the word "Symbol", and name is any identifierName
     */
    function isWellKnownSymbolSyntactically(node) {
        return ts.isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression);
    }
    ts.isWellKnownSymbolSyntactically = isWellKnownSymbolSyntactically;
    function getPropertyNameForPropertyNameNode(name) {
        switch (name.kind) {
            case 73 /* Identifier */:
                return name.escapedText;
            case 10 /* StringLiteral */:
            case 8 /* NumericLiteral */:
                return ts.escapeLeadingUnderscores(name.text);
            case 150 /* ComputedPropertyName */:
                var nameExpression = name.expression;
                if (isWellKnownSymbolSyntactically(nameExpression)) {
                    return getPropertyNameForKnownSymbolName(ts.idText(nameExpression.name));
                }
                else if (isStringOrNumericLiteralLike(nameExpression)) {
                    return ts.escapeLeadingUnderscores(nameExpression.text);
                }
                return undefined;
            default:
                return ts.Debug.assertNever(name);
        }
    }
    ts.getPropertyNameForPropertyNameNode = getPropertyNameForPropertyNameNode;
    function isPropertyNameLiteral(node) {
        switch (node.kind) {
            case 73 /* Identifier */:
            case 10 /* StringLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 8 /* NumericLiteral */:
                return true;
            default:
                return false;
        }
    }
    ts.isPropertyNameLiteral = isPropertyNameLiteral;
    function getTextOfIdentifierOrLiteral(node) {
        return node.kind === 73 /* Identifier */ ? ts.idText(node) : node.text;
    }
    ts.getTextOfIdentifierOrLiteral = getTextOfIdentifierOrLiteral;
    function getEscapedTextOfIdentifierOrLiteral(node) {
        return node.kind === 73 /* Identifier */ ? node.escapedText : ts.escapeLeadingUnderscores(node.text);
    }
    ts.getEscapedTextOfIdentifierOrLiteral = getEscapedTextOfIdentifierOrLiteral;
    function getPropertyNameForKnownSymbolName(symbolName) {
        return "__@" + symbolName;
    }
    ts.getPropertyNameForKnownSymbolName = getPropertyNameForKnownSymbolName;
    function isKnownSymbol(symbol) {
        return ts.startsWith(symbol.escapedName, "__@");
    }
    ts.isKnownSymbol = isKnownSymbol;
    /**
     * Includes the word "Symbol" with unicode escapes
     */
    function isESSymbolIdentifier(node) {
        return node.kind === 73 /* Identifier */ && node.escapedText === "Symbol";
    }
    ts.isESSymbolIdentifier = isESSymbolIdentifier;
    function isPushOrUnshiftIdentifier(node) {
        return node.escapedText === "push" || node.escapedText === "unshift";
    }
    ts.isPushOrUnshiftIdentifier = isPushOrUnshiftIdentifier;
    function isParameterDeclaration(node) {
        var root = getRootDeclaration(node);
        return root.kind === 152 /* Parameter */;
    }
    ts.isParameterDeclaration = isParameterDeclaration;
    function getRootDeclaration(node) {
        while (node.kind === 187 /* BindingElement */) {
            node = node.parent.parent;
        }
        return node;
    }
    ts.getRootDeclaration = getRootDeclaration;
    function nodeStartsNewLexicalEnvironment(node) {
        var kind = node.kind;
        return kind === 158 /* Constructor */
            || kind === 197 /* FunctionExpression */
            || kind === 240 /* FunctionDeclaration */
            || kind === 198 /* ArrowFunction */
            || kind === 157 /* MethodDeclaration */
            || kind === 159 /* GetAccessor */
            || kind === 160 /* SetAccessor */
            || kind === 245 /* ModuleDeclaration */
            || kind === 285 /* SourceFile */;
    }
    ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment;
    function nodeIsSynthesized(range) {
        return ts.positionIsSynthesized(range.pos)
            || ts.positionIsSynthesized(range.end);
    }
    ts.nodeIsSynthesized = nodeIsSynthesized;
    function getOriginalSourceFile(sourceFile) {
        return ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile;
    }
    ts.getOriginalSourceFile = getOriginalSourceFile;
    var Associativity;
    (function (Associativity) {
        Associativity[Associativity["Left"] = 0] = "Left";
        Associativity[Associativity["Right"] = 1] = "Right";
    })(Associativity = ts.Associativity || (ts.Associativity = {}));
    function getExpressionAssociativity(expression) {
        var operator = getOperator(expression);
        var hasArguments = expression.kind === 193 /* NewExpression */ && expression.arguments !== undefined;
        return getOperatorAssociativity(expression.kind, operator, hasArguments);
    }
    ts.getExpressionAssociativity = getExpressionAssociativity;
    function getOperatorAssociativity(kind, operator, hasArguments) {
        switch (kind) {
            case 193 /* NewExpression */:
                return hasArguments ? 0 /* Left */ : 1 /* Right */;
            case 203 /* PrefixUnaryExpression */:
            case 200 /* TypeOfExpression */:
            case 201 /* VoidExpression */:
            case 199 /* DeleteExpression */:
            case 202 /* AwaitExpression */:
            case 206 /* ConditionalExpression */:
            case 208 /* YieldExpression */:
                return 1 /* Right */;
            case 205 /* BinaryExpression */:
                switch (operator) {
                    case 41 /* AsteriskAsteriskToken */:
                    case 60 /* EqualsToken */:
                    case 61 /* PlusEqualsToken */:
                    case 62 /* MinusEqualsToken */:
                    case 64 /* AsteriskAsteriskEqualsToken */:
                    case 63 /* AsteriskEqualsToken */:
                    case 65 /* SlashEqualsToken */:
                    case 66 /* PercentEqualsToken */:
                    case 67 /* LessThanLessThanEqualsToken */:
                    case 68 /* GreaterThanGreaterThanEqualsToken */:
                    case 69 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                    case 70 /* AmpersandEqualsToken */:
                    case 72 /* CaretEqualsToken */:
                    case 71 /* BarEqualsToken */:
                        return 1 /* Right */;
                }
        }
        return 0 /* Left */;
    }
    ts.getOperatorAssociativity = getOperatorAssociativity;
    function getExpressionPrecedence(expression) {
        var operator = getOperator(expression);
        var hasArguments = expression.kind === 193 /* NewExpression */ && expression.arguments !== undefined;
        return getOperatorPrecedence(expression.kind, operator, hasArguments);
    }
    ts.getExpressionPrecedence = getExpressionPrecedence;
    function getOperator(expression) {
        if (expression.kind === 205 /* BinaryExpression */) {
            return expression.operatorToken.kind;
        }
        else if (expression.kind === 203 /* PrefixUnaryExpression */ || expression.kind === 204 /* PostfixUnaryExpression */) {
            return expression.operator;
        }
        else {
            return expression.kind;
        }
    }
    ts.getOperator = getOperator;
    function getOperatorPrecedence(nodeKind, operatorKind, hasArguments) {
        switch (nodeKind) {
            case 315 /* CommaListExpression */:
                return 0;
            case 209 /* SpreadElement */:
                return 1;
            case 208 /* YieldExpression */:
                return 2;
            case 206 /* ConditionalExpression */:
                return 4;
            case 205 /* BinaryExpression */:
                switch (operatorKind) {
                    case 27 /* CommaToken */:
                        return 0;
                    case 60 /* EqualsToken */:
                    case 61 /* PlusEqualsToken */:
                    case 62 /* MinusEqualsToken */:
                    case 64 /* AsteriskAsteriskEqualsToken */:
                    case 63 /* AsteriskEqualsToken */:
                    case 65 /* SlashEqualsToken */:
                    case 66 /* PercentEqualsToken */:
                    case 67 /* LessThanLessThanEqualsToken */:
                    case 68 /* GreaterThanGreaterThanEqualsToken */:
                    case 69 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                    case 70 /* AmpersandEqualsToken */:
                    case 72 /* CaretEqualsToken */:
                    case 71 /* BarEqualsToken */:
                        return 3;
                    default:
                        return getBinaryOperatorPrecedence(operatorKind);
                }
            case 203 /* PrefixUnaryExpression */:
            case 200 /* TypeOfExpression */:
            case 201 /* VoidExpression */:
            case 199 /* DeleteExpression */:
            case 202 /* AwaitExpression */:
                return 16;
            case 204 /* PostfixUnaryExpression */:
                return 17;
            case 192 /* CallExpression */:
                return 18;
            case 193 /* NewExpression */:
                return hasArguments ? 19 : 18;
            case 194 /* TaggedTemplateExpression */:
            case 190 /* PropertyAccessExpression */:
            case 191 /* ElementAccessExpression */:
                return 19;
            case 101 /* ThisKeyword */:
            case 99 /* SuperKeyword */:
            case 73 /* Identifier */:
            case 97 /* NullKeyword */:
            case 103 /* TrueKeyword */:
            case 88 /* FalseKeyword */:
            case 8 /* NumericLiteral */:
            case 9 /* BigIntLiteral */:
            case 10 /* StringLiteral */:
            case 188 /* ArrayLiteralExpression */:
            case 189 /* ObjectLiteralExpression */:
            case 197 /* FunctionExpression */:
            case 198 /* ArrowFunction */:
            case 210 /* ClassExpression */:
            case 261 /* JsxElement */:
            case 262 /* JsxSelfClosingElement */:
            case 265 /* JsxFragment */:
            case 13 /* RegularExpressionLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 207 /* TemplateExpression */:
            case 196 /* ParenthesizedExpression */:
            case 211 /* OmittedExpression */:
                return 20;
            default:
                return -1;
        }
    }
    ts.getOperatorPrecedence = getOperatorPrecedence;
    function getBinaryOperatorPrecedence(kind) {
        switch (kind) {
            case 55 /* BarBarToken */:
                return 5;
            case 54 /* AmpersandAmpersandToken */:
                return 6;
            case 50 /* BarToken */:
                return 7;
            case 51 /* CaretToken */:
                return 8;
            case 49 /* AmpersandToken */:
                return 9;
            case 33 /* EqualsEqualsToken */:
            case 34 /* ExclamationEqualsToken */:
            case 35 /* EqualsEqualsEqualsToken */:
            case 36 /* ExclamationEqualsEqualsToken */:
                return 10;
            case 28 /* LessThanToken */:
            case 30 /* GreaterThanToken */:
            case 31 /* LessThanEqualsToken */:
            case 32 /* GreaterThanEqualsToken */:
            case 95 /* InstanceOfKeyword */:
            case 94 /* InKeyword */:
            case 120 /* AsKeyword */:
                return 11;
            case 46 /* LessThanLessThanToken */:
            case 47 /* GreaterThanGreaterThanToken */:
            case 48 /* GreaterThanGreaterThanGreaterThanToken */:
                return 12;
            case 38 /* PlusToken */:
            case 39 /* MinusToken */:
                return 13;
            case 40 /* AsteriskToken */:
            case 42 /* SlashToken */:
            case 43 /* PercentToken */:
                return 14;
            case 41 /* AsteriskAsteriskToken */:
                return 15;
        }
        // -1 is lower than all other precedences.  Returning it will cause binary expression
        // parsing to stop.
        return -1;
    }
    ts.getBinaryOperatorPrecedence = getBinaryOperatorPrecedence;
    function createDiagnosticCollection() {
        var nonFileDiagnostics = []; // See GH#19873
        var filesWithDiagnostics = [];
        var fileDiagnostics = ts.createMap();
        var hasReadNonFileDiagnostics = false;
        return {
            add: add,
            lookup: lookup,
            getGlobalDiagnostics: getGlobalDiagnostics,
            getDiagnostics: getDiagnostics,
            reattachFileDiagnostics: reattachFileDiagnostics
        };
        function reattachFileDiagnostics(newFile) {
            ts.forEach(fileDiagnostics.get(newFile.fileName), function (diagnostic) { return diagnostic.file = newFile; });
        }
        function lookup(diagnostic) {
            var diagnostics;
            if (diagnostic.file) {
                diagnostics = fileDiagnostics.get(diagnostic.file.fileName);
            }
            else {
                diagnostics = nonFileDiagnostics;
            }
            if (!diagnostics) {
                return undefined;
            }
            var result = ts.binarySearch(diagnostics, diagnostic, ts.identity, ts.compareDiagnosticsSkipRelatedInformation);
            if (result >= 0) {
                return diagnostics[result];
            }
            return undefined;
        }
        function add(diagnostic) {
            var diagnostics;
            if (diagnostic.file) {
                diagnostics = fileDiagnostics.get(diagnostic.file.fileName);
                if (!diagnostics) {
                    diagnostics = []; // See GH#19873
                    fileDiagnostics.set(diagnostic.file.fileName, diagnostics);
                    ts.insertSorted(filesWithDiagnostics, diagnostic.file.fileName, ts.compareStringsCaseSensitive);
                }
            }
            else {
                // If we've already read the non-file diagnostics, do not modify the existing array.
                if (hasReadNonFileDiagnostics) {
                    hasReadNonFileDiagnostics = false;
                    nonFileDiagnostics = nonFileDiagnostics.slice();
                }
                diagnostics = nonFileDiagnostics;
            }
            ts.insertSorted(diagnostics, diagnostic, ts.compareDiagnostics);
        }
        function getGlobalDiagnostics() {
            hasReadNonFileDiagnostics = true;
            return nonFileDiagnostics;
        }
        function getDiagnostics(fileName) {
            if (fileName) {
                return fileDiagnostics.get(fileName) || [];
            }
            var fileDiags = ts.flatMapToMutable(filesWithDiagnostics, function (f) { return fileDiagnostics.get(f); });
            if (!nonFileDiagnostics.length) {
                return fileDiags;
            }
            fileDiags.unshift.apply(fileDiags, nonFileDiagnostics);
            return fileDiags;
        }
    }
    ts.createDiagnosticCollection = createDiagnosticCollection;
    // This consists of the first 19 unprintable ASCII characters, canonical escapes, lineSeparator,
    // paragraphSeparator, and nextLine. The latter three are just desirable to suppress new lines in
    // the language service. These characters should be escaped when printing, and if any characters are added,
    // the map below must be updated. Note that this regexp *does not* include the 'delete' character.
    // There is no reason for this other than that JSON.stringify does not handle it either.
    var doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
    var singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
    var backtickQuoteEscapedCharsRegExp = /[\\\`\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
    var escapedCharsMap = ts.createMapFromTemplate({
        "\t": "\\t",
        "\v": "\\v",
        "\f": "\\f",
        "\b": "\\b",
        "\r": "\\r",
        "\n": "\\n",
        "\\": "\\\\",
        "\"": "\\\"",
        "\'": "\\\'",
        "\`": "\\\`",
        "\u2028": "\\u2028",
        "\u2029": "\\u2029",
        "\u0085": "\\u0085" // nextLine
    });
    /**
     * Based heavily on the abstract 'Quote'/'QuoteJSONString' operation from ECMA-262 (24.3.2.2),
     * but augmented for a few select characters (e.g. lineSeparator, paragraphSeparator, nextLine)
     * Note that this doesn't actually wrap the input in double quotes.
     */
    function escapeString(s, quoteChar) {
        var escapedCharsRegExp = quoteChar === 96 /* backtick */ ? backtickQuoteEscapedCharsRegExp :
            quoteChar === 39 /* singleQuote */ ? singleQuoteEscapedCharsRegExp :
                doubleQuoteEscapedCharsRegExp;
        return s.replace(escapedCharsRegExp, getReplacement);
    }
    ts.escapeString = escapeString;
    function getReplacement(c, offset, input) {
        if (c.charCodeAt(0) === 0 /* nullCharacter */) {
            var lookAhead = input.charCodeAt(offset + c.length);
            if (lookAhead >= 48 /* _0 */ && lookAhead <= 57 /* _9 */) {
                // If the null character is followed by digits, print as a hex escape to prevent the result from parsing as an octal (which is forbidden in strict mode)
                return "\\x00";
            }
            // Otherwise, keep printing a literal \0 for the null character
            return "\\0";
        }
        return escapedCharsMap.get(c) || get16BitUnicodeEscapeSequence(c.charCodeAt(0));
    }
    function isIntrinsicJsxName(name) {
        var ch = name.charCodeAt(0);
        return (ch >= 97 /* a */ && ch <= 122 /* z */) || ts.stringContains(name, "-");
    }
    ts.isIntrinsicJsxName = isIntrinsicJsxName;
    function get16BitUnicodeEscapeSequence(charCode) {
        var hexCharCode = charCode.toString(16).toUpperCase();
        var paddedHexCode = ("0000" + hexCharCode).slice(-4);
        return "\\u" + paddedHexCode;
    }
    var nonAsciiCharacters = /[^\u0000-\u007F]/g;
    function escapeNonAsciiString(s, quoteChar) {
        s = escapeString(s, quoteChar);
        // Replace non-ASCII characters with '\uNNNN' escapes if any exist.
        // Otherwise just return the original string.
        return nonAsciiCharacters.test(s) ?
            s.replace(nonAsciiCharacters, function (c) { return get16BitUnicodeEscapeSequence(c.charCodeAt(0)); }) :
            s;
    }
    ts.escapeNonAsciiString = escapeNonAsciiString;
    var indentStrings = ["", "    "];
    function getIndentString(level) {
        if (indentStrings[level] === undefined) {
            indentStrings[level] = getIndentString(level - 1) + indentStrings[1];
        }
        return indentStrings[level];
    }
    ts.getIndentString = getIndentString;
    function getIndentSize() {
        return indentStrings[1].length;
    }
    ts.getIndentSize = getIndentSize;
    function createTextWriter(newLine) {
        var output;
        var indent;
        var lineStart;
        var lineCount;
        var linePos;
        function updateLineCountAndPosFor(s) {
            var lineStartsOfS = ts.computeLineStarts(s);
            if (lineStartsOfS.length > 1) {
                lineCount = lineCount + lineStartsOfS.length - 1;
                linePos = output.length - s.length + ts.last(lineStartsOfS);
                lineStart = (linePos - output.length) === 0;
            }
            else {
                lineStart = false;
            }
        }
        function write(s) {
            if (s && s.length) {
                if (lineStart) {
                    s = getIndentString(indent) + s;
                    lineStart = false;
                }
                output += s;
                updateLineCountAndPosFor(s);
            }
        }
        function reset() {
            output = "";
            indent = 0;
            lineStart = true;
            lineCount = 0;
            linePos = 0;
        }
        function rawWrite(s) {
            if (s !== undefined) {
                output += s;
                updateLineCountAndPosFor(s);
            }
        }
        function writeLiteral(s) {
            if (s && s.length) {
                write(s);
            }
        }
        function writeLine() {
            if (!lineStart) {
                output += newLine;
                lineCount++;
                linePos = output.length;
                lineStart = true;
            }
        }
        function getTextPosWithWriteLine() {
            return lineStart ? output.length : (output.length + newLine.length);
        }
        reset();
        return {
            write: write,
            rawWrite: rawWrite,
            writeLiteral: writeLiteral,
            writeLine: writeLine,
            increaseIndent: function () { indent++; },
            decreaseIndent: function () { indent--; },
            getIndent: function () { return indent; },
            getTextPos: function () { return output.length; },
            getLine: function () { return lineCount; },
            getColumn: function () { return lineStart ? indent * getIndentSize() : output.length - linePos; },
            getText: function () { return output; },
            isAtStartOfLine: function () { return lineStart; },
            clear: reset,
            reportInaccessibleThisError: ts.noop,
            reportPrivateInBaseOfClassExpression: ts.noop,
            reportInaccessibleUniqueSymbolError: ts.noop,
            trackSymbol: ts.noop,
            writeKeyword: write,
            writeOperator: write,
            writeParameter: write,
            writeProperty: write,
            writePunctuation: write,
            writeSpace: write,
            writeStringLiteral: write,
            writeSymbol: function (s, _) { return write(s); },
            writeTrailingSemicolon: write,
            writeComment: write,
            getTextPosWithWriteLine: getTextPosWithWriteLine
        };
    }
    ts.createTextWriter = createTextWriter;
    function getTrailingSemicolonOmittingWriter(writer) {
        var pendingTrailingSemicolon = false;
        function commitPendingTrailingSemicolon() {
            if (pendingTrailingSemicolon) {
                writer.writeTrailingSemicolon(";");
                pendingTrailingSemicolon = false;
            }
        }
        return __assign({}, writer, { writeTrailingSemicolon: function () {
                pendingTrailingSemicolon = true;
            },
            writeLiteral: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeLiteral(s);
            },
            writeStringLiteral: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeStringLiteral(s);
            },
            writeSymbol: function (s, sym) {
                commitPendingTrailingSemicolon();
                writer.writeSymbol(s, sym);
            },
            writePunctuation: function (s) {
                commitPendingTrailingSemicolon();
                writer.writePunctuation(s);
            },
            writeKeyword: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeKeyword(s);
            },
            writeOperator: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeOperator(s);
            },
            writeParameter: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeParameter(s);
            },
            writeSpace: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeSpace(s);
            },
            writeProperty: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeProperty(s);
            },
            writeComment: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeComment(s);
            },
            writeLine: function () {
                commitPendingTrailingSemicolon();
                writer.writeLine();
            },
            increaseIndent: function () {
                commitPendingTrailingSemicolon();
                writer.increaseIndent();
            },
            decreaseIndent: function () {
                commitPendingTrailingSemicolon();
                writer.decreaseIndent();
            } });
    }
    ts.getTrailingSemicolonOmittingWriter = getTrailingSemicolonOmittingWriter;
    function getResolvedExternalModuleName(host, file, referenceFile) {
        return file.moduleName || getExternalModuleNameFromPath(host, file.fileName, referenceFile && referenceFile.fileName);
    }
    ts.getResolvedExternalModuleName = getResolvedExternalModuleName;
    function getExternalModuleNameFromDeclaration(host, resolver, declaration) {
        var file = resolver.getExternalModuleFileFromDeclaration(declaration);
        if (!file || file.isDeclarationFile) {
            return undefined;
        }
        return getResolvedExternalModuleName(host, file);
    }
    ts.getExternalModuleNameFromDeclaration = getExternalModuleNameFromDeclaration;
    /**
     * Resolves a local path to a path which is absolute to the base of the emit
     */
    function getExternalModuleNameFromPath(host, fileName, referencePath) {
        var getCanonicalFileName = function (f) { return host.getCanonicalFileName(f); };
        var dir = toPath(referencePath ? ts.getDirectoryPath(referencePath) : host.getCommonSourceDirectory(), host.getCurrentDirectory(), getCanonicalFileName);
        var filePath = ts.getNormalizedAbsolutePath(fileName, host.getCurrentDirectory());
        var relativePath = ts.getRelativePathToDirectoryOrUrl(dir, filePath, dir, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
        var extensionless = ts.removeFileExtension(relativePath);
        return referencePath ? ts.ensurePathIsNonModuleName(extensionless) : extensionless;
    }
    ts.getExternalModuleNameFromPath = getExternalModuleNameFromPath;
    function getOwnEmitOutputFilePath(fileName, host, extension) {
        var compilerOptions = host.getCompilerOptions();
        var emitOutputFilePathWithoutExtension;
        if (compilerOptions.outDir) {
            emitOutputFilePathWithoutExtension = ts.removeFileExtension(getSourceFilePathInNewDir(fileName, host, compilerOptions.outDir));
        }
        else {
            emitOutputFilePathWithoutExtension = ts.removeFileExtension(fileName);
        }
        return emitOutputFilePathWithoutExtension + extension;
    }
    ts.getOwnEmitOutputFilePath = getOwnEmitOutputFilePath;
    function getDeclarationEmitOutputFilePath(fileName, host) {
        return getDeclarationEmitOutputFilePathWorker(fileName, host.getCompilerOptions(), host.getCurrentDirectory(), host.getCommonSourceDirectory(), function (f) { return host.getCanonicalFileName(f); });
    }
    ts.getDeclarationEmitOutputFilePath = getDeclarationEmitOutputFilePath;
    function getDeclarationEmitOutputFilePathWorker(fileName, options, currentDirectory, commonSourceDirectory, getCanonicalFileName) {
        var outputDir = options.declarationDir || options.outDir; // Prefer declaration folder if specified
        var path = outputDir
            ? getSourceFilePathInNewDirWorker(fileName, outputDir, currentDirectory, commonSourceDirectory, getCanonicalFileName)
            : fileName;
        return ts.removeFileExtension(path) + ".d.ts" /* Dts */;
    }
    ts.getDeclarationEmitOutputFilePathWorker = getDeclarationEmitOutputFilePathWorker;
    /**
     * Gets the source files that are expected to have an emit output.
     *
     * Originally part of `forEachExpectedEmitFile`, this functionality was extracted to support
     * transformations.
     *
     * @param host An EmitHost.
     * @param targetSourceFile An optional target source file to emit.
     */
    function getSourceFilesToEmit(host, targetSourceFile) {
        var options = host.getCompilerOptions();
        var isSourceFileFromExternalLibrary = function (file) { return host.isSourceFileFromExternalLibrary(file); };
        var getResolvedProjectReferenceToRedirect = function (fileName) { return host.getResolvedProjectReferenceToRedirect(fileName); };
        if (options.outFile || options.out) {
            var moduleKind = ts.getEmitModuleKind(options);
            var moduleEmitEnabled_1 = options.emitDeclarationOnly || moduleKind === ts.ModuleKind.AMD || moduleKind === ts.ModuleKind.System;
            // Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified
            return ts.filter(host.getSourceFiles(), function (sourceFile) {
                return (moduleEmitEnabled_1 || !ts.isExternalModule(sourceFile)) && sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary, getResolvedProjectReferenceToRedirect);
            });
        }
        else {
            var sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
            return ts.filter(sourceFiles, function (sourceFile) { return sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary, getResolvedProjectReferenceToRedirect); });
        }
    }
    ts.getSourceFilesToEmit = getSourceFilesToEmit;
    /** Don't call this for `--outFile`, just for `--outDir` or plain emit. `--outFile` needs additional checks. */
    function sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary, getResolvedProjectReferenceToRedirect) {
        return !(options.noEmitForJsFiles && isSourceFileJS(sourceFile)) &&
            !sourceFile.isDeclarationFile &&
            !isSourceFileFromExternalLibrary(sourceFile) &&
            !(isJsonSourceFile(sourceFile) && getResolvedProjectReferenceToRedirect(sourceFile.fileName));
    }
    ts.sourceFileMayBeEmitted = sourceFileMayBeEmitted;
    function getSourceFilePathInNewDir(fileName, host, newDirPath) {
        return getSourceFilePathInNewDirWorker(fileName, newDirPath, host.getCurrentDirectory(), host.getCommonSourceDirectory(), function (f) { return host.getCanonicalFileName(f); });
    }
    ts.getSourceFilePathInNewDir = getSourceFilePathInNewDir;
    function getSourceFilePathInNewDirWorker(fileName, newDirPath, currentDirectory, commonSourceDirectory, getCanonicalFileName) {
        var sourceFilePath = ts.getNormalizedAbsolutePath(fileName, currentDirectory);
        var isSourceFileInCommonSourceDirectory = getCanonicalFileName(sourceFilePath).indexOf(getCanonicalFileName(commonSourceDirectory)) === 0;
        sourceFilePath = isSourceFileInCommonSourceDirectory ? sourceFilePath.substring(commonSourceDirectory.length) : sourceFilePath;
        return ts.combinePaths(newDirPath, sourceFilePath);
    }
    ts.getSourceFilePathInNewDirWorker = getSourceFilePathInNewDirWorker;
    function writeFile(host, diagnostics, fileName, data, writeByteOrderMark, sourceFiles) {
        host.writeFile(fileName, data, writeByteOrderMark, function (hostErrorMessage) {
            diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage));
        }, sourceFiles);
    }
    ts.writeFile = writeFile;
    function getLineOfLocalPosition(currentSourceFile, pos) {
        return ts.getLineAndCharacterOfPosition(currentSourceFile, pos).line;
    }
    ts.getLineOfLocalPosition = getLineOfLocalPosition;
    function getLineOfLocalPositionFromLineMap(lineMap, pos) {
        return ts.computeLineAndCharacterOfPosition(lineMap, pos).line;
    }
    ts.getLineOfLocalPositionFromLineMap = getLineOfLocalPositionFromLineMap;
    function getFirstConstructorWithBody(node) {
        return ts.find(node.members, function (member) { return ts.isConstructorDeclaration(member) && nodeIsPresent(member.body); });
    }
    ts.getFirstConstructorWithBody = getFirstConstructorWithBody;
    function getSetAccessorValueParameter(accessor) {
        if (accessor && accessor.parameters.length > 0) {
            var hasThis = accessor.parameters.length === 2 && parameterIsThisKeyword(accessor.parameters[0]);
            return accessor.parameters[hasThis ? 1 : 0];
        }
    }
    /** Get the type annotation for the value parameter. */
    function getSetAccessorTypeAnnotationNode(accessor) {
        var parameter = getSetAccessorValueParameter(accessor);
        return parameter && parameter.type;
    }
    ts.getSetAccessorTypeAnnotationNode = getSetAccessorTypeAnnotationNode;
    function getThisParameter(signature) {
        // callback tags do not currently support this parameters
        if (signature.parameters.length && !ts.isJSDocSignature(signature)) {
            var thisParameter = signature.parameters[0];
            if (parameterIsThisKeyword(thisParameter)) {
                return thisParameter;
            }
        }
    }
    ts.getThisParameter = getThisParameter;
    function parameterIsThisKeyword(parameter) {
        return isThisIdentifier(parameter.name);
    }
    ts.parameterIsThisKeyword = parameterIsThisKeyword;
    function isThisIdentifier(node) {
        return !!node && node.kind === 73 /* Identifier */ && identifierIsThisKeyword(node);
    }
    ts.isThisIdentifier = isThisIdentifier;
    function identifierIsThisKeyword(id) {
        return id.originalKeywordKind === 101 /* ThisKeyword */;
    }
    ts.identifierIsThisKeyword = identifierIsThisKeyword;
    function getAllAccessorDeclarations(declarations, accessor) {
        // TODO: GH#18217
        var firstAccessor;
        var secondAccessor;
        var getAccessor;
        var setAccessor;
        if (hasDynamicName(accessor)) {
            firstAccessor = accessor;
            if (accessor.kind === 159 /* GetAccessor */) {
                getAccessor = accessor;
            }
            else if (accessor.kind === 160 /* SetAccessor */) {
                setAccessor = accessor;
            }
            else {
                ts.Debug.fail("Accessor has wrong kind");
            }
        }
        else {
            ts.forEach(declarations, function (member) {
                if (ts.isAccessor(member)
                    && hasModifier(member, 32 /* Static */) === hasModifier(accessor, 32 /* Static */)) {
                    var memberName = getPropertyNameForPropertyNameNode(member.name);
                    var accessorName = getPropertyNameForPropertyNameNode(accessor.name);
                    if (memberName === accessorName) {
                        if (!firstAccessor) {
                            firstAccessor = member;
                        }
                        else if (!secondAccessor) {
                            secondAccessor = member;
                        }
                        if (member.kind === 159 /* GetAccessor */ && !getAccessor) {
                            getAccessor = member;
                        }
                        if (member.kind === 160 /* SetAccessor */ && !setAccessor) {
                            setAccessor = member;
                        }
                    }
                }
            });
        }
        return {
            firstAccessor: firstAccessor,
            secondAccessor: secondAccessor,
            getAccessor: getAccessor,
            setAccessor: setAccessor
        };
    }
    ts.getAllAccessorDeclarations = getAllAccessorDeclarations;
    /**
     * Gets the effective type annotation of a variable, parameter, or property. If the node was
     * parsed in a JavaScript file, gets the type annotation from JSDoc.
     */
    function getEffectiveTypeAnnotationNode(node) {
        var type = node.type;
        if (type || !isInJSFile(node))
            return type;
        return ts.isJSDocPropertyLikeTag(node) ? node.typeExpression && node.typeExpression.type : ts.getJSDocType(node);
    }
    ts.getEffectiveTypeAnnotationNode = getEffectiveTypeAnnotationNode;
    function getTypeAnnotationNode(node) {
        return node.type;
    }
    ts.getTypeAnnotationNode = getTypeAnnotationNode;
    /**
     * Gets the effective return type annotation of a signature. If the node was parsed in a
     * JavaScript file, gets the return type annotation from JSDoc.
     */
    function getEffectiveReturnTypeNode(node) {
        return ts.isJSDocSignature(node) ?
            node.type && node.type.typeExpression && node.type.typeExpression.type :
            node.type || (isInJSFile(node) ? ts.getJSDocReturnType(node) : undefined);
    }
    ts.getEffectiveReturnTypeNode = getEffectiveReturnTypeNode;
    function getJSDocTypeParameterDeclarations(node) {
        return ts.flatMap(ts.getJSDocTags(node), function (tag) { return isNonTypeAliasTemplate(tag) ? tag.typeParameters : undefined; });
    }
    ts.getJSDocTypeParameterDeclarations = getJSDocTypeParameterDeclarations;
    /** template tags are only available when a typedef isn't already using them */
    function isNonTypeAliasTemplate(tag) {
        return ts.isJSDocTemplateTag(tag) && !(tag.parent.kind === 297 /* JSDocComment */ && tag.parent.tags.some(isJSDocTypeAlias));
    }
    /**
     * Gets the effective type annotation of the value parameter of a set accessor. If the node
     * was parsed in a JavaScript file, gets the type annotation from JSDoc.
     */
    function getEffectiveSetAccessorTypeAnnotationNode(node) {
        var parameter = getSetAccessorValueParameter(node);
        return parameter && getEffectiveTypeAnnotationNode(parameter);
    }
    ts.getEffectiveSetAccessorTypeAnnotationNode = getEffectiveSetAccessorTypeAnnotationNode;
    function emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments) {
        emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, node.pos, leadingComments);
    }
    ts.emitNewLineBeforeLeadingComments = emitNewLineBeforeLeadingComments;
    function emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, pos, leadingComments) {
        // If the leading comments start on different line than the start of node, write new line
        if (leadingComments && leadingComments.length && pos !== leadingComments[0].pos &&
            getLineOfLocalPositionFromLineMap(lineMap, pos) !== getLineOfLocalPositionFromLineMap(lineMap, leadingComments[0].pos)) {
            writer.writeLine();
        }
    }
    ts.emitNewLineBeforeLeadingCommentsOfPosition = emitNewLineBeforeLeadingCommentsOfPosition;
    function emitNewLineBeforeLeadingCommentOfPosition(lineMap, writer, pos, commentPos) {
        // If the leading comments start on different line than the start of node, write new line
        if (pos !== commentPos &&
            getLineOfLocalPositionFromLineMap(lineMap, pos) !== getLineOfLocalPositionFromLineMap(lineMap, commentPos)) {
            writer.writeLine();
        }
    }
    ts.emitNewLineBeforeLeadingCommentOfPosition = emitNewLineBeforeLeadingCommentOfPosition;
    function emitComments(text, lineMap, writer, comments, leadingSeparator, trailingSeparator, newLine, writeComment) {
        if (comments && comments.length > 0) {
            if (leadingSeparator) {
                writer.writeSpace(" ");
            }
            var emitInterveningSeparator = false;
            for (var _i = 0, comments_1 = comments; _i < comments_1.length; _i++) {
                var comment = comments_1[_i];
                if (emitInterveningSeparator) {
                    writer.writeSpace(" ");
                    emitInterveningSeparator = false;
                }
                writeComment(text, lineMap, writer, comment.pos, comment.end, newLine);
                if (comment.hasTrailingNewLine) {
                    writer.writeLine();
                }
                else {
                    emitInterveningSeparator = true;
                }
            }
            if (emitInterveningSeparator && trailingSeparator) {
                writer.writeSpace(" ");
            }
        }
    }
    ts.emitComments = emitComments;
    /**
     * Detached comment is a comment at the top of file or function body that is separated from
     * the next statement by space.
     */
    function emitDetachedComments(text, lineMap, writer, writeComment, node, newLine, removeComments) {
        var leadingComments;
        var currentDetachedCommentInfo;
        if (removeComments) {
            // removeComments is true, only reserve pinned comment at the top of file
            // For example:
            //      /*! Pinned Comment */
            //
            //      var x = 10;
            if (node.pos === 0) {
                leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedCommentLocal);
            }
        }
        else {
            // removeComments is false, just get detached as normal and bypass the process to filter comment
            leadingComments = ts.getLeadingCommentRanges(text, node.pos);
        }
        if (leadingComments) {
            var detachedComments = [];
            var lastComment = void 0;
            for (var _i = 0, leadingComments_1 = leadingComments; _i < leadingComments_1.length; _i++) {
                var comment = leadingComments_1[_i];
                if (lastComment) {
                    var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, lastComment.end);
                    var commentLine = getLineOfLocalPositionFromLineMap(lineMap, comment.pos);
                    if (commentLine >= lastCommentLine + 2) {
                        // There was a blank line between the last comment and this comment.  This
                        // comment is not part of the copyright comments.  Return what we have so
                        // far.
                        break;
                    }
                }
                detachedComments.push(comment);
                lastComment = comment;
            }
            if (detachedComments.length) {
                // All comments look like they could have been part of the copyright header.  Make
                // sure there is at least one blank line between it and the node.  If not, it's not
                // a copyright header.
                var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, ts.last(detachedComments).end);
                var nodeLine = getLineOfLocalPositionFromLineMap(lineMap, ts.skipTrivia(text, node.pos));
                if (nodeLine >= lastCommentLine + 2) {
                    // Valid detachedComments
                    emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments);
                    emitComments(text, lineMap, writer, detachedComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
                    currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: ts.last(detachedComments).end };
                }
            }
        }
        return currentDetachedCommentInfo;
        function isPinnedCommentLocal(comment) {
            return isPinnedComment(text, comment.pos);
        }
    }
    ts.emitDetachedComments = emitDetachedComments;
    function writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine) {
        if (text.charCodeAt(commentPos + 1) === 42 /* asterisk */) {
            var firstCommentLineAndCharacter = ts.computeLineAndCharacterOfPosition(lineMap, commentPos);
            var lineCount = lineMap.length;
            var firstCommentLineIndent = void 0;
            for (var pos = commentPos, currentLine = firstCommentLineAndCharacter.line; pos < commentEnd; currentLine++) {
                var nextLineStart = (currentLine + 1) === lineCount
                    ? text.length + 1
                    : lineMap[currentLine + 1];
                if (pos !== commentPos) {
                    // If we are not emitting first line, we need to write the spaces to adjust the alignment
                    if (firstCommentLineIndent === undefined) {
                        firstCommentLineIndent = calculateIndent(text, lineMap[firstCommentLineAndCharacter.line], commentPos);
                    }
                    // These are number of spaces writer is going to write at current indent
                    var currentWriterIndentSpacing = writer.getIndent() * getIndentSize();
                    // Number of spaces we want to be writing
                    // eg: Assume writer indent
                    // module m {
                    //         /* starts at character 9 this is line 1
                    //    * starts at character pos 4 line                        --1  = 8 - 8 + 3
                    //   More left indented comment */                            --2  = 8 - 8 + 2
                    //     class c { }
                    // }
                    // module m {
                    //     /* this is line 1 -- Assume current writer indent 8
                    //      * line                                                --3 = 8 - 4 + 5
                    //            More right indented comment */                  --4 = 8 - 4 + 11
                    //     class c { }
                    // }
                    var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(text, pos, nextLineStart);
                    if (spacesToEmit > 0) {
                        var numberOfSingleSpacesToEmit = spacesToEmit % getIndentSize();
                        var indentSizeSpaceString = getIndentString((spacesToEmit - numberOfSingleSpacesToEmit) / getIndentSize());
                        // Write indent size string ( in eg 1: = "", 2: "" , 3: string with 8 spaces 4: string with 12 spaces
                        writer.rawWrite(indentSizeSpaceString);
                        // Emit the single spaces (in eg: 1: 3 spaces, 2: 2 spaces, 3: 1 space, 4: 3 spaces)
                        while (numberOfSingleSpacesToEmit) {
                            writer.rawWrite(" ");
                            numberOfSingleSpacesToEmit--;
                        }
                    }
                    else {
                        // No spaces to emit write empty string
                        writer.rawWrite("");
                    }
                }
                // Write the comment line text
                writeTrimmedCurrentLine(text, commentEnd, writer, newLine, pos, nextLineStart);
                pos = nextLineStart;
            }
        }
        else {
            // Single line comment of style //....
            writer.writeComment(text.substring(commentPos, commentEnd));
        }
    }
    ts.writeCommentRange = writeCommentRange;
    function writeTrimmedCurrentLine(text, commentEnd, writer, newLine, pos, nextLineStart) {
        var end = Math.min(commentEnd, nextLineStart - 1);
        var currentLineText = text.substring(pos, end).replace(/^\s+|\s+$/g, "");
        if (currentLineText) {
            // trimmed forward and ending spaces text
            writer.writeComment(currentLineText);
            if (end !== commentEnd) {
                writer.writeLine();
            }
        }
        else {
            // Empty string - make sure we write empty line
            writer.rawWrite(newLine);
        }
    }
    function calculateIndent(text, pos, end) {
        var currentLineIndent = 0;
        for (; pos < end && ts.isWhiteSpaceSingleLine(text.charCodeAt(pos)); pos++) {
            if (text.charCodeAt(pos) === 9 /* tab */) {
                // Tabs = TabSize = indent size and go to next tabStop
                currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
            }
            else {
                // Single space
                currentLineIndent++;
            }
        }
        return currentLineIndent;
    }
    function hasModifiers(node) {
        return getModifierFlags(node) !== 0 /* None */;
    }
    ts.hasModifiers = hasModifiers;
    function hasModifier(node, flags) {
        return !!getSelectedModifierFlags(node, flags);
    }
    ts.hasModifier = hasModifier;
    function hasStaticModifier(node) {
        return hasModifier(node, 32 /* Static */);
    }
    ts.hasStaticModifier = hasStaticModifier;
    function hasReadonlyModifier(node) {
        return hasModifier(node, 64 /* Readonly */);
    }
    ts.hasReadonlyModifier = hasReadonlyModifier;
    function getSelectedModifierFlags(node, flags) {
        return getModifierFlags(node) & flags;
    }
    ts.getSelectedModifierFlags = getSelectedModifierFlags;
    function getModifierFlags(node) {
        if (node.modifierFlagsCache & 536870912 /* HasComputedFlags */) {
            return node.modifierFlagsCache & ~536870912 /* HasComputedFlags */;
        }
        var flags = getModifierFlagsNoCache(node);
        node.modifierFlagsCache = flags | 536870912 /* HasComputedFlags */;
        return flags;
    }
    ts.getModifierFlags = getModifierFlags;
    function getModifierFlagsNoCache(node) {
        var flags = 0 /* None */;
        if (node.modifiers) {
            for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
                var modifier = _a[_i];
                flags |= modifierToFlag(modifier.kind);
            }
        }
        if (node.flags & 4 /* NestedNamespace */ || (node.kind === 73 /* Identifier */ && node.isInJSDocNamespace)) {
            flags |= 1 /* Export */;
        }
        return flags;
    }
    ts.getModifierFlagsNoCache = getModifierFlagsNoCache;
    function modifierToFlag(token) {
        switch (token) {
            case 117 /* StaticKeyword */: return 32 /* Static */;
            case 116 /* PublicKeyword */: return 4 /* Public */;
            case 115 /* ProtectedKeyword */: return 16 /* Protected */;
            case 114 /* PrivateKeyword */: return 8 /* Private */;
            case 119 /* AbstractKeyword */: return 128 /* Abstract */;
            case 86 /* ExportKeyword */: return 1 /* Export */;
            case 126 /* DeclareKeyword */: return 2 /* Ambient */;
            case 78 /* ConstKeyword */: return 2048 /* Const */;
            case 81 /* DefaultKeyword */: return 512 /* Default */;
            case 122 /* AsyncKeyword */: return 256 /* Async */;
            case 134 /* ReadonlyKeyword */: return 64 /* Readonly */;
        }
        return 0 /* None */;
    }
    ts.modifierToFlag = modifierToFlag;
    function isLogicalOperator(token) {
        return token === 55 /* BarBarToken */
            || token === 54 /* AmpersandAmpersandToken */
            || token === 52 /* ExclamationToken */;
    }
    ts.isLogicalOperator = isLogicalOperator;
    function isAssignmentOperator(token) {
        return token >= 60 /* FirstAssignment */ && token <= 72 /* LastAssignment */;
    }
    ts.isAssignmentOperator = isAssignmentOperator;
    /** Get `C` given `N` if `N` is in the position `class C extends N` where `N` is an ExpressionWithTypeArguments. */
    function tryGetClassExtendingExpressionWithTypeArguments(node) {
        var cls = tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node);
        return cls && !cls.isImplements ? cls.class : undefined;
    }
    ts.tryGetClassExtendingExpressionWithTypeArguments = tryGetClassExtendingExpressionWithTypeArguments;
    function tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node) {
        return ts.isExpressionWithTypeArguments(node)
            && ts.isHeritageClause(node.parent)
            && ts.isClassLike(node.parent.parent)
            ? { class: node.parent.parent, isImplements: node.parent.token === 110 /* ImplementsKeyword */ }
            : undefined;
    }
    ts.tryGetClassImplementingOrExtendingExpressionWithTypeArguments = tryGetClassImplementingOrExtendingExpressionWithTypeArguments;
    function isAssignmentExpression(node, excludeCompoundAssignment) {
        return ts.isBinaryExpression(node)
            && (excludeCompoundAssignment
                ? node.operatorToken.kind === 60 /* EqualsToken */
                : isAssignmentOperator(node.operatorToken.kind))
            && ts.isLeftHandSideExpression(node.left);
    }
    ts.isAssignmentExpression = isAssignmentExpression;
    function isDestructuringAssignment(node) {
        if (isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) {
            var kind = node.left.kind;
            return kind === 189 /* ObjectLiteralExpression */
                || kind === 188 /* ArrayLiteralExpression */;
        }
        return false;
    }
    ts.isDestructuringAssignment = isDestructuringAssignment;
    function isExpressionWithTypeArgumentsInClassExtendsClause(node) {
        return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined;
    }
    ts.isExpressionWithTypeArgumentsInClassExtendsClause = isExpressionWithTypeArgumentsInClassExtendsClause;
    function isEntityNameExpression(node) {
        return node.kind === 73 /* Identifier */ || isPropertyAccessEntityNameExpression(node);
    }
    ts.isEntityNameExpression = isEntityNameExpression;
    function isPropertyAccessEntityNameExpression(node) {
        return ts.isPropertyAccessExpression(node) && isEntityNameExpression(node.expression);
    }
    ts.isPropertyAccessEntityNameExpression = isPropertyAccessEntityNameExpression;
    function tryGetPropertyAccessOrIdentifierToString(expr) {
        if (ts.isPropertyAccessExpression(expr)) {
            return tryGetPropertyAccessOrIdentifierToString(expr.expression) + "." + expr.name;
        }
        if (ts.isIdentifier(expr)) {
            return ts.unescapeLeadingUnderscores(expr.escapedText);
        }
        return undefined;
    }
    ts.tryGetPropertyAccessOrIdentifierToString = tryGetPropertyAccessOrIdentifierToString;
    function isPrototypeAccess(node) {
        return ts.isPropertyAccessExpression(node) && node.name.escapedText === "prototype";
    }
    ts.isPrototypeAccess = isPrototypeAccess;
    function isRightSideOfQualifiedNameOrPropertyAccess(node) {
        return (node.parent.kind === 149 /* QualifiedName */ && node.parent.right === node) ||
            (node.parent.kind === 190 /* PropertyAccessExpression */ && node.parent.name === node);
    }
    ts.isRightSideOfQualifiedNameOrPropertyAccess = isRightSideOfQualifiedNameOrPropertyAccess;
    function isEmptyObjectLiteral(expression) {
        return expression.kind === 189 /* ObjectLiteralExpression */ &&
            expression.properties.length === 0;
    }
    ts.isEmptyObjectLiteral = isEmptyObjectLiteral;
    function isEmptyArrayLiteral(expression) {
        return expression.kind === 188 /* ArrayLiteralExpression */ &&
            expression.elements.length === 0;
    }
    ts.isEmptyArrayLiteral = isEmptyArrayLiteral;
    function getLocalSymbolForExportDefault(symbol) {
        return isExportDefaultSymbol(symbol) ? symbol.declarations[0].localSymbol : undefined;
    }
    ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault;
    function isExportDefaultSymbol(symbol) {
        return symbol && ts.length(symbol.declarations) > 0 && hasModifier(symbol.declarations[0], 512 /* Default */);
    }
    /** Return ".ts", ".d.ts", or ".tsx", if that is the extension. */
    function tryExtractTSExtension(fileName) {
        return ts.find(ts.supportedTSExtensionsForExtractExtension, function (extension) { return ts.fileExtensionIs(fileName, extension); });
    }
    ts.tryExtractTSExtension = tryExtractTSExtension;
    /**
     * Replace each instance of non-ascii characters by one, two, three, or four escape sequences
     * representing the UTF-8 encoding of the character, and return the expanded char code list.
     */
    function getExpandedCharCodes(input) {
        var output = [];
        var length = input.length;
        for (var i = 0; i < length; i++) {
            var charCode = input.charCodeAt(i);
            // handle utf8
            if (charCode < 0x80) {
                output.push(charCode);
            }
            else if (charCode < 0x800) {
                output.push((charCode >> 6) | 192);
                output.push((charCode & 63) | 128);
            }
            else if (charCode < 0x10000) {
                output.push((charCode >> 12) | 224);
                output.push(((charCode >> 6) & 63) | 128);
                output.push((charCode & 63) | 128);
            }
            else if (charCode < 0x20000) {
                output.push((charCode >> 18) | 240);
                output.push(((charCode >> 12) & 63) | 128);
                output.push(((charCode >> 6) & 63) | 128);
                output.push((charCode & 63) | 128);
            }
            else {
                ts.Debug.assert(false, "Unexpected code point");
            }
        }
        return output;
    }
    var base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    /**
     * Converts a string to a base-64 encoded ASCII string.
     */
    function convertToBase64(input) {
        var result = "";
        var charCodes = getExpandedCharCodes(input);
        var i = 0;
        var length = charCodes.length;
        var byte1, byte2, byte3, byte4;
        while (i < length) {
            // Convert every 6-bits in the input 3 character points
            // into a base64 digit
            byte1 = charCodes[i] >> 2;
            byte2 = (charCodes[i] & 3) << 4 | charCodes[i + 1] >> 4;
            byte3 = (charCodes[i + 1] & 15) << 2 | charCodes[i + 2] >> 6;
            byte4 = charCodes[i + 2] & 63;
            // We are out of characters in the input, set the extra
            // digits to 64 (padding character).
            if (i + 1 >= length) {
                byte3 = byte4 = 64;
            }
            else if (i + 2 >= length) {
                byte4 = 64;
            }
            // Write to the output
            result += base64Digits.charAt(byte1) + base64Digits.charAt(byte2) + base64Digits.charAt(byte3) + base64Digits.charAt(byte4);
            i += 3;
        }
        return result;
    }
    ts.convertToBase64 = convertToBase64;
    function getStringFromExpandedCharCodes(codes) {
        var output = "";
        var i = 0;
        var length = codes.length;
        while (i < length) {
            var charCode = codes[i];
            if (charCode < 0x80) {
                output += String.fromCharCode(charCode);
                i++;
            }
            else if ((charCode & 192) === 192) {
                var value = charCode & 63;
                i++;
                var nextCode = codes[i];
                while ((nextCode & 192) === 128) {
                    value = (value << 6) | (nextCode & 63);
                    i++;
                    nextCode = codes[i];
                }
                // `value` may be greater than 10FFFF (the maximum unicode codepoint) - JS will just make this into an invalid character for us
                output += String.fromCharCode(value);
            }
            else {
                // We don't want to kill the process when decoding fails (due to a following char byte not
                // following a leading char), so we just print the (bad) value
                output += String.fromCharCode(charCode);
                i++;
            }
        }
        return output;
    }
    function base64encode(host, input) {
        if (host && host.base64encode) {
            return host.base64encode(input);
        }
        return convertToBase64(input);
    }
    ts.base64encode = base64encode;
    function base64decode(host, input) {
        if (host && host.base64decode) {
            return host.base64decode(input);
        }
        var length = input.length;
        var expandedCharCodes = [];
        var i = 0;
        while (i < length) {
            // Stop decoding once padding characters are present
            if (input.charCodeAt(i) === base64Digits.charCodeAt(64)) {
                break;
            }
            // convert 4 input digits into three characters, ignoring padding characters at the end
            var ch1 = base64Digits.indexOf(input[i]);
            var ch2 = base64Digits.indexOf(input[i + 1]);
            var ch3 = base64Digits.indexOf(input[i + 2]);
            var ch4 = base64Digits.indexOf(input[i + 3]);
            var code1 = ((ch1 & 63) << 2) | ((ch2 >> 4) & 3);
            var code2 = ((ch2 & 15) << 4) | ((ch3 >> 2) & 15);
            var code3 = ((ch3 & 3) << 6) | (ch4 & 63);
            if (code2 === 0 && ch3 !== 0) { // code2 decoded to zero, but ch3 was padding - elide code2 and code3
                expandedCharCodes.push(code1);
            }
            else if (code3 === 0 && ch4 !== 0) { // code3 decoded to zero, but ch4 was padding, elide code3
                expandedCharCodes.push(code1, code2);
            }
            else {
                expandedCharCodes.push(code1, code2, code3);
            }
            i += 4;
        }
        return getStringFromExpandedCharCodes(expandedCharCodes);
    }
    ts.base64decode = base64decode;
    function readJson(path, host) {
        try {
            var jsonText = host.readFile(path);
            if (!jsonText)
                return {};
            var result = ts.parseConfigFileTextToJson(path, jsonText);
            if (result.error) {
                return {};
            }
            return result.config;
        }
        catch (e) {
            // gracefully handle if readFile fails or returns not JSON
            return {};
        }
    }
    ts.readJson = readJson;
    function directoryProbablyExists(directoryName, host) {
        // if host does not support 'directoryExists' assume that directory will exist
        return !host.directoryExists || host.directoryExists(directoryName);
    }
    ts.directoryProbablyExists = directoryProbablyExists;
    var carriageReturnLineFeed = "\r\n";
    var lineFeed = "\n";
    function getNewLineCharacter(options, getNewLine) {
        switch (options.newLine) {
            case 0 /* CarriageReturnLineFeed */:
                return carriageReturnLineFeed;
            case 1 /* LineFeed */:
                return lineFeed;
        }
        return getNewLine ? getNewLine() : ts.sys ? ts.sys.newLine : carriageReturnLineFeed;
    }
    ts.getNewLineCharacter = getNewLineCharacter;
    /**
     * Creates a new TextRange from the provided pos and end.
     *
     * @param pos The start position.
     * @param end The end position.
     */
    function createRange(pos, end) {
        if (end === void 0) { end = pos; }
        ts.Debug.assert(end >= pos || end === -1);
        return { pos: pos, end: end };
    }
    ts.createRange = createRange;
    /**
     * Creates a new TextRange from a provided range with a new end position.
     *
     * @param range A TextRange.
     * @param end The new end position.
     */
    function moveRangeEnd(range, end) {
        return createRange(range.pos, end);
    }
    ts.moveRangeEnd = moveRangeEnd;
    /**
     * Creates a new TextRange from a provided range with a new start position.
     *
     * @param range A TextRange.
     * @param pos The new Start position.
     */
    function moveRangePos(range, pos) {
        return createRange(pos, range.end);
    }
    ts.moveRangePos = moveRangePos;
    /**
     * Moves the start position of a range past any decorators.
     */
    function moveRangePastDecorators(node) {
        return node.decorators && node.decorators.length > 0
            ? moveRangePos(node, node.decorators.end)
            : node;
    }
    ts.moveRangePastDecorators = moveRangePastDecorators;
    /**
     * Moves the start position of a range past any decorators or modifiers.
     */
    function moveRangePastModifiers(node) {
        return node.modifiers && node.modifiers.length > 0
            ? moveRangePos(node, node.modifiers.end)
            : moveRangePastDecorators(node);
    }
    ts.moveRangePastModifiers = moveRangePastModifiers;
    /**
     * Determines whether a TextRange has the same start and end positions.
     *
     * @param range A TextRange.
     */
    function isCollapsedRange(range) {
        return range.pos === range.end;
    }
    ts.isCollapsedRange = isCollapsedRange;
    /**
     * Creates a new TextRange for a token at the provides start position.
     *
     * @param pos The start position.
     * @param token The token.
     */
    function createTokenRange(pos, token) {
        return createRange(pos, pos + ts.tokenToString(token).length);
    }
    ts.createTokenRange = createTokenRange;
    function rangeIsOnSingleLine(range, sourceFile) {
        return rangeStartIsOnSameLineAsRangeEnd(range, range, sourceFile);
    }
    ts.rangeIsOnSingleLine = rangeIsOnSingleLine;
    function rangeStartPositionsAreOnSameLine(range1, range2, sourceFile) {
        return positionsAreOnSameLine(getStartPositionOfRange(range1, sourceFile), getStartPositionOfRange(range2, sourceFile), sourceFile);
    }
    ts.rangeStartPositionsAreOnSameLine = rangeStartPositionsAreOnSameLine;
    function rangeEndPositionsAreOnSameLine(range1, range2, sourceFile) {
        return positionsAreOnSameLine(range1.end, range2.end, sourceFile);
    }
    ts.rangeEndPositionsAreOnSameLine = rangeEndPositionsAreOnSameLine;
    function rangeStartIsOnSameLineAsRangeEnd(range1, range2, sourceFile) {
        return positionsAreOnSameLine(getStartPositionOfRange(range1, sourceFile), range2.end, sourceFile);
    }
    ts.rangeStartIsOnSameLineAsRangeEnd = rangeStartIsOnSameLineAsRangeEnd;
    function rangeEndIsOnSameLineAsRangeStart(range1, range2, sourceFile) {
        return positionsAreOnSameLine(range1.end, getStartPositionOfRange(range2, sourceFile), sourceFile);
    }
    ts.rangeEndIsOnSameLineAsRangeStart = rangeEndIsOnSameLineAsRangeStart;
    function isNodeArrayMultiLine(list, sourceFile) {
        return !positionsAreOnSameLine(list.pos, list.end, sourceFile);
    }
    ts.isNodeArrayMultiLine = isNodeArrayMultiLine;
    function positionsAreOnSameLine(pos1, pos2, sourceFile) {
        return pos1 === pos2 ||
            getLineOfLocalPosition(sourceFile, pos1) === getLineOfLocalPosition(sourceFile, pos2);
    }
    ts.positionsAreOnSameLine = positionsAreOnSameLine;
    function getStartPositionOfRange(range, sourceFile) {
        return ts.positionIsSynthesized(range.pos) ? -1 : ts.skipTrivia(sourceFile.text, range.pos);
    }
    ts.getStartPositionOfRange = getStartPositionOfRange;
    /**
     * Determines whether a name was originally the declaration name of an enum or namespace
     * declaration.
     */
    function isDeclarationNameOfEnumOrNamespace(node) {
        var parseNode = ts.getParseTreeNode(node);
        if (parseNode) {
            switch (parseNode.parent.kind) {
                case 244 /* EnumDeclaration */:
                case 245 /* ModuleDeclaration */:
                    return parseNode === parseNode.parent.name;
            }
        }
        return false;
    }
    ts.isDeclarationNameOfEnumOrNamespace = isDeclarationNameOfEnumOrNamespace;
    function getInitializedVariables(node) {
        return ts.filter(node.declarations, isInitializedVariable);
    }
    ts.getInitializedVariables = getInitializedVariables;
    function isInitializedVariable(node) {
        return node.initializer !== undefined;
    }
    function isWatchSet(options) {
        // Firefox has Object.prototype.watch
        return options.watch && options.hasOwnProperty("watch");
    }
    ts.isWatchSet = isWatchSet;
    function closeFileWatcher(watcher) {
        watcher.close();
    }
    ts.closeFileWatcher = closeFileWatcher;
    function getCheckFlags(symbol) {
        return symbol.flags & 33554432 /* Transient */ ? symbol.checkFlags : 0;
    }
    ts.getCheckFlags = getCheckFlags;
    function getDeclarationModifierFlagsFromSymbol(s) {
        if (s.valueDeclaration) {
            var flags = ts.getCombinedModifierFlags(s.valueDeclaration);
            return s.parent && s.parent.flags & 32 /* Class */ ? flags : flags & ~28 /* AccessibilityModifier */;
        }
        if (getCheckFlags(s) & 6 /* Synthetic */) {
            var checkFlags = s.checkFlags;
            var accessModifier = checkFlags & 1024 /* ContainsPrivate */ ? 8 /* Private */ :
                checkFlags & 256 /* ContainsPublic */ ? 4 /* Public */ :
                    16 /* Protected */;
            var staticModifier = checkFlags & 2048 /* ContainsStatic */ ? 32 /* Static */ : 0;
            return accessModifier | staticModifier;
        }
        if (s.flags & 4194304 /* Prototype */) {
            return 4 /* Public */ | 32 /* Static */;
        }
        return 0;
    }
    ts.getDeclarationModifierFlagsFromSymbol = getDeclarationModifierFlagsFromSymbol;
    function skipAlias(symbol, checker) {
        return symbol.flags & 2097152 /* Alias */ ? checker.getAliasedSymbol(symbol) : symbol;
    }
    ts.skipAlias = skipAlias;
    /** See comment on `declareModuleMember` in `binder.ts`. */
    function getCombinedLocalAndExportSymbolFlags(symbol) {
        return symbol.exportSymbol ? symbol.exportSymbol.flags | symbol.flags : symbol.flags;
    }
    ts.getCombinedLocalAndExportSymbolFlags = getCombinedLocalAndExportSymbolFlags;
    function isWriteOnlyAccess(node) {
        return accessKind(node) === 1 /* Write */;
    }
    ts.isWriteOnlyAccess = isWriteOnlyAccess;
    function isWriteAccess(node) {
        return accessKind(node) !== 0 /* Read */;
    }
    ts.isWriteAccess = isWriteAccess;
    var AccessKind;
    (function (AccessKind) {
        /** Only reads from a variable. */
        AccessKind[AccessKind["Read"] = 0] = "Read";
        /** Only writes to a variable without using the result. E.g.: `x++;`. */
        AccessKind[AccessKind["Write"] = 1] = "Write";
        /** Writes to a variable and uses the result as an expression. E.g.: `f(x++);`. */
        AccessKind[AccessKind["ReadWrite"] = 2] = "ReadWrite";
    })(AccessKind || (AccessKind = {}));
    function accessKind(node) {
        var parent = node.parent;
        if (!parent)
            return 0 /* Read */;
        switch (parent.kind) {
            case 196 /* ParenthesizedExpression */:
                return accessKind(parent);
            case 204 /* PostfixUnaryExpression */:
            case 203 /* PrefixUnaryExpression */:
                var operator = parent.operator;
                return operator === 44 /* PlusPlusToken */ || operator === 45 /* MinusMinusToken */ ? writeOrReadWrite() : 0 /* Read */;
            case 205 /* BinaryExpression */:
                var _a = parent, left = _a.left, operatorToken = _a.operatorToken;
                return left === node && isAssignmentOperator(operatorToken.kind) ?
                    operatorToken.kind === 60 /* EqualsToken */ ? 1 /* Write */ : writeOrReadWrite()
                    : 0 /* Read */;
            case 190 /* PropertyAccessExpression */:
                return parent.name !== node ? 0 /* Read */ : accessKind(parent);
            case 276 /* PropertyAssignment */: {
                var parentAccess = accessKind(parent.parent);
                // In `({ x: varname }) = { x: 1 }`, the left `x` is a read, the right `x` is a write.
                return node === parent.name ? reverseAccessKind(parentAccess) : parentAccess;
            }
            case 277 /* ShorthandPropertyAssignment */:
                // Assume it's the local variable being accessed, since we don't check public properties for --noUnusedLocals.
                return node === parent.objectAssignmentInitializer ? 0 /* Read */ : accessKind(parent.parent);
            case 188 /* ArrayLiteralExpression */:
                return accessKind(parent);
            default:
                return 0 /* Read */;
        }
        function writeOrReadWrite() {
            // If grandparent is not an ExpressionStatement, this is used as an expression in addition to having a side effect.
            return parent.parent && skipParenthesesUp(parent.parent).kind === 222 /* ExpressionStatement */ ? 1 /* Write */ : 2 /* ReadWrite */;
        }
    }
    function reverseAccessKind(a) {
        switch (a) {
            case 0 /* Read */:
                return 1 /* Write */;
            case 1 /* Write */:
                return 0 /* Read */;
            case 2 /* ReadWrite */:
                return 2 /* ReadWrite */;
            default:
                return ts.Debug.assertNever(a);
        }
    }
    function compareDataObjects(dst, src) {
        if (!dst || !src || Object.keys(dst).length !== Object.keys(src).length) {
            return false;
        }
        for (var e in dst) {
            if (typeof dst[e] === "object") {
                if (!compareDataObjects(dst[e], src[e])) {
                    return false;
                }
            }
            else if (typeof dst[e] !== "function") {
                if (dst[e] !== src[e]) {
                    return false;
                }
            }
        }
        return true;
    }
    ts.compareDataObjects = compareDataObjects;
    /**
     * clears already present map by calling onDeleteExistingValue callback before deleting that key/value
     */
    function clearMap(map, onDeleteValue) {
        // Remove all
        map.forEach(onDeleteValue);
        map.clear();
    }
    ts.clearMap = clearMap;
    /**
     * Mutates the map with newMap such that keys in map will be same as newMap.
     */
    function mutateMap(map, newMap, options) {
        var createNewValue = options.createNewValue, onDeleteValue = options.onDeleteValue, onExistingValue = options.onExistingValue;
        // Needs update
        map.forEach(function (existingValue, key) {
            var valueInNewMap = newMap.get(key);
            // Not present any more in new map, remove it
            if (valueInNewMap === undefined) {
                map.delete(key);
                onDeleteValue(existingValue, key);
            }
            // If present notify about existing values
            else if (onExistingValue) {
                onExistingValue(existingValue, valueInNewMap, key);
            }
        });
        // Add new values that are not already present
        newMap.forEach(function (valueInNewMap, key) {
            if (!map.has(key)) {
                // New values
                map.set(key, createNewValue(key, valueInNewMap));
            }
        });
    }
    ts.mutateMap = mutateMap;
    /** Calls `callback` on `directory` and every ancestor directory it has, returning the first defined result. */
    function forEachAncestorDirectory(directory, callback) {
        while (true) {
            var result = callback(directory);
            if (result !== undefined) {
                return result;
            }
            var parentPath = ts.getDirectoryPath(directory);
            if (parentPath === directory) {
                return undefined;
            }
            directory = parentPath;
        }
    }
    ts.forEachAncestorDirectory = forEachAncestorDirectory;
    // Return true if the given type is the constructor type for an abstract class
    function isAbstractConstructorType(type) {
        return !!(getObjectFlags(type) & 16 /* Anonymous */) && !!type.symbol && isAbstractConstructorSymbol(type.symbol);
    }
    ts.isAbstractConstructorType = isAbstractConstructorType;
    function isAbstractConstructorSymbol(symbol) {
        if (symbol.flags & 32 /* Class */) {
            var declaration = getClassLikeDeclarationOfSymbol(symbol);
            return !!declaration && hasModifier(declaration, 128 /* Abstract */);
        }
        return false;
    }
    ts.isAbstractConstructorSymbol = isAbstractConstructorSymbol;
    function getClassLikeDeclarationOfSymbol(symbol) {
        return ts.find(symbol.declarations, ts.isClassLike);
    }
    ts.getClassLikeDeclarationOfSymbol = getClassLikeDeclarationOfSymbol;
    function getObjectFlags(type) {
        return type.flags & 3899392 /* ObjectFlagsType */ ? type.objectFlags : 0;
    }
    ts.getObjectFlags = getObjectFlags;
    function typeHasCallOrConstructSignatures(type, checker) {
        return checker.getSignaturesOfType(type, 0 /* Call */).length !== 0 || checker.getSignaturesOfType(type, 1 /* Construct */).length !== 0;
    }
    ts.typeHasCallOrConstructSignatures = typeHasCallOrConstructSignatures;
    function forSomeAncestorDirectory(directory, callback) {
        return !!forEachAncestorDirectory(directory, function (d) { return callback(d) ? true : undefined; });
    }
    ts.forSomeAncestorDirectory = forSomeAncestorDirectory;
    function isUMDExportSymbol(symbol) {
        return !!symbol && !!symbol.declarations && !!symbol.declarations[0] && ts.isNamespaceExportDeclaration(symbol.declarations[0]);
    }
    ts.isUMDExportSymbol = isUMDExportSymbol;
    function showModuleSpecifier(_a) {
        var moduleSpecifier = _a.moduleSpecifier;
        return ts.isStringLiteral(moduleSpecifier) ? moduleSpecifier.text : getTextOfNode(moduleSpecifier);
    }
    ts.showModuleSpecifier = showModuleSpecifier;
    function getLastChild(node) {
        var lastChild;
        ts.forEachChild(node, function (child) {
            if (nodeIsPresent(child))
                lastChild = child;
        }, function (children) {
            // As an optimization, jump straight to the end of the list.
            for (var i = children.length - 1; i >= 0; i--) {
                if (nodeIsPresent(children[i])) {
                    lastChild = children[i];
                    break;
                }
            }
        });
        return lastChild;
    }
    ts.getLastChild = getLastChild;
    function addToSeen(seen, key, value) {
        if (value === void 0) { value = true; }
        key = String(key);
        if (seen.has(key)) {
            return false;
        }
        seen.set(key, value);
        return true;
    }
    ts.addToSeen = addToSeen;
    function isObjectTypeDeclaration(node) {
        return ts.isClassLike(node) || ts.isInterfaceDeclaration(node) || ts.isTypeLiteralNode(node);
    }
    ts.isObjectTypeDeclaration = isObjectTypeDeclaration;
    function isTypeNodeKind(kind) {
        return (kind >= 164 /* FirstTypeNode */ && kind <= 184 /* LastTypeNode */)
            || kind === 121 /* AnyKeyword */
            || kind === 144 /* UnknownKeyword */
            || kind === 136 /* NumberKeyword */
            || kind === 147 /* BigIntKeyword */
            || kind === 137 /* ObjectKeyword */
            || kind === 124 /* BooleanKeyword */
            || kind === 139 /* StringKeyword */
            || kind === 140 /* SymbolKeyword */
            || kind === 101 /* ThisKeyword */
            || kind === 107 /* VoidKeyword */
            || kind === 142 /* UndefinedKeyword */
            || kind === 97 /* NullKeyword */
            || kind === 133 /* NeverKeyword */
            || kind === 212 /* ExpressionWithTypeArguments */
            || kind === 290 /* JSDocAllType */
            || kind === 291 /* JSDocUnknownType */
            || kind === 292 /* JSDocNullableType */
            || kind === 293 /* JSDocNonNullableType */
            || kind === 294 /* JSDocOptionalType */
            || kind === 295 /* JSDocFunctionType */
            || kind === 296 /* JSDocVariadicType */;
    }
    ts.isTypeNodeKind = isTypeNodeKind;
    function isAccessExpression(node) {
        return node.kind === 190 /* PropertyAccessExpression */ || node.kind === 191 /* ElementAccessExpression */;
    }
    ts.isAccessExpression = isAccessExpression;
    function isBundleFileTextLike(section) {
        switch (section.kind) {
            case "text" /* Text */:
            case "internal" /* Internal */:
                return true;
            default:
                return false;
        }
    }
    ts.isBundleFileTextLike = isBundleFileTextLike;
})(ts || (ts = {}));
(function (ts) {
    function getDefaultLibFileName(options) {
        switch (options.target) {
            case 8 /* ESNext */:
                return "lib.esnext.full.d.ts";
            case 7 /* ES2020 */:
                return "lib.es2020.full.d.ts";
            case 6 /* ES2019 */:
                return "lib.es2019.full.d.ts";
            case 5 /* ES2018 */:
                return "lib.es2018.full.d.ts";
            case 4 /* ES2017 */:
                return "lib.es2017.full.d.ts";
            case 3 /* ES2016 */:
                return "lib.es2016.full.d.ts";
            case 2 /* ES2015 */:
                return "lib.es6.d.ts"; // We don't use lib.es2015.full.d.ts due to breaking change.
            default:
                return "lib.d.ts";
        }
    }
    ts.getDefaultLibFileName = getDefaultLibFileName;
    function textSpanEnd(span) {
        return span.start + span.length;
    }
    ts.textSpanEnd = textSpanEnd;
    function textSpanIsEmpty(span) {
        return span.length === 0;
    }
    ts.textSpanIsEmpty = textSpanIsEmpty;
    function textSpanContainsPosition(span, position) {
        return position >= span.start && position < textSpanEnd(span);
    }
    ts.textSpanContainsPosition = textSpanContainsPosition;
    /* @internal */
    function textRangeContainsPositionInclusive(span, position) {
        return position >= span.pos && position <= span.end;
    }
    ts.textRangeContainsPositionInclusive = textRangeContainsPositionInclusive;
    // Returns true if 'span' contains 'other'.
    function textSpanContainsTextSpan(span, other) {
        return other.start >= span.start && textSpanEnd(other) <= textSpanEnd(span);
    }
    ts.textSpanContainsTextSpan = textSpanContainsTextSpan;
    function textSpanOverlapsWith(span, other) {
        return textSpanOverlap(span, other) !== undefined;
    }
    ts.textSpanOverlapsWith = textSpanOverlapsWith;
    function textSpanOverlap(span1, span2) {
        var overlap = textSpanIntersection(span1, span2);
        return overlap && overlap.length === 0 ? undefined : overlap;
    }
    ts.textSpanOverlap = textSpanOverlap;
    function textSpanIntersectsWithTextSpan(span, other) {
        return decodedTextSpanIntersectsWith(span.start, span.length, other.start, other.length);
    }
    ts.textSpanIntersectsWithTextSpan = textSpanIntersectsWithTextSpan;
    function textSpanIntersectsWith(span, start, length) {
        return decodedTextSpanIntersectsWith(span.start, span.length, start, length);
    }
    ts.textSpanIntersectsWith = textSpanIntersectsWith;
    function decodedTextSpanIntersectsWith(start1, length1, start2, length2) {
        var end1 = start1 + length1;
        var end2 = start2 + length2;
        return start2 <= end1 && end2 >= start1;
    }
    ts.decodedTextSpanIntersectsWith = decodedTextSpanIntersectsWith;
    function textSpanIntersectsWithPosition(span, position) {
        return position <= textSpanEnd(span) && position >= span.start;
    }
    ts.textSpanIntersectsWithPosition = textSpanIntersectsWithPosition;
    function textSpanIntersection(span1, span2) {
        var start = Math.max(span1.start, span2.start);
        var end = Math.min(textSpanEnd(span1), textSpanEnd(span2));
        return start <= end ? createTextSpanFromBounds(start, end) : undefined;
    }
    ts.textSpanIntersection = textSpanIntersection;
    function createTextSpan(start, length) {
        if (start < 0) {
            throw new Error("start < 0");
        }
        if (length < 0) {
            throw new Error("length < 0");
        }
        return { start: start, length: length };
    }
    ts.createTextSpan = createTextSpan;
    function createTextSpanFromBounds(start, end) {
        return createTextSpan(start, end - start);
    }
    ts.createTextSpanFromBounds = createTextSpanFromBounds;
    function textChangeRangeNewSpan(range) {
        return createTextSpan(range.span.start, range.newLength);
    }
    ts.textChangeRangeNewSpan = textChangeRangeNewSpan;
    function textChangeRangeIsUnchanged(range) {
        return textSpanIsEmpty(range.span) && range.newLength === 0;
    }
    ts.textChangeRangeIsUnchanged = textChangeRangeIsUnchanged;
    function createTextChangeRange(span, newLength) {
        if (newLength < 0) {
            throw new Error("newLength < 0");
        }
        return { span: span, newLength: newLength };
    }
    ts.createTextChangeRange = createTextChangeRange;
    ts.unchangedTextChangeRange = createTextChangeRange(createTextSpan(0, 0), 0);
    /**
     * Called to merge all the changes that occurred across several versions of a script snapshot
     * into a single change.  i.e. if a user keeps making successive edits to a script we will
     * have a text change from V1 to V2, V2 to V3, ..., Vn.
     *
     * This function will then merge those changes into a single change range valid between V1 and
     * Vn.
     */
    function collapseTextChangeRangesAcrossMultipleVersions(changes) {
        if (changes.length === 0) {
            return ts.unchangedTextChangeRange;
        }
        if (changes.length === 1) {
            return changes[0];
        }
        // We change from talking about { { oldStart, oldLength }, newLength } to { oldStart, oldEnd, newEnd }
        // as it makes things much easier to reason about.
        var change0 = changes[0];
        var oldStartN = change0.span.start;
        var oldEndN = textSpanEnd(change0.span);
        var newEndN = oldStartN + change0.newLength;
        for (var i = 1; i < changes.length; i++) {
            var nextChange = changes[i];
            // Consider the following case:
            // i.e. two edits.  The first represents the text change range { { 10, 50 }, 30 }.  i.e. The span starting
            // at 10, with length 50 is reduced to length 30.  The second represents the text change range { { 30, 30 }, 40 }.
            // i.e. the span starting at 30 with length 30 is increased to length 40.
            //
            //      0         10        20        30        40        50        60        70        80        90        100
            //      -------------------------------------------------------------------------------------------------------
            //                |                                                 /
            //                |                                            /----
            //  T1            |                                       /----
            //                |                                  /----
            //                |                             /----
            //      -------------------------------------------------------------------------------------------------------
            //                                     |                            \
            //                                     |                               \
            //   T2                                |                                 \
            //                                     |                                   \
            //                                     |                                      \
            //      -------------------------------------------------------------------------------------------------------
            //
            // Merging these turns out to not be too difficult.  First, determining the new start of the change is trivial
            // it's just the min of the old and new starts.  i.e.:
            //
            //      0         10        20        30        40        50        60        70        80        90        100
            //      ------------------------------------------------------------*------------------------------------------
            //                |                                                 /
            //                |                                            /----
            //  T1            |                                       /----
            //                |                                  /----
            //                |                             /----
            //      ----------------------------------------$-------------------$------------------------------------------
            //                .                    |                            \
            //                .                    |                               \
            //   T2           .                    |                                 \
            //                .                    |                                   \
            //                .                    |                                      \
            //      ----------------------------------------------------------------------*--------------------------------
            //
            // (Note the dots represent the newly inferred start.
            // Determining the new and old end is also pretty simple.  Basically it boils down to paying attention to the
            // absolute positions at the asterisks, and the relative change between the dollar signs. Basically, we see
            // which if the two $'s precedes the other, and we move that one forward until they line up.  in this case that
            // means:
            //
            //      0         10        20        30        40        50        60        70        80        90        100
            //      --------------------------------------------------------------------------------*----------------------
            //                |                                                                     /
            //                |                                                                /----
            //  T1            |                                                           /----
            //                |                                                      /----
            //                |                                                 /----
            //      ------------------------------------------------------------$------------------------------------------
            //                .                    |                            \
            //                .                    |                               \
            //   T2           .                    |                                 \
            //                .                    |                                   \
            //                .                    |                                      \
            //      ----------------------------------------------------------------------*--------------------------------
            //
            // In other words (in this case), we're recognizing that the second edit happened after where the first edit
            // ended with a delta of 20 characters (60 - 40).  Thus, if we go back in time to where the first edit started
            // that's the same as if we started at char 80 instead of 60.
            //
            // As it so happens, the same logic applies if the second edit precedes the first edit.  In that case rather
            // than pushing the first edit forward to match the second, we'll push the second edit forward to match the
            // first.
            //
            // In this case that means we have { oldStart: 10, oldEnd: 80, newEnd: 70 } or, in TextChangeRange
            // semantics: { { start: 10, length: 70 }, newLength: 60 }
            //
            // The math then works out as follows.
            // If we have { oldStart1, oldEnd1, newEnd1 } and { oldStart2, oldEnd2, newEnd2 } then we can compute the
            // final result like so:
            //
            // {
            //      oldStart3: Min(oldStart1, oldStart2),
            //      oldEnd3: Max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)),
            //      newEnd3: Max(newEnd2, newEnd2 + (newEnd1 - oldEnd2))
            // }
            var oldStart1 = oldStartN;
            var oldEnd1 = oldEndN;
            var newEnd1 = newEndN;
            var oldStart2 = nextChange.span.start;
            var oldEnd2 = textSpanEnd(nextChange.span);
            var newEnd2 = oldStart2 + nextChange.newLength;
            oldStartN = Math.min(oldStart1, oldStart2);
            oldEndN = Math.max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1));
            newEndN = Math.max(newEnd2, newEnd2 + (newEnd1 - oldEnd2));
        }
        return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), /*newLength*/ newEndN - oldStartN);
    }
    ts.collapseTextChangeRangesAcrossMultipleVersions = collapseTextChangeRangesAcrossMultipleVersions;
    function getTypeParameterOwner(d) {
        if (d && d.kind === 151 /* TypeParameter */) {
            for (var current = d; current; current = current.parent) {
                if (ts.isFunctionLike(current) || ts.isClassLike(current) || current.kind === 242 /* InterfaceDeclaration */) {
                    return current;
                }
            }
        }
    }
    ts.getTypeParameterOwner = getTypeParameterOwner;
    function isParameterPropertyDeclaration(node) {
        return ts.hasModifier(node, 92 /* ParameterPropertyModifier */) && node.parent.kind === 158 /* Constructor */;
    }
    ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration;
    function isEmptyBindingPattern(node) {
        if (ts.isBindingPattern(node)) {
            return ts.every(node.elements, isEmptyBindingElement);
        }
        return false;
    }
    ts.isEmptyBindingPattern = isEmptyBindingPattern;
    function isEmptyBindingElement(node) {
        if (ts.isOmittedExpression(node)) {
            return true;
        }
        return isEmptyBindingPattern(node.name);
    }
    ts.isEmptyBindingElement = isEmptyBindingElement;
    function walkUpBindingElementsAndPatterns(binding) {
        var node = binding.parent;
        while (ts.isBindingElement(node.parent)) {
            node = node.parent.parent;
        }
        return node.parent;
    }
    ts.walkUpBindingElementsAndPatterns = walkUpBindingElementsAndPatterns;
    function getCombinedFlags(node, getFlags) {
        if (ts.isBindingElement(node)) {
            node = walkUpBindingElementsAndPatterns(node);
        }
        var flags = getFlags(node);
        if (node.kind === 238 /* VariableDeclaration */) {
            node = node.parent;
        }
        if (node && node.kind === 239 /* VariableDeclarationList */) {
            flags |= getFlags(node);
            node = node.parent;
        }
        if (node && node.kind === 220 /* VariableStatement */) {
            flags |= getFlags(node);
        }
        return flags;
    }
    function getCombinedModifierFlags(node) {
        return getCombinedFlags(node, ts.getModifierFlags);
    }
    ts.getCombinedModifierFlags = getCombinedModifierFlags;
    // Returns the node flags for this node and all relevant parent nodes.  This is done so that
    // nodes like variable declarations and binding elements can returned a view of their flags
    // that includes the modifiers from their container.  i.e. flags like export/declare aren't
    // stored on the variable declaration directly, but on the containing variable statement
    // (if it has one).  Similarly, flags for let/const are store on the variable declaration
    // list.  By calling this function, all those flags are combined so that the client can treat
    // the node as if it actually had those flags.
    function getCombinedNodeFlags(node) {
        return getCombinedFlags(node, function (n) { return n.flags; });
    }
    ts.getCombinedNodeFlags = getCombinedNodeFlags;
    /**
     * Checks to see if the locale is in the appropriate format,
     * and if it is, attempts to set the appropriate language.
     */
    function validateLocaleAndSetLanguage(locale, sys, errors) {
        var matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase());
        if (!matchResult) {
            if (errors) {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1, "en", "ja-jp"));
            }
            return;
        }
        var language = matchResult[1];
        var territory = matchResult[3];
        // First try the entire locale, then fall back to just language if that's all we have.
        // Either ways do not fail, and fallback to the English diagnostic strings.
        if (!trySetLanguageAndTerritory(language, territory, errors)) {
            trySetLanguageAndTerritory(language, /*territory*/ undefined, errors);
        }
        // Set the UI locale for string collation
        ts.setUILocale(locale);
        function trySetLanguageAndTerritory(language, territory, errors) {
            var compilerFilePath = ts.normalizePath(sys.getExecutingFilePath());
            var containingDirectoryPath = ts.getDirectoryPath(compilerFilePath);
            var filePath = ts.combinePaths(containingDirectoryPath, language);
            if (territory) {
                filePath = filePath + "-" + territory;
            }
            filePath = sys.resolvePath(ts.combinePaths(filePath, "diagnosticMessages.generated.json"));
            if (!sys.fileExists(filePath)) {
                return false;
            }
            // TODO: Add codePage support for readFile?
            var fileContents = "";
            try {
                fileContents = sys.readFile(filePath);
            }
            catch (e) {
                if (errors) {
                    errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unable_to_open_file_0, filePath));
                }
                return false;
            }
            try {
                // tslint:disable-next-line no-unnecessary-qualifier (making clear this is a global mutation!)
                ts.localizedDiagnosticMessages = JSON.parse(fileContents);
            }
            catch (_a) {
                if (errors) {
                    errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Corrupted_locale_file_0, filePath));
                }
                return false;
            }
            return true;
        }
    }
    ts.validateLocaleAndSetLanguage = validateLocaleAndSetLanguage;
    function getOriginalNode(node, nodeTest) {
        if (node) {
            while (node.original !== undefined) {
                node = node.original;
            }
        }
        return !nodeTest || nodeTest(node) ? node : undefined;
    }
    ts.getOriginalNode = getOriginalNode;
    /**
     * Gets a value indicating whether a node originated in the parse tree.
     *
     * @param node The node to test.
     */
    function isParseTreeNode(node) {
        return (node.flags & 8 /* Synthesized */) === 0;
    }
    ts.isParseTreeNode = isParseTreeNode;
    function getParseTreeNode(node, nodeTest) {
        if (node === undefined || isParseTreeNode(node)) {
            return node;
        }
        node = getOriginalNode(node);
        if (isParseTreeNode(node) && (!nodeTest || nodeTest(node))) {
            return node;
        }
        return undefined;
    }
    ts.getParseTreeNode = getParseTreeNode;
    /** Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__' */
    function escapeLeadingUnderscores(identifier) {
        return (identifier.length >= 2 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ ? "_" + identifier : identifier);
    }
    ts.escapeLeadingUnderscores = escapeLeadingUnderscores;
    /**
     * Remove extra underscore from escaped identifier text content.
     *
     * @param identifier The escaped identifier text.
     * @returns The unescaped identifier text.
     */
    function unescapeLeadingUnderscores(identifier) {
        var id = identifier;
        return id.length >= 3 && id.charCodeAt(0) === 95 /* _ */ && id.charCodeAt(1) === 95 /* _ */ && id.charCodeAt(2) === 95 /* _ */ ? id.substr(1) : id;
    }
    ts.unescapeLeadingUnderscores = unescapeLeadingUnderscores;
    function idText(identifier) {
        return unescapeLeadingUnderscores(identifier.escapedText);
    }
    ts.idText = idText;
    function symbolName(symbol) {
        return unescapeLeadingUnderscores(symbol.escapedName);
    }
    ts.symbolName = symbolName;
    /**
     * A JSDocTypedef tag has an _optional_ name field - if a name is not directly present, we should
     * attempt to draw the name from the node the declaration is on (as that declaration is what its' symbol
     * will be merged with)
     */
    function nameForNamelessJSDocTypedef(declaration) {
        var hostNode = declaration.parent.parent;
        if (!hostNode) {
            return undefined;
        }
        // Covers classes, functions - any named declaration host node
        if (ts.isDeclaration(hostNode)) {
            return getDeclarationIdentifier(hostNode);
        }
        // Covers remaining cases (returning undefined if none match).
        switch (hostNode.kind) {
            case 220 /* VariableStatement */:
                if (hostNode.declarationList && hostNode.declarationList.declarations[0]) {
                    return getDeclarationIdentifier(hostNode.declarationList.declarations[0]);
                }
                break;
            case 222 /* ExpressionStatement */:
                var expr = hostNode.expression;
                switch (expr.kind) {
                    case 190 /* PropertyAccessExpression */:
                        return expr.name;
                    case 191 /* ElementAccessExpression */:
                        var arg = expr.argumentExpression;
                        if (ts.isIdentifier(arg)) {
                            return arg;
                        }
                }
                break;
            case 196 /* ParenthesizedExpression */: {
                return getDeclarationIdentifier(hostNode.expression);
            }
            case 234 /* LabeledStatement */: {
                if (ts.isDeclaration(hostNode.statement) || ts.isExpression(hostNode.statement)) {
                    return getDeclarationIdentifier(hostNode.statement);
                }
                break;
            }
        }
    }
    function getDeclarationIdentifier(node) {
        var name = getNameOfDeclaration(node);
        return name && ts.isIdentifier(name) ? name : undefined;
    }
    function getNameOfJSDocTypedef(declaration) {
        return declaration.name || nameForNamelessJSDocTypedef(declaration);
    }
    ts.getNameOfJSDocTypedef = getNameOfJSDocTypedef;
    /** @internal */
    function isNamedDeclaration(node) {
        return !!node.name; // A 'name' property should always be a DeclarationName.
    }
    ts.isNamedDeclaration = isNamedDeclaration;
    /** @internal */
    function getNonAssignedNameOfDeclaration(declaration) {
        switch (declaration.kind) {
            case 73 /* Identifier */:
                return declaration;
            case 311 /* JSDocPropertyTag */:
            case 305 /* JSDocParameterTag */: {
                var name = declaration.name;
                if (name.kind === 149 /* QualifiedName */) {
                    return name.right;
                }
                break;
            }
            case 192 /* CallExpression */:
            case 205 /* BinaryExpression */: {
                var expr = declaration;
                switch (ts.getAssignmentDeclarationKind(expr)) {
                    case 1 /* ExportsProperty */:
                    case 4 /* ThisProperty */:
                    case 5 /* Property */:
                    case 3 /* PrototypeProperty */:
                        return expr.left.name;
                    case 7 /* ObjectDefinePropertyValue */:
                    case 8 /* ObjectDefinePropertyExports */:
                    case 9 /* ObjectDefinePrototypeProperty */:
                        return expr.arguments[1];
                    default:
                        return undefined;
                }
            }
            case 310 /* JSDocTypedefTag */:
                return getNameOfJSDocTypedef(declaration);
            case 255 /* ExportAssignment */: {
                var expression = declaration.expression;
                return ts.isIdentifier(expression) ? expression : undefined;
            }
        }
        return declaration.name;
    }
    ts.getNonAssignedNameOfDeclaration = getNonAssignedNameOfDeclaration;
    function getNameOfDeclaration(declaration) {
        if (declaration === undefined)
            return undefined;
        return getNonAssignedNameOfDeclaration(declaration) ||
            (ts.isFunctionExpression(declaration) || ts.isClassExpression(declaration) ? getAssignedName(declaration) : undefined);
    }
    ts.getNameOfDeclaration = getNameOfDeclaration;
    function getAssignedName(node) {
        if (!node.parent) {
            return undefined;
        }
        else if (ts.isPropertyAssignment(node.parent) || ts.isBindingElement(node.parent)) {
            return node.parent.name;
        }
        else if (ts.isBinaryExpression(node.parent) && node === node.parent.right) {
            if (ts.isIdentifier(node.parent.left)) {
                return node.parent.left;
            }
            else if (ts.isPropertyAccessExpression(node.parent.left)) {
                return node.parent.left.name;
            }
        }
    }
    /**
     * Gets the JSDoc parameter tags for the node if present.
     *
     * @remarks Returns any JSDoc param tag whose name matches the provided
     * parameter, whether a param tag on a containing function
     * expression, or a param tag on a variable declaration whose
     * initializer is the containing function. The tags closest to the
     * node are returned first, so in the previous example, the param
     * tag on the containing function expression would be first.
     *
     * For binding patterns, parameter tags are matched by position.
     */
    function getJSDocParameterTags(param) {
        if (param.name) {
            if (ts.isIdentifier(param.name)) {
                var name_1 = param.name.escapedText;
                return getJSDocTags(param.parent).filter(function (tag) { return ts.isJSDocParameterTag(tag) && ts.isIdentifier(tag.name) && tag.name.escapedText === name_1; });
            }
            else {
                var i = param.parent.parameters.indexOf(param);
                ts.Debug.assert(i > -1, "Parameters should always be in their parents' parameter list");
                var paramTags = getJSDocTags(param.parent).filter(ts.isJSDocParameterTag);
                if (i < paramTags.length) {
                    return [paramTags[i]];
                }
            }
        }
        // return empty array for: out-of-order binding patterns and JSDoc function syntax, which has un-named parameters
        return ts.emptyArray;
    }
    ts.getJSDocParameterTags = getJSDocParameterTags;
    /**
     * Gets the JSDoc type parameter tags for the node if present.
     *
     * @remarks Returns any JSDoc template tag whose names match the provided
     * parameter, whether a template tag on a containing function
     * expression, or a template tag on a variable declaration whose
     * initializer is the containing function. The tags closest to the
     * node are returned first, so in the previous example, the template
     * tag on the containing function expression would be first.
     */
    function getJSDocTypeParameterTags(param) {
        var name = param.name.escapedText;
        return getJSDocTags(param.parent).filter(function (tag) {
            return ts.isJSDocTemplateTag(tag) && tag.typeParameters.some(function (tp) { return tp.name.escapedText === name; });
        });
    }
    ts.getJSDocTypeParameterTags = getJSDocTypeParameterTags;
    /**
     * Return true if the node has JSDoc parameter tags.
     *
     * @remarks Includes parameter tags that are not directly on the node,
     * for example on a variable declaration whose initializer is a function expression.
     */
    function hasJSDocParameterTags(node) {
        return !!getFirstJSDocTag(node, ts.isJSDocParameterTag);
    }
    ts.hasJSDocParameterTags = hasJSDocParameterTags;
    /** Gets the JSDoc augments tag for the node if present */
    function getJSDocAugmentsTag(node) {
        return getFirstJSDocTag(node, ts.isJSDocAugmentsTag);
    }
    ts.getJSDocAugmentsTag = getJSDocAugmentsTag;
    /** Gets the JSDoc class tag for the node if present */
    function getJSDocClassTag(node) {
        return getFirstJSDocTag(node, ts.isJSDocClassTag);
    }
    ts.getJSDocClassTag = getJSDocClassTag;
    /** Gets the JSDoc enum tag for the node if present */
    function getJSDocEnumTag(node) {
        return getFirstJSDocTag(node, ts.isJSDocEnumTag);
    }
    ts.getJSDocEnumTag = getJSDocEnumTag;
    /** Gets the JSDoc this tag for the node if present */
    function getJSDocThisTag(node) {
        return getFirstJSDocTag(node, ts.isJSDocThisTag);
    }
    ts.getJSDocThisTag = getJSDocThisTag;
    /** Gets the JSDoc return tag for the node if present */
    function getJSDocReturnTag(node) {
        return getFirstJSDocTag(node, ts.isJSDocReturnTag);
    }
    ts.getJSDocReturnTag = getJSDocReturnTag;
    /** Gets the JSDoc template tag for the node if present */
    function getJSDocTemplateTag(node) {
        return getFirstJSDocTag(node, ts.isJSDocTemplateTag);
    }
    ts.getJSDocTemplateTag = getJSDocTemplateTag;
    /** Gets the JSDoc type tag for the node if present and valid */
    function getJSDocTypeTag(node) {
        // We should have already issued an error if there were multiple type jsdocs, so just use the first one.
        var tag = getFirstJSDocTag(node, ts.isJSDocTypeTag);
        if (tag && tag.typeExpression && tag.typeExpression.type) {
            return tag;
        }
        return undefined;
    }
    ts.getJSDocTypeTag = getJSDocTypeTag;
    /**
     * Gets the type node for the node if provided via JSDoc.
     *
     * @remarks The search includes any JSDoc param tag that relates
     * to the provided parameter, for example a type tag on the
     * parameter itself, or a param tag on a containing function
     * expression, or a param tag on a variable declaration whose
     * initializer is the containing function. The tags closest to the
     * node are examined first, so in the previous example, the type
     * tag directly on the node would be returned.
     */
    function getJSDocType(node) {
        var tag = getFirstJSDocTag(node, ts.isJSDocTypeTag);
        if (!tag && ts.isParameter(node)) {
            tag = ts.find(getJSDocParameterTags(node), function (tag) { return !!tag.typeExpression; });
        }
        return tag && tag.typeExpression && tag.typeExpression.type;
    }
    ts.getJSDocType = getJSDocType;
    /**
     * Gets the return type node for the node if provided via JSDoc return tag or type tag.
     *
     * @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
     * gets the type from inside the braces, after the fat arrow, etc.
     */
    function getJSDocReturnType(node) {
        var returnTag = getJSDocReturnTag(node);
        if (returnTag && returnTag.typeExpression) {
            return returnTag.typeExpression.type;
        }
        var typeTag = getJSDocTypeTag(node);
        if (typeTag && typeTag.typeExpression) {
            var type = typeTag.typeExpression.type;
            if (ts.isTypeLiteralNode(type)) {
                var sig = ts.find(type.members, ts.isCallSignatureDeclaration);
                return sig && sig.type;
            }
            if (ts.isFunctionTypeNode(type)) {
                return type.type;
            }
        }
    }
    ts.getJSDocReturnType = getJSDocReturnType;
    /** Get all JSDoc tags related to a node, including those on parent nodes. */
    function getJSDocTags(node) {
        var tags = node.jsDocCache;
        // If cache is 'null', that means we did the work of searching for JSDoc tags and came up with nothing.
        if (tags === undefined) {
            var comments = ts.getJSDocCommentsAndTags(node);
            ts.Debug.assert(comments.length < 2 || comments[0] !== comments[1]);
            node.jsDocCache = tags = ts.flatMap(comments, function (j) { return ts.isJSDoc(j) ? j.tags : j; });
        }
        return tags;
    }
    ts.getJSDocTags = getJSDocTags;
    /** Get the first JSDoc tag of a specified kind, or undefined if not present. */
    function getFirstJSDocTag(node, predicate) {
        return ts.find(getJSDocTags(node), predicate);
    }
    /** Gets all JSDoc tags of a specified kind, or undefined if not present. */
    function getAllJSDocTagsOfKind(node, kind) {
        return getJSDocTags(node).filter(function (doc) { return doc.kind === kind; });
    }
    ts.getAllJSDocTagsOfKind = getAllJSDocTagsOfKind;
    /**
     * Gets the effective type parameters. If the node was parsed in a
     * JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
     */
    function getEffectiveTypeParameterDeclarations(node) {
        if (ts.isJSDocSignature(node)) {
            return ts.emptyArray;
        }
        if (ts.isJSDocTypeAlias(node)) {
            ts.Debug.assert(node.parent.kind === 297 /* JSDocComment */);
            return ts.flatMap(node.parent.tags, function (tag) { return ts.isJSDocTemplateTag(tag) ? tag.typeParameters : undefined; });
        }
        if (node.typeParameters) {
            return node.typeParameters;
        }
        if (ts.isInJSFile(node)) {
            var decls = ts.getJSDocTypeParameterDeclarations(node);
            if (decls.length) {
                return decls;
            }
            var typeTag = getJSDocType(node);
            if (typeTag && ts.isFunctionTypeNode(typeTag) && typeTag.typeParameters) {
                return typeTag.typeParameters;
            }
        }
        return ts.emptyArray;
    }
    ts.getEffectiveTypeParameterDeclarations = getEffectiveTypeParameterDeclarations;
    function getEffectiveConstraintOfTypeParameter(node) {
        return node.constraint ? node.constraint
            : ts.isJSDocTemplateTag(node.parent) && node === node.parent.typeParameters[0]
                ? node.parent.constraint
                : undefined;
    }
    ts.getEffectiveConstraintOfTypeParameter = getEffectiveConstraintOfTypeParameter;
})(ts || (ts = {}));
// Simple node tests of the form `node.kind === SyntaxKind.Foo`.
(function (ts) {
    // Literals
    function isNumericLiteral(node) {
        return node.kind === 8 /* NumericLiteral */;
    }
    ts.isNumericLiteral = isNumericLiteral;
    function isBigIntLiteral(node) {
        return node.kind === 9 /* BigIntLiteral */;
    }
    ts.isBigIntLiteral = isBigIntLiteral;
    function isStringLiteral(node) {
        return node.kind === 10 /* StringLiteral */;
    }
    ts.isStringLiteral = isStringLiteral;
    function isJsxText(node) {
        return node.kind === 11 /* JsxText */;
    }
    ts.isJsxText = isJsxText;
    function isRegularExpressionLiteral(node) {
        return node.kind === 13 /* RegularExpressionLiteral */;
    }
    ts.isRegularExpressionLiteral = isRegularExpressionLiteral;
    function isNoSubstitutionTemplateLiteral(node) {
        return node.kind === 14 /* NoSubstitutionTemplateLiteral */;
    }
    ts.isNoSubstitutionTemplateLiteral = isNoSubstitutionTemplateLiteral;
    // Pseudo-literals
    function isTemplateHead(node) {
        return node.kind === 15 /* TemplateHead */;
    }
    ts.isTemplateHead = isTemplateHead;
    function isTemplateMiddle(node) {
        return node.kind === 16 /* TemplateMiddle */;
    }
    ts.isTemplateMiddle = isTemplateMiddle;
    function isTemplateTail(node) {
        return node.kind === 17 /* TemplateTail */;
    }
    ts.isTemplateTail = isTemplateTail;
    function isIdentifier(node) {
        return node.kind === 73 /* Identifier */;
    }
    ts.isIdentifier = isIdentifier;
    // Names
    function isQualifiedName(node) {
        return node.kind === 149 /* QualifiedName */;
    }
    ts.isQualifiedName = isQualifiedName;
    function isComputedPropertyName(node) {
        return node.kind === 150 /* ComputedPropertyName */;
    }
    ts.isComputedPropertyName = isComputedPropertyName;
    // Signature elements
    function isTypeParameterDeclaration(node) {
        return node.kind === 151 /* TypeParameter */;
    }
    ts.isTypeParameterDeclaration = isTypeParameterDeclaration;
    function isParameter(node) {
        return node.kind === 152 /* Parameter */;
    }
    ts.isParameter = isParameter;
    function isDecorator(node) {
        return node.kind === 153 /* Decorator */;
    }
    ts.isDecorator = isDecorator;
    // TypeMember
    function isPropertySignature(node) {
        return node.kind === 154 /* PropertySignature */;
    }
    ts.isPropertySignature = isPropertySignature;
    function isPropertyDeclaration(node) {
        return node.kind === 155 /* PropertyDeclaration */;
    }
    ts.isPropertyDeclaration = isPropertyDeclaration;
    function isMethodSignature(node) {
        return node.kind === 156 /* MethodSignature */;
    }
    ts.isMethodSignature = isMethodSignature;
    function isMethodDeclaration(node) {
        return node.kind === 157 /* MethodDeclaration */;
    }
    ts.isMethodDeclaration = isMethodDeclaration;
    function isConstructorDeclaration(node) {
        return node.kind === 158 /* Constructor */;
    }
    ts.isConstructorDeclaration = isConstructorDeclaration;
    function isGetAccessorDeclaration(node) {
        return node.kind === 159 /* GetAccessor */;
    }
    ts.isGetAccessorDeclaration = isGetAccessorDeclaration;
    function isSetAccessorDeclaration(node) {
        return node.kind === 160 /* SetAccessor */;
    }
    ts.isSetAccessorDeclaration = isSetAccessorDeclaration;
    function isCallSignatureDeclaration(node) {
        return node.kind === 161 /* CallSignature */;
    }
    ts.isCallSignatureDeclaration = isCallSignatureDeclaration;
    function isConstructSignatureDeclaration(node) {
        return node.kind === 162 /* ConstructSignature */;
    }
    ts.isConstructSignatureDeclaration = isConstructSignatureDeclaration;
    function isIndexSignatureDeclaration(node) {
        return node.kind === 163 /* IndexSignature */;
    }
    ts.isIndexSignatureDeclaration = isIndexSignatureDeclaration;
    /* @internal */
    function isGetOrSetAccessorDeclaration(node) {
        return node.kind === 160 /* SetAccessor */ || node.kind === 159 /* GetAccessor */;
    }
    ts.isGetOrSetAccessorDeclaration = isGetOrSetAccessorDeclaration;
    // Type
    function isTypePredicateNode(node) {
        return node.kind === 164 /* TypePredicate */;
    }
    ts.isTypePredicateNode = isTypePredicateNode;
    function isTypeReferenceNode(node) {
        return node.kind === 165 /* TypeReference */;
    }
    ts.isTypeReferenceNode = isTypeReferenceNode;
    function isFunctionTypeNode(node) {
        return node.kind === 166 /* FunctionType */;
    }
    ts.isFunctionTypeNode = isFunctionTypeNode;
    function isConstructorTypeNode(node) {
        return node.kind === 167 /* ConstructorType */;
    }
    ts.isConstructorTypeNode = isConstructorTypeNode;
    function isTypeQueryNode(node) {
        return node.kind === 168 /* TypeQuery */;
    }
    ts.isTypeQueryNode = isTypeQueryNode;
    function isTypeLiteralNode(node) {
        return node.kind === 169 /* TypeLiteral */;
    }
    ts.isTypeLiteralNode = isTypeLiteralNode;
    function isArrayTypeNode(node) {
        return node.kind === 170 /* ArrayType */;
    }
    ts.isArrayTypeNode = isArrayTypeNode;
    function isTupleTypeNode(node) {
        return node.kind === 171 /* TupleType */;
    }
    ts.isTupleTypeNode = isTupleTypeNode;
    function isUnionTypeNode(node) {
        return node.kind === 174 /* UnionType */;
    }
    ts.isUnionTypeNode = isUnionTypeNode;
    function isIntersectionTypeNode(node) {
        return node.kind === 175 /* IntersectionType */;
    }
    ts.isIntersectionTypeNode = isIntersectionTypeNode;
    function isConditionalTypeNode(node) {
        return node.kind === 176 /* ConditionalType */;
    }
    ts.isConditionalTypeNode = isConditionalTypeNode;
    function isInferTypeNode(node) {
        return node.kind === 177 /* InferType */;
    }
    ts.isInferTypeNode = isInferTypeNode;
    function isParenthesizedTypeNode(node) {
        return node.kind === 178 /* ParenthesizedType */;
    }
    ts.isParenthesizedTypeNode = isParenthesizedTypeNode;
    function isThisTypeNode(node) {
        return node.kind === 179 /* ThisType */;
    }
    ts.isThisTypeNode = isThisTypeNode;
    function isTypeOperatorNode(node) {
        return node.kind === 180 /* TypeOperator */;
    }
    ts.isTypeOperatorNode = isTypeOperatorNode;
    function isIndexedAccessTypeNode(node) {
        return node.kind === 181 /* IndexedAccessType */;
    }
    ts.isIndexedAccessTypeNode = isIndexedAccessTypeNode;
    function isMappedTypeNode(node) {
        return node.kind === 182 /* MappedType */;
    }
    ts.isMappedTypeNode = isMappedTypeNode;
    function isLiteralTypeNode(node) {
        return node.kind === 183 /* LiteralType */;
    }
    ts.isLiteralTypeNode = isLiteralTypeNode;
    function isImportTypeNode(node) {
        return node.kind === 184 /* ImportType */;
    }
    ts.isImportTypeNode = isImportTypeNode;
    // Binding patterns
    function isObjectBindingPattern(node) {
        return node.kind === 185 /* ObjectBindingPattern */;
    }
    ts.isObjectBindingPattern = isObjectBindingPattern;
    function isArrayBindingPattern(node) {
        return node.kind === 186 /* ArrayBindingPattern */;
    }
    ts.isArrayBindingPattern = isArrayBindingPattern;
    function isBindingElement(node) {
        return node.kind === 187 /* BindingElement */;
    }
    ts.isBindingElement = isBindingElement;
    // Expression
    function isArrayLiteralExpression(node) {
        return node.kind === 188 /* ArrayLiteralExpression */;
    }
    ts.isArrayLiteralExpression = isArrayLiteralExpression;
    function isObjectLiteralExpression(node) {
        return node.kind === 189 /* ObjectLiteralExpression */;
    }
    ts.isObjectLiteralExpression = isObjectLiteralExpression;
    function isPropertyAccessExpression(node) {
        return node.kind === 190 /* PropertyAccessExpression */;
    }
    ts.isPropertyAccessExpression = isPropertyAccessExpression;
    function isElementAccessExpression(node) {
        return node.kind === 191 /* ElementAccessExpression */;
    }
    ts.isElementAccessExpression = isElementAccessExpression;
    function isCallExpression(node) {
        return node.kind === 192 /* CallExpression */;
    }
    ts.isCallExpression = isCallExpression;
    function isNewExpression(node) {
        return node.kind === 193 /* NewExpression */;
    }
    ts.isNewExpression = isNewExpression;
    function isTaggedTemplateExpression(node) {
        return node.kind === 194 /* TaggedTemplateExpression */;
    }
    ts.isTaggedTemplateExpression = isTaggedTemplateExpression;
    function isTypeAssertion(node) {
        return node.kind === 195 /* TypeAssertionExpression */;
    }
    ts.isTypeAssertion = isTypeAssertion;
    function isConstTypeReference(node) {
        return isTypeReferenceNode(node) && isIdentifier(node.typeName) &&
            node.typeName.escapedText === "const" && !node.typeArguments;
    }
    ts.isConstTypeReference = isConstTypeReference;
    function isParenthesizedExpression(node) {
        return node.kind === 196 /* ParenthesizedExpression */;
    }
    ts.isParenthesizedExpression = isParenthesizedExpression;
    function skipPartiallyEmittedExpressions(node) {
        while (node.kind === 314 /* PartiallyEmittedExpression */) {
            node = node.expression;
        }
        return node;
    }
    ts.skipPartiallyEmittedExpressions = skipPartiallyEmittedExpressions;
    function isFunctionExpression(node) {
        return node.kind === 197 /* FunctionExpression */;
    }
    ts.isFunctionExpression = isFunctionExpression;
    function isArrowFunction(node) {
        return node.kind === 198 /* ArrowFunction */;
    }
    ts.isArrowFunction = isArrowFunction;
    function isDeleteExpression(node) {
        return node.kind === 199 /* DeleteExpression */;
    }
    ts.isDeleteExpression = isDeleteExpression;
    function isTypeOfExpression(node) {
        return node.kind === 200 /* TypeOfExpression */;
    }
    ts.isTypeOfExpression = isTypeOfExpression;
    function isVoidExpression(node) {
        return node.kind === 201 /* VoidExpression */;
    }
    ts.isVoidExpression = isVoidExpression;
    function isAwaitExpression(node) {
        return node.kind === 202 /* AwaitExpression */;
    }
    ts.isAwaitExpression = isAwaitExpression;
    function isPrefixUnaryExpression(node) {
        return node.kind === 203 /* PrefixUnaryExpression */;
    }
    ts.isPrefixUnaryExpression = isPrefixUnaryExpression;
    function isPostfixUnaryExpression(node) {
        return node.kind === 204 /* PostfixUnaryExpression */;
    }
    ts.isPostfixUnaryExpression = isPostfixUnaryExpression;
    function isBinaryExpression(node) {
        return node.kind === 205 /* BinaryExpression */;
    }
    ts.isBinaryExpression = isBinaryExpression;
    function isConditionalExpression(node) {
        return node.kind === 206 /* ConditionalExpression */;
    }
    ts.isConditionalExpression = isConditionalExpression;
    function isTemplateExpression(node) {
        return node.kind === 207 /* TemplateExpression */;
    }
    ts.isTemplateExpression = isTemplateExpression;
    function isYieldExpression(node) {
        return node.kind === 208 /* YieldExpression */;
    }
    ts.isYieldExpression = isYieldExpression;
    function isSpreadElement(node) {
        return node.kind === 209 /* SpreadElement */;
    }
    ts.isSpreadElement = isSpreadElement;
    function isClassExpression(node) {
        return node.kind === 210 /* ClassExpression */;
    }
    ts.isClassExpression = isClassExpression;
    function isOmittedExpression(node) {
        return node.kind === 211 /* OmittedExpression */;
    }
    ts.isOmittedExpression = isOmittedExpression;
    function isExpressionWithTypeArguments(node) {
        return node.kind === 212 /* ExpressionWithTypeArguments */;
    }
    ts.isExpressionWithTypeArguments = isExpressionWithTypeArguments;
    function isAsExpression(node) {
        return node.kind === 213 /* AsExpression */;
    }
    ts.isAsExpression = isAsExpression;
    function isNonNullExpression(node) {
        return node.kind === 214 /* NonNullExpression */;
    }
    ts.isNonNullExpression = isNonNullExpression;
    function isMetaProperty(node) {
        return node.kind === 215 /* MetaProperty */;
    }
    ts.isMetaProperty = isMetaProperty;
    // Misc
    function isTemplateSpan(node) {
        return node.kind === 217 /* TemplateSpan */;
    }
    ts.isTemplateSpan = isTemplateSpan;
    function isSemicolonClassElement(node) {
        return node.kind === 218 /* SemicolonClassElement */;
    }
    ts.isSemicolonClassElement = isSemicolonClassElement;
    // Block
    function isBlock(node) {
        return node.kind === 219 /* Block */;
    }
    ts.isBlock = isBlock;
    function isVariableStatement(node) {
        return node.kind === 220 /* VariableStatement */;
    }
    ts.isVariableStatement = isVariableStatement;
    function isEmptyStatement(node) {
        return node.kind === 221 /* EmptyStatement */;
    }
    ts.isEmptyStatement = isEmptyStatement;
    function isExpressionStatement(node) {
        return node.kind === 222 /* ExpressionStatement */;
    }
    ts.isExpressionStatement = isExpressionStatement;
    function isIfStatement(node) {
        return node.kind === 223 /* IfStatement */;
    }
    ts.isIfStatement = isIfStatement;
    function isDoStatement(node) {
        return node.kind === 224 /* DoStatement */;
    }
    ts.isDoStatement = isDoStatement;
    function isWhileStatement(node) {
        return node.kind === 225 /* WhileStatement */;
    }
    ts.isWhileStatement = isWhileStatement;
    function isForStatement(node) {
        return node.kind === 226 /* ForStatement */;
    }
    ts.isForStatement = isForStatement;
    function isForInStatement(node) {
        return node.kind === 227 /* ForInStatement */;
    }
    ts.isForInStatement = isForInStatement;
    function isForOfStatement(node) {
        return node.kind === 228 /* ForOfStatement */;
    }
    ts.isForOfStatement = isForOfStatement;
    function isContinueStatement(node) {
        return node.kind === 229 /* ContinueStatement */;
    }
    ts.isContinueStatement = isContinueStatement;
    function isBreakStatement(node) {
        return node.kind === 230 /* BreakStatement */;
    }
    ts.isBreakStatement = isBreakStatement;
    function isBreakOrContinueStatement(node) {
        return node.kind === 230 /* BreakStatement */ || node.kind === 229 /* ContinueStatement */;
    }
    ts.isBreakOrContinueStatement = isBreakOrContinueStatement;
    function isReturnStatement(node) {
        return node.kind === 231 /* ReturnStatement */;
    }
    ts.isReturnStatement = isReturnStatement;
    function isWithStatement(node) {
        return node.kind === 232 /* WithStatement */;
    }
    ts.isWithStatement = isWithStatement;
    function isSwitchStatement(node) {
        return node.kind === 233 /* SwitchStatement */;
    }
    ts.isSwitchStatement = isSwitchStatement;
    function isLabeledStatement(node) {
        return node.kind === 234 /* LabeledStatement */;
    }
    ts.isLabeledStatement = isLabeledStatement;
    function isThrowStatement(node) {
        return node.kind === 235 /* ThrowStatement */;
    }
    ts.isThrowStatement = isThrowStatement;
    function isTryStatement(node) {
        return node.kind === 236 /* TryStatement */;
    }
    ts.isTryStatement = isTryStatement;
    function isDebuggerStatement(node) {
        return node.kind === 237 /* DebuggerStatement */;
    }
    ts.isDebuggerStatement = isDebuggerStatement;
    function isVariableDeclaration(node) {
        return node.kind === 238 /* VariableDeclaration */;
    }
    ts.isVariableDeclaration = isVariableDeclaration;
    function isVariableDeclarationList(node) {
        return node.kind === 239 /* VariableDeclarationList */;
    }
    ts.isVariableDeclarationList = isVariableDeclarationList;
    function isFunctionDeclaration(node) {
        return node.kind === 240 /* FunctionDeclaration */;
    }
    ts.isFunctionDeclaration = isFunctionDeclaration;
    function isClassDeclaration(node) {
        return node.kind === 241 /* ClassDeclaration */;
    }
    ts.isClassDeclaration = isClassDeclaration;
    function isInterfaceDeclaration(node) {
        return node.kind === 242 /* InterfaceDeclaration */;
    }
    ts.isInterfaceDeclaration = isInterfaceDeclaration;
    function isTypeAliasDeclaration(node) {
        return node.kind === 243 /* TypeAliasDeclaration */;
    }
    ts.isTypeAliasDeclaration = isTypeAliasDeclaration;
    function isEnumDeclaration(node) {
        return node.kind === 244 /* EnumDeclaration */;
    }
    ts.isEnumDeclaration = isEnumDeclaration;
    function isModuleDeclaration(node) {
        return node.kind === 245 /* ModuleDeclaration */;
    }
    ts.isModuleDeclaration = isModuleDeclaration;
    function isModuleBlock(node) {
        return node.kind === 246 /* ModuleBlock */;
    }
    ts.isModuleBlock = isModuleBlock;
    function isCaseBlock(node) {
        return node.kind === 247 /* CaseBlock */;
    }
    ts.isCaseBlock = isCaseBlock;
    function isNamespaceExportDeclaration(node) {
        return node.kind === 248 /* NamespaceExportDeclaration */;
    }
    ts.isNamespaceExportDeclaration = isNamespaceExportDeclaration;
    function isImportEqualsDeclaration(node) {
        return node.kind === 249 /* ImportEqualsDeclaration */;
    }
    ts.isImportEqualsDeclaration = isImportEqualsDeclaration;
    function isImportDeclaration(node) {
        return node.kind === 250 /* ImportDeclaration */;
    }
    ts.isImportDeclaration = isImportDeclaration;
    function isImportClause(node) {
        return node.kind === 251 /* ImportClause */;
    }
    ts.isImportClause = isImportClause;
    function isNamespaceImport(node) {
        return node.kind === 252 /* NamespaceImport */;
    }
    ts.isNamespaceImport = isNamespaceImport;
    function isNamedImports(node) {
        return node.kind === 253 /* NamedImports */;
    }
    ts.isNamedImports = isNamedImports;
    function isImportSpecifier(node) {
        return node.kind === 254 /* ImportSpecifier */;
    }
    ts.isImportSpecifier = isImportSpecifier;
    function isExportAssignment(node) {
        return node.kind === 255 /* ExportAssignment */;
    }
    ts.isExportAssignment = isExportAssignment;
    function isExportDeclaration(node) {
        return node.kind === 256 /* ExportDeclaration */;
    }
    ts.isExportDeclaration = isExportDeclaration;
    function isNamedExports(node) {
        return node.kind === 257 /* NamedExports */;
    }
    ts.isNamedExports = isNamedExports;
    function isExportSpecifier(node) {
        return node.kind === 258 /* ExportSpecifier */;
    }
    ts.isExportSpecifier = isExportSpecifier;
    function isMissingDeclaration(node) {
        return node.kind === 259 /* MissingDeclaration */;
    }
    ts.isMissingDeclaration = isMissingDeclaration;
    // Module References
    function isExternalModuleReference(node) {
        return node.kind === 260 /* ExternalModuleReference */;
    }
    ts.isExternalModuleReference = isExternalModuleReference;
    // JSX
    function isJsxElement(node) {
        return node.kind === 261 /* JsxElement */;
    }
    ts.isJsxElement = isJsxElement;
    function isJsxSelfClosingElement(node) {
        return node.kind === 262 /* JsxSelfClosingElement */;
    }
    ts.isJsxSelfClosingElement = isJsxSelfClosingElement;
    function isJsxOpeningElement(node) {
        return node.kind === 263 /* JsxOpeningElement */;
    }
    ts.isJsxOpeningElement = isJsxOpeningElement;
    function isJsxClosingElement(node) {
        return node.kind === 264 /* JsxClosingElement */;
    }
    ts.isJsxClosingElement = isJsxClosingElement;
    function isJsxFragment(node) {
        return node.kind === 265 /* JsxFragment */;
    }
    ts.isJsxFragment = isJsxFragment;
    function isJsxOpeningFragment(node) {
        return node.kind === 266 /* JsxOpeningFragment */;
    }
    ts.isJsxOpeningFragment = isJsxOpeningFragment;
    function isJsxClosingFragment(node) {
        return node.kind === 267 /* JsxClosingFragment */;
    }
    ts.isJsxClosingFragment = isJsxClosingFragment;
    function isJsxAttribute(node) {
        return node.kind === 268 /* JsxAttribute */;
    }
    ts.isJsxAttribute = isJsxAttribute;
    function isJsxAttributes(node) {
        return node.kind === 269 /* JsxAttributes */;
    }
    ts.isJsxAttributes = isJsxAttributes;
    function isJsxSpreadAttribute(node) {
        return node.kind === 270 /* JsxSpreadAttribute */;
    }
    ts.isJsxSpreadAttribute = isJsxSpreadAttribute;
    function isJsxExpression(node) {
        return node.kind === 271 /* JsxExpression */;
    }
    ts.isJsxExpression = isJsxExpression;
    // Clauses
    function isCaseClause(node) {
        return node.kind === 272 /* CaseClause */;
    }
    ts.isCaseClause = isCaseClause;
    function isDefaultClause(node) {
        return node.kind === 273 /* DefaultClause */;
    }
    ts.isDefaultClause = isDefaultClause;
    function isHeritageClause(node) {
        return node.kind === 274 /* HeritageClause */;
    }
    ts.isHeritageClause = isHeritageClause;
    function isCatchClause(node) {
        return node.kind === 275 /* CatchClause */;
    }
    ts.isCatchClause = isCatchClause;
    // Property assignments
    function isPropertyAssignment(node) {
        return node.kind === 276 /* PropertyAssignment */;
    }
    ts.isPropertyAssignment = isPropertyAssignment;
    function isShorthandPropertyAssignment(node) {
        return node.kind === 277 /* ShorthandPropertyAssignment */;
    }
    ts.isShorthandPropertyAssignment = isShorthandPropertyAssignment;
    function isSpreadAssignment(node) {
        return node.kind === 278 /* SpreadAssignment */;
    }
    ts.isSpreadAssignment = isSpreadAssignment;
    // Enum
    function isEnumMember(node) {
        return node.kind === 279 /* EnumMember */;
    }
    ts.isEnumMember = isEnumMember;
    // Top-level nodes
    function isSourceFile(node) {
        return node.kind === 285 /* SourceFile */;
    }
    ts.isSourceFile = isSourceFile;
    function isBundle(node) {
        return node.kind === 286 /* Bundle */;
    }
    ts.isBundle = isBundle;
    function isUnparsedSource(node) {
        return node.kind === 287 /* UnparsedSource */;
    }
    ts.isUnparsedSource = isUnparsedSource;
    function isUnparsedPrepend(node) {
        return node.kind === 281 /* UnparsedPrepend */;
    }
    ts.isUnparsedPrepend = isUnparsedPrepend;
    function isUnparsedTextLike(node) {
        switch (node.kind) {
            case 282 /* UnparsedText */:
            case 283 /* UnparsedInternalText */:
                return true;
            default:
                return false;
        }
    }
    ts.isUnparsedTextLike = isUnparsedTextLike;
    function isUnparsedNode(node) {
        return isUnparsedTextLike(node) ||
            node.kind === 280 /* UnparsedPrologue */ ||
            node.kind === 284 /* UnparsedSyntheticReference */;
    }
    ts.isUnparsedNode = isUnparsedNode;
    // JSDoc
    function isJSDocTypeExpression(node) {
        return node.kind === 289 /* JSDocTypeExpression */;
    }
    ts.isJSDocTypeExpression = isJSDocTypeExpression;
    function isJSDocAllType(node) {
        return node.kind === 290 /* JSDocAllType */;
    }
    ts.isJSDocAllType = isJSDocAllType;
    function isJSDocUnknownType(node) {
        return node.kind === 291 /* JSDocUnknownType */;
    }
    ts.isJSDocUnknownType = isJSDocUnknownType;
    function isJSDocNullableType(node) {
        return node.kind === 292 /* JSDocNullableType */;
    }
    ts.isJSDocNullableType = isJSDocNullableType;
    function isJSDocNonNullableType(node) {
        return node.kind === 293 /* JSDocNonNullableType */;
    }
    ts.isJSDocNonNullableType = isJSDocNonNullableType;
    function isJSDocOptionalType(node) {
        return node.kind === 294 /* JSDocOptionalType */;
    }
    ts.isJSDocOptionalType = isJSDocOptionalType;
    function isJSDocFunctionType(node) {
        return node.kind === 295 /* JSDocFunctionType */;
    }
    ts.isJSDocFunctionType = isJSDocFunctionType;
    function isJSDocVariadicType(node) {
        return node.kind === 296 /* JSDocVariadicType */;
    }
    ts.isJSDocVariadicType = isJSDocVariadicType;
    function isJSDoc(node) {
        return node.kind === 297 /* JSDocComment */;
    }
    ts.isJSDoc = isJSDoc;
    function isJSDocAugmentsTag(node) {
        return node.kind === 301 /* JSDocAugmentsTag */;
    }
    ts.isJSDocAugmentsTag = isJSDocAugmentsTag;
    function isJSDocClassTag(node) {
        return node.kind === 302 /* JSDocClassTag */;
    }
    ts.isJSDocClassTag = isJSDocClassTag;
    function isJSDocEnumTag(node) {
        return node.kind === 304 /* JSDocEnumTag */;
    }
    ts.isJSDocEnumTag = isJSDocEnumTag;
    function isJSDocThisTag(node) {
        return node.kind === 307 /* JSDocThisTag */;
    }
    ts.isJSDocThisTag = isJSDocThisTag;
    function isJSDocParameterTag(node) {
        return node.kind === 305 /* JSDocParameterTag */;
    }
    ts.isJSDocParameterTag = isJSDocParameterTag;
    function isJSDocReturnTag(node) {
        return node.kind === 306 /* JSDocReturnTag */;
    }
    ts.isJSDocReturnTag = isJSDocReturnTag;
    function isJSDocTypeTag(node) {
        return node.kind === 308 /* JSDocTypeTag */;
    }
    ts.isJSDocTypeTag = isJSDocTypeTag;
    function isJSDocTemplateTag(node) {
        return node.kind === 309 /* JSDocTemplateTag */;
    }
    ts.isJSDocTemplateTag = isJSDocTemplateTag;
    function isJSDocTypedefTag(node) {
        return node.kind === 310 /* JSDocTypedefTag */;
    }
    ts.isJSDocTypedefTag = isJSDocTypedefTag;
    function isJSDocPropertyTag(node) {
        return node.kind === 311 /* JSDocPropertyTag */;
    }
    ts.isJSDocPropertyTag = isJSDocPropertyTag;
    function isJSDocPropertyLikeTag(node) {
        return node.kind === 311 /* JSDocPropertyTag */ || node.kind === 305 /* JSDocParameterTag */;
    }
    ts.isJSDocPropertyLikeTag = isJSDocPropertyLikeTag;
    function isJSDocTypeLiteral(node) {
        return node.kind === 298 /* JSDocTypeLiteral */;
    }
    ts.isJSDocTypeLiteral = isJSDocTypeLiteral;
    function isJSDocCallbackTag(node) {
        return node.kind === 303 /* JSDocCallbackTag */;
    }
    ts.isJSDocCallbackTag = isJSDocCallbackTag;
    function isJSDocSignature(node) {
        return node.kind === 299 /* JSDocSignature */;
    }
    ts.isJSDocSignature = isJSDocSignature;
})(ts || (ts = {}));
// Node tests
//
// All node tests in the following list should *not* reference parent pointers so that
// they may be used with transformations.
(function (ts) {
    /* @internal */
    function isSyntaxList(n) {
        return n.kind === 312 /* SyntaxList */;
    }
    ts.isSyntaxList = isSyntaxList;
    /* @internal */
    function isNode(node) {
        return isNodeKind(node.kind);
    }
    ts.isNode = isNode;
    /* @internal */
    function isNodeKind(kind) {
        return kind >= 149 /* FirstNode */;
    }
    ts.isNodeKind = isNodeKind;
    /**
     * True if node is of some token syntax kind.
     * For example, this is true for an IfKeyword but not for an IfStatement.
     * Literals are considered tokens, except TemplateLiteral, but does include TemplateHead/Middle/Tail.
     */
    function isToken(n) {
        return n.kind >= 0 /* FirstToken */ && n.kind <= 148 /* LastToken */;
    }
    ts.isToken = isToken;
    // Node Arrays
    /* @internal */
    function isNodeArray(array) {
        return array.hasOwnProperty("pos") && array.hasOwnProperty("end");
    }
    ts.isNodeArray = isNodeArray;
    // Literals
    /* @internal */
    function isLiteralKind(kind) {
        return 8 /* FirstLiteralToken */ <= kind && kind <= 14 /* LastLiteralToken */;
    }
    ts.isLiteralKind = isLiteralKind;
    function isLiteralExpression(node) {
        return isLiteralKind(node.kind);
    }
    ts.isLiteralExpression = isLiteralExpression;
    // Pseudo-literals
    /* @internal */
    function isTemplateLiteralKind(kind) {
        return 14 /* FirstTemplateToken */ <= kind && kind <= 17 /* LastTemplateToken */;
    }
    ts.isTemplateLiteralKind = isTemplateLiteralKind;
    function isTemplateLiteralToken(node) {
        return isTemplateLiteralKind(node.kind);
    }
    ts.isTemplateLiteralToken = isTemplateLiteralToken;
    function isTemplateMiddleOrTemplateTail(node) {
        var kind = node.kind;
        return kind === 16 /* TemplateMiddle */
            || kind === 17 /* TemplateTail */;
    }
    ts.isTemplateMiddleOrTemplateTail = isTemplateMiddleOrTemplateTail;
    function isImportOrExportSpecifier(node) {
        return ts.isImportSpecifier(node) || ts.isExportSpecifier(node);
    }
    ts.isImportOrExportSpecifier = isImportOrExportSpecifier;
    function isStringTextContainingNode(node) {
        return node.kind === 10 /* StringLiteral */ || isTemplateLiteralKind(node.kind);
    }
    ts.isStringTextContainingNode = isStringTextContainingNode;
    // Identifiers
    /* @internal */
    function isGeneratedIdentifier(node) {
        return ts.isIdentifier(node) && (node.autoGenerateFlags & 7 /* KindMask */) > 0 /* None */;
    }
    ts.isGeneratedIdentifier = isGeneratedIdentifier;
    // Keywords
    /* @internal */
    function isModifierKind(token) {
        switch (token) {
            case 119 /* AbstractKeyword */:
            case 122 /* AsyncKeyword */:
            case 78 /* ConstKeyword */:
            case 126 /* DeclareKeyword */:
            case 81 /* DefaultKeyword */:
            case 86 /* ExportKeyword */:
            case 116 /* PublicKeyword */:
            case 114 /* PrivateKeyword */:
            case 115 /* ProtectedKeyword */:
            case 134 /* ReadonlyKeyword */:
            case 117 /* StaticKeyword */:
                return true;
        }
        return false;
    }
    ts.isModifierKind = isModifierKind;
    /* @internal */
    function isParameterPropertyModifier(kind) {
        return !!(ts.modifierToFlag(kind) & 92 /* ParameterPropertyModifier */);
    }
    ts.isParameterPropertyModifier = isParameterPropertyModifier;
    /* @internal */
    function isClassMemberModifier(idToken) {
        return isParameterPropertyModifier(idToken) || idToken === 117 /* StaticKeyword */;
    }
    ts.isClassMemberModifier = isClassMemberModifier;
    function isModifier(node) {
        return isModifierKind(node.kind);
    }
    ts.isModifier = isModifier;
    function isEntityName(node) {
        var kind = node.kind;
        return kind === 149 /* QualifiedName */
            || kind === 73 /* Identifier */;
    }
    ts.isEntityName = isEntityName;
    function isPropertyName(node) {
        var kind = node.kind;
        return kind === 73 /* Identifier */
            || kind === 10 /* StringLiteral */
            || kind === 8 /* NumericLiteral */
            || kind === 150 /* ComputedPropertyName */;
    }
    ts.isPropertyName = isPropertyName;
    function isBindingName(node) {
        var kind = node.kind;
        return kind === 73 /* Identifier */
            || kind === 185 /* ObjectBindingPattern */
            || kind === 186 /* ArrayBindingPattern */;
    }
    ts.isBindingName = isBindingName;
    // Functions
    function isFunctionLike(node) {
        return node && isFunctionLikeKind(node.kind);
    }
    ts.isFunctionLike = isFunctionLike;
    /* @internal */
    function isFunctionLikeDeclaration(node) {
        return node && isFunctionLikeDeclarationKind(node.kind);
    }
    ts.isFunctionLikeDeclaration = isFunctionLikeDeclaration;
    function isFunctionLikeDeclarationKind(kind) {
        switch (kind) {
            case 240 /* FunctionDeclaration */:
            case 157 /* MethodDeclaration */:
            case 158 /* Constructor */:
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
            case 197 /* FunctionExpression */:
            case 198 /* ArrowFunction */:
                return true;
            default:
                return false;
        }
    }
    /* @internal */
    function isFunctionLikeKind(kind) {
        switch (kind) {
            case 156 /* MethodSignature */:
            case 161 /* CallSignature */:
            case 299 /* JSDocSignature */:
            case 162 /* ConstructSignature */:
            case 163 /* IndexSignature */:
            case 166 /* FunctionType */:
            case 295 /* JSDocFunctionType */:
            case 167 /* ConstructorType */:
                return true;
            default:
                return isFunctionLikeDeclarationKind(kind);
        }
    }
    ts.isFunctionLikeKind = isFunctionLikeKind;
    /* @internal */
    function isFunctionOrModuleBlock(node) {
        return ts.isSourceFile(node) || ts.isModuleBlock(node) || ts.isBlock(node) && isFunctionLike(node.parent);
    }
    ts.isFunctionOrModuleBlock = isFunctionOrModuleBlock;
    // Classes
    function isClassElement(node) {
        var kind = node.kind;
        return kind === 158 /* Constructor */
            || kind === 155 /* PropertyDeclaration */
            || kind === 157 /* MethodDeclaration */
            || kind === 159 /* GetAccessor */
            || kind === 160 /* SetAccessor */
            || kind === 163 /* IndexSignature */
            || kind === 218 /* SemicolonClassElement */;
    }
    ts.isClassElement = isClassElement;
    function isClassLike(node) {
        return node && (node.kind === 241 /* ClassDeclaration */ || node.kind === 210 /* ClassExpression */);
    }
    ts.isClassLike = isClassLike;
    function isAccessor(node) {
        return node && (node.kind === 159 /* GetAccessor */ || node.kind === 160 /* SetAccessor */);
    }
    ts.isAccessor = isAccessor;
    /* @internal */
    function isMethodOrAccessor(node) {
        switch (node.kind) {
            case 157 /* MethodDeclaration */:
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
                return true;
            default:
                return false;
        }
    }
    ts.isMethodOrAccessor = isMethodOrAccessor;
    // Type members
    function isTypeElement(node) {
        var kind = node.kind;
        return kind === 162 /* ConstructSignature */
            || kind === 161 /* CallSignature */
            || kind === 154 /* PropertySignature */
            || kind === 156 /* MethodSignature */
            || kind === 163 /* IndexSignature */;
    }
    ts.isTypeElement = isTypeElement;
    function isClassOrTypeElement(node) {
        return isTypeElement(node) || isClassElement(node);
    }
    ts.isClassOrTypeElement = isClassOrTypeElement;
    function isObjectLiteralElementLike(node) {
        var kind = node.kind;
        return kind === 276 /* PropertyAssignment */
            || kind === 277 /* ShorthandPropertyAssignment */
            || kind === 278 /* SpreadAssignment */
            || kind === 157 /* MethodDeclaration */
            || kind === 159 /* GetAccessor */
            || kind === 160 /* SetAccessor */;
    }
    ts.isObjectLiteralElementLike = isObjectLiteralElementLike;
    // Type
    /**
     * Node test that determines whether a node is a valid type node.
     * This differs from the `isPartOfTypeNode` function which determines whether a node is *part*
     * of a TypeNode.
     */
    function isTypeNode(node) {
        return ts.isTypeNodeKind(node.kind);
    }
    ts.isTypeNode = isTypeNode;
    function isFunctionOrConstructorTypeNode(node) {
        switch (node.kind) {
            case 166 /* FunctionType */:
            case 167 /* ConstructorType */:
                return true;
        }
        return false;
    }
    ts.isFunctionOrConstructorTypeNode = isFunctionOrConstructorTypeNode;
    // Binding patterns
    /* @internal */
    function isBindingPattern(node) {
        if (node) {
            var kind = node.kind;
            return kind === 186 /* ArrayBindingPattern */
                || kind === 185 /* ObjectBindingPattern */;
        }
        return false;
    }
    ts.isBindingPattern = isBindingPattern;
    /* @internal */
    function isAssignmentPattern(node) {
        var kind = node.kind;
        return kind === 188 /* ArrayLiteralExpression */
            || kind === 189 /* ObjectLiteralExpression */;
    }
    ts.isAssignmentPattern = isAssignmentPattern;
    /* @internal */
    function isArrayBindingElement(node) {
        var kind = node.kind;
        return kind === 187 /* BindingElement */
            || kind === 211 /* OmittedExpression */;
    }
    ts.isArrayBindingElement = isArrayBindingElement;
    /**
     * Determines whether the BindingOrAssignmentElement is a BindingElement-like declaration
     */
    /* @internal */
    function isDeclarationBindingElement(bindingElement) {
        switch (bindingElement.kind) {
            case 238 /* VariableDeclaration */:
            case 152 /* Parameter */:
            case 187 /* BindingElement */:
                return true;
        }
        return false;
    }
    ts.isDeclarationBindingElement = isDeclarationBindingElement;
    /**
     * Determines whether a node is a BindingOrAssignmentPattern
     */
    /* @internal */
    function isBindingOrAssignmentPattern(node) {
        return isObjectBindingOrAssignmentPattern(node)
            || isArrayBindingOrAssignmentPattern(node);
    }
    ts.isBindingOrAssignmentPattern = isBindingOrAssignmentPattern;
    /**
     * Determines whether a node is an ObjectBindingOrAssignmentPattern
     */
    /* @internal */
    function isObjectBindingOrAssignmentPattern(node) {
        switch (node.kind) {
            case 185 /* ObjectBindingPattern */:
            case 189 /* ObjectLiteralExpression */:
                return true;
        }
        return false;
    }
    ts.isObjectBindingOrAssignmentPattern = isObjectBindingOrAssignmentPattern;
    /**
     * Determines whether a node is an ArrayBindingOrAssignmentPattern
     */
    /* @internal */
    function isArrayBindingOrAssignmentPattern(node) {
        switch (node.kind) {
            case 186 /* ArrayBindingPattern */:
            case 188 /* ArrayLiteralExpression */:
                return true;
        }
        return false;
    }
    ts.isArrayBindingOrAssignmentPattern = isArrayBindingOrAssignmentPattern;
    /* @internal */
    function isPropertyAccessOrQualifiedNameOrImportTypeNode(node) {
        var kind = node.kind;
        return kind === 190 /* PropertyAccessExpression */
            || kind === 149 /* QualifiedName */
            || kind === 184 /* ImportType */;
    }
    ts.isPropertyAccessOrQualifiedNameOrImportTypeNode = isPropertyAccessOrQualifiedNameOrImportTypeNode;
    // Expression
    function isPropertyAccessOrQualifiedName(node) {
        var kind = node.kind;
        return kind === 190 /* PropertyAccessExpression */
            || kind === 149 /* QualifiedName */;
    }
    ts.isPropertyAccessOrQualifiedName = isPropertyAccessOrQualifiedName;
    function isCallLikeExpression(node) {
        switch (node.kind) {
            case 263 /* JsxOpeningElement */:
            case 262 /* JsxSelfClosingElement */:
            case 192 /* CallExpression */:
            case 193 /* NewExpression */:
            case 194 /* TaggedTemplateExpression */:
            case 153 /* Decorator */:
                return true;
            default:
                return false;
        }
    }
    ts.isCallLikeExpression = isCallLikeExpression;
    function isCallOrNewExpression(node) {
        return node.kind === 192 /* CallExpression */ || node.kind === 193 /* NewExpression */;
    }
    ts.isCallOrNewExpression = isCallOrNewExpression;
    function isTemplateLiteral(node) {
        var kind = node.kind;
        return kind === 207 /* TemplateExpression */
            || kind === 14 /* NoSubstitutionTemplateLiteral */;
    }
    ts.isTemplateLiteral = isTemplateLiteral;
    /* @internal */
    function isLeftHandSideExpression(node) {
        return isLeftHandSideExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind);
    }
    ts.isLeftHandSideExpression = isLeftHandSideExpression;
    function isLeftHandSideExpressionKind(kind) {
        switch (kind) {
            case 190 /* PropertyAccessExpression */:
            case 191 /* ElementAccessExpression */:
            case 193 /* NewExpression */:
            case 192 /* CallExpression */:
            case 261 /* JsxElement */:
            case 262 /* JsxSelfClosingElement */:
            case 265 /* JsxFragment */:
            case 194 /* TaggedTemplateExpression */:
            case 188 /* ArrayLiteralExpression */:
            case 196 /* ParenthesizedExpression */:
            case 189 /* ObjectLiteralExpression */:
            case 210 /* ClassExpression */:
            case 197 /* FunctionExpression */:
            case 73 /* Identifier */:
            case 13 /* RegularExpressionLiteral */:
            case 8 /* NumericLiteral */:
            case 9 /* BigIntLiteral */:
            case 10 /* StringLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 207 /* TemplateExpression */:
            case 88 /* FalseKeyword */:
            case 97 /* NullKeyword */:
            case 101 /* ThisKeyword */:
            case 103 /* TrueKeyword */:
            case 99 /* SuperKeyword */:
            case 214 /* NonNullExpression */:
            case 215 /* MetaProperty */:
            case 93 /* ImportKeyword */: // technically this is only an Expression if it's in a CallExpression
                return true;
            default:
                return false;
        }
    }
    /* @internal */
    function isUnaryExpression(node) {
        return isUnaryExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind);
    }
    ts.isUnaryExpression = isUnaryExpression;
    function isUnaryExpressionKind(kind) {
        switch (kind) {
            case 203 /* PrefixUnaryExpression */:
            case 204 /* PostfixUnaryExpression */:
            case 199 /* DeleteExpression */:
            case 200 /* TypeOfExpression */:
            case 201 /* VoidExpression */:
            case 202 /* AwaitExpression */:
            case 195 /* TypeAssertionExpression */:
                return true;
            default:
                return isLeftHandSideExpressionKind(kind);
        }
    }
    /* @internal */
    function isUnaryExpressionWithWrite(expr) {
        switch (expr.kind) {
            case 204 /* PostfixUnaryExpression */:
                return true;
            case 203 /* PrefixUnaryExpression */:
                return expr.operator === 44 /* PlusPlusToken */ ||
                    expr.operator === 45 /* MinusMinusToken */;
            default:
                return false;
        }
    }
    ts.isUnaryExpressionWithWrite = isUnaryExpressionWithWrite;
    /* @internal */
    /**
     * Determines whether a node is an expression based only on its kind.
     * Use `isExpressionNode` if not in transforms.
     */
    function isExpression(node) {
        return isExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind);
    }
    ts.isExpression = isExpression;
    function isExpressionKind(kind) {
        switch (kind) {
            case 206 /* ConditionalExpression */:
            case 208 /* YieldExpression */:
            case 198 /* ArrowFunction */:
            case 205 /* BinaryExpression */:
            case 209 /* SpreadElement */:
            case 213 /* AsExpression */:
            case 211 /* OmittedExpression */:
            case 315 /* CommaListExpression */:
            case 314 /* PartiallyEmittedExpression */:
                return true;
            default:
                return isUnaryExpressionKind(kind);
        }
    }
    function isAssertionExpression(node) {
        var kind = node.kind;
        return kind === 195 /* TypeAssertionExpression */
            || kind === 213 /* AsExpression */;
    }
    ts.isAssertionExpression = isAssertionExpression;
    /* @internal */
    function isPartiallyEmittedExpression(node) {
        return node.kind === 314 /* PartiallyEmittedExpression */;
    }
    ts.isPartiallyEmittedExpression = isPartiallyEmittedExpression;
    /* @internal */
    function isNotEmittedStatement(node) {
        return node.kind === 313 /* NotEmittedStatement */;
    }
    ts.isNotEmittedStatement = isNotEmittedStatement;
    /* @internal */
    function isNotEmittedOrPartiallyEmittedNode(node) {
        return isNotEmittedStatement(node)
            || isPartiallyEmittedExpression(node);
    }
    ts.isNotEmittedOrPartiallyEmittedNode = isNotEmittedOrPartiallyEmittedNode;
    function isIterationStatement(node, lookInLabeledStatements) {
        switch (node.kind) {
            case 226 /* ForStatement */:
            case 227 /* ForInStatement */:
            case 228 /* ForOfStatement */:
            case 224 /* DoStatement */:
            case 225 /* WhileStatement */:
                return true;
            case 234 /* LabeledStatement */:
                return lookInLabeledStatements && isIterationStatement(node.statement, lookInLabeledStatements);
        }
        return false;
    }
    ts.isIterationStatement = isIterationStatement;
    /* @internal */
    function isForInOrOfStatement(node) {
        return node.kind === 227 /* ForInStatement */ || node.kind === 228 /* ForOfStatement */;
    }
    ts.isForInOrOfStatement = isForInOrOfStatement;
    // Element
    /* @internal */
    function isConciseBody(node) {
        return ts.isBlock(node)
            || isExpression(node);
    }
    ts.isConciseBody = isConciseBody;
    /* @internal */
    function isFunctionBody(node) {
        return ts.isBlock(node);
    }
    ts.isFunctionBody = isFunctionBody;
    /* @internal */
    function isForInitializer(node) {
        return ts.isVariableDeclarationList(node)
            || isExpression(node);
    }
    ts.isForInitializer = isForInitializer;
    /* @internal */
    function isModuleBody(node) {
        var kind = node.kind;
        return kind === 246 /* ModuleBlock */
            || kind === 245 /* ModuleDeclaration */
            || kind === 73 /* Identifier */;
    }
    ts.isModuleBody = isModuleBody;
    /* @internal */
    function isNamespaceBody(node) {
        var kind = node.kind;
        return kind === 246 /* ModuleBlock */
            || kind === 245 /* ModuleDeclaration */;
    }
    ts.isNamespaceBody = isNamespaceBody;
    /* @internal */
    function isJSDocNamespaceBody(node) {
        var kind = node.kind;
        return kind === 73 /* Identifier */
            || kind === 245 /* ModuleDeclaration */;
    }
    ts.isJSDocNamespaceBody = isJSDocNamespaceBody;
    /* @internal */
    function isNamedImportBindings(node) {
        var kind = node.kind;
        return kind === 253 /* NamedImports */
            || kind === 252 /* NamespaceImport */;
    }
    ts.isNamedImportBindings = isNamedImportBindings;
    /* @internal */
    function isModuleOrEnumDeclaration(node) {
        return node.kind === 245 /* ModuleDeclaration */ || node.kind === 244 /* EnumDeclaration */;
    }
    ts.isModuleOrEnumDeclaration = isModuleOrEnumDeclaration;
    function isDeclarationKind(kind) {
        return kind === 198 /* ArrowFunction */
            || kind === 187 /* BindingElement */
            || kind === 241 /* ClassDeclaration */
            || kind === 210 /* ClassExpression */
            || kind === 158 /* Constructor */
            || kind === 244 /* EnumDeclaration */
            || kind === 279 /* EnumMember */
            || kind === 258 /* ExportSpecifier */
            || kind === 240 /* FunctionDeclaration */
            || kind === 197 /* FunctionExpression */
            || kind === 159 /* GetAccessor */
            || kind === 251 /* ImportClause */
            || kind === 249 /* ImportEqualsDeclaration */
            || kind === 254 /* ImportSpecifier */
            || kind === 242 /* InterfaceDeclaration */
            || kind === 268 /* JsxAttribute */
            || kind === 157 /* MethodDeclaration */
            || kind === 156 /* MethodSignature */
            || kind === 245 /* ModuleDeclaration */
            || kind === 248 /* NamespaceExportDeclaration */
            || kind === 252 /* NamespaceImport */
            || kind === 152 /* Parameter */
            || kind === 276 /* PropertyAssignment */
            || kind === 155 /* PropertyDeclaration */
            || kind === 154 /* PropertySignature */
            || kind === 160 /* SetAccessor */
            || kind === 277 /* ShorthandPropertyAssignment */
            || kind === 243 /* TypeAliasDeclaration */
            || kind === 151 /* TypeParameter */
            || kind === 238 /* VariableDeclaration */
            || kind === 310 /* JSDocTypedefTag */
            || kind === 303 /* JSDocCallbackTag */
            || kind === 311 /* JSDocPropertyTag */;
    }
    function isDeclarationStatementKind(kind) {
        return kind === 240 /* FunctionDeclaration */
            || kind === 259 /* MissingDeclaration */
            || kind === 241 /* ClassDeclaration */
            || kind === 242 /* InterfaceDeclaration */
            || kind === 243 /* TypeAliasDeclaration */
            || kind === 244 /* EnumDeclaration */
            || kind === 245 /* ModuleDeclaration */
            || kind === 250 /* ImportDeclaration */
            || kind === 249 /* ImportEqualsDeclaration */
            || kind === 256 /* ExportDeclaration */
            || kind === 255 /* ExportAssignment */
            || kind === 248 /* NamespaceExportDeclaration */;
    }
    function isStatementKindButNotDeclarationKind(kind) {
        return kind === 230 /* BreakStatement */
            || kind === 229 /* ContinueStatement */
            || kind === 237 /* DebuggerStatement */
            || kind === 224 /* DoStatement */
            || kind === 222 /* ExpressionStatement */
            || kind === 221 /* EmptyStatement */
            || kind === 227 /* ForInStatement */
            || kind === 228 /* ForOfStatement */
            || kind === 226 /* ForStatement */
            || kind === 223 /* IfStatement */
            || kind === 234 /* LabeledStatement */
            || kind === 231 /* ReturnStatement */
            || kind === 233 /* SwitchStatement */
            || kind === 235 /* ThrowStatement */
            || kind === 236 /* TryStatement */
            || kind === 220 /* VariableStatement */
            || kind === 225 /* WhileStatement */
            || kind === 232 /* WithStatement */
            || kind === 313 /* NotEmittedStatement */
            || kind === 317 /* EndOfDeclarationMarker */
            || kind === 316 /* MergeDeclarationMarker */;
    }
    /* @internal */
    function isDeclaration(node) {
        if (node.kind === 151 /* TypeParameter */) {
            return (node.parent && node.parent.kind !== 309 /* JSDocTemplateTag */) || ts.isInJSFile(node);
        }
        return isDeclarationKind(node.kind);
    }
    ts.isDeclaration = isDeclaration;
    /* @internal */
    function isDeclarationStatement(node) {
        return isDeclarationStatementKind(node.kind);
    }
    ts.isDeclarationStatement = isDeclarationStatement;
    /**
     * Determines whether the node is a statement that is not also a declaration
     */
    /* @internal */
    function isStatementButNotDeclaration(node) {
        return isStatementKindButNotDeclarationKind(node.kind);
    }
    ts.isStatementButNotDeclaration = isStatementButNotDeclaration;
    /* @internal */
    function isStatement(node) {
        var kind = node.kind;
        return isStatementKindButNotDeclarationKind(kind)
            || isDeclarationStatementKind(kind)
            || isBlockStatement(node);
    }
    ts.isStatement = isStatement;
    function isBlockStatement(node) {
        if (node.kind !== 219 /* Block */)
            return false;
        if (node.parent !== undefined) {
            if (node.parent.kind === 236 /* TryStatement */ || node.parent.kind === 275 /* CatchClause */) {
                return false;
            }
        }
        return !ts.isFunctionBlock(node);
    }
    // Module references
    /* @internal */
    function isModuleReference(node) {
        var kind = node.kind;
        return kind === 260 /* ExternalModuleReference */
            || kind === 149 /* QualifiedName */
            || kind === 73 /* Identifier */;
    }
    ts.isModuleReference = isModuleReference;
    // JSX
    /* @internal */
    function isJsxTagNameExpression(node) {
        var kind = node.kind;
        return kind === 101 /* ThisKeyword */
            || kind === 73 /* Identifier */
            || kind === 190 /* PropertyAccessExpression */;
    }
    ts.isJsxTagNameExpression = isJsxTagNameExpression;
    /* @internal */
    function isJsxChild(node) {
        var kind = node.kind;
        return kind === 261 /* JsxElement */
            || kind === 271 /* JsxExpression */
            || kind === 262 /* JsxSelfClosingElement */
            || kind === 11 /* JsxText */
            || kind === 265 /* JsxFragment */;
    }
    ts.isJsxChild = isJsxChild;
    /* @internal */
    function isJsxAttributeLike(node) {
        var kind = node.kind;
        return kind === 268 /* JsxAttribute */
            || kind === 270 /* JsxSpreadAttribute */;
    }
    ts.isJsxAttributeLike = isJsxAttributeLike;
    /* @internal */
    function isStringLiteralOrJsxExpression(node) {
        var kind = node.kind;
        return kind === 10 /* StringLiteral */
            || kind === 271 /* JsxExpression */;
    }
    ts.isStringLiteralOrJsxExpression = isStringLiteralOrJsxExpression;
    function isJsxOpeningLikeElement(node) {
        var kind = node.kind;
        return kind === 263 /* JsxOpeningElement */
            || kind === 262 /* JsxSelfClosingElement */;
    }
    ts.isJsxOpeningLikeElement = isJsxOpeningLikeElement;
    // Clauses
    function isCaseOrDefaultClause(node) {
        var kind = node.kind;
        return kind === 272 /* CaseClause */
            || kind === 273 /* DefaultClause */;
    }
    ts.isCaseOrDefaultClause = isCaseOrDefaultClause;
    // JSDoc
    /** True if node is of some JSDoc syntax kind. */
    /* @internal */
    function isJSDocNode(node) {
        return node.kind >= 289 /* FirstJSDocNode */ && node.kind <= 311 /* LastJSDocNode */;
    }
    ts.isJSDocNode = isJSDocNode;
    /** True if node is of a kind that may contain comment text. */
    function isJSDocCommentContainingNode(node) {
        return node.kind === 297 /* JSDocComment */ || isJSDocTag(node) || ts.isJSDocTypeLiteral(node) || ts.isJSDocSignature(node);
    }
    ts.isJSDocCommentContainingNode = isJSDocCommentContainingNode;
    // TODO: determine what this does before making it public.
    /* @internal */
    function isJSDocTag(node) {
        return node.kind >= 300 /* FirstJSDocTagNode */ && node.kind <= 311 /* LastJSDocTagNode */;
    }
    ts.isJSDocTag = isJSDocTag;
    function isSetAccessor(node) {
        return node.kind === 160 /* SetAccessor */;
    }
    ts.isSetAccessor = isSetAccessor;
    function isGetAccessor(node) {
        return node.kind === 159 /* GetAccessor */;
    }
    ts.isGetAccessor = isGetAccessor;
    /** True if has jsdoc nodes attached to it. */
    /* @internal */
    // TODO: GH#19856 Would like to return `node is Node & { jsDoc: JSDoc[] }` but it causes long compile times
    function hasJSDocNodes(node) {
        var jsDoc = node.jsDoc;
        return !!jsDoc && jsDoc.length > 0;
    }
    ts.hasJSDocNodes = hasJSDocNodes;
    /** True if has type node attached to it. */
    /* @internal */
    function hasType(node) {
        return !!node.type;
    }
    ts.hasType = hasType;
    /** True if has initializer node attached to it. */
    /* @internal */
    function hasInitializer(node) {
        return !!node.initializer;
    }
    ts.hasInitializer = hasInitializer;
    /** True if has initializer node attached to it. */
    /* @internal */
    function hasOnlyExpressionInitializer(node) {
        return hasInitializer(node) && !ts.isForStatement(node) && !ts.isForInStatement(node) && !ts.isForOfStatement(node) && !ts.isJsxAttribute(node);
    }
    ts.hasOnlyExpressionInitializer = hasOnlyExpressionInitializer;
    function isObjectLiteralElement(node) {
        return node.kind === 268 /* JsxAttribute */ || node.kind === 270 /* JsxSpreadAttribute */ || isObjectLiteralElementLike(node);
    }
    ts.isObjectLiteralElement = isObjectLiteralElement;
    /* @internal */
    function isTypeReferenceType(node) {
        return node.kind === 165 /* TypeReference */ || node.kind === 212 /* ExpressionWithTypeArguments */;
    }
    ts.isTypeReferenceType = isTypeReferenceType;
    var MAX_SMI_X86 = 1073741823;
    /* @internal */
    function guessIndentation(lines) {
        var indentation = MAX_SMI_X86;
        for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) {
            var line = lines_1[_i];
            if (!line.length) {
                continue;
            }
            var i = 0;
            for (; i < line.length && i < indentation; i++) {
                if (!ts.isWhiteSpaceLike(line.charCodeAt(i))) {
                    break;
                }
            }
            if (i < indentation) {
                indentation = i;
            }
            if (indentation === 0) {
                return 0;
            }
        }
        return indentation === MAX_SMI_X86 ? undefined : indentation;
    }
    ts.guessIndentation = guessIndentation;
    function isStringLiteralLike(node) {
        return node.kind === 10 /* StringLiteral */ || node.kind === 14 /* NoSubstitutionTemplateLiteral */;
    }
    ts.isStringLiteralLike = isStringLiteralLike;
})(ts || (ts = {}));
/* @internal */
(function (ts) {
    function isNamedImportsOrExports(node) {
        return node.kind === 253 /* NamedImports */ || node.kind === 257 /* NamedExports */;
    }
    ts.isNamedImportsOrExports = isNamedImportsOrExports;
    function Symbol(flags, name) {
        this.flags = flags;
        this.escapedName = name;
        this.declarations = undefined;
        this.valueDeclaration = undefined;
        this.id = undefined;
        this.mergeId = undefined;
        this.parent = undefined;
    }
    function Type(checker, flags) {
        this.flags = flags;
        if (ts.Debug.isDebugging) {
            this.checker = checker;
        }
    }
    function Signature() { } // tslint:disable-line no-empty
    function Node(kind, pos, end) {
        this.pos = pos;
        this.end = end;
        this.kind = kind;
        this.id = 0;
        this.flags = 0 /* None */;
        this.modifierFlagsCache = 0 /* None */;
        this.transformFlags = 0 /* None */;
        this.parent = undefined;
        this.original = undefined;
    }
    function SourceMapSource(fileName, text, skipTrivia) {
        this.fileName = fileName;
        this.text = text;
        this.skipTrivia = skipTrivia || (function (pos) { return pos; });
    }
    ts.objectAllocator = {
        getNodeConstructor: function () { return Node; },
        getTokenConstructor: function () { return Node; },
        getIdentifierConstructor: function () { return Node; },
        getSourceFileConstructor: function () { return Node; },
        getSymbolConstructor: function () { return Symbol; },
        getTypeConstructor: function () { return Type; },
        getSignatureConstructor: function () { return Signature; },
        getSourceMapSourceConstructor: function () { return SourceMapSource; },
    };
    function formatStringFromArgs(text, args, baseIndex) {
        if (baseIndex === void 0) { baseIndex = 0; }
        return text.replace(/{(\d+)}/g, function (_match, index) { return "" + ts.Debug.assertDefined(args[+index + baseIndex]); });
    }
    ts.formatStringFromArgs = formatStringFromArgs;
    function getLocaleSpecificMessage(message) {
        return ts.localizedDiagnosticMessages && ts.localizedDiagnosticMessages[message.key] || message.message;
    }
    ts.getLocaleSpecificMessage = getLocaleSpecificMessage;
    function createFileDiagnostic(file, start, length, message) {
        ts.Debug.assertGreaterThanOrEqual(start, 0);
        ts.Debug.assertGreaterThanOrEqual(length, 0);
        if (file) {
            ts.Debug.assertLessThanOrEqual(start, file.text.length);
            ts.Debug.assertLessThanOrEqual(start + length, file.text.length);
        }
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 4) {
            text = formatStringFromArgs(text, arguments, 4);
        }
        return {
            file: file,
            start: start,
            length: length,
            messageText: text,
            category: message.category,
            code: message.code,
            reportsUnnecessary: message.reportsUnnecessary,
        };
    }
    ts.createFileDiagnostic = createFileDiagnostic;
    function formatMessage(_dummy, message) {
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 2) {
            text = formatStringFromArgs(text, arguments, 2);
        }
        return text;
    }
    ts.formatMessage = formatMessage;
    function createCompilerDiagnostic(message) {
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 1) {
            text = formatStringFromArgs(text, arguments, 1);
        }
        return {
            file: undefined,
            start: undefined,
            length: undefined,
            messageText: text,
            category: message.category,
            code: message.code,
            reportsUnnecessary: message.reportsUnnecessary,
        };
    }
    ts.createCompilerDiagnostic = createCompilerDiagnostic;
    function createCompilerDiagnosticFromMessageChain(chain) {
        return {
            file: undefined,
            start: undefined,
            length: undefined,
            code: chain.code,
            category: chain.category,
            messageText: chain.next ? chain : chain.messageText,
        };
    }
    ts.createCompilerDiagnosticFromMessageChain = createCompilerDiagnosticFromMessageChain;
    function chainDiagnosticMessages(details, message) {
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 2) {
            text = formatStringFromArgs(text, arguments, 2);
        }
        return {
            messageText: text,
            category: message.category,
            code: message.code,
            next: details
        };
    }
    ts.chainDiagnosticMessages = chainDiagnosticMessages;
    function concatenateDiagnosticMessageChains(headChain, tailChain) {
        var lastChain = headChain;
        while (lastChain.next) {
            lastChain = lastChain.next;
        }
        lastChain.next = tailChain;
        return headChain;
    }
    ts.concatenateDiagnosticMessageChains = concatenateDiagnosticMessageChains;
    function getDiagnosticFilePath(diagnostic) {
        return diagnostic.file ? diagnostic.file.path : undefined;
    }
    function compareDiagnostics(d1, d2) {
        return compareDiagnosticsSkipRelatedInformation(d1, d2) ||
            compareRelatedInformation(d1, d2) ||
            0 /* EqualTo */;
    }
    ts.compareDiagnostics = compareDiagnostics;
    function compareDiagnosticsSkipRelatedInformation(d1, d2) {
        return ts.compareStringsCaseSensitive(getDiagnosticFilePath(d1), getDiagnosticFilePath(d2)) ||
            ts.compareValues(d1.start, d2.start) ||
            ts.compareValues(d1.length, d2.length) ||
            ts.compareValues(d1.code, d2.code) ||
            compareMessageText(d1.messageText, d2.messageText) ||
            0 /* EqualTo */;
    }
    ts.compareDiagnosticsSkipRelatedInformation = compareDiagnosticsSkipRelatedInformation;
    function compareRelatedInformation(d1, d2) {
        if (!d1.relatedInformation && !d2.relatedInformation) {
            return 0 /* EqualTo */;
        }
        if (d1.relatedInformation && d2.relatedInformation) {
            return ts.compareValues(d1.relatedInformation.length, d2.relatedInformation.length) || ts.forEach(d1.relatedInformation, function (d1i, index) {
                var d2i = d2.relatedInformation[index];
                return compareDiagnostics(d1i, d2i); // EqualTo is 0, so falsy, and will cause the next item to be compared
            }) || 0 /* EqualTo */;
        }
        return d1.relatedInformation ? -1 /* LessThan */ : 1 /* GreaterThan */;
    }
    function compareMessageText(t1, t2) {
        var text1 = t1;
        var text2 = t2;
        while (text1 && text2) {
            // We still have both chains.
            var string1 = ts.isString(text1) ? text1 : text1.messageText;
            var string2 = ts.isString(text2) ? text2 : text2.messageText;
            var res = ts.compareStringsCaseSensitive(string1, string2);
            if (res) {
                return res;
            }
            text1 = ts.isString(text1) ? undefined : text1.next;
            text2 = ts.isString(text2) ? undefined : text2.next;
        }
        if (!text1 && !text2) {
            // if the chains are done, then these messages are the same.
            return 0 /* EqualTo */;
        }
        // We still have one chain remaining.  The shorter chain should come first.
        return text1 ? 1 /* GreaterThan */ : -1 /* LessThan */;
    }
    function getEmitScriptTarget(compilerOptions) {
        return compilerOptions.target || 0 /* ES3 */;
    }
    ts.getEmitScriptTarget = getEmitScriptTarget;
    function getEmitModuleKind(compilerOptions) {
        return typeof compilerOptions.module === "number" ?
            compilerOptions.module :
            getEmitScriptTarget(compilerOptions) >= 2 /* ES2015 */ ? ts.ModuleKind.ES2015 : ts.ModuleKind.CommonJS;
    }
    ts.getEmitModuleKind = getEmitModuleKind;
    function getEmitModuleResolutionKind(compilerOptions) {
        var moduleResolution = compilerOptions.moduleResolution;
        if (moduleResolution === undefined) {
            moduleResolution = getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS ? ts.ModuleResolutionKind.NodeJs : ts.ModuleResolutionKind.Classic;
        }
        return moduleResolution;
    }
    ts.getEmitModuleResolutionKind = getEmitModuleResolutionKind;
    function hasJsonModuleEmitEnabled(options) {
        switch (getEmitModuleKind(options)) {
            case ts.ModuleKind.CommonJS:
            case ts.ModuleKind.AMD:
            case ts.ModuleKind.ES2015:
            case ts.ModuleKind.ESNext:
                return true;
            default:
                return false;
        }
    }
    ts.hasJsonModuleEmitEnabled = hasJsonModuleEmitEnabled;
    function unreachableCodeIsError(options) {
        return options.allowUnreachableCode === false;
    }
    ts.unreachableCodeIsError = unreachableCodeIsError;
    function unusedLabelIsError(options) {
        return options.allowUnusedLabels === false;
    }
    ts.unusedLabelIsError = unusedLabelIsError;
    function getAreDeclarationMapsEnabled(options) {
        return !!(getEmitDeclarations(options) && options.declarationMap);
    }
    ts.getAreDeclarationMapsEnabled = getAreDeclarationMapsEnabled;
    function getAllowSyntheticDefaultImports(compilerOptions) {
        var moduleKind = getEmitModuleKind(compilerOptions);
        return compilerOptions.allowSyntheticDefaultImports !== undefined
            ? compilerOptions.allowSyntheticDefaultImports
            : compilerOptions.esModuleInterop ||
                moduleKind === ts.ModuleKind.System;
    }
    ts.getAllowSyntheticDefaultImports = getAllowSyntheticDefaultImports;
    function getEmitDeclarations(compilerOptions) {
        return !!(compilerOptions.declaration || compilerOptions.composite);
    }
    ts.getEmitDeclarations = getEmitDeclarations;
    function isIncrementalCompilation(options) {
        return !!(options.incremental || options.composite);
    }
    ts.isIncrementalCompilation = isIncrementalCompilation;
    function getStrictOptionValue(compilerOptions, flag) {
        return compilerOptions[flag] === undefined ? !!compilerOptions.strict : !!compilerOptions[flag];
    }
    ts.getStrictOptionValue = getStrictOptionValue;
    function compilerOptionsAffectSemanticDiagnostics(newOptions, oldOptions) {
        return oldOptions !== newOptions &&
            ts.semanticDiagnosticsOptionDeclarations.some(function (option) { return !ts.isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)); });
    }
    ts.compilerOptionsAffectSemanticDiagnostics = compilerOptionsAffectSemanticDiagnostics;
    function compilerOptionsAffectEmit(newOptions, oldOptions) {
        return oldOptions !== newOptions &&
            ts.affectsEmitOptionDeclarations.some(function (option) { return !ts.isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)); });
    }
    ts.compilerOptionsAffectEmit = compilerOptionsAffectEmit;
    function getCompilerOptionValue(options, option) {
        return option.strictFlag ? getStrictOptionValue(options, option.name) : options[option.name];
    }
    ts.getCompilerOptionValue = getCompilerOptionValue;
    function hasZeroOrOneAsteriskCharacter(str) {
        var seenAsterisk = false;
        for (var i = 0; i < str.length; i++) {
            if (str.charCodeAt(i) === 42 /* asterisk */) {
                if (!seenAsterisk) {
                    seenAsterisk = true;
                }
                else {
                    // have already seen asterisk
                    return false;
                }
            }
        }
        return true;
    }
    ts.hasZeroOrOneAsteriskCharacter = hasZeroOrOneAsteriskCharacter;
    /**
     * Internally, we represent paths as strings with '/' as the directory separator.
     * When we make system calls (eg: LanguageServiceHost.getDirectory()),
     * we expect the host to correctly handle paths in our specified format.
     */
    ts.directorySeparator = "/";
    var altDirectorySeparator = "\\";
    var urlSchemeSeparator = "://";
    var backslashRegExp = /\\/g;
    /**
     * Normalize path separators.
     */
    function normalizeSlashes(path) {
        return path.replace(backslashRegExp, ts.directorySeparator);
    }
    ts.normalizeSlashes = normalizeSlashes;
    function isVolumeCharacter(charCode) {
        return (charCode >= 97 /* a */ && charCode <= 122 /* z */) ||
            (charCode >= 65 /* A */ && charCode <= 90 /* Z */);
    }
    function getFileUrlVolumeSeparatorEnd(url, start) {
        var ch0 = url.charCodeAt(start);
        if (ch0 === 58 /* colon */)
            return start + 1;
        if (ch0 === 37 /* percent */ && url.charCodeAt(start + 1) === 51 /* _3 */) {
            var ch2 = url.charCodeAt(start + 2);
            if (ch2 === 97 /* a */ || ch2 === 65 /* A */)
                return start + 3;
        }
        return -1;
    }
    /**
     * Returns length of the root part of a path or URL (i.e. length of "/", "x:/", "//server/share/, file:///user/files").
     * If the root is part of a URL, the twos-complement of the root length is returned.
     */
    function getEncodedRootLength(path) {
        if (!path)
            return 0;
        var ch0 = path.charCodeAt(0);
        // POSIX or UNC
        if (ch0 === 47 /* slash */ || ch0 === 92 /* backslash */) {
            if (path.charCodeAt(1) !== ch0)
                return 1; // POSIX: "/" (or non-normalized "\")
            var p1 = path.indexOf(ch0 === 47 /* slash */ ? ts.directorySeparator : altDirectorySeparator, 2);
            if (p1 < 0)
                return path.length; // UNC: "//server" or "\\server"
            return p1 + 1; // UNC: "//server/" or "\\server\"
        }
        // DOS
        if (isVolumeCharacter(ch0) && path.charCodeAt(1) === 58 /* colon */) {
            var ch2 = path.charCodeAt(2);
            if (ch2 === 47 /* slash */ || ch2 === 92 /* backslash */)
                return 3; // DOS: "c:/" or "c:\"
            if (path.length === 2)
                return 2; // DOS: "c:" (but not "c:d")
        }
        // URL
        var schemeEnd = path.indexOf(urlSchemeSeparator);
        if (schemeEnd !== -1) {
            var authorityStart = schemeEnd + urlSchemeSeparator.length;
            var authorityEnd = path.indexOf(ts.directorySeparator, authorityStart);
            if (authorityEnd !== -1) { // URL: "file:///", "file://server/", "file://server/path"
                // For local "file" URLs, include the leading DOS volume (if present).
                // Per https://www.ietf.org/rfc/rfc1738.txt, a host of "" or "localhost" is a
                // special case interpreted as "the machine from which the URL is being interpreted".
                var scheme = path.slice(0, schemeEnd);
                var authority = path.slice(authorityStart, authorityEnd);
                if (scheme === "file" && (authority === "" || authority === "localhost") &&
                    isVolumeCharacter(path.charCodeAt(authorityEnd + 1))) {
                    var volumeSeparatorEnd = getFileUrlVolumeSeparatorEnd(path, authorityEnd + 2);
                    if (volumeSeparatorEnd !== -1) {
                        if (path.charCodeAt(volumeSeparatorEnd) === 47 /* slash */) {
                            // URL: "file:///c:/", "file://localhost/c:/", "file:///c%3a/", "file://localhost/c%3a/"
                            return ~(volumeSeparatorEnd + 1);
                        }
                        if (volumeSeparatorEnd === path.length) {
                            // URL: "file:///c:", "file://localhost/c:", "file:///c$3a", "file://localhost/c%3a"
                            // but not "file:///c:d" or "file:///c%3ad"
                            return ~volumeSeparatorEnd;
                        }
                    }
                }
                return ~(authorityEnd + 1); // URL: "file://server/", "http://server/"
            }
            return ~path.length; // URL: "file://server", "http://server"
        }
        // relative
        return 0;
    }
    /**
     * Returns length of the root part of a path or URL (i.e. length of "/", "x:/", "//server/share/, file:///user/files").
     *
     * For example:
     * ```ts
     * getRootLength("a") === 0                   // ""
     * getRootLength("/") === 1                   // "/"
     * getRootLength("c:") === 2                  // "c:"
     * getRootLength("c:d") === 0                 // ""
     * getRootLength("c:/") === 3                 // "c:/"
     * getRootLength("c:\\") === 3                // "c:\\"
     * getRootLength("//server") === 7            // "//server"
     * getRootLength("//server/share") === 8      // "//server/"
     * getRootLength("\\\\server") === 7          // "\\\\server"
     * getRootLength("\\\\server\\share") === 8   // "\\\\server\\"
     * getRootLength("file:///path") === 8        // "file:///"
     * getRootLength("file:///c:") === 10         // "file:///c:"
     * getRootLength("file:///c:d") === 8         // "file:///"
     * getRootLength("file:///c:/path") === 11    // "file:///c:/"
     * getRootLength("file://server") === 13      // "file://server"
     * getRootLength("file://server/path") === 14 // "file://server/"
     * getRootLength("http://server") === 13      // "http://server"
     * getRootLength("http://server/path") === 14 // "http://server/"
     * ```
     */
    function getRootLength(path) {
        var rootLength = getEncodedRootLength(path);
        return rootLength < 0 ? ~rootLength : rootLength;
    }
    ts.getRootLength = getRootLength;
    // TODO(rbuckton): replace references with `resolvePath`
    function normalizePath(path) {
        return ts.resolvePath(path);
    }
    ts.normalizePath = normalizePath;
    function normalizePathAndParts(path) {
        path = normalizeSlashes(path);
        var _a = reducePathComponents(getPathComponents(path)), root = _a[0], parts = _a.slice(1);
        if (parts.length) {
            var joinedParts = root + parts.join(ts.directorySeparator);
            return { path: ts.hasTrailingDirectorySeparator(path) ? ts.ensureTrailingDirectorySeparator(joinedParts) : joinedParts, parts: parts };
        }
        else {
            return { path: root, parts: parts };
        }
    }
    ts.normalizePathAndParts = normalizePathAndParts;
    function getDirectoryPath(path) {
        path = normalizeSlashes(path);
        // If the path provided is itself the root, then return it.
        var rootLength = getRootLength(path);
        if (rootLength === path.length)
            return path;
        // return the leading portion of the path up to the last (non-terminal) directory separator
        // but not including any trailing directory separator.
        path = ts.removeTrailingDirectorySeparator(path);
        return path.slice(0, Math.max(rootLength, path.lastIndexOf(ts.directorySeparator)));
    }
    ts.getDirectoryPath = getDirectoryPath;
    function startsWithDirectory(fileName, directoryName, getCanonicalFileName) {
        var canonicalFileName = getCanonicalFileName(fileName);
        var canonicalDirectoryName = getCanonicalFileName(directoryName);
        return ts.startsWith(canonicalFileName, canonicalDirectoryName + "/") || ts.startsWith(canonicalFileName, canonicalDirectoryName + "\\");
    }
    ts.startsWithDirectory = startsWithDirectory;
    function isUrl(path) {
        return getEncodedRootLength(path) < 0;
    }
    ts.isUrl = isUrl;
    function pathIsRelative(path) {
        return /^\.\.?($|[\\/])/.test(path);
    }
    ts.pathIsRelative = pathIsRelative;
    /**
     * Determines whether a path is an absolute path (e.g. starts with `/`, or a dos path
     * like `c:`, `c:\` or `c:/`).
     */
    function isRootedDiskPath(path) {
        return getEncodedRootLength(path) > 0;
    }
    ts.isRootedDiskPath = isRootedDiskPath;
    /**
     * Determines whether a path consists only of a path root.
     */
    function isDiskPathRoot(path) {
        var rootLength = getEncodedRootLength(path);
        return rootLength > 0 && rootLength === path.length;
    }
    ts.isDiskPathRoot = isDiskPathRoot;
    function convertToRelativePath(absoluteOrRelativePath, basePath, getCanonicalFileName) {
        return !isRootedDiskPath(absoluteOrRelativePath)
            ? absoluteOrRelativePath
            : ts.getRelativePathToDirectoryOrUrl(basePath, absoluteOrRelativePath, basePath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
    }
    ts.convertToRelativePath = convertToRelativePath;
    function pathComponents(path, rootLength) {
        var root = path.substring(0, rootLength);
        var rest = path.substring(rootLength).split(ts.directorySeparator);
        if (rest.length && !ts.lastOrUndefined(rest))
            rest.pop();
        return [root].concat(rest);
    }
    /**
     * Parse a path into an array containing a root component (at index 0) and zero or more path
     * components (at indices > 0). The result is not normalized.
     * If the path is relative, the root component is `""`.
     * If the path is absolute, the root component includes the first path separator (`/`).
     */
    function getPathComponents(path, currentDirectory) {
        if (currentDirectory === void 0) { currentDirectory = ""; }
        path = ts.combinePaths(currentDirectory, path);
        var rootLength = getRootLength(path);
        return pathComponents(path, rootLength);
    }
    ts.getPathComponents = getPathComponents;
    /**
     * Reduce an array of path components to a more simplified path by navigating any
     * `"."` or `".."` entries in the path.
     */
    function reducePathComponents(components) {
        if (!ts.some(components))
            return [];
        var reduced = [components[0]];
        for (var i = 1; i < components.length; i++) {
            var component = components[i];
            if (!component)
                continue;
            if (component === ".")
                continue;
            if (component === "..") {
                if (reduced.length > 1) {
                    if (reduced[reduced.length - 1] !== "..") {
                        reduced.pop();
                        continue;
                    }
                }
                else if (reduced[0])
                    continue;
            }
            reduced.push(component);
        }
        return reduced;
    }
    ts.reducePathComponents = reducePathComponents;
    /**
     * Parse a path into an array containing a root component (at index 0) and zero or more path
     * components (at indices > 0). The result is normalized.
     * If the path is relative, the root component is `""`.
     * If the path is absolute, the root component includes the first path separator (`/`).
     */
    function getNormalizedPathComponents(path, currentDirectory) {
        return reducePathComponents(getPathComponents(path, currentDirectory));
    }
    ts.getNormalizedPathComponents = getNormalizedPathComponents;
    function getNormalizedAbsolutePath(fileName, currentDirectory) {
        return getPathFromPathComponents(getNormalizedPathComponents(fileName, currentDirectory));
    }
    ts.getNormalizedAbsolutePath = getNormalizedAbsolutePath;
    /**
     * Formats a parsed path consisting of a root component (at index 0) and zero or more path
     * segments (at indices > 0).
     */
    function getPathFromPathComponents(pathComponents) {
        if (pathComponents.length === 0)
            return "";
        var root = pathComponents[0] && ts.ensureTrailingDirectorySeparator(pathComponents[0]);
        return root + pathComponents.slice(1).join(ts.directorySeparator);
    }
    ts.getPathFromPathComponents = getPathFromPathComponents;
    function getNormalizedAbsolutePathWithoutRoot(fileName, currentDirectory) {
        return getPathWithoutRoot(getNormalizedPathComponents(fileName, currentDirectory));
    }
    ts.getNormalizedAbsolutePathWithoutRoot = getNormalizedAbsolutePathWithoutRoot;
    function getPathWithoutRoot(pathComponents) {
        if (pathComponents.length === 0)
            return "";
        return pathComponents.slice(1).join(ts.directorySeparator);
    }
})(ts || (ts = {}));
/* @internal */
(function (ts) {
    function getPathComponentsRelativeTo(from, to, stringEqualityComparer, getCanonicalFileName) {
        var fromComponents = ts.reducePathComponents(ts.getPathComponents(from));
        var toComponents = ts.reducePathComponents(ts.getPathComponents(to));
        var start;
        for (start = 0; start < fromComponents.length && start < toComponents.length; start++) {
            var fromComponent = getCanonicalFileName(fromComponents[start]);
            var toComponent = getCanonicalFileName(toComponents[start]);
            var comparer = start === 0 ? ts.equateStringsCaseInsensitive : stringEqualityComparer;
            if (!comparer(fromComponent, toComponent))
                break;
        }
        if (start === 0) {
            return toComponents;
        }
        var components = toComponents.slice(start);
        var relative = [];
        for (; start < fromComponents.length; start++) {
            relative.push("..");
        }
        return [""].concat(relative, components);
    }
    ts.getPathComponentsRelativeTo = getPathComponentsRelativeTo;
    function getRelativePathFromFile(from, to, getCanonicalFileName) {
        return ensurePathIsNonModuleName(getRelativePathFromDirectory(ts.getDirectoryPath(from), to, getCanonicalFileName));
    }
    ts.getRelativePathFromFile = getRelativePathFromFile;
    function getRelativePathFromDirectory(fromDirectory, to, getCanonicalFileNameOrIgnoreCase) {
        ts.Debug.assert((ts.getRootLength(fromDirectory) > 0) === (ts.getRootLength(to) > 0), "Paths must either both be absolute or both be relative");
        var getCanonicalFileName = typeof getCanonicalFileNameOrIgnoreCase === "function" ? getCanonicalFileNameOrIgnoreCase : ts.identity;
        var ignoreCase = typeof getCanonicalFileNameOrIgnoreCase === "boolean" ? getCanonicalFileNameOrIgnoreCase : false;
        var pathComponents = getPathComponentsRelativeTo(fromDirectory, to, ignoreCase ? ts.equateStringsCaseInsensitive : ts.equateStringsCaseSensitive, getCanonicalFileName);
        return ts.getPathFromPathComponents(pathComponents);
    }
    ts.getRelativePathFromDirectory = getRelativePathFromDirectory;
    function getRelativePathToDirectoryOrUrl(directoryPathOrUrl, relativeOrAbsolutePath, currentDirectory, getCanonicalFileName, isAbsolutePathAnUrl) {
        var pathComponents = getPathComponentsRelativeTo(resolvePath(currentDirectory, directoryPathOrUrl), resolvePath(currentDirectory, relativeOrAbsolutePath), ts.equateStringsCaseSensitive, getCanonicalFileName);
        var firstComponent = pathComponents[0];
        if (isAbsolutePathAnUrl && ts.isRootedDiskPath(firstComponent)) {
            var prefix = firstComponent.charAt(0) === ts.directorySeparator ? "file://" : "file:///";
            pathComponents[0] = prefix + firstComponent;
        }
        return ts.getPathFromPathComponents(pathComponents);
    }
    ts.getRelativePathToDirectoryOrUrl = getRelativePathToDirectoryOrUrl;
    /**
     * Ensures a path is either absolute (prefixed with `/` or `c:`) or dot-relative (prefixed
     * with `./` or `../`) so as not to be confused with an unprefixed module name.
     */
    function ensurePathIsNonModuleName(path) {
        return ts.getRootLength(path) === 0 && !ts.pathIsRelative(path) ? "./" + path : path;
    }
    ts.ensurePathIsNonModuleName = ensurePathIsNonModuleName;
    function getBaseFileName(path, extensions, ignoreCase) {
        path = ts.normalizeSlashes(path);
        // if the path provided is itself the root, then it has not file name.
        var rootLength = ts.getRootLength(path);
        if (rootLength === path.length)
            return "";
        // return the trailing portion of the path starting after the last (non-terminal) directory
        // separator but not including any trailing directory separator.
        path = removeTrailingDirectorySeparator(path);
        var name = path.slice(Math.max(ts.getRootLength(path), path.lastIndexOf(ts.directorySeparator) + 1));
        var extension = extensions !== undefined && ignoreCase !== undefined ? getAnyExtensionFromPath(name, extensions, ignoreCase) : undefined;
        return extension ? name.slice(0, name.length - extension.length) : name;
    }
    ts.getBaseFileName = getBaseFileName;
    /**
     * Combines paths. If a path is absolute, it replaces any previous path.
     */
    function combinePaths(path) {
        var paths = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            paths[_i - 1] = arguments[_i];
        }
        if (path)
            path = ts.normalizeSlashes(path);
        for (var _a = 0, paths_1 = paths; _a < paths_1.length; _a++) {
            var relativePath = paths_1[_a];
            if (!relativePath)
                continue;
            relativePath = ts.normalizeSlashes(relativePath);
            if (!path || ts.getRootLength(relativePath) !== 0) {
                path = relativePath;
            }
            else {
                path = ensureTrailingDirectorySeparator(path) + relativePath;
            }
        }
        return path;
    }
    ts.combinePaths = combinePaths;
    /**
     * Combines and resolves paths. If a path is absolute, it replaces any previous path. Any
     * `.` and `..` path components are resolved.
     */
    function resolvePath(path) {
        var paths = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            paths[_i - 1] = arguments[_i];
        }
        var combined = ts.some(paths) ? combinePaths.apply(void 0, [path].concat(paths)) : ts.normalizeSlashes(path);
        var normalized = ts.getPathFromPathComponents(ts.reducePathComponents(ts.getPathComponents(combined)));
        return normalized && hasTrailingDirectorySeparator(combined) ? ensureTrailingDirectorySeparator(normalized) : normalized;
    }
    ts.resolvePath = resolvePath;
    /**
     * Determines whether a path has a trailing separator (`/` or `\\`).
     */
    function hasTrailingDirectorySeparator(path) {
        if (path.length === 0)
            return false;
        var ch = path.charCodeAt(path.length - 1);
        return ch === 47 /* slash */ || ch === 92 /* backslash */;
    }
    ts.hasTrailingDirectorySeparator = hasTrailingDirectorySeparator;
    function removeTrailingDirectorySeparator(path) {
        if (hasTrailingDirectorySeparator(path)) {
            return path.substr(0, path.length - 1);
        }
        return path;
    }
    ts.removeTrailingDirectorySeparator = removeTrailingDirectorySeparator;
    function ensureTrailingDirectorySeparator(path) {
        if (!hasTrailingDirectorySeparator(path)) {
            return path + ts.directorySeparator;
        }
        return path;
    }
    ts.ensureTrailingDirectorySeparator = ensureTrailingDirectorySeparator;
    // check path for these segments: '', '.'. '..'
    var relativePathSegmentRegExp = /(^|\/)\.{0,2}($|\/)/;
    function comparePathsWorker(a, b, componentComparer) {
        if (a === b)
            return 0 /* EqualTo */;
        if (a === undefined)
            return -1 /* LessThan */;
        if (b === undefined)
            return 1 /* GreaterThan */;
        // NOTE: Performance optimization - shortcut if the root segments differ as there would be no
        //       need to perform path reduction.
        var aRoot = a.substring(0, ts.getRootLength(a));
        var bRoot = b.substring(0, ts.getRootLength(b));
        var result = ts.compareStringsCaseInsensitive(aRoot, bRoot);
        if (result !== 0 /* EqualTo */) {
            return result;
        }
        // NOTE: Performance optimization - shortcut if there are no relative path segments in
        //       the non-root portion of the path
        var aRest = a.substring(aRoot.length);
        var bRest = b.substring(bRoot.length);
        if (!relativePathSegmentRegExp.test(aRest) && !relativePathSegmentRegExp.test(bRest)) {
            return componentComparer(aRest, bRest);
        }
        // The path contains a relative path segment. Normalize the paths and perform a slower component
        // by component comparison.
        var aComponents = ts.reducePathComponents(ts.getPathComponents(a));
        var bComponents = ts.reducePathComponents(ts.getPathComponents(b));
        var sharedLength = Math.min(aComponents.length, bComponents.length);
        for (var i = 1; i < sharedLength; i++) {
            var result_1 = componentComparer(aComponents[i], bComponents[i]);
            if (result_1 !== 0 /* EqualTo */) {
                return result_1;
            }
        }
        return ts.compareValues(aComponents.length, bComponents.length);
    }
    /**
     * Performs a case-sensitive comparison of two paths.
     */
    function comparePathsCaseSensitive(a, b) {
        return comparePathsWorker(a, b, ts.compareStringsCaseSensitive);
    }
    ts.comparePathsCaseSensitive = comparePathsCaseSensitive;
    /**
     * Performs a case-insensitive comparison of two paths.
     */
    function comparePathsCaseInsensitive(a, b) {
        return comparePathsWorker(a, b, ts.compareStringsCaseInsensitive);
    }
    ts.comparePathsCaseInsensitive = comparePathsCaseInsensitive;
    function comparePaths(a, b, currentDirectory, ignoreCase) {
        if (typeof currentDirectory === "string") {
            a = combinePaths(currentDirectory, a);
            b = combinePaths(currentDirectory, b);
        }
        else if (typeof currentDirectory === "boolean") {
            ignoreCase = currentDirectory;
        }
        return comparePathsWorker(a, b, ts.getStringComparer(ignoreCase));
    }
    ts.comparePaths = comparePaths;
    function containsPath(parent, child, currentDirectory, ignoreCase) {
        if (typeof currentDirectory === "string") {
            parent = combinePaths(currentDirectory, parent);
            child = combinePaths(currentDirectory, child);
        }
        else if (typeof currentDirectory === "boolean") {
            ignoreCase = currentDirectory;
        }
        if (parent === undefined || child === undefined)
            return false;
        if (parent === child)
            return true;
        var parentComponents = ts.reducePathComponents(ts.getPathComponents(parent));
        var childComponents = ts.reducePathComponents(ts.getPathComponents(child));
        if (childComponents.length < parentComponents.length) {
            return false;
        }
        var componentEqualityComparer = ignoreCase ? ts.equateStringsCaseInsensitive : ts.equateStringsCaseSensitive;
        for (var i = 0; i < parentComponents.length; i++) {
            var equalityComparer = i === 0 ? ts.equateStringsCaseInsensitive : componentEqualityComparer;
            if (!equalityComparer(parentComponents[i], childComponents[i])) {
                return false;
            }
        }
        return true;
    }
    ts.containsPath = containsPath;
    function isDirectorySeparator(charCode) {
        return charCode === 47 /* slash */ || charCode === 92 /* backslash */;
    }
    function stripLeadingDirectorySeparator(s) {
        return isDirectorySeparator(s.charCodeAt(0)) ? s.slice(1) : undefined;
    }
    function tryRemoveDirectoryPrefix(path, dirPath, getCanonicalFileName) {
        var withoutPrefix = ts.tryRemovePrefix(path, dirPath, getCanonicalFileName);
        return withoutPrefix === undefined ? undefined : stripLeadingDirectorySeparator(withoutPrefix);
    }
    ts.tryRemoveDirectoryPrefix = tryRemoveDirectoryPrefix;
    // Reserved characters, forces escaping of any non-word (or digit), non-whitespace character.
    // It may be inefficient (we could just match (/[-[\]{}()*+?.,\\^$|#\s]/g), but this is future
    // proof.
    var reservedCharacterPattern = /[^\w\s\/]/g;
    function regExpEscape(text) {
        return text.replace(reservedCharacterPattern, escapeRegExpCharacter);
    }
    ts.regExpEscape = regExpEscape;
    function escapeRegExpCharacter(match) {
        return "\\" + match;
    }
    var wildcardCharCodes = [42 /* asterisk */, 63 /* question */];
    function hasExtension(fileName) {
        return ts.stringContains(getBaseFileName(fileName), ".");
    }
    ts.hasExtension = hasExtension;
    ts.commonPackageFolders = ["node_modules", "bower_components", "jspm_packages"];
    var implicitExcludePathRegexPattern = "(?!(" + ts.commonPackageFolders.join("|") + ")(/|$))";
    var filesMatcher = {
        /**
         * Matches any single directory segment unless it is the last segment and a .min.js file
         * Breakdown:
         *  [^./]                   # matches everything up to the first . character (excluding directory separators)
         *  (\\.(?!min\\.js$))?     # matches . characters but not if they are part of the .min.js file extension
         */
        singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*",
        /**
         * Regex for the ** wildcard. Matches any number of subdirectories. When used for including
         * files or directories, does not match subdirectories that start with a . character
         */
        doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?",
        replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment); }
    };
    var directoriesMatcher = {
        singleAsteriskRegexFragment: "[^/]*",
        /**
         * Regex for the ** wildcard. Matches any number of subdirectories. When used for including
         * files or directories, does not match subdirectories that start with a . character
         */
        doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?",
        replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment); }
    };
    var excludeMatcher = {
        singleAsteriskRegexFragment: "[^/]*",
        doubleAsteriskRegexFragment: "(/.+?)?",
        replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment); }
    };
    var wildcardMatchers = {
        files: filesMatcher,
        directories: directoriesMatcher,
        exclude: excludeMatcher
    };
    function getRegularExpressionForWildcard(specs, basePath, usage) {
        var patterns = getRegularExpressionsForWildcards(specs, basePath, usage);
        if (!patterns || !patterns.length) {
            return undefined;
        }
        var pattern = patterns.map(function (pattern) { return "(" + pattern + ")"; }).join("|");
        // If excluding, match "foo/bar/baz...", but if including, only allow "foo".
        var terminator = usage === "exclude" ? "($|/)" : "$";
        return "^(" + pattern + ")" + terminator;
    }
    ts.getRegularExpressionForWildcard = getRegularExpressionForWildcard;
    function getRegularExpressionsForWildcards(specs, basePath, usage) {
        if (specs === undefined || specs.length === 0) {
            return undefined;
        }
        return ts.flatMap(specs, function (spec) {
            return spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]);
        });
    }
    ts.getRegularExpressionsForWildcards = getRegularExpressionsForWildcards;
    /**
     * An "includes" path "foo" is implicitly a glob "foo/** /*" (without the space) if its last component has no extension,
     * and does not contain any glob characters itself.
     */
    function isImplicitGlob(lastPathComponent) {
        return !/[.*?]/.test(lastPathComponent);
    }
    ts.isImplicitGlob = isImplicitGlob;
    function getSubPatternFromSpec(spec, basePath, usage, _a) {
        var singleAsteriskRegexFragment = _a.singleAsteriskRegexFragment, doubleAsteriskRegexFragment = _a.doubleAsteriskRegexFragment, replaceWildcardCharacter = _a.replaceWildcardCharacter;
        var subpattern = "";
        var hasWrittenComponent = false;
        var components = ts.getNormalizedPathComponents(spec, basePath);
        var lastComponent = ts.last(components);
        if (usage !== "exclude" && lastComponent === "**") {
            return undefined;
        }
        // getNormalizedPathComponents includes the separator for the root component.
        // We need to remove to create our regex correctly.
        components[0] = removeTrailingDirectorySeparator(components[0]);
        if (isImplicitGlob(lastComponent)) {
            components.push("**", "*");
        }
        var optionalCount = 0;
        for (var _i = 0, components_1 = components; _i < components_1.length; _i++) {
            var component = components_1[_i];
            if (component === "**") {
                subpattern += doubleAsteriskRegexFragment;
            }
            else {
                if (usage === "directories") {
                    subpattern += "(";
                    optionalCount++;
                }
                if (hasWrittenComponent) {
                    subpattern += ts.directorySeparator;
                }
                if (usage !== "exclude") {
                    var componentPattern = "";
                    // The * and ? wildcards should not match directories or files that start with . if they
                    // appear first in a component. Dotted directories and files can be included explicitly
                    // like so: **/.*/.*
                    if (component.charCodeAt(0) === 42 /* asterisk */) {
                        componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?";
                        component = component.substr(1);
                    }
                    else if (component.charCodeAt(0) === 63 /* question */) {
                        componentPattern += "[^./]";
                        component = component.substr(1);
                    }
                    componentPattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
                    // Patterns should not include subfolders like node_modules unless they are
                    // explicitly included as part of the path.
                    //
                    // As an optimization, if the component pattern is the same as the component,
                    // then there definitely were no wildcard characters and we do not need to
                    // add the exclusion pattern.
                    if (componentPattern !== component) {
                        subpattern += implicitExcludePathRegexPattern;
                    }
                    subpattern += componentPattern;
                }
                else {
                    subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
                }
            }
            hasWrittenComponent = true;
        }
        while (optionalCount > 0) {
            subpattern += ")?";
            optionalCount--;
        }
        return subpattern;
    }
    function replaceWildcardCharacter(match, singleAsteriskRegexFragment) {
        return match === "*" ? singleAsteriskRegexFragment : match === "?" ? "[^/]" : "\\" + match;
    }
    /** @param path directory of the tsconfig.json */
    function getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory) {
        path = ts.normalizePath(path);
        currentDirectory = ts.normalizePath(currentDirectory);
        var absolutePath = combinePaths(currentDirectory, path);
        return {
            includeFilePatterns: ts.map(getRegularExpressionsForWildcards(includes, absolutePath, "files"), function (pattern) { return "^" + pattern + "$"; }),
            includeFilePattern: getRegularExpressionForWildcard(includes, absolutePath, "files"),
            includeDirectoryPattern: getRegularExpressionForWildcard(includes, absolutePath, "directories"),
            excludePattern: getRegularExpressionForWildcard(excludes, absolutePath, "exclude"),
            basePaths: getBasePaths(path, includes, useCaseSensitiveFileNames)
        };
    }
    ts.getFileMatcherPatterns = getFileMatcherPatterns;
    function getRegexFromPattern(pattern, useCaseSensitiveFileNames) {
        return new RegExp(pattern, useCaseSensitiveFileNames ? "" : "i");
    }
    ts.getRegexFromPattern = getRegexFromPattern;
    /** @param path directory of the tsconfig.json */
    function matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries, realpath) {
        path = ts.normalizePath(path);
        currentDirectory = ts.normalizePath(currentDirectory);
        var patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory);
        var includeFileRegexes = patterns.includeFilePatterns && patterns.includeFilePatterns.map(function (pattern) { return getRegexFromPattern(pattern, useCaseSensitiveFileNames); });
        var includeDirectoryRegex = patterns.includeDirectoryPattern && getRegexFromPattern(patterns.includeDirectoryPattern, useCaseSensitiveFileNames);
        var excludeRegex = patterns.excludePattern && getRegexFromPattern(patterns.excludePattern, useCaseSensitiveFileNames);
        // Associate an array of results with each include regex. This keeps results in order of the "include" order.
        // If there are no "includes", then just put everything in results[0].
        var results = includeFileRegexes ? includeFileRegexes.map(function () { return []; }) : [[]];
        var visited = ts.createMap();
        var toCanonical = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        for (var _i = 0, _a = patterns.basePaths; _i < _a.length; _i++) {
            var basePath = _a[_i];
            visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth);
        }
        return ts.flatten(results);
        function visitDirectory(path, absolutePath, depth) {
            var canonicalPath = toCanonical(realpath(absolutePath));
            if (visited.has(canonicalPath))
                return;
            visited.set(canonicalPath, true);
            var _a = getFileSystemEntries(path), files = _a.files, directories = _a.directories;
            var _loop_1 = function (current) {
                var name = combinePaths(path, current);
                var absoluteName = combinePaths(absolutePath, current);
                if (extensions && !ts.fileExtensionIsOneOf(name, extensions))
                    return "continue";
                if (excludeRegex && excludeRegex.test(absoluteName))
                    return "continue";
                if (!includeFileRegexes) {
                    results[0].push(name);
                }
                else {
                    var includeIndex = ts.findIndex(includeFileRegexes, function (re) { return re.test(absoluteName); });
                    if (includeIndex !== -1) {
                        results[includeIndex].push(name);
                    }
                }
            };
            for (var _i = 0, _b = ts.sort(files, ts.compareStringsCaseSensitive); _i < _b.length; _i++) {
                var current = _b[_i];
                _loop_1(current);
            }
            if (depth !== undefined) {
                depth--;
                if (depth === 0) {
                    return;
                }
            }
            for (var _c = 0, _d = ts.sort(directories, ts.compareStringsCaseSensitive); _c < _d.length; _c++) {
                var current = _d[_c];
                var name = combinePaths(path, current);
                var absoluteName = combinePaths(absolutePath, current);
                if ((!includeDirectoryRegex || includeDirectoryRegex.test(absoluteName)) &&
                    (!excludeRegex || !excludeRegex.test(absoluteName))) {
                    visitDirectory(name, absoluteName, depth);
                }
            }
        }
    }
    ts.matchFiles = matchFiles;
    /**
     * Computes the unique non-wildcard base paths amongst the provided include patterns.
     */
    function getBasePaths(path, includes, useCaseSensitiveFileNames) {
        // Storage for our results in the form of literal paths (e.g. the paths as written by the user).
        var basePaths = [path];
        if (includes) {
            // Storage for literal base paths amongst the include patterns.
            var includeBasePaths = [];
            for (var _i = 0, includes_1 = includes; _i < includes_1.length; _i++) {
                var include = includes_1[_i];
                // We also need to check the relative paths by converting them to absolute and normalizing
                // in case they escape the base path (e.g "..\somedirectory")
                var absolute = ts.isRootedDiskPath(include) ? include : ts.normalizePath(combinePaths(path, include));
                // Append the literal and canonical candidate base paths.
                includeBasePaths.push(getIncludeBasePath(absolute));
            }
            // Sort the offsets array using either the literal or canonical path representations.
            includeBasePaths.sort(ts.getStringComparer(!useCaseSensitiveFileNames));
            var _loop_2 = function (includeBasePath) {
                if (ts.every(basePaths, function (basePath) { return !containsPath(basePath, includeBasePath, path, !useCaseSensitiveFileNames); })) {
                    basePaths.push(includeBasePath);
                }
            };
            // Iterate over each include base path and include unique base paths that are not a
            // subpath of an existing base path
            for (var _a = 0, includeBasePaths_1 = includeBasePaths; _a < includeBasePaths_1.length; _a++) {
                var includeBasePath = includeBasePaths_1[_a];
                _loop_2(includeBasePath);
            }
        }
        return basePaths;
    }
    function getIncludeBasePath(absolute) {
        var wildcardOffset = ts.indexOfAnyCharCode(absolute, wildcardCharCodes);
        if (wildcardOffset < 0) {
            // No "*" or "?" in the path
            return !hasExtension(absolute)
                ? absolute
                : removeTrailingDirectorySeparator(ts.getDirectoryPath(absolute));
        }
        return absolute.substring(0, absolute.lastIndexOf(ts.directorySeparator, wildcardOffset));
    }
    function ensureScriptKind(fileName, scriptKind) {
        // Using scriptKind as a condition handles both:
        // - 'scriptKind' is unspecified and thus it is `undefined`
        // - 'scriptKind' is set and it is `Unknown` (0)
        // If the 'scriptKind' is 'undefined' or 'Unknown' then we attempt
        // to get the ScriptKind from the file name. If it cannot be resolved
        // from the file name then the default 'TS' script kind is returned.
        return scriptKind || getScriptKindFromFileName(fileName) || 3 /* TS */;
    }
    ts.ensureScriptKind = ensureScriptKind;
    function getScriptKindFromFileName(fileName) {
        var ext = fileName.substr(fileName.lastIndexOf("."));
        switch (ext.toLowerCase()) {
            case ".js" /* Js */:
                return 1 /* JS */;
            case ".jsx" /* Jsx */:
                return 2 /* JSX */;
            case ".ts" /* Ts */:
                return 3 /* TS */;
            case ".tsx" /* Tsx */:
                return 4 /* TSX */;
            case ".json" /* Json */:
                return 6 /* JSON */;
            default:
                return 0 /* Unknown */;
        }
    }
    ts.getScriptKindFromFileName = getScriptKindFromFileName;
    /**
     *  List of supported extensions in order of file resolution precedence.
     */
    ts.supportedTSExtensions = [".ts" /* Ts */, ".tsx" /* Tsx */, ".d.ts" /* Dts */];
    ts.supportedTSExtensionsWithJson = [".ts" /* Ts */, ".tsx" /* Tsx */, ".d.ts" /* Dts */, ".json" /* Json */];
    /** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */
    ts.supportedTSExtensionsForExtractExtension = [".d.ts" /* Dts */, ".ts" /* Ts */, ".tsx" /* Tsx */];
    ts.supportedJSExtensions = [".js" /* Js */, ".jsx" /* Jsx */];
    ts.supportedJSAndJsonExtensions = [".js" /* Js */, ".jsx" /* Jsx */, ".json" /* Json */];
    var allSupportedExtensions = ts.supportedTSExtensions.concat(ts.supportedJSExtensions);
    var allSupportedExtensionsWithJson = ts.supportedTSExtensions.concat(ts.supportedJSExtensions, [".json" /* Json */]);
    function getSupportedExtensions(options, extraFileExtensions) {
        var needJsExtensions = options && options.allowJs;
        if (!extraFileExtensions || extraFileExtensions.length === 0) {
            return needJsExtensions ? allSupportedExtensions : ts.supportedTSExtensions;
        }
        var extensions = (needJsExtensions ? allSupportedExtensions : ts.supportedTSExtensions).concat(ts.mapDefined(extraFileExtensions, function (x) { return x.scriptKind === 7 /* Deferred */ || needJsExtensions && isJSLike(x.scriptKind) ? x.extension : undefined; }));
        return ts.deduplicate(extensions, ts.equateStringsCaseSensitive, ts.compareStringsCaseSensitive);
    }
    ts.getSupportedExtensions = getSupportedExtensions;
    function getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions) {
        if (!options || !options.resolveJsonModule) {
            return supportedExtensions;
        }
        if (supportedExtensions === allSupportedExtensions) {
            return allSupportedExtensionsWithJson;
        }
        if (supportedExtensions === ts.supportedTSExtensions) {
            return ts.supportedTSExtensionsWithJson;
        }
        return supportedExtensions.concat([".json" /* Json */]);
    }
    ts.getSuppoertedExtensionsWithJsonIfResolveJsonModule = getSuppoertedExtensionsWithJsonIfResolveJsonModule;
    function isJSLike(scriptKind) {
        return scriptKind === 1 /* JS */ || scriptKind === 2 /* JSX */;
    }
    function hasJSFileExtension(fileName) {
        return ts.some(ts.supportedJSExtensions, function (extension) { return ts.fileExtensionIs(fileName, extension); });
    }
    ts.hasJSFileExtension = hasJSFileExtension;
    function hasJSOrJsonFileExtension(fileName) {
        return ts.supportedJSAndJsonExtensions.some(function (ext) { return ts.fileExtensionIs(fileName, ext); });
    }
    ts.hasJSOrJsonFileExtension = hasJSOrJsonFileExtension;
    function hasTSFileExtension(fileName) {
        return ts.some(ts.supportedTSExtensions, function (extension) { return ts.fileExtensionIs(fileName, extension); });
    }
    ts.hasTSFileExtension = hasTSFileExtension;
    function isSupportedSourceFileName(fileName, compilerOptions, extraFileExtensions) {
        if (!fileName) {
            return false;
        }
        var supportedExtensions = getSupportedExtensions(compilerOptions, extraFileExtensions);
        for (var _i = 0, _a = getSuppoertedExtensionsWithJsonIfResolveJsonModule(compilerOptions, supportedExtensions); _i < _a.length; _i++) {
            var extension = _a[_i];
            if (ts.fileExtensionIs(fileName, extension)) {
                return true;
            }
        }
        return false;
    }
    ts.isSupportedSourceFileName = isSupportedSourceFileName;
    /**
     * Extension boundaries by priority. Lower numbers indicate higher priorities, and are
     * aligned to the offset of the highest priority extension in the
     * allSupportedExtensions array.
     */
    var ExtensionPriority;
    (function (ExtensionPriority) {
        ExtensionPriority[ExtensionPriority["TypeScriptFiles"] = 0] = "TypeScriptFiles";
        ExtensionPriority[ExtensionPriority["DeclarationAndJavaScriptFiles"] = 2] = "DeclarationAndJavaScriptFiles";
        ExtensionPriority[ExtensionPriority["Highest"] = 0] = "Highest";
        ExtensionPriority[ExtensionPriority["Lowest"] = 2] = "Lowest";
    })(ExtensionPriority = ts.ExtensionPriority || (ts.ExtensionPriority = {}));
    function getExtensionPriority(path, supportedExtensions) {
        for (var i = supportedExtensions.length - 1; i >= 0; i--) {
            if (ts.fileExtensionIs(path, supportedExtensions[i])) {
                return adjustExtensionPriority(i, supportedExtensions);
            }
        }
        // If its not in the list of supported extensions, this is likely a
        // TypeScript file with a non-ts extension
        return 0 /* Highest */;
    }
    ts.getExtensionPriority = getExtensionPriority;
    /**
     * Adjusts an extension priority to be the highest priority within the same range.
     */
    function adjustExtensionPriority(extensionPriority, supportedExtensions) {
        if (extensionPriority < 2 /* DeclarationAndJavaScriptFiles */) {
            return 0 /* TypeScriptFiles */;
        }
        else if (extensionPriority < supportedExtensions.length) {
            return 2 /* DeclarationAndJavaScriptFiles */;
        }
        else {
            return supportedExtensions.length;
        }
    }
    ts.adjustExtensionPriority = adjustExtensionPriority;
    /**
     * Gets the next lowest extension priority for a given priority.
     */
    function getNextLowestExtensionPriority(extensionPriority, supportedExtensions) {
        if (extensionPriority < 2 /* DeclarationAndJavaScriptFiles */) {
            return 2 /* DeclarationAndJavaScriptFiles */;
        }
        else {
            return supportedExtensions.length;
        }
    }
    ts.getNextLowestExtensionPriority = getNextLowestExtensionPriority;
    var extensionsToRemove = [".d.ts" /* Dts */, ".ts" /* Ts */, ".js" /* Js */, ".tsx" /* Tsx */, ".jsx" /* Jsx */, ".json" /* Json */];
    function removeFileExtension(path) {
        for (var _i = 0, extensionsToRemove_1 = extensionsToRemove; _i < extensionsToRemove_1.length; _i++) {
            var ext = extensionsToRemove_1[_i];
            var extensionless = tryRemoveExtension(path, ext);
            if (extensionless !== undefined) {
                return extensionless;
            }
        }
        return path;
    }
    ts.removeFileExtension = removeFileExtension;
    function tryRemoveExtension(path, extension) {
        return ts.fileExtensionIs(path, extension) ? removeExtension(path, extension) : undefined;
    }
    ts.tryRemoveExtension = tryRemoveExtension;
    function removeExtension(path, extension) {
        return path.substring(0, path.length - extension.length);
    }
    ts.removeExtension = removeExtension;
    function changeExtension(path, newExtension) {
        return changeAnyExtension(path, newExtension, extensionsToRemove, /*ignoreCase*/ false);
    }
    ts.changeExtension = changeExtension;
    function changeAnyExtension(path, ext, extensions, ignoreCase) {
        var pathext = extensions !== undefined && ignoreCase !== undefined ? getAnyExtensionFromPath(path, extensions, ignoreCase) : getAnyExtensionFromPath(path);
        return pathext ? path.slice(0, path.length - pathext.length) + (ts.startsWith(ext, ".") ? ext : "." + ext) : path;
    }
    ts.changeAnyExtension = changeAnyExtension;
    function tryParsePattern(pattern) {
        // This should be verified outside of here and a proper error thrown.
        ts.Debug.assert(ts.hasZeroOrOneAsteriskCharacter(pattern));
        var indexOfStar = pattern.indexOf("*");
        return indexOfStar === -1 ? undefined : {
            prefix: pattern.substr(0, indexOfStar),
            suffix: pattern.substr(indexOfStar + 1)
        };
    }
    ts.tryParsePattern = tryParsePattern;
    function positionIsSynthesized(pos) {
        // This is a fast way of testing the following conditions:
        //  pos === undefined || pos === null || isNaN(pos) || pos < 0;
        return !(pos >= 0);
    }
    ts.positionIsSynthesized = positionIsSynthesized;
    /** True if an extension is one of the supported TypeScript extensions. */
    function extensionIsTS(ext) {
        return ext === ".ts" /* Ts */ || ext === ".tsx" /* Tsx */ || ext === ".d.ts" /* Dts */;
    }
    ts.extensionIsTS = extensionIsTS;
    function resolutionExtensionIsTSOrJson(ext) {
        return extensionIsTS(ext) || ext === ".json" /* Json */;
    }
    ts.resolutionExtensionIsTSOrJson = resolutionExtensionIsTSOrJson;
    /**
     * Gets the extension from a path.
     * Path must have a valid extension.
     */
    function extensionFromPath(path) {
        var ext = tryGetExtensionFromPath(path);
        return ext !== undefined ? ext : ts.Debug.fail("File " + path + " has unknown extension.");
    }
    ts.extensionFromPath = extensionFromPath;
    function isAnySupportedFileExtension(path) {
        return tryGetExtensionFromPath(path) !== undefined;
    }
    ts.isAnySupportedFileExtension = isAnySupportedFileExtension;
    function tryGetExtensionFromPath(path) {
        return ts.find(extensionsToRemove, function (e) { return ts.fileExtensionIs(path, e); });
    }
    ts.tryGetExtensionFromPath = tryGetExtensionFromPath;
    function getAnyExtensionFromPathWorker(path, extensions, stringEqualityComparer) {
        if (typeof extensions === "string")
            extensions = [extensions];
        for (var _i = 0, extensions_2 = extensions; _i < extensions_2.length; _i++) {
            var extension = extensions_2[_i];
            if (!ts.startsWith(extension, "."))
                extension = "." + extension;
            if (path.length >= extension.length && path.charAt(path.length - extension.length) === ".") {
                var pathExtension = path.slice(path.length - extension.length);
                if (stringEqualityComparer(pathExtension, extension)) {
                    return pathExtension;
                }
            }
        }
        return "";
    }
    function getAnyExtensionFromPath(path, extensions, ignoreCase) {
        // Retrieves any string from the final "." onwards from a base file name.
        // Unlike extensionFromPath, which throws an exception on unrecognized extensions.
        if (extensions) {
            return getAnyExtensionFromPathWorker(path, extensions, ignoreCase ? ts.equateStringsCaseInsensitive : ts.equateStringsCaseSensitive);
        }
        var baseFileName = getBaseFileName(path);
        var extensionIndex = baseFileName.lastIndexOf(".");
        if (extensionIndex >= 0) {
            return baseFileName.substring(extensionIndex);
        }
        return "";
    }
    ts.getAnyExtensionFromPath = getAnyExtensionFromPath;
    function isCheckJsEnabledForFile(sourceFile, compilerOptions) {
        return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs;
    }
    ts.isCheckJsEnabledForFile = isCheckJsEnabledForFile;
    ts.emptyFileSystemEntries = {
        files: ts.emptyArray,
        directories: ts.emptyArray
    };
    /**
     * patternStrings contains both pattern strings (containing "*") and regular strings.
     * Return an exact match if possible, or a pattern match, or undefined.
     * (These are verified by verifyCompilerOptions to have 0 or 1 "*" characters.)
     */
    function matchPatternOrExact(patternStrings, candidate) {
        var patterns = [];
        for (var _i = 0, patternStrings_1 = patternStrings; _i < patternStrings_1.length; _i++) {
            var patternString = patternStrings_1[_i];
            var pattern = tryParsePattern(patternString);
            if (pattern) {
                patterns.push(pattern);
            }
            else if (patternString === candidate) {
                // pattern was matched as is - no need to search further
                return patternString;
            }
        }
        return ts.findBestPatternMatch(patterns, function (_) { return _; }, candidate);
    }
    ts.matchPatternOrExact = matchPatternOrExact;
    function sliceAfter(arr, value) {
        var index = arr.indexOf(value);
        ts.Debug.assert(index !== -1);
        return arr.slice(index);
    }
    ts.sliceAfter = sliceAfter;
    function addRelatedInfo(diagnostic) {
        var _a;
        var relatedInformation = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            relatedInformation[_i - 1] = arguments[_i];
        }
        if (!diagnostic.relatedInformation) {
            diagnostic.relatedInformation = [];
        }
        (_a = diagnostic.relatedInformation).push.apply(_a, relatedInformation);
        return diagnostic;
    }
    ts.addRelatedInfo = addRelatedInfo;
    function minAndMax(arr, getValue) {
        ts.Debug.assert(arr.length !== 0);
        var min = getValue(arr[0]);
        var max = min;
        for (var i = 1; i < arr.length; i++) {
            var value = getValue(arr[i]);
            if (value < min) {
                min = value;
            }
            else if (value > max) {
                max = value;
            }
        }
        return { min: min, max: max };
    }
    ts.minAndMax = minAndMax;
    var NodeSet = /** @class */ (function () {
        function NodeSet() {
            this.map = ts.createMap();
        }
        NodeSet.prototype.add = function (node) {
            this.map.set(String(ts.getNodeId(node)), node);
        };
        NodeSet.prototype.tryAdd = function (node) {
            if (this.has(node))
                return false;
            this.add(node);
            return true;
        };
        NodeSet.prototype.has = function (node) {
            return this.map.has(String(ts.getNodeId(node)));
        };
        NodeSet.prototype.forEach = function (cb) {
            this.map.forEach(cb);
        };
        NodeSet.prototype.some = function (pred) {
            return ts.forEachEntry(this.map, pred) || false;
        };
        return NodeSet;
    }());
    ts.NodeSet = NodeSet;
    var NodeMap = /** @class */ (function () {
        function NodeMap() {
            this.map = ts.createMap();
        }
        NodeMap.prototype.get = function (node) {
            var res = this.map.get(String(ts.getNodeId(node)));
            return res && res.value;
        };
        NodeMap.prototype.getOrUpdate = function (node, setValue) {
            var res = this.get(node);
            if (res)
                return res;
            var value = setValue();
            this.set(node, value);
            return value;
        };
        NodeMap.prototype.set = function (node, value) {
            this.map.set(String(ts.getNodeId(node)), { node: node, value: value });
        };
        NodeMap.prototype.has = function (node) {
            return this.map.has(String(ts.getNodeId(node)));
        };
        NodeMap.prototype.forEach = function (cb) {
            this.map.forEach(function (_a) {
                var node = _a.node, value = _a.value;
                return cb(value, node);
            });
        };
        return NodeMap;
    }());
    ts.NodeMap = NodeMap;
    function rangeOfNode(node) {
        return { pos: ts.getTokenPosOfNode(node), end: node.end };
    }
    ts.rangeOfNode = rangeOfNode;
    function rangeOfTypeParameters(typeParameters) {
        // Include the `<>`
        return { pos: typeParameters.pos - 1, end: typeParameters.end + 1 };
    }
    ts.rangeOfTypeParameters = rangeOfTypeParameters;
    function skipTypeChecking(sourceFile, options) {
        // If skipLibCheck is enabled, skip reporting errors if file is a declaration file.
        // If skipDefaultLibCheck is enabled, skip reporting errors if file contains a
        // '/// <reference no-default-lib="true"/>' directive.
        return options.skipLibCheck && sourceFile.isDeclarationFile || options.skipDefaultLibCheck && sourceFile.hasNoDefaultLib;
    }
    ts.skipTypeChecking = skipTypeChecking;
    function isJsonEqual(a, b) {
        return a === b || typeof a === "object" && a !== null && typeof b === "object" && b !== null && ts.equalOwnProperties(a, b, isJsonEqual);
    }
    ts.isJsonEqual = isJsonEqual;
    function getOrUpdate(map, key, getDefault) {
        var got = map.get(key);
        if (got === undefined) {
            var value = getDefault();
            map.set(key, value);
            return value;
        }
        else {
            return got;
        }
    }
    ts.getOrUpdate = getOrUpdate;
    /**
     * Converts a bigint literal string, e.g. `0x1234n`,
     * to its decimal string representation, e.g. `4660`.
     */
    function parsePseudoBigInt(stringValue) {
        var log2Base;
        switch (stringValue.charCodeAt(1)) { // "x" in "0x123"
            case 98 /* b */:
            case 66 /* B */: // 0b or 0B
                log2Base = 1;
                break;
            case 111 /* o */:
            case 79 /* O */: // 0o or 0O
                log2Base = 3;
                break;
            case 120 /* x */:
            case 88 /* X */: // 0x or 0X
                log2Base = 4;
                break;
            default: // already in decimal; omit trailing "n"
                var nIndex = stringValue.length - 1;
                // Skip leading 0s
                var nonZeroStart = 0;
                while (stringValue.charCodeAt(nonZeroStart) === 48 /* _0 */) {
                    nonZeroStart++;
                }
                return stringValue.slice(nonZeroStart, nIndex) || "0";
        }
        // Omit leading "0b", "0o", or "0x", and trailing "n"
        var startIndex = 2, endIndex = stringValue.length - 1;
        var bitsNeeded = (endIndex - startIndex) * log2Base;
        // Stores the value specified by the string as a LE array of 16-bit integers
        // using Uint16 instead of Uint32 so combining steps can use bitwise operators
        var segments = new Uint16Array((bitsNeeded >>> 4) + (bitsNeeded & 15 ? 1 : 0));
        // Add the digits, one at a time
        for (var i = endIndex - 1, bitOffset = 0; i >= startIndex; i--, bitOffset += log2Base) {
            var segment = bitOffset >>> 4;
            var digitChar = stringValue.charCodeAt(i);
            // Find character range: 0-9 < A-F < a-f
            var digit = digitChar <= 57 /* _9 */
                ? digitChar - 48 /* _0 */
                : 10 + digitChar -
                    (digitChar <= 70 /* F */ ? 65 /* A */ : 97 /* a */);
            var shiftedDigit = digit << (bitOffset & 15);
            segments[segment] |= shiftedDigit;
            var residual = shiftedDigit >>> 16;
            if (residual)
                segments[segment + 1] |= residual; // overflows segment
        }
        // Repeatedly divide segments by 10 and add remainder to base10Value
        var base10Value = "";
        var firstNonzeroSegment = segments.length - 1;
        var segmentsRemaining = true;
        while (segmentsRemaining) {
            var mod10 = 0;
            segmentsRemaining = false;
            for (var segment = firstNonzeroSegment; segment >= 0; segment--) {
                var newSegment = mod10 << 16 | segments[segment];
                var segmentValue = (newSegment / 10) | 0;
                segments[segment] = segmentValue;
                mod10 = newSegment - segmentValue * 10;
                if (segmentValue && !segmentsRemaining) {
                    firstNonzeroSegment = segment;
                    segmentsRemaining = true;
                }
            }
            base10Value = mod10 + base10Value;
        }
        return base10Value;
    }
    ts.parsePseudoBigInt = parsePseudoBigInt;
    function pseudoBigIntToString(_a) {
        var negative = _a.negative, base10Value = _a.base10Value;
        return (negative && base10Value !== "0" ? "-" : "") + base10Value;
    }
    ts.pseudoBigIntToString = pseudoBigIntToString;
})(ts || (ts = {}));
var ts;
(function (ts) {
    var SignatureFlags;
    (function (SignatureFlags) {
        SignatureFlags[SignatureFlags["None"] = 0] = "None";
        SignatureFlags[SignatureFlags["Yield"] = 1] = "Yield";
        SignatureFlags[SignatureFlags["Await"] = 2] = "Await";
        SignatureFlags[SignatureFlags["Type"] = 4] = "Type";
        SignatureFlags[SignatureFlags["IgnoreMissingOpenBrace"] = 16] = "IgnoreMissingOpenBrace";
        SignatureFlags[SignatureFlags["JSDoc"] = 32] = "JSDoc";
    })(SignatureFlags || (SignatureFlags = {}));
    // tslint:disable variable-name
    var NodeConstructor;
    var TokenConstructor;
    var IdentifierConstructor;
    var SourceFileConstructor;
    // tslint:enable variable-name
    function createNode(kind, pos, end) {
        if (kind === 285 /* SourceFile */) {
            return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end);
        }
        else if (kind === 73 /* Identifier */) {
            return new (IdentifierConstructor || (IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor()))(kind, pos, end);
        }
        else if (!ts.isNodeKind(kind)) {
            return new (TokenConstructor || (TokenConstructor = ts.objectAllocator.getTokenConstructor()))(kind, pos, end);
        }
        else {
            return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end);
        }
    }
    ts.createNode = createNode;
    function visitNode(cbNode, node) {
        return node && cbNode(node);
    }
    function visitNodes(cbNode, cbNodes, nodes) {
        if (nodes) {
            if (cbNodes) {
                return cbNodes(nodes);
            }
            for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
                var node = nodes_1[_i];
                var result = cbNode(node);
                if (result) {
                    return result;
                }
            }
        }
    }
    /*@internal*/
    function isJSDocLikeText(text, start) {
        return text.charCodeAt(start + 1) === 42 /* asterisk */ &&
            text.charCodeAt(start + 2) === 42 /* asterisk */ &&
            text.charCodeAt(start + 3) !== 47 /* slash */;
    }
    ts.isJSDocLikeText = isJSDocLikeText;
    /**
     * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes
     * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise,
     * embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns
     * a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned.
     *
     * @param node a given node to visit its children
     * @param cbNode a callback to be invoked for all child nodes
     * @param cbNodes a callback to be invoked for embedded array
     *
     * @remarks `forEachChild` must visit the children of a node in the order
     * that they appear in the source code. The language service depends on this property to locate nodes by position.
     */
    function forEachChild(node, cbNode, cbNodes) {
        if (!node || node.kind <= 148 /* LastToken */) {
            return;
        }
        switch (node.kind) {
            case 149 /* QualifiedName */:
                return visitNode(cbNode, node.left) ||
                    visitNode(cbNode, node.right);
            case 151 /* TypeParameter */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.constraint) ||
                    visitNode(cbNode, node.default) ||
                    visitNode(cbNode, node.expression);
            case 277 /* ShorthandPropertyAssignment */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.exclamationToken) ||
                    visitNode(cbNode, node.equalsToken) ||
                    visitNode(cbNode, node.objectAssignmentInitializer);
            case 278 /* SpreadAssignment */:
                return visitNode(cbNode, node.expression);
            case 152 /* Parameter */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.dotDotDotToken) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.initializer);
            case 155 /* PropertyDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.exclamationToken) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.initializer);
            case 154 /* PropertySignature */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.initializer);
            case 276 /* PropertyAssignment */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.initializer);
            case 238 /* VariableDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.exclamationToken) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.initializer);
            case 187 /* BindingElement */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.dotDotDotToken) ||
                    visitNode(cbNode, node.propertyName) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.initializer);
            case 166 /* FunctionType */:
            case 167 /* ConstructorType */:
            case 161 /* CallSignature */:
            case 162 /* ConstructSignature */:
            case 163 /* IndexSignature */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.parameters) ||
                    visitNode(cbNode, node.type);
            case 157 /* MethodDeclaration */:
            case 156 /* MethodSignature */:
            case 158 /* Constructor */:
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
            case 197 /* FunctionExpression */:
            case 240 /* FunctionDeclaration */:
            case 198 /* ArrowFunction */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.asteriskToken) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.exclamationToken) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.parameters) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.equalsGreaterThanToken) ||
                    visitNode(cbNode, node.body);
            case 165 /* TypeReference */:
                return visitNode(cbNode, node.typeName) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments);
            case 164 /* TypePredicate */:
                return visitNode(cbNode, node.parameterName) ||
                    visitNode(cbNode, node.type);
            case 168 /* TypeQuery */:
                return visitNode(cbNode, node.exprName);
            case 169 /* TypeLiteral */:
                return visitNodes(cbNode, cbNodes, node.members);
            case 170 /* ArrayType */:
                return visitNode(cbNode, node.elementType);
            case 171 /* TupleType */:
                return visitNodes(cbNode, cbNodes, node.elementTypes);
            case 174 /* UnionType */:
            case 175 /* IntersectionType */:
                return visitNodes(cbNode, cbNodes, node.types);
            case 176 /* ConditionalType */:
                return visitNode(cbNode, node.checkType) ||
                    visitNode(cbNode, node.extendsType) ||
                    visitNode(cbNode, node.trueType) ||
                    visitNode(cbNode, node.falseType);
            case 177 /* InferType */:
                return visitNode(cbNode, node.typeParameter);
            case 184 /* ImportType */:
                return visitNode(cbNode, node.argument) ||
                    visitNode(cbNode, node.qualifier) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments);
            case 178 /* ParenthesizedType */:
            case 180 /* TypeOperator */:
                return visitNode(cbNode, node.type);
            case 181 /* IndexedAccessType */:
                return visitNode(cbNode, node.objectType) ||
                    visitNode(cbNode, node.indexType);
            case 182 /* MappedType */:
                return visitNode(cbNode, node.readonlyToken) ||
                    visitNode(cbNode, node.typeParameter) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.type);
            case 183 /* LiteralType */:
                return visitNode(cbNode, node.literal);
            case 185 /* ObjectBindingPattern */:
            case 186 /* ArrayBindingPattern */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 188 /* ArrayLiteralExpression */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 189 /* ObjectLiteralExpression */:
                return visitNodes(cbNode, cbNodes, node.properties);
            case 190 /* PropertyAccessExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.name);
            case 191 /* ElementAccessExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.argumentExpression);
            case 192 /* CallExpression */:
            case 193 /* NewExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments) ||
                    visitNodes(cbNode, cbNodes, node.arguments);
            case 194 /* TaggedTemplateExpression */:
                return visitNode(cbNode, node.tag) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments) ||
                    visitNode(cbNode, node.template);
            case 195 /* TypeAssertionExpression */:
                return visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.expression);
            case 196 /* ParenthesizedExpression */:
                return visitNode(cbNode, node.expression);
            case 199 /* DeleteExpression */:
                return visitNode(cbNode, node.expression);
            case 200 /* TypeOfExpression */:
                return visitNode(cbNode, node.expression);
            case 201 /* VoidExpression */:
                return visitNode(cbNode, node.expression);
            case 203 /* PrefixUnaryExpression */:
                return visitNode(cbNode, node.operand);
            case 208 /* YieldExpression */:
                return visitNode(cbNode, node.asteriskToken) ||
                    visitNode(cbNode, node.expression);
            case 202 /* AwaitExpression */:
                return visitNode(cbNode, node.expression);
            case 204 /* PostfixUnaryExpression */:
                return visitNode(cbNode, node.operand);
            case 205 /* BinaryExpression */:
                return visitNode(cbNode, node.left) ||
                    visitNode(cbNode, node.operatorToken) ||
                    visitNode(cbNode, node.right);
            case 213 /* AsExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.type);
            case 214 /* NonNullExpression */:
                return visitNode(cbNode, node.expression);
            case 215 /* MetaProperty */:
                return visitNode(cbNode, node.name);
            case 206 /* ConditionalExpression */:
                return visitNode(cbNode, node.condition) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.whenTrue) ||
                    visitNode(cbNode, node.colonToken) ||
                    visitNode(cbNode, node.whenFalse);
            case 209 /* SpreadElement */:
                return visitNode(cbNode, node.expression);
            case 219 /* Block */:
            case 246 /* ModuleBlock */:
                return visitNodes(cbNode, cbNodes, node.statements);
            case 285 /* SourceFile */:
                return visitNodes(cbNode, cbNodes, node.statements) ||
                    visitNode(cbNode, node.endOfFileToken);
            case 220 /* VariableStatement */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.declarationList);
            case 239 /* VariableDeclarationList */:
                return visitNodes(cbNode, cbNodes, node.declarations);
            case 222 /* ExpressionStatement */:
                return visitNode(cbNode, node.expression);
            case 223 /* IfStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.thenStatement) ||
                    visitNode(cbNode, node.elseStatement);
            case 224 /* DoStatement */:
                return visitNode(cbNode, node.statement) ||
                    visitNode(cbNode, node.expression);
            case 225 /* WhileStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 226 /* ForStatement */:
                return visitNode(cbNode, node.initializer) ||
                    visitNode(cbNode, node.condition) ||
                    visitNode(cbNode, node.incrementor) ||
                    visitNode(cbNode, node.statement);
            case 227 /* ForInStatement */:
                return visitNode(cbNode, node.initializer) ||
                    visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 228 /* ForOfStatement */:
                return visitNode(cbNode, node.awaitModifier) ||
                    visitNode(cbNode, node.initializer) ||
                    visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 229 /* ContinueStatement */:
            case 230 /* BreakStatement */:
                return visitNode(cbNode, node.label);
            case 231 /* ReturnStatement */:
                return visitNode(cbNode, node.expression);
            case 232 /* WithStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 233 /* SwitchStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.caseBlock);
            case 247 /* CaseBlock */:
                return visitNodes(cbNode, cbNodes, node.clauses);
            case 272 /* CaseClause */:
                return visitNode(cbNode, node.expression) ||
                    visitNodes(cbNode, cbNodes, node.statements);
            case 273 /* DefaultClause */:
                return visitNodes(cbNode, cbNodes, node.statements);
            case 234 /* LabeledStatement */:
                return visitNode(cbNode, node.label) ||
                    visitNode(cbNode, node.statement);
            case 235 /* ThrowStatement */:
                return visitNode(cbNode, node.expression);
            case 236 /* TryStatement */:
                return visitNode(cbNode, node.tryBlock) ||
                    visitNode(cbNode, node.catchClause) ||
                    visitNode(cbNode, node.finallyBlock);
            case 275 /* CatchClause */:
                return visitNode(cbNode, node.variableDeclaration) ||
                    visitNode(cbNode, node.block);
            case 153 /* Decorator */:
                return visitNode(cbNode, node.expression);
            case 241 /* ClassDeclaration */:
            case 210 /* ClassExpression */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.heritageClauses) ||
                    visitNodes(cbNode, cbNodes, node.members);
            case 242 /* InterfaceDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.heritageClauses) ||
                    visitNodes(cbNode, cbNodes, node.members);
            case 243 /* TypeAliasDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNode(cbNode, node.type);
            case 244 /* EnumDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.members);
            case 279 /* EnumMember */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.initializer);
            case 245 /* ModuleDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.body);
            case 249 /* ImportEqualsDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.moduleReference);
            case 250 /* ImportDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.importClause) ||
                    visitNode(cbNode, node.moduleSpecifier);
            case 251 /* ImportClause */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.namedBindings);
            case 248 /* NamespaceExportDeclaration */:
                return visitNode(cbNode, node.name);
            case 252 /* NamespaceImport */:
                return visitNode(cbNode, node.name);
            case 253 /* NamedImports */:
            case 257 /* NamedExports */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 256 /* ExportDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.exportClause) ||
                    visitNode(cbNode, node.moduleSpecifier);
            case 254 /* ImportSpecifier */:
            case 258 /* ExportSpecifier */:
                return visitNode(cbNode, node.propertyName) ||
                    visitNode(cbNode, node.name);
            case 255 /* ExportAssignment */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.expression);
            case 207 /* TemplateExpression */:
                return visitNode(cbNode, node.head) || visitNodes(cbNode, cbNodes, node.templateSpans);
            case 217 /* TemplateSpan */:
                return visitNode(cbNode, node.expression) || visitNode(cbNode, node.literal);
            case 150 /* ComputedPropertyName */:
                return visitNode(cbNode, node.expression);
            case 274 /* HeritageClause */:
                return visitNodes(cbNode, cbNodes, node.types);
            case 212 /* ExpressionWithTypeArguments */:
                return visitNode(cbNode, node.expression) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments);
            case 260 /* ExternalModuleReference */:
                return visitNode(cbNode, node.expression);
            case 259 /* MissingDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators);
            case 315 /* CommaListExpression */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 261 /* JsxElement */:
                return visitNode(cbNode, node.openingElement) ||
                    visitNodes(cbNode, cbNodes, node.children) ||
                    visitNode(cbNode, node.closingElement);
            case 265 /* JsxFragment */:
                return visitNode(cbNode, node.openingFragment) ||
                    visitNodes(cbNode, cbNodes, node.children) ||
                    visitNode(cbNode, node.closingFragment);
            case 262 /* JsxSelfClosingElement */:
            case 263 /* JsxOpeningElement */:
                return visitNode(cbNode, node.tagName) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments) ||
                    visitNode(cbNode, node.attributes);
            case 269 /* JsxAttributes */:
                return visitNodes(cbNode, cbNodes, node.properties);
            case 268 /* JsxAttribute */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.initializer);
            case 270 /* JsxSpreadAttribute */:
                return visitNode(cbNode, node.expression);
            case 271 /* JsxExpression */:
                return visitNode(cbNode, node.dotDotDotToken) ||
                    visitNode(cbNode, node.expression);
            case 264 /* JsxClosingElement */:
                return visitNode(cbNode, node.tagName);
            case 172 /* OptionalType */:
            case 173 /* RestType */:
            case 289 /* JSDocTypeExpression */:
            case 293 /* JSDocNonNullableType */:
            case 292 /* JSDocNullableType */:
            case 294 /* JSDocOptionalType */:
            case 296 /* JSDocVariadicType */:
                return visitNode(cbNode, node.type);
            case 295 /* JSDocFunctionType */:
                return visitNodes(cbNode, cbNodes, node.parameters) ||
                    visitNode(cbNode, node.type);
            case 297 /* JSDocComment */:
                return visitNodes(cbNode, cbNodes, node.tags);
            case 305 /* JSDocParameterTag */:
            case 311 /* JSDocPropertyTag */:
                return visitNode(cbNode, node.tagName) ||
                    (node.isNameFirst
                        ? visitNode(cbNode, node.name) ||
                            visitNode(cbNode, node.typeExpression)
                        : visitNode(cbNode, node.typeExpression) ||
                            visitNode(cbNode, node.name));
            case 301 /* JSDocAugmentsTag */:
                return visitNode(cbNode, node.tagName) ||
                    visitNode(cbNode, node.class);
            case 309 /* JSDocTemplateTag */:
                return visitNode(cbNode, node.tagName) ||
                    visitNode(cbNode, node.constraint) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters);
            case 310 /* JSDocTypedefTag */:
                return visitNode(cbNode, node.tagName) ||
                    (node.typeExpression &&
                        node.typeExpression.kind === 289 /* JSDocTypeExpression */
                        ? visitNode(cbNode, node.typeExpression) ||
                            visitNode(cbNode, node.fullName)
                        : visitNode(cbNode, node.fullName) ||
                            visitNode(cbNode, node.typeExpression));
            case 303 /* JSDocCallbackTag */:
                return visitNode(cbNode, node.tagName) ||
                    visitNode(cbNode, node.fullName) ||
                    visitNode(cbNode, node.typeExpression);
            case 306 /* JSDocReturnTag */:
            case 308 /* JSDocTypeTag */:
            case 307 /* JSDocThisTag */:
            case 304 /* JSDocEnumTag */:
                return visitNode(cbNode, node.tagName) ||
                    visitNode(cbNode, node.typeExpression);
            case 299 /* JSDocSignature */:
                return ts.forEach(node.typeParameters, cbNode) ||
                    ts.forEach(node.parameters, cbNode) ||
                    visitNode(cbNode, node.type);
            case 298 /* JSDocTypeLiteral */:
                return ts.forEach(node.jsDocPropertyTags, cbNode);
            case 300 /* JSDocTag */:
            case 302 /* JSDocClassTag */:
                return visitNode(cbNode, node.tagName);
            case 314 /* PartiallyEmittedExpression */:
                return visitNode(cbNode, node.expression);
        }
    }
    ts.forEachChild = forEachChild;
    function createSourceFile(fileName, sourceText, languageVersion, setParentNodes, scriptKind) {
        if (setParentNodes === void 0) { setParentNodes = false; }
        ts.performance.mark("beforeParse");
        var result;
        if (languageVersion === 100 /* JSON */) {
            result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, 6 /* JSON */);
        }
        else {
            result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind);
        }
        ts.performance.mark("afterParse");
        ts.performance.measure("Parse", "beforeParse", "afterParse");
        return result;
    }
    ts.createSourceFile = createSourceFile;
    function parseIsolatedEntityName(text, languageVersion) {
        return Parser.parseIsolatedEntityName(text, languageVersion);
    }
    ts.parseIsolatedEntityName = parseIsolatedEntityName;
    /**
     * Parse json text into SyntaxTree and return node and parse errors if any
     * @param fileName
     * @param sourceText
     */
    function parseJsonText(fileName, sourceText) {
        return Parser.parseJsonText(fileName, sourceText);
    }
    ts.parseJsonText = parseJsonText;
    // See also `isExternalOrCommonJsModule` in utilities.ts
    function isExternalModule(file) {
        return file.externalModuleIndicator !== undefined;
    }
    ts.isExternalModule = isExternalModule;
    // Produces a new SourceFile for the 'newText' provided. The 'textChangeRange' parameter
    // indicates what changed between the 'text' that this SourceFile has and the 'newText'.
    // The SourceFile will be created with the compiler attempting to reuse as many nodes from
    // this file as possible.
    //
    // Note: this function mutates nodes from this SourceFile. That means any existing nodes
    // from this SourceFile that are being held onto may change as a result (including
    // becoming detached from any SourceFile).  It is recommended that this SourceFile not
    // be used once 'update' is called on it.
    function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
        if (aggressiveChecks === void 0) { aggressiveChecks = false; }
        var newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks);
        // Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import.
        // We will manually port the flag to the new source file.
        newSourceFile.flags |= (sourceFile.flags & 1572864 /* PermanentlySetIncrementalFlags */);
        return newSourceFile;
    }
    ts.updateSourceFile = updateSourceFile;
    /* @internal */
    function parseIsolatedJSDocComment(content, start, length) {
        var result = Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length);
        if (result && result.jsDoc) {
            // because the jsDocComment was parsed out of the source file, it might
            // not be covered by the fixupParentReferences.
            Parser.fixupParentReferences(result.jsDoc);
        }
        return result;
    }
    ts.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
    /* @internal */
    // Exposed only for testing.
    function parseJSDocTypeExpressionForTests(content, start, length) {
        return Parser.JSDocParser.parseJSDocTypeExpressionForTests(content, start, length);
    }
    ts.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests;
    // Implement the parser as a singleton module.  We do this for perf reasons because creating
    // parser instances can actually be expensive enough to impact us on projects with many source
    // files.
    var Parser;
    (function (Parser) {
        // Share a single scanner across all calls to parse a source file.  This helps speed things
        // up by avoiding the cost of creating/compiling scanners over and over again.
        var scanner = ts.createScanner(8 /* Latest */, /*skipTrivia*/ true);
        var disallowInAndDecoratorContext = 2048 /* DisallowInContext */ | 8192 /* DecoratorContext */;
        // capture constructors in 'initializeState' to avoid null checks
        // tslint:disable variable-name
        var NodeConstructor;
        var TokenConstructor;
        var IdentifierConstructor;
        var SourceFileConstructor;
        // tslint:enable variable-name
        var sourceFile;
        var parseDiagnostics;
        var syntaxCursor;
        var currentToken;
        var sourceText;
        var nodeCount;
        var identifiers;
        var identifierCount;
        var parsingContext;
        // Flags that dictate what parsing context we're in.  For example:
        // Whether or not we are in strict parsing mode.  All that changes in strict parsing mode is
        // that some tokens that would be considered identifiers may be considered keywords.
        //
        // When adding more parser context flags, consider which is the more common case that the
        // flag will be in.  This should be the 'false' state for that flag.  The reason for this is
        // that we don't store data in our nodes unless the value is in the *non-default* state.  So,
        // for example, more often than code 'allows-in' (or doesn't 'disallow-in').  We opt for
        // 'disallow-in' set to 'false'.  Otherwise, if we had 'allowsIn' set to 'true', then almost
        // all nodes would need extra state on them to store this info.
        //
        // Note: 'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6
        // grammar specification.
        //
        // An important thing about these context concepts.  By default they are effectively inherited
        // while parsing through every grammar production.  i.e. if you don't change them, then when
        // you parse a sub-production, it will have the same context values as the parent production.
        // This is great most of the time.  After all, consider all the 'expression' grammar productions
        // and how nearly all of them pass along the 'in' and 'yield' context values:
        //
        // EqualityExpression[In, Yield] :
        //      RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] == RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] != RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] === RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] !== RelationalExpression[?In, ?Yield]
        //
        // Where you have to be careful is then understanding what the points are in the grammar
        // where the values are *not* passed along.  For example:
        //
        // SingleNameBinding[Yield,GeneratorParameter]
        //      [+GeneratorParameter]BindingIdentifier[Yield] Initializer[In]opt
        //      [~GeneratorParameter]BindingIdentifier[?Yield]Initializer[In, ?Yield]opt
        //
        // Here this is saying that if the GeneratorParameter context flag is set, that we should
        // explicitly set the 'yield' context flag to false before calling into the BindingIdentifier
        // and we should explicitly unset the 'yield' context flag before calling into the Initializer.
        // production.  Conversely, if the GeneratorParameter context flag is not set, then we
        // should leave the 'yield' context flag alone.
        //
        // Getting this all correct is tricky and requires careful reading of the grammar to
        // understand when these values should be changed versus when they should be inherited.
        //
        // Note: it should not be necessary to save/restore these flags during speculative/lookahead
        // parsing.  These context flags are naturally stored and restored through normal recursive
        // descent parsing and unwinding.
        var contextFlags;
        // Whether or not we've had a parse error since creating the last AST node.  If we have
        // encountered an error, it will be stored on the next AST node we create.  Parse errors
        // can be broken down into three categories:
        //
        // 1) An error that occurred during scanning.  For example, an unterminated literal, or a
        //    character that was completely not understood.
        //
        // 2) A token was expected, but was not present.  This type of error is commonly produced
        //    by the 'parseExpected' function.
        //
        // 3) A token was present that no parsing function was able to consume.  This type of error
        //    only occurs in the 'abortParsingListOrMoveToNextToken' function when the parser
        //    decides to skip the token.
        //
        // In all of these cases, we want to mark the next node as having had an error before it.
        // With this mark, we can know in incremental settings if this node can be reused, or if
        // we have to reparse it.  If we don't keep this information around, we may just reuse the
        // node.  in that event we would then not produce the same errors as we did before, causing
        // significant confusion problems.
        //
        // Note: it is necessary that this value be saved/restored during speculative/lookahead
        // parsing.  During lookahead parsing, we will often create a node.  That node will have
        // this value attached, and then this value will be set back to 'false'.  If we decide to
        // rewind, we must get back to the same value we had prior to the lookahead.
        //
        // Note: any errors at the end of the file that do not precede a regular node, should get
        // attached to the EOF token.
        var parseErrorBeforeNextFinishedNode = false;
        function parseSourceFile(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes, scriptKind) {
            if (setParentNodes === void 0) { setParentNodes = false; }
            scriptKind = ts.ensureScriptKind(fileName, scriptKind);
            if (scriptKind === 6 /* JSON */) {
                var result_2 = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes);
                ts.convertToObjectWorker(result_2, result_2.parseDiagnostics, /*returnValue*/ false, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
                result_2.referencedFiles = ts.emptyArray;
                result_2.typeReferenceDirectives = ts.emptyArray;
                result_2.libReferenceDirectives = ts.emptyArray;
                result_2.amdDependencies = ts.emptyArray;
                result_2.hasNoDefaultLib = false;
                result_2.pragmas = ts.emptyMap;
                return result_2;
            }
            initializeState(sourceText, languageVersion, syntaxCursor, scriptKind);
            var result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind);
            clearState();
            return result;
        }
        Parser.parseSourceFile = parseSourceFile;
        function parseIsolatedEntityName(content, languageVersion) {
            // Choice of `isDeclarationFile` should be arbitrary
            initializeState(content, languageVersion, /*syntaxCursor*/ undefined, 1 /* JS */);
            // Prime the scanner.
            nextToken();
            var entityName = parseEntityName(/*allowReservedWords*/ true);
            var isInvalid = token() === 1 /* EndOfFileToken */ && !parseDiagnostics.length;
            clearState();
            return isInvalid ? entityName : undefined;
        }
        Parser.parseIsolatedEntityName = parseIsolatedEntityName;
        function parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes) {
            if (languageVersion === void 0) { languageVersion = 2 /* ES2015 */; }
            initializeState(sourceText, languageVersion, syntaxCursor, 6 /* JSON */);
            // Set source file so that errors will be reported with this file name
            sourceFile = createSourceFile(fileName, 2 /* ES2015 */, 6 /* JSON */, /*isDeclaration*/ false);
            sourceFile.flags = contextFlags;
            // Prime the scanner.
            nextToken();
            var pos = getNodePos();
            if (token() === 1 /* EndOfFileToken */) {
                sourceFile.statements = createNodeArray([], pos, pos);
                sourceFile.endOfFileToken = parseTokenNode();
            }
            else {
                var statement = createNode(222 /* ExpressionStatement */);
                switch (token()) {
                    case 22 /* OpenBracketToken */:
                        statement.expression = parseArrayLiteralExpression();
                        break;
                    case 103 /* TrueKeyword */:
                    case 88 /* FalseKeyword */:
                    case 97 /* NullKeyword */:
                        statement.expression = parseTokenNode();
                        break;
                    case 39 /* MinusToken */:
                        if (lookAhead(function () { return nextToken() === 8 /* NumericLiteral */ && nextToken() !== 57 /* ColonToken */; })) {
                            statement.expression = parsePrefixUnaryExpression();
                        }
                        else {
                            statement.expression = parseObjectLiteralExpression();
                        }
                        break;
                    case 8 /* NumericLiteral */:
                    case 10 /* StringLiteral */:
                        if (lookAhead(function () { return nextToken() !== 57 /* ColonToken */; })) {
                            statement.expression = parseLiteralNode();
                            break;
                        }
                    // falls through
                    default:
                        statement.expression = parseObjectLiteralExpression();
                        break;
                }
                finishNode(statement);
                sourceFile.statements = createNodeArray([statement], pos);
                sourceFile.endOfFileToken = parseExpectedToken(1 /* EndOfFileToken */, ts.Diagnostics.Unexpected_token);
            }
            if (setParentNodes) {
                fixupParentReferences(sourceFile);
            }
            sourceFile.parseDiagnostics = parseDiagnostics;
            var result = sourceFile;
            clearState();
            return result;
        }
        Parser.parseJsonText = parseJsonText;
        function getLanguageVariant(scriptKind) {
            // .tsx and .jsx files are treated as jsx language variant.
            return scriptKind === 4 /* TSX */ || scriptKind === 2 /* JSX */ || scriptKind === 1 /* JS */ || scriptKind === 6 /* JSON */ ? 1 /* JSX */ : 0 /* Standard */;
        }
        function initializeState(_sourceText, languageVersion, _syntaxCursor, scriptKind) {
            NodeConstructor = ts.objectAllocator.getNodeConstructor();
            TokenConstructor = ts.objectAllocator.getTokenConstructor();
            IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor();
            SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor();
            sourceText = _sourceText;
            syntaxCursor = _syntaxCursor;
            parseDiagnostics = [];
            parsingContext = 0;
            identifiers = ts.createMap();
            identifierCount = 0;
            nodeCount = 0;
            switch (scriptKind) {
                case 1 /* JS */:
                case 2 /* JSX */:
                    contextFlags = 65536 /* JavaScriptFile */;
                    break;
                case 6 /* JSON */:
                    contextFlags = 65536 /* JavaScriptFile */ | 16777216 /* JsonFile */;
                    break;
                default:
                    contextFlags = 0 /* None */;
                    break;
            }
            parseErrorBeforeNextFinishedNode = false;
            // Initialize and prime the scanner before parsing the source elements.
            scanner.setText(sourceText);
            scanner.setOnError(scanError);
            scanner.setScriptTarget(languageVersion);
            scanner.setLanguageVariant(getLanguageVariant(scriptKind));
        }
        function clearState() {
            // Clear out the text the scanner is pointing at, so it doesn't keep anything alive unnecessarily.
            scanner.setText("");
            scanner.setOnError(undefined);
            // Clear any data.  We don't want to accidentally hold onto it for too long.
            parseDiagnostics = undefined;
            sourceFile = undefined;
            identifiers = undefined;
            syntaxCursor = undefined;
            sourceText = undefined;
        }
        function parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind) {
            var isDeclarationFile = isDeclarationFileName(fileName);
            if (isDeclarationFile) {
                contextFlags |= 4194304 /* Ambient */;
            }
            sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile);
            sourceFile.flags = contextFlags;
            // Prime the scanner.
            nextToken();
            // A member of ReadonlyArray<T> isn't assignable to a member of T[] (and prevents a direct cast) - but this is where we set up those members so they can be readonly in the future
            processCommentPragmas(sourceFile, sourceText);
            processPragmasIntoFields(sourceFile, reportPragmaDiagnostic);
            sourceFile.statements = parseList(0 /* SourceElements */, parseStatement);
            ts.Debug.assert(token() === 1 /* EndOfFileToken */);
            sourceFile.endOfFileToken = addJSDocComment(parseTokenNode());
            setExternalModuleIndicator(sourceFile);
            sourceFile.nodeCount = nodeCount;
            sourceFile.identifierCount = identifierCount;
            sourceFile.identifiers = identifiers;
            sourceFile.parseDiagnostics = parseDiagnostics;
            if (setParentNodes) {
                fixupParentReferences(sourceFile);
            }
            return sourceFile;
            function reportPragmaDiagnostic(pos, end, diagnostic) {
                parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, pos, end, diagnostic));
            }
        }
        function addJSDocComment(node) {
            ts.Debug.assert(!node.jsDoc); // Should only be called once per node
            var jsDoc = ts.mapDefined(ts.getJSDocCommentRanges(node, sourceFile.text), function (comment) { return JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); });
            if (jsDoc.length)
                node.jsDoc = jsDoc;
            return node;
        }
        function fixupParentReferences(rootNode) {
            // normally parent references are set during binding. However, for clients that only need
            // a syntax tree, and no semantic features, then the binding process is an unnecessary
            // overhead.  This functions allows us to set all the parents, without all the expense of
            // binding.
            var parent = rootNode;
            forEachChild(rootNode, visitNode);
            return;
            function visitNode(n) {
                // walk down setting parents that differ from the parent we think it should be.  This
                // allows us to quickly bail out of setting parents for subtrees during incremental
                // parsing
                if (n.parent !== parent) {
                    n.parent = parent;
                    var saveParent = parent;
                    parent = n;
                    forEachChild(n, visitNode);
                    if (ts.hasJSDocNodes(n)) {
                        for (var _i = 0, _a = n.jsDoc; _i < _a.length; _i++) {
                            var jsDoc = _a[_i];
                            jsDoc.parent = n;
                            parent = jsDoc;
                            forEachChild(jsDoc, visitNode);
                        }
                    }
                    parent = saveParent;
                }
            }
        }
        Parser.fixupParentReferences = fixupParentReferences;
        function createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile) {
            // code from createNode is inlined here so createNode won't have to deal with special case of creating source files
            // this is quite rare comparing to other nodes and createNode should be as fast as possible
            var sourceFile = new SourceFileConstructor(285 /* SourceFile */, /*pos*/ 0, /* end */ sourceText.length);
            nodeCount++;
            sourceFile.text = sourceText;
            sourceFile.bindDiagnostics = [];
            sourceFile.bindSuggestionDiagnostics = undefined;
            sourceFile.languageVersion = languageVersion;
            sourceFile.fileName = ts.normalizePath(fileName);
            sourceFile.languageVariant = getLanguageVariant(scriptKind);
            sourceFile.isDeclarationFile = isDeclarationFile;
            sourceFile.scriptKind = scriptKind;
            return sourceFile;
        }
        function setContextFlag(val, flag) {
            if (val) {
                contextFlags |= flag;
            }
            else {
                contextFlags &= ~flag;
            }
        }
        function setDisallowInContext(val) {
            setContextFlag(val, 2048 /* DisallowInContext */);
        }
        function setYieldContext(val) {
            setContextFlag(val, 4096 /* YieldContext */);
        }
        function setDecoratorContext(val) {
            setContextFlag(val, 8192 /* DecoratorContext */);
        }
        function setAwaitContext(val) {
            setContextFlag(val, 16384 /* AwaitContext */);
        }
        function doOutsideOfContext(context, func) {
            // contextFlagsToClear will contain only the context flags that are
            // currently set that we need to temporarily clear
            // We don't just blindly reset to the previous flags to ensure
            // that we do not mutate cached flags for the incremental
            // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and
            // HasAggregatedChildData).
            var contextFlagsToClear = context & contextFlags;
            if (contextFlagsToClear) {
                // clear the requested context flags
                setContextFlag(/*val*/ false, contextFlagsToClear);
                var result = func();
                // restore the context flags we just cleared
                setContextFlag(/*val*/ true, contextFlagsToClear);
                return result;
            }
            // no need to do anything special as we are not in any of the requested contexts
            return func();
        }
        function doInsideOfContext(context, func) {
            // contextFlagsToSet will contain only the context flags that
            // are not currently set that we need to temporarily enable.
            // We don't just blindly reset to the previous flags to ensure
            // that we do not mutate cached flags for the incremental
            // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and
            // HasAggregatedChildData).
            var contextFlagsToSet = context & ~contextFlags;
            if (contextFlagsToSet) {
                // set the requested context flags
                setContextFlag(/*val*/ true, contextFlagsToSet);
                var result = func();
                // reset the context flags we just set
                setContextFlag(/*val*/ false, contextFlagsToSet);
                return result;
            }
            // no need to do anything special as we are already in all of the requested contexts
            return func();
        }
        function allowInAnd(func) {
            return doOutsideOfContext(2048 /* DisallowInContext */, func);
        }
        function disallowInAnd(func) {
            return doInsideOfContext(2048 /* DisallowInContext */, func);
        }
        function doInYieldContext(func) {
            return doInsideOfContext(4096 /* YieldContext */, func);
        }
        function doInDecoratorContext(func) {
            return doInsideOfContext(8192 /* DecoratorContext */, func);
        }
        function doInAwaitContext(func) {
            return doInsideOfContext(16384 /* AwaitContext */, func);
        }
        function doOutsideOfAwaitContext(func) {
            return doOutsideOfContext(16384 /* AwaitContext */, func);
        }
        function doInYieldAndAwaitContext(func) {
            return doInsideOfContext(4096 /* YieldContext */ | 16384 /* AwaitContext */, func);
        }
        function inContext(flags) {
            return (contextFlags & flags) !== 0;
        }
        function inYieldContext() {
            return inContext(4096 /* YieldContext */);
        }
        function inDisallowInContext() {
            return inContext(2048 /* DisallowInContext */);
        }
        function inDecoratorContext() {
            return inContext(8192 /* DecoratorContext */);
        }
        function inAwaitContext() {
            return inContext(16384 /* AwaitContext */);
        }
        function parseErrorAtCurrentToken(message, arg0) {
            parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), message, arg0);
        }
        function parseErrorAtPosition(start, length, message, arg0) {
            // Don't report another error if it would just be at the same position as the last error.
            var lastError = ts.lastOrUndefined(parseDiagnostics);
            if (!lastError || start !== lastError.start) {
                parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, start, length, message, arg0));
            }
            // Mark that we've encountered an error.  We'll set an appropriate bit on the next
            // node we finish so that it can't be reused incrementally.
            parseErrorBeforeNextFinishedNode = true;
        }
        function parseErrorAt(start, end, message, arg0) {
            parseErrorAtPosition(start, end - start, message, arg0);
        }
        function parseErrorAtRange(range, message, arg0) {
            parseErrorAt(range.pos, range.end, message, arg0);
        }
        function scanError(message, length) {
            parseErrorAtPosition(scanner.getTextPos(), length, message);
        }
        function getNodePos() {
            return scanner.getStartPos();
        }
        // Use this function to access the current token instead of reading the currentToken
        // variable. Since function results aren't narrowed in control flow analysis, this ensures
        // that the type checker doesn't make wrong assumptions about the type of the current
        // token (e.g. a call to nextToken() changes the current token but the checker doesn't
        // reason about this side effect).  Mainstream VMs inline simple functions like this, so
        // there is no performance penalty.
        function token() {
            return currentToken;
        }
        function nextToken() {
            return currentToken = scanner.scan();
        }
        function nextTokenJSDoc() {
            return currentToken = scanner.scanJsDocToken();
        }
        function reScanGreaterToken() {
            return currentToken = scanner.reScanGreaterToken();
        }
        function reScanSlashToken() {
            return currentToken = scanner.reScanSlashToken();
        }
        function reScanTemplateToken() {
            return currentToken = scanner.reScanTemplateToken();
        }
        function reScanLessThanToken() {
            return currentToken = scanner.reScanLessThanToken();
        }
        function scanJsxIdentifier() {
            return currentToken = scanner.scanJsxIdentifier();
        }
        function scanJsxText() {
            return currentToken = scanner.scanJsxToken();
        }
        function scanJsxAttributeValue() {
            return currentToken = scanner.scanJsxAttributeValue();
        }
        function speculationHelper(callback, isLookAhead) {
            // Keep track of the state we'll need to rollback to if lookahead fails (or if the
            // caller asked us to always reset our state).
            var saveToken = currentToken;
            var saveParseDiagnosticsLength = parseDiagnostics.length;
            var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
            // Note: it is not actually necessary to save/restore the context flags here.  That's
            // because the saving/restoring of these flags happens naturally through the recursive
            // descent nature of our parser.  However, we still store this here just so we can
            // assert that invariant holds.
            var saveContextFlags = contextFlags;
            // If we're only looking ahead, then tell the scanner to only lookahead as well.
            // Otherwise, if we're actually speculatively parsing, then tell the scanner to do the
            // same.
            var result = isLookAhead
                ? scanner.lookAhead(callback)
                : scanner.tryScan(callback);
            ts.Debug.assert(saveContextFlags === contextFlags);
            // If our callback returned something 'falsy' or we're just looking ahead,
            // then unconditionally restore us to where we were.
            if (!result || isLookAhead) {
                currentToken = saveToken;
                parseDiagnostics.length = saveParseDiagnosticsLength;
                parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode;
            }
            return result;
        }
        /** Invokes the provided callback then unconditionally restores the parser to the state it
         * was in immediately prior to invoking the callback.  The result of invoking the callback
         * is returned from this function.
         */
        function lookAhead(callback) {
            return speculationHelper(callback, /*isLookAhead*/ true);
        }
        /** Invokes the provided callback.  If the callback returns something falsy, then it restores
         * the parser to the state it was in immediately prior to invoking the callback.  If the
         * callback returns something truthy, then the parser state is not rolled back.  The result
         * of invoking the callback is returned from this function.
         */
        function tryParse(callback) {
            return speculationHelper(callback, /*isLookAhead*/ false);
        }
        // Ignore strict mode flag because we will report an error in type checker instead.
        function isIdentifier() {
            if (token() === 73 /* Identifier */) {
                return true;
            }
            // If we have a 'yield' keyword, and we're in the [yield] context, then 'yield' is
            // considered a keyword and is not an identifier.
            if (token() === 118 /* YieldKeyword */ && inYieldContext()) {
                return false;
            }
            // If we have a 'await' keyword, and we're in the [Await] context, then 'await' is
            // considered a keyword and is not an identifier.
            if (token() === 123 /* AwaitKeyword */ && inAwaitContext()) {
                return false;
            }
            return token() > 109 /* LastReservedWord */;
        }
        function parseExpected(kind, diagnosticMessage, shouldAdvance) {
            if (shouldAdvance === void 0) { shouldAdvance = true; }
            if (token() === kind) {
                if (shouldAdvance) {
                    nextToken();
                }
                return true;
            }
            // Report specific message if provided with one.  Otherwise, report generic fallback message.
            if (diagnosticMessage) {
                parseErrorAtCurrentToken(diagnosticMessage);
            }
            else {
                parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(kind));
            }
            return false;
        }
        function parseExpectedJSDoc(kind) {
            if (token() === kind) {
                nextTokenJSDoc();
                return true;
            }
            parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(kind));
            return false;
        }
        function parseOptional(t) {
            if (token() === t) {
                nextToken();
                return true;
            }
            return false;
        }
        function parseOptionalToken(t) {
            if (token() === t) {
                return parseTokenNode();
            }
            return undefined;
        }
        function parseOptionalTokenJSDoc(t) {
            if (token() === t) {
                return parseTokenNodeJSDoc();
            }
            return undefined;
        }
        function parseExpectedToken(t, diagnosticMessage, arg0) {
            return parseOptionalToken(t) ||
                createMissingNode(t, /*reportAtCurrentPosition*/ false, diagnosticMessage || ts.Diagnostics._0_expected, arg0 || ts.tokenToString(t));
        }
        function parseExpectedTokenJSDoc(t) {
            return parseOptionalTokenJSDoc(t) ||
                createMissingNode(t, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(t));
        }
        function parseTokenNode() {
            var node = createNode(token());
            nextToken();
            return finishNode(node);
        }
        function parseTokenNodeJSDoc() {
            var node = createNode(token());
            nextTokenJSDoc();
            return finishNode(node);
        }
        function canParseSemicolon() {
            // If there's a real semicolon, then we can always parse it out.
            if (token() === 26 /* SemicolonToken */) {
                return true;
            }
            // We can parse out an optional semicolon in ASI cases in the following cases.
            return token() === 19 /* CloseBraceToken */ || token() === 1 /* EndOfFileToken */ || scanner.hasPrecedingLineBreak();
        }
        function parseSemicolon() {
            if (canParseSemicolon()) {
                if (token() === 26 /* SemicolonToken */) {
                    // consume the semicolon if it was explicitly provided.
                    nextToken();
                }
                return true;
            }
            else {
                return parseExpected(26 /* SemicolonToken */);
            }
        }
        function createNode(kind, pos) {
            nodeCount++;
            var p = pos >= 0 ? pos : scanner.getStartPos();
            return ts.isNodeKind(kind) || kind === 0 /* Unknown */ ? new NodeConstructor(kind, p, p) :
                kind === 73 /* Identifier */ ? new IdentifierConstructor(kind, p, p) :
                    new TokenConstructor(kind, p, p);
        }
        function createNodeWithJSDoc(kind, pos) {
            var node = createNode(kind, pos);
            if (scanner.getTokenFlags() & 2 /* PrecedingJSDocComment */) {
                addJSDocComment(node);
            }
            return node;
        }
        function createNodeArray(elements, pos, end) {
            // Since the element list of a node array is typically created by starting with an empty array and
            // repeatedly calling push(), the list may not have the optimal memory layout. We invoke slice() for
            // small arrays (1 to 4 elements) to give the VM a chance to allocate an optimal representation.
            var length = elements.length;
            var array = (length >= 1 && length <= 4 ? elements.slice() : elements);
            array.pos = pos;
            array.end = end === undefined ? scanner.getStartPos() : end;
            return array;
        }
        function finishNode(node, end) {
            node.end = end === undefined ? scanner.getStartPos() : end;
            if (contextFlags) {
                node.flags |= contextFlags;
            }
            // Keep track on the node if we encountered an error while parsing it.  If we did, then
            // we cannot reuse the node incrementally.  Once we've marked this node, clear out the
            // flag so that we don't mark any subsequent nodes.
            if (parseErrorBeforeNextFinishedNode) {
                parseErrorBeforeNextFinishedNode = false;
                node.flags |= 32768 /* ThisNodeHasError */;
            }
            return node;
        }
        function createMissingNode(kind, reportAtCurrentPosition, diagnosticMessage, arg0) {
            if (reportAtCurrentPosition) {
                parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0);
            }
            else if (diagnosticMessage) {
                parseErrorAtCurrentToken(diagnosticMessage, arg0);
            }
            var result = createNode(kind);
            if (kind === 73 /* Identifier */) {
                result.escapedText = "";
            }
            else if (ts.isLiteralKind(kind) || ts.isTemplateLiteralKind(kind)) {
                result.text = "";
            }
            return finishNode(result);
        }
        function internIdentifier(text) {
            var identifier = identifiers.get(text);
            if (identifier === undefined) {
                identifiers.set(text, identifier = text);
            }
            return identifier;
        }
        // An identifier that starts with two underscores has an extra underscore character prepended to it to avoid issues
        // with magic property names like '__proto__'. The 'identifiers' object is used to share a single string instance for
        // each identifier in order to reduce memory consumption.
        function createIdentifier(isIdentifier, diagnosticMessage) {
            identifierCount++;
            if (isIdentifier) {
                var node = createNode(73 /* Identifier */);
                // Store original token kind if it is not just an Identifier so we can report appropriate error later in type checker
                if (token() !== 73 /* Identifier */) {
                    node.originalKeywordKind = token();
                }
                node.escapedText = ts.escapeLeadingUnderscores(internIdentifier(scanner.getTokenValue()));
                nextToken();
                return finishNode(node);
            }
            // Only for end of file because the error gets reported incorrectly on embedded script tags.
            var reportAtCurrentPosition = token() === 1 /* EndOfFileToken */;
            return createMissingNode(73 /* Identifier */, reportAtCurrentPosition, diagnosticMessage || ts.Diagnostics.Identifier_expected);
        }
        function parseIdentifier(diagnosticMessage) {
            return createIdentifier(isIdentifier(), diagnosticMessage);
        }
        function parseIdentifierName(diagnosticMessage) {
            return createIdentifier(ts.tokenIsIdentifierOrKeyword(token()), diagnosticMessage);
        }
        function isLiteralPropertyName() {
            return ts.tokenIsIdentifierOrKeyword(token()) ||
                token() === 10 /* StringLiteral */ ||
                token() === 8 /* NumericLiteral */;
        }
        function parsePropertyNameWorker(allowComputedPropertyNames) {
            if (token() === 10 /* StringLiteral */ || token() === 8 /* NumericLiteral */) {
                var node = parseLiteralNode();
                node.text = internIdentifier(node.text);
                return node;
            }
            if (allowComputedPropertyNames && token() === 22 /* OpenBracketToken */) {
                return parseComputedPropertyName();
            }
            return parseIdentifierName();
        }
        function parsePropertyName() {
            return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true);
        }
        function parseComputedPropertyName() {
            // PropertyName [Yield]:
            //      LiteralPropertyName
            //      ComputedPropertyName[?Yield]
            var node = createNode(150 /* ComputedPropertyName */);
            parseExpected(22 /* OpenBracketToken */);
            // We parse any expression (including a comma expression). But the grammar
            // says that only an assignment expression is allowed, so the grammar checker
            // will error if it sees a comma expression.
            node.expression = allowInAnd(parseExpression);
            parseExpected(23 /* CloseBracketToken */);
            return finishNode(node);
        }
        function parseContextualModifier(t) {
            return token() === t && tryParse(nextTokenCanFollowModifier);
        }
        function nextTokenIsOnSameLineAndCanFollowModifier() {
            nextToken();
            if (scanner.hasPrecedingLineBreak()) {
                return false;
            }
            return canFollowModifier();
        }
        function nextTokenCanFollowModifier() {
            switch (token()) {
                case 78 /* ConstKeyword */:
                    // 'const' is only a modifier if followed by 'enum'.
                    return nextToken() === 85 /* EnumKeyword */;
                case 86 /* ExportKeyword */:
                    nextToken();
                    if (token() === 81 /* DefaultKeyword */) {
                        return lookAhead(nextTokenCanFollowDefaultKeyword);
                    }
                    return token() !== 40 /* AsteriskToken */ && token() !== 120 /* AsKeyword */ && token() !== 18 /* OpenBraceToken */ && canFollowModifier();
                case 81 /* DefaultKeyword */:
                    return nextTokenCanFollowDefaultKeyword();
                case 117 /* StaticKeyword */:
                case 127 /* GetKeyword */:
                case 138 /* SetKeyword */:
                    nextToken();
                    return canFollowModifier();
                default:
                    return nextTokenIsOnSameLineAndCanFollowModifier();
            }
        }
        function parseAnyContextualModifier() {
            return ts.isModifierKind(token()) && tryParse(nextTokenCanFollowModifier);
        }
        function canFollowModifier() {
            return token() === 22 /* OpenBracketToken */
                || token() === 18 /* OpenBraceToken */
                || token() === 40 /* AsteriskToken */
                || token() === 25 /* DotDotDotToken */
                || isLiteralPropertyName();
        }
        function nextTokenCanFollowDefaultKeyword() {
            nextToken();
            return token() === 77 /* ClassKeyword */ || token() === 91 /* FunctionKeyword */ ||
                token() === 111 /* InterfaceKeyword */ ||
                (token() === 119 /* AbstractKeyword */ && lookAhead(nextTokenIsClassKeywordOnSameLine)) ||
                (token() === 122 /* AsyncKeyword */ && lookAhead(nextTokenIsFunctionKeywordOnSameLine));
        }
        // True if positioned at the start of a list element
        function isListElement(parsingContext, inErrorRecovery) {
            var node = currentNode(parsingContext);
            if (node) {
                return true;
            }
            switch (parsingContext) {
                case 0 /* SourceElements */:
                case 1 /* BlockStatements */:
                case 3 /* SwitchClauseStatements */:
                    // If we're in error recovery, then we don't want to treat ';' as an empty statement.
                    // The problem is that ';' can show up in far too many contexts, and if we see one
                    // and assume it's a statement, then we may bail out inappropriately from whatever
                    // we're parsing.  For example, if we have a semicolon in the middle of a class, then
                    // we really don't want to assume the class is over and we're on a statement in the
                    // outer module.  We just want to consume and move on.
                    return !(token() === 26 /* SemicolonToken */ && inErrorRecovery) && isStartOfStatement();
                case 2 /* SwitchClauses */:
                    return token() === 75 /* CaseKeyword */ || token() === 81 /* DefaultKeyword */;
                case 4 /* TypeMembers */:
                    return lookAhead(isTypeMemberStart);
                case 5 /* ClassMembers */:
                    // We allow semicolons as class elements (as specified by ES6) as long as we're
                    // not in error recovery.  If we're in error recovery, we don't want an errant
                    // semicolon to be treated as a class member (since they're almost always used
                    // for statements.
                    return lookAhead(isClassMemberStart) || (token() === 26 /* SemicolonToken */ && !inErrorRecovery);
                case 6 /* EnumMembers */:
                    // Include open bracket computed properties. This technically also lets in indexers,
                    // which would be a candidate for improved error reporting.
                    return token() === 22 /* OpenBracketToken */ || isLiteralPropertyName();
                case 12 /* ObjectLiteralMembers */:
                    switch (token()) {
                        case 22 /* OpenBracketToken */:
                        case 40 /* AsteriskToken */:
                        case 25 /* DotDotDotToken */:
                        case 24 /* DotToken */: // Not an object literal member, but don't want to close the object (see `tests/cases/fourslash/completionsDotInObjectLiteral.ts`)
                            return true;
                        default:
                            return isLiteralPropertyName();
                    }
                case 18 /* RestProperties */:
                    return isLiteralPropertyName();
                case 9 /* ObjectBindingElements */:
                    return token() === 22 /* OpenBracketToken */ || token() === 25 /* DotDotDotToken */ || isLiteralPropertyName();
                case 7 /* HeritageClauseElement */:
                    // If we see `{ ... }` then only consume it as an expression if it is followed by `,` or `{`
                    // That way we won't consume the body of a class in its heritage clause.
                    if (token() === 18 /* OpenBraceToken */) {
                        return lookAhead(isValidHeritageClauseObjectLiteral);
                    }
                    if (!inErrorRecovery) {
                        return isStartOfLeftHandSideExpression() && !isHeritageClauseExtendsOrImplementsKeyword();
                    }
                    else {
                        // If we're in error recovery we tighten up what we're willing to match.
                        // That way we don't treat something like "this" as a valid heritage clause
                        // element during recovery.
                        return isIdentifier() && !isHeritageClauseExtendsOrImplementsKeyword();
                    }
                case 8 /* VariableDeclarations */:
                    return isIdentifierOrPattern();
                case 10 /* ArrayBindingElements */:
                    return token() === 27 /* CommaToken */ || token() === 25 /* DotDotDotToken */ || isIdentifierOrPattern();
                case 19 /* TypeParameters */:
                    return isIdentifier();
                case 15 /* ArrayLiteralMembers */:
                    switch (token()) {
                        case 27 /* CommaToken */:
                        case 24 /* DotToken */: // Not an array literal member, but don't want to close the array (see `tests/cases/fourslash/completionsDotInArrayLiteralInObjectLiteral.ts`)
                            return true;
                    }
                // falls through
                case 11 /* ArgumentExpressions */:
                    return token() === 25 /* DotDotDotToken */ || isStartOfExpression();
                case 16 /* Parameters */:
                    return isStartOfParameter(/*isJSDocParameter*/ false);
                case 17 /* JSDocParameters */:
                    return isStartOfParameter(/*isJSDocParameter*/ true);
                case 20 /* TypeArguments */:
                case 21 /* TupleElementTypes */:
                    return token() === 27 /* CommaToken */ || isStartOfType();
                case 22 /* HeritageClauses */:
                    return isHeritageClause();
                case 23 /* ImportOrExportSpecifiers */:
                    return ts.tokenIsIdentifierOrKeyword(token());
                case 13 /* JsxAttributes */:
                    return ts.tokenIsIdentifierOrKeyword(token()) || token() === 18 /* OpenBraceToken */;
                case 14 /* JsxChildren */:
                    return true;
            }
            return ts.Debug.fail("Non-exhaustive case in 'isListElement'.");
        }
        function isValidHeritageClauseObjectLiteral() {
            ts.Debug.assert(token() === 18 /* OpenBraceToken */);
            if (nextToken() === 19 /* CloseBraceToken */) {
                // if we see "extends {}" then only treat the {} as what we're extending (and not
                // the class body) if we have:
                //
                //      extends {} {
                //      extends {},
                //      extends {} extends
                //      extends {} implements
                var next = nextToken();
                return next === 27 /* CommaToken */ || next === 18 /* OpenBraceToken */ || next === 87 /* ExtendsKeyword */ || next === 110 /* ImplementsKeyword */;
            }
            return true;
        }
        function nextTokenIsIdentifier() {
            nextToken();
            return isIdentifier();
        }
        function nextTokenIsIdentifierOrKeyword() {
            nextToken();
            return ts.tokenIsIdentifierOrKeyword(token());
        }
        function nextTokenIsIdentifierOrKeywordOrGreaterThan() {
            nextToken();
            return ts.tokenIsIdentifierOrKeywordOrGreaterThan(token());
        }
        function isHeritageClauseExtendsOrImplementsKeyword() {
            if (token() === 110 /* ImplementsKeyword */ ||
                token() === 87 /* ExtendsKeyword */) {
                return lookAhead(nextTokenIsStartOfExpression);
            }
            return false;
        }
        function nextTokenIsStartOfExpression() {
            nextToken();
            return isStartOfExpression();
        }
        function nextTokenIsStartOfType() {
            nextToken();
            return isStartOfType();
        }
        // True if positioned at a list terminator
        function isListTerminator(kind) {
            if (token() === 1 /* EndOfFileToken */) {
                // Being at the end of the file ends all lists.
                return true;
            }
            switch (kind) {
                case 1 /* BlockStatements */:
                case 2 /* SwitchClauses */:
                case 4 /* TypeMembers */:
                case 5 /* ClassMembers */:
                case 6 /* EnumMembers */:
                case 12 /* ObjectLiteralMembers */:
                case 9 /* ObjectBindingElements */:
                case 23 /* ImportOrExportSpecifiers */:
                    return token() === 19 /* CloseBraceToken */;
                case 3 /* SwitchClauseStatements */:
                    return token() === 19 /* CloseBraceToken */ || token() === 75 /* CaseKeyword */ || token() === 81 /* DefaultKeyword */;
                case 7 /* HeritageClauseElement */:
                    return token() === 18 /* OpenBraceToken */ || token() === 87 /* ExtendsKeyword */ || token() === 110 /* ImplementsKeyword */;
                case 8 /* VariableDeclarations */:
                    return isVariableDeclaratorListTerminator();
                case 19 /* TypeParameters */:
                    // Tokens other than '>' are here for better error recovery
                    return token() === 30 /* GreaterThanToken */ || token() === 20 /* OpenParenToken */ || token() === 18 /* OpenBraceToken */ || token() === 87 /* ExtendsKeyword */ || token() === 110 /* ImplementsKeyword */;
                case 11 /* ArgumentExpressions */:
                    // Tokens other than ')' are here for better error recovery
                    return token() === 21 /* CloseParenToken */ || token() === 26 /* SemicolonToken */;
                case 15 /* ArrayLiteralMembers */:
                case 21 /* TupleElementTypes */:
                case 10 /* ArrayBindingElements */:
                    return token() === 23 /* CloseBracketToken */;
                case 17 /* JSDocParameters */:
                case 16 /* Parameters */:
                case 18 /* RestProperties */:
                    // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery
                    return token() === 21 /* CloseParenToken */ || token() === 23 /* CloseBracketToken */ /*|| token === SyntaxKind.OpenBraceToken*/;
                case 20 /* TypeArguments */:
                    // All other tokens should cause the type-argument to terminate except comma token
                    return token() !== 27 /* CommaToken */;
                case 22 /* HeritageClauses */:
                    return token() === 18 /* OpenBraceToken */ || token() === 19 /* CloseBraceToken */;
                case 13 /* JsxAttributes */:
                    return token() === 30 /* GreaterThanToken */ || token() === 42 /* SlashToken */;
                case 14 /* JsxChildren */:
                    return token() === 28 /* LessThanToken */ && lookAhead(nextTokenIsSlash);
                default:
                    return false;
            }
        }
        function isVariableDeclaratorListTerminator() {
            // If we can consume a semicolon (either explicitly, or with ASI), then consider us done
            // with parsing the list of variable declarators.
            if (canParseSemicolon()) {
                return true;
            }
            // in the case where we're parsing the variable declarator of a 'for-in' statement, we
            // are done if we see an 'in' keyword in front of us. Same with for-of
            if (isInOrOfKeyword(token())) {
                return true;
            }
            // ERROR RECOVERY TWEAK:
            // For better error recovery, if we see an '=>' then we just stop immediately.  We've got an
            // arrow function here and it's going to be very unlikely that we'll resynchronize and get
            // another variable declaration.
            if (token() === 37 /* EqualsGreaterThanToken */) {
                return true;
            }
            // Keep trying to parse out variable declarators.
            return false;
        }
        // True if positioned at element or terminator of the current list or any enclosing list
        function isInSomeParsingContext() {
            for (var kind = 0; kind < 24 /* Count */; kind++) {
                if (parsingContext & (1 << kind)) {
                    if (isListElement(kind, /*inErrorRecovery*/ true) || isListTerminator(kind)) {
                        return true;
                    }
                }
            }
            return false;
        }
        // Parses a list of elements
        function parseList(kind, parseElement) {
            var saveParsingContext = parsingContext;
            parsingContext |= 1 << kind;
            var list = [];
            var listPos = getNodePos();
            while (!isListTerminator(kind)) {
                if (isListElement(kind, /*inErrorRecovery*/ false)) {
                    var element = parseListElement(kind, parseElement);
                    list.push(element);
                    continue;
                }
                if (abortParsingListOrMoveToNextToken(kind)) {
                    break;
                }
            }
            parsingContext = saveParsingContext;
            return createNodeArray(list, listPos);
        }
        function parseListElement(parsingContext, parseElement) {
            var node = currentNode(parsingContext);
            if (node) {
                return consumeNode(node);
            }
            return parseElement();
        }
        function currentNode(parsingContext) {
            // If we don't have a cursor or the parsing context isn't reusable, there's nothing to reuse.
            //
            // If there is an outstanding parse error that we've encountered, but not attached to
            // some node, then we cannot get a node from the old source tree.  This is because we
            // want to mark the next node we encounter as being unusable.
            //
            // Note: This may be too conservative.  Perhaps we could reuse the node and set the bit
            // on it (or its leftmost child) as having the error.  For now though, being conservative
            // is nice and likely won't ever affect perf.
            if (!syntaxCursor || !isReusableParsingContext(parsingContext) || parseErrorBeforeNextFinishedNode) {
                return undefined;
            }
            var node = syntaxCursor.currentNode(scanner.getStartPos());
            // Can't reuse a missing node.
            // Can't reuse a node that intersected the change range.
            // Can't reuse a node that contains a parse error.  This is necessary so that we
            // produce the same set of errors again.
            if (ts.nodeIsMissing(node) || node.intersectsChange || ts.containsParseError(node)) {
                return undefined;
            }
            // We can only reuse a node if it was parsed under the same strict mode that we're
            // currently in.  i.e. if we originally parsed a node in non-strict mode, but then
            // the user added 'using strict' at the top of the file, then we can't use that node
            // again as the presence of strict mode may cause us to parse the tokens in the file
            // differently.
            //
            // Note: we *can* reuse tokens when the strict mode changes.  That's because tokens
            // are unaffected by strict mode.  It's just the parser will decide what to do with it
            // differently depending on what mode it is in.
            //
            // This also applies to all our other context flags as well.
            var nodeContextFlags = node.flags & 12679168 /* ContextFlags */;
            if (nodeContextFlags !== contextFlags) {
                return undefined;
            }
            // Ok, we have a node that looks like it could be reused.  Now verify that it is valid
            // in the current list parsing context that we're currently at.
            if (!canReuseNode(node, parsingContext)) {
                return undefined;
            }
            if (node.jsDocCache) {
                // jsDocCache may include tags from parent nodes, which might have been modified.
                node.jsDocCache = undefined;
            }
            return node;
        }
        function consumeNode(node) {
            // Move the scanner so it is after the node we just consumed.
            scanner.setTextPos(node.end);
            nextToken();
            return node;
        }
        function isReusableParsingContext(parsingContext) {
            switch (parsingContext) {
                case 5 /* ClassMembers */:
                case 2 /* SwitchClauses */:
                case 0 /* SourceElements */:
                case 1 /* BlockStatements */:
                case 3 /* SwitchClauseStatements */:
                case 6 /* EnumMembers */:
                case 4 /* TypeMembers */:
                case 8 /* VariableDeclarations */:
                case 17 /* JSDocParameters */:
                case 16 /* Parameters */:
                    return true;
            }
            return false;
        }
        function canReuseNode(node, parsingContext) {
            switch (parsingContext) {
                case 5 /* ClassMembers */:
                    return isReusableClassMember(node);
                case 2 /* SwitchClauses */:
                    return isReusableSwitchClause(node);
                case 0 /* SourceElements */:
                case 1 /* BlockStatements */:
                case 3 /* SwitchClauseStatements */:
                    return isReusableStatement(node);
                case 6 /* EnumMembers */:
                    return isReusableEnumMember(node);
                case 4 /* TypeMembers */:
                    return isReusableTypeMember(node);
                case 8 /* VariableDeclarations */:
                    return isReusableVariableDeclaration(node);
                case 17 /* JSDocParameters */:
                case 16 /* Parameters */:
                    return isReusableParameter(node);
                // Any other lists we do not care about reusing nodes in.  But feel free to add if
                // you can do so safely.  Danger areas involve nodes that may involve speculative
                // parsing.  If speculative parsing is involved with the node, then the range the
                // parser reached while looking ahead might be in the edited range (see the example
                // in canReuseVariableDeclaratorNode for a good case of this).
                // case ParsingContext.HeritageClauses:
                // This would probably be safe to reuse.  There is no speculative parsing with
                // heritage clauses.
                // case ParsingContext.TypeParameters:
                // This would probably be safe to reuse.  There is no speculative parsing with
                // type parameters.  Note that that's because type *parameters* only occur in
                // unambiguous *type* contexts.  While type *arguments* occur in very ambiguous
                // *expression* contexts.
                // case ParsingContext.TupleElementTypes:
                // This would probably be safe to reuse.  There is no speculative parsing with
                // tuple types.
                // Technically, type argument list types are probably safe to reuse.  While
                // speculative parsing is involved with them (since type argument lists are only
                // produced from speculative parsing a < as a type argument list), we only have
                // the types because speculative parsing succeeded.  Thus, the lookahead never
                // went past the end of the list and rewound.
                // case ParsingContext.TypeArguments:
                // Note: these are almost certainly not safe to ever reuse.  Expressions commonly
                // need a large amount of lookahead, and we should not reuse them as they may
                // have actually intersected the edit.
                // case ParsingContext.ArgumentExpressions:
                // This is not safe to reuse for the same reason as the 'AssignmentExpression'
                // cases.  i.e. a property assignment may end with an expression, and thus might
                // have lookahead far beyond it's old node.
                // case ParsingContext.ObjectLiteralMembers:
                // This is probably not safe to reuse.  There can be speculative parsing with
                // type names in a heritage clause.  There can be generic names in the type
                // name list, and there can be left hand side expressions (which can have type
                // arguments.)
                // case ParsingContext.HeritageClauseElement:
                // Perhaps safe to reuse, but it's unlikely we'd see more than a dozen attributes
                // on any given element. Same for children.
                // case ParsingContext.JsxAttributes:
                // case ParsingContext.JsxChildren:
            }
            return false;
        }
        function isReusableClassMember(node) {
            if (node) {
                switch (node.kind) {
                    case 158 /* Constructor */:
                    case 163 /* IndexSignature */:
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                    case 155 /* PropertyDeclaration */:
                    case 218 /* SemicolonClassElement */:
                        return true;
                    case 157 /* MethodDeclaration */:
                        // Method declarations are not necessarily reusable.  An object-literal
                        // may have a method calls "constructor(...)" and we must reparse that
                        // into an actual .ConstructorDeclaration.
                        var methodDeclaration = node;
                        var nameIsConstructor = methodDeclaration.name.kind === 73 /* Identifier */ &&
                            methodDeclaration.name.originalKeywordKind === 125 /* ConstructorKeyword */;
                        return !nameIsConstructor;
                }
            }
            return false;
        }
        function isReusableSwitchClause(node) {
            if (node) {
                switch (node.kind) {
                    case 272 /* CaseClause */:
                    case 273 /* DefaultClause */:
                        return true;
                }
            }
            return false;
        }
        function isReusableStatement(node) {
            if (node) {
                switch (node.kind) {
                    case 240 /* FunctionDeclaration */:
                    case 220 /* VariableStatement */:
                    case 219 /* Block */:
                    case 223 /* IfStatement */:
                    case 222 /* ExpressionStatement */:
                    case 235 /* ThrowStatement */:
                    case 231 /* ReturnStatement */:
                    case 233 /* SwitchStatement */:
                    case 230 /* BreakStatement */:
                    case 229 /* ContinueStatement */:
                    case 227 /* ForInStatement */:
                    case 228 /* ForOfStatement */:
                    case 226 /* ForStatement */:
                    case 225 /* WhileStatement */:
                    case 232 /* WithStatement */:
                    case 221 /* EmptyStatement */:
                    case 236 /* TryStatement */:
                    case 234 /* LabeledStatement */:
                    case 224 /* DoStatement */:
                    case 237 /* DebuggerStatement */:
                    case 250 /* ImportDeclaration */:
                    case 249 /* ImportEqualsDeclaration */:
                    case 256 /* ExportDeclaration */:
                    case 255 /* ExportAssignment */:
                    case 245 /* ModuleDeclaration */:
                    case 241 /* ClassDeclaration */:
                    case 242 /* InterfaceDeclaration */:
                    case 244 /* EnumDeclaration */:
                    case 243 /* TypeAliasDeclaration */:
                        return true;
                }
            }
            return false;
        }
        function isReusableEnumMember(node) {
            return node.kind === 279 /* EnumMember */;
        }
        function isReusableTypeMember(node) {
            if (node) {
                switch (node.kind) {
                    case 162 /* ConstructSignature */:
                    case 156 /* MethodSignature */:
                    case 163 /* IndexSignature */:
                    case 154 /* PropertySignature */:
                    case 161 /* CallSignature */:
                        return true;
                }
            }
            return false;
        }
        function isReusableVariableDeclaration(node) {
            if (node.kind !== 238 /* VariableDeclaration */) {
                return false;
            }
            // Very subtle incremental parsing bug.  Consider the following code:
            //
            //      let v = new List < A, B
            //
            // This is actually legal code.  It's a list of variable declarators "v = new List<A"
            // on one side and "B" on the other. If you then change that to:
            //
            //      let v = new List < A, B >()
            //
            // then we have a problem.  "v = new List<A" doesn't intersect the change range, so we
            // start reparsing at "B" and we completely fail to handle this properly.
            //
            // In order to prevent this, we do not allow a variable declarator to be reused if it
            // has an initializer.
            var variableDeclarator = node;
            return variableDeclarator.initializer === undefined;
        }
        function isReusableParameter(node) {
            if (node.kind !== 152 /* Parameter */) {
                return false;
            }
            // See the comment in isReusableVariableDeclaration for why we do this.
            var parameter = node;
            return parameter.initializer === undefined;
        }
        // Returns true if we should abort parsing.
        function abortParsingListOrMoveToNextToken(kind) {
            parseErrorAtCurrentToken(parsingContextErrors(kind));
            if (isInSomeParsingContext()) {
                return true;
            }
            nextToken();
            return false;
        }
        function parsingContextErrors(context) {
            switch (context) {
                case 0 /* SourceElements */: return ts.Diagnostics.Declaration_or_statement_expected;
                case 1 /* BlockStatements */: return ts.Diagnostics.Declaration_or_statement_expected;
                case 2 /* SwitchClauses */: return ts.Diagnostics.case_or_default_expected;
                case 3 /* SwitchClauseStatements */: return ts.Diagnostics.Statement_expected;
                case 18 /* RestProperties */: // fallthrough
                case 4 /* TypeMembers */: return ts.Diagnostics.Property_or_signature_expected;
                case 5 /* ClassMembers */: return ts.Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected;
                case 6 /* EnumMembers */: return ts.Diagnostics.Enum_member_expected;
                case 7 /* HeritageClauseElement */: return ts.Diagnostics.Expression_expected;
                case 8 /* VariableDeclarations */: return ts.Diagnostics.Variable_declaration_expected;
                case 9 /* ObjectBindingElements */: return ts.Diagnostics.Property_destructuring_pattern_expected;
                case 10 /* ArrayBindingElements */: return ts.Diagnostics.Array_element_destructuring_pattern_expected;
                case 11 /* ArgumentExpressions */: return ts.Diagnostics.Argument_expression_expected;
                case 12 /* ObjectLiteralMembers */: return ts.Diagnostics.Property_assignment_expected;
                case 15 /* ArrayLiteralMembers */: return ts.Diagnostics.Expression_or_comma_expected;
                case 17 /* JSDocParameters */: return ts.Diagnostics.Parameter_declaration_expected;
                case 16 /* Parameters */: return ts.Diagnostics.Parameter_declaration_expected;
                case 19 /* TypeParameters */: return ts.Diagnostics.Type_parameter_declaration_expected;
                case 20 /* TypeArguments */: return ts.Diagnostics.Type_argument_expected;
                case 21 /* TupleElementTypes */: return ts.Diagnostics.Type_expected;
                case 22 /* HeritageClauses */: return ts.Diagnostics.Unexpected_token_expected;
                case 23 /* ImportOrExportSpecifiers */: return ts.Diagnostics.Identifier_expected;
                case 13 /* JsxAttributes */: return ts.Diagnostics.Identifier_expected;
                case 14 /* JsxChildren */: return ts.Diagnostics.Identifier_expected;
                default: return undefined; // TODO: GH#18217 `default: Debug.assertNever(context);`
            }
        }
        // Parses a comma-delimited list of elements
        function parseDelimitedList(kind, parseElement, considerSemicolonAsDelimiter) {
            var saveParsingContext = parsingContext;
            parsingContext |= 1 << kind;
            var list = [];
            var listPos = getNodePos();
            var commaStart = -1; // Meaning the previous token was not a comma
            while (true) {
                if (isListElement(kind, /*inErrorRecovery*/ false)) {
                    var startPos = scanner.getStartPos();
                    list.push(parseListElement(kind, parseElement));
                    commaStart = scanner.getTokenPos();
                    if (parseOptional(27 /* CommaToken */)) {
                        // No need to check for a zero length node since we know we parsed a comma
                        continue;
                    }
                    commaStart = -1; // Back to the state where the last token was not a comma
                    if (isListTerminator(kind)) {
                        break;
                    }
                    // We didn't get a comma, and the list wasn't terminated, explicitly parse
                    // out a comma so we give a good error message.
                    parseExpected(27 /* CommaToken */);
                    // If the token was a semicolon, and the caller allows that, then skip it and
                    // continue.  This ensures we get back on track and don't result in tons of
                    // parse errors.  For example, this can happen when people do things like use
                    // a semicolon to delimit object literal members.   Note: we'll have already
                    // reported an error when we called parseExpected above.
                    if (considerSemicolonAsDelimiter && token() === 26 /* SemicolonToken */ && !scanner.hasPrecedingLineBreak()) {
                        nextToken();
                    }
                    if (startPos === scanner.getStartPos()) {
                        // What we're parsing isn't actually remotely recognizable as a element and we've consumed no tokens whatsoever
                        // Consume a token to advance the parser in some way and avoid an infinite loop
                        // This can happen when we're speculatively parsing parenthesized expressions which we think may be arrow functions,
                        // or when a modifier keyword which is disallowed as a parameter name (ie, `static` in strict mode) is supplied
                        nextToken();
                    }
                    continue;
                }
                if (isListTerminator(kind)) {
                    break;
                }
                if (abortParsingListOrMoveToNextToken(kind)) {
                    break;
                }
            }
            parsingContext = saveParsingContext;
            var result = createNodeArray(list, listPos);
            // Recording the trailing comma is deliberately done after the previous
            // loop, and not just if we see a list terminator. This is because the list
            // may have ended incorrectly, but it is still important to know if there
            // was a trailing comma.
            // Check if the last token was a comma.
            if (commaStart >= 0) {
                // Always preserve a trailing comma by marking it on the NodeArray
                result.hasTrailingComma = true;
            }
            return result;
        }
        function createMissingList() {
            var list = createNodeArray([], getNodePos());
            list.isMissingList = true;
            return list;
        }
        function isMissingList(arr) {
            return !!arr.isMissingList;
        }
        function parseBracketedList(kind, parseElement, open, close) {
            if (parseExpected(open)) {
                var result = parseDelimitedList(kind, parseElement);
                parseExpected(close);
                return result;
            }
            return createMissingList();
        }
        function parseEntityName(allowReservedWords, diagnosticMessage) {
            var entity = allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage);
            var dotPos = scanner.getStartPos();
            while (parseOptional(24 /* DotToken */)) {
                if (token() === 28 /* LessThanToken */) {
                    // the entity is part of a JSDoc-style generic, so record the trailing dot for later error reporting
                    entity.jsdocDotPos = dotPos;
                    break;
                }
                dotPos = scanner.getStartPos();
                entity = createQualifiedName(entity, parseRightSideOfDot(allowReservedWords));
            }
            return entity;
        }
        function createQualifiedName(entity, name) {
            var node = createNode(149 /* QualifiedName */, entity.pos);
            node.left = entity;
            node.right = name;
            return finishNode(node);
        }
        function parseRightSideOfDot(allowIdentifierNames) {
            // Technically a keyword is valid here as all identifiers and keywords are identifier names.
            // However, often we'll encounter this in error situations when the identifier or keyword
            // is actually starting another valid construct.
            //
            // So, we check for the following specific case:
            //
            //      name.
            //      identifierOrKeyword identifierNameOrKeyword
            //
            // Note: the newlines are important here.  For example, if that above code
            // were rewritten into:
            //
            //      name.identifierOrKeyword
            //      identifierNameOrKeyword
            //
            // Then we would consider it valid.  That's because ASI would take effect and
            // the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword".
            // In the first case though, ASI will not take effect because there is not a
            // line terminator after the identifier or keyword.
            if (scanner.hasPrecedingLineBreak() && ts.tokenIsIdentifierOrKeyword(token())) {
                var matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
                if (matchesPattern) {
                    // Report that we need an identifier.  However, report it right after the dot,
                    // and not on the next token.  This is because the next token might actually
                    // be an identifier and the error would be quite confusing.
                    return createMissingNode(73 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Identifier_expected);
                }
            }
            return allowIdentifierNames ? parseIdentifierName() : parseIdentifier();
        }
        function parseTemplateExpression() {
            var template = createNode(207 /* TemplateExpression */);
            template.head = parseTemplateHead();
            ts.Debug.assert(template.head.kind === 15 /* TemplateHead */, "Template head has wrong token kind");
            var list = [];
            var listPos = getNodePos();
            do {
                list.push(parseTemplateSpan());
            } while (ts.last(list).literal.kind === 16 /* TemplateMiddle */);
            template.templateSpans = createNodeArray(list, listPos);
            return finishNode(template);
        }
        function parseTemplateSpan() {
            var span = createNode(217 /* TemplateSpan */);
            span.expression = allowInAnd(parseExpression);
            var literal;
            if (token() === 19 /* CloseBraceToken */) {
                reScanTemplateToken();
                literal = parseTemplateMiddleOrTemplateTail();
            }
            else {
                literal = parseExpectedToken(17 /* TemplateTail */, ts.Diagnostics._0_expected, ts.tokenToString(19 /* CloseBraceToken */));
            }
            span.literal = literal;
            return finishNode(span);
        }
        function parseLiteralNode() {
            return parseLiteralLikeNode(token());
        }
        function parseTemplateHead() {
            var fragment = parseLiteralLikeNode(token());
            ts.Debug.assert(fragment.kind === 15 /* TemplateHead */, "Template head has wrong token kind");
            return fragment;
        }
        function parseTemplateMiddleOrTemplateTail() {
            var fragment = parseLiteralLikeNode(token());
            ts.Debug.assert(fragment.kind === 16 /* TemplateMiddle */ || fragment.kind === 17 /* TemplateTail */, "Template fragment has wrong token kind");
            return fragment;
        }
        function parseLiteralLikeNode(kind) {
            var node = createNode(kind);
            node.text = scanner.getTokenValue();
            if (scanner.hasExtendedUnicodeEscape()) {
                node.hasExtendedUnicodeEscape = true;
            }
            if (scanner.isUnterminated()) {
                node.isUnterminated = true;
            }
            // Octal literals are not allowed in strict mode or ES5
            // Note that theoretically the following condition would hold true literals like 009,
            // which is not octal.But because of how the scanner separates the tokens, we would
            // never get a token like this. Instead, we would get 00 and 9 as two separate tokens.
            // We also do not need to check for negatives because any prefix operator would be part of a
            // parent unary expression.
            if (node.kind === 8 /* NumericLiteral */) {
                node.numericLiteralFlags = scanner.getTokenFlags() & 1008 /* NumericLiteralFlags */;
            }
            nextToken();
            finishNode(node);
            return node;
        }
        // TYPES
        function parseTypeReference() {
            var node = createNode(165 /* TypeReference */);
            node.typeName = parseEntityName(/*allowReservedWords*/ true, ts.Diagnostics.Type_expected);
            if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === 28 /* LessThanToken */) {
                node.typeArguments = parseBracketedList(20 /* TypeArguments */, parseType, 28 /* LessThanToken */, 30 /* GreaterThanToken */);
            }
            return finishNode(node);
        }
        // If true, we should abort parsing an error function.
        function typeHasArrowFunctionBlockingParseError(node) {
            switch (node.kind) {
                case 165 /* TypeReference */:
                    return ts.nodeIsMissing(node.typeName);
                case 166 /* FunctionType */:
                case 167 /* ConstructorType */: {
                    var _a = node, parameters = _a.parameters, type = _a.type;
                    return isMissingList(parameters) || typeHasArrowFunctionBlockingParseError(type);
                }
                case 178 /* ParenthesizedType */:
                    return typeHasArrowFunctionBlockingParseError(node.type);
                default:
                    return false;
            }
        }
        function parseThisTypePredicate(lhs) {
            nextToken();
            var node = createNode(164 /* TypePredicate */, lhs.pos);
            node.parameterName = lhs;
            node.type = parseType();
            return finishNode(node);
        }
        function parseThisTypeNode() {
            var node = createNode(179 /* ThisType */);
            nextToken();
            return finishNode(node);
        }
        function parseJSDocAllType(postFixEquals) {
            var result = createNode(290 /* JSDocAllType */);
            if (postFixEquals) {
                return createPostfixType(294 /* JSDocOptionalType */, result);
            }
            else {
                nextToken();
            }
            return finishNode(result);
        }
        function parseJSDocNonNullableType() {
            var result = createNode(293 /* JSDocNonNullableType */);
            nextToken();
            result.type = parseNonArrayType();
            return finishNode(result);
        }
        function parseJSDocUnknownOrNullableType() {
            var pos = scanner.getStartPos();
            // skip the ?
            nextToken();
            // Need to lookahead to decide if this is a nullable or unknown type.
            // Here are cases where we'll pick the unknown type:
            //
            //      Foo(?,
            //      { a: ? }
            //      Foo(?)
            //      Foo<?>
            //      Foo(?=
            //      (?|
            if (token() === 27 /* CommaToken */ ||
                token() === 19 /* CloseBraceToken */ ||
                token() === 21 /* CloseParenToken */ ||
                token() === 30 /* GreaterThanToken */ ||
                token() === 60 /* EqualsToken */ ||
                token() === 50 /* BarToken */) {
                var result = createNode(291 /* JSDocUnknownType */, pos);
                return finishNode(result);
            }
            else {
                var result = createNode(292 /* JSDocNullableType */, pos);
                result.type = parseType();
                return finishNode(result);
            }
        }
        function parseJSDocFunctionType() {
            if (lookAhead(nextTokenIsOpenParen)) {
                var result = createNodeWithJSDoc(295 /* JSDocFunctionType */);
                nextToken();
                fillSignature(57 /* ColonToken */, 4 /* Type */ | 32 /* JSDoc */, result);
                return finishNode(result);
            }
            var node = createNode(165 /* TypeReference */);
            node.typeName = parseIdentifierName();
            return finishNode(node);
        }
        function parseJSDocParameter() {
            var parameter = createNode(152 /* Parameter */);
            if (token() === 101 /* ThisKeyword */ || token() === 96 /* NewKeyword */) {
                parameter.name = parseIdentifierName();
                parseExpected(57 /* ColonToken */);
            }
            parameter.type = parseJSDocType();
            return finishNode(parameter);
        }
        function parseJSDocType() {
            scanner.setInJSDocType(true);
            var dotdotdot = parseOptionalToken(25 /* DotDotDotToken */);
            var type = parseTypeOrTypePredicate();
            scanner.setInJSDocType(false);
            if (dotdotdot) {
                var variadic = createNode(296 /* JSDocVariadicType */, dotdotdot.pos);
                variadic.type = type;
                type = finishNode(variadic);
            }
            if (token() === 60 /* EqualsToken */) {
                return createPostfixType(294 /* JSDocOptionalType */, type);
            }
            return type;
        }
        function parseTypeQuery() {
            var node = createNode(168 /* TypeQuery */);
            parseExpected(105 /* TypeOfKeyword */);
            node.exprName = parseEntityName(/*allowReservedWords*/ true);
            return finishNode(node);
        }
        function parseTypeParameter() {
            var node = createNode(151 /* TypeParameter */);
            node.name = parseIdentifier();
            if (parseOptional(87 /* ExtendsKeyword */)) {
                // It's not uncommon for people to write improper constraints to a generic.  If the
                // user writes a constraint that is an expression and not an actual type, then parse
                // it out as an expression (so we can recover well), but report that a type is needed
                // instead.
                if (isStartOfType() || !isStartOfExpression()) {
                    node.constraint = parseType();
                }
                else {
                    // It was not a type, and it looked like an expression.  Parse out an expression
                    // here so we recover well.  Note: it is important that we call parseUnaryExpression
                    // and not parseExpression here.  If the user has:
                    //
                    //      <T extends "">
                    //
                    // We do *not* want to consume the `>` as we're consuming the expression for "".
                    node.expression = parseUnaryExpressionOrHigher();
                }
            }
            if (parseOptional(60 /* EqualsToken */)) {
                node.default = parseType();
            }
            return finishNode(node);
        }
        function parseTypeParameters() {
            if (token() === 28 /* LessThanToken */) {
                return parseBracketedList(19 /* TypeParameters */, parseTypeParameter, 28 /* LessThanToken */, 30 /* GreaterThanToken */);
            }
        }
        function parseParameterType() {
            if (parseOptional(57 /* ColonToken */)) {
                return parseType();
            }
            return undefined;
        }
        function isStartOfParameter(isJSDocParameter) {
            return token() === 25 /* DotDotDotToken */ ||
                isIdentifierOrPattern() ||
                ts.isModifierKind(token()) ||
                token() === 58 /* AtToken */ ||
                isStartOfType(/*inStartOfParameter*/ !isJSDocParameter);
        }
        function parseParameter() {
            var node = createNodeWithJSDoc(152 /* Parameter */);
            if (token() === 101 /* ThisKeyword */) {
                node.name = createIdentifier(/*isIdentifier*/ true);
                node.type = parseParameterType();
                return finishNode(node);
            }
            node.decorators = parseDecorators();
            node.modifiers = parseModifiers();
            node.dotDotDotToken = parseOptionalToken(25 /* DotDotDotToken */);
            // FormalParameter [Yield,Await]:
            //      BindingElement[?Yield,?Await]
            node.name = parseIdentifierOrPattern();
            if (ts.getFullWidth(node.name) === 0 && !ts.hasModifiers(node) && ts.isModifierKind(token())) {
                // in cases like
                // 'use strict'
                // function foo(static)
                // isParameter('static') === true, because of isModifier('static')
                // however 'static' is not a legal identifier in a strict mode.
                // so result of this function will be ParameterDeclaration (flags = 0, name = missing, type = undefined, initializer = undefined)
                // and current token will not change => parsing of the enclosing parameter list will last till the end of time (or OOM)
                // to avoid this we'll advance cursor to the next token.
                nextToken();
            }
            node.questionToken = parseOptionalToken(56 /* QuestionToken */);
            node.type = parseParameterType();
            node.initializer = parseInitializer();
            return finishNode(node);
        }
        /**
         * Note: If returnToken is EqualsGreaterThanToken, `signature.type` will always be defined.
         * @returns If return type parsing succeeds
         */
        function fillSignature(returnToken, flags, signature) {
            if (!(flags & 32 /* JSDoc */)) {
                signature.typeParameters = parseTypeParameters();
            }
            var parametersParsedSuccessfully = parseParameterList(signature, flags);
            if (shouldParseReturnType(returnToken, !!(flags & 4 /* Type */))) {
                signature.type = parseTypeOrTypePredicate();
                if (typeHasArrowFunctionBlockingParseError(signature.type))
                    return false;
            }
            return parametersParsedSuccessfully;
        }
        function shouldParseReturnType(returnToken, isType) {
            if (returnToken === 37 /* EqualsGreaterThanToken */) {
                parseExpected(returnToken);
                return true;
            }
            else if (parseOptional(57 /* ColonToken */)) {
                return true;
            }
            else if (isType && token() === 37 /* EqualsGreaterThanToken */) {
                // This is easy to get backward, especially in type contexts, so parse the type anyway
                parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(57 /* ColonToken */));
                nextToken();
                return true;
            }
            return false;
        }
        // Returns true on success.
        function parseParameterList(signature, flags) {
            // FormalParameters [Yield,Await]: (modified)
            //      [empty]
            //      FormalParameterList[?Yield,Await]
            //
            // FormalParameter[Yield,Await]: (modified)
            //      BindingElement[?Yield,Await]
            //
            // BindingElement [Yield,Await]: (modified)
            //      SingleNameBinding[?Yield,?Await]
            //      BindingPattern[?Yield,?Await]Initializer [In, ?Yield,?Await] opt
            //
            // SingleNameBinding [Yield,Await]:
            //      BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt
            if (!parseExpected(20 /* OpenParenToken */)) {
                signature.parameters = createMissingList();
                return false;
            }
            var savedYieldContext = inYieldContext();
            var savedAwaitContext = inAwaitContext();
            setYieldContext(!!(flags & 1 /* Yield */));
            setAwaitContext(!!(flags & 2 /* Await */));
            signature.parameters = flags & 32 /* JSDoc */ ?
                parseDelimitedList(17 /* JSDocParameters */, parseJSDocParameter) :
                parseDelimitedList(16 /* Parameters */, parseParameter);
            setYieldContext(savedYieldContext);
            setAwaitContext(savedAwaitContext);
            return parseExpected(21 /* CloseParenToken */);
        }
        function parseTypeMemberSemicolon() {
            // We allow type members to be separated by commas or (possibly ASI) semicolons.
            // First check if it was a comma.  If so, we're done with the member.
            if (parseOptional(27 /* CommaToken */)) {
                return;
            }
            // Didn't have a comma.  We must have a (possible ASI) semicolon.
            parseSemicolon();
        }
        function parseSignatureMember(kind) {
            var node = createNodeWithJSDoc(kind);
            if (kind === 162 /* ConstructSignature */) {
                parseExpected(96 /* NewKeyword */);
            }
            fillSignature(57 /* ColonToken */, 4 /* Type */, node);
            parseTypeMemberSemicolon();
            return finishNode(node);
        }
        function isIndexSignature() {
            return token() === 22 /* OpenBracketToken */ && lookAhead(isUnambiguouslyIndexSignature);
        }
        function isUnambiguouslyIndexSignature() {
            // The only allowed sequence is:
            //
            //   [id:
            //
            // However, for error recovery, we also check the following cases:
            //
            //   [...
            //   [id,
            //   [id?,
            //   [id?:
            //   [id?]
            //   [public id
            //   [private id
            //   [protected id
            //   []
            //
            nextToken();
            if (token() === 25 /* DotDotDotToken */ || token() === 23 /* CloseBracketToken */) {
                return true;
            }
            if (ts.isModifierKind(token())) {
                nextToken();
                if (isIdentifier()) {
                    return true;
                }
            }
            else if (!isIdentifier()) {
                return false;
            }
            else {
                // Skip the identifier
                nextToken();
            }
            // A colon signifies a well formed indexer
            // A comma should be a badly formed indexer because comma expressions are not allowed
            // in computed properties.
            if (token() === 57 /* ColonToken */ || token() === 27 /* CommaToken */) {
                return true;
            }
            // Question mark could be an indexer with an optional property,
            // or it could be a conditional expression in a computed property.
            if (token() !== 56 /* QuestionToken */) {
                return false;
            }
            // If any of the following tokens are after the question mark, it cannot
            // be a conditional expression, so treat it as an indexer.
            nextToken();
            return token() === 57 /* ColonToken */ || token() === 27 /* CommaToken */ || token() === 23 /* CloseBracketToken */;
        }
        function parseIndexSignatureDeclaration(node) {
            node.kind = 163 /* IndexSignature */;
            node.parameters = parseBracketedList(16 /* Parameters */, parseParameter, 22 /* OpenBracketToken */, 23 /* CloseBracketToken */);
            node.type = parseTypeAnnotation();
            parseTypeMemberSemicolon();
            return finishNode(node);
        }
        function parsePropertyOrMethodSignature(node) {
            node.name = parsePropertyName();
            node.questionToken = parseOptionalToken(56 /* QuestionToken */);
            if (token() === 20 /* OpenParenToken */ || token() === 28 /* LessThanToken */) {
                node.kind = 156 /* MethodSignature */;
                // Method signatures don't exist in expression contexts.  So they have neither
                // [Yield] nor [Await]
                fillSignature(57 /* ColonToken */, 4 /* Type */, node);
            }
            else {
                node.kind = 154 /* PropertySignature */;
                node.type = parseTypeAnnotation();
                if (token() === 60 /* EqualsToken */) {
                    // Although type literal properties cannot not have initializers, we attempt
                    // to parse an initializer so we can report in the checker that an interface
                    // property or type literal property cannot have an initializer.
                    node.initializer = parseInitializer();
                }
            }
            parseTypeMemberSemicolon();
            return finishNode(node);
        }
        function isTypeMemberStart() {
            // Return true if we have the start of a signature member
            if (token() === 20 /* OpenParenToken */ || token() === 28 /* LessThanToken */) {
                return true;
            }
            var idToken = false;
            // Eat up all modifiers, but hold on to the last one in case it is actually an identifier
            while (ts.isModifierKind(token())) {
                idToken = true;
                nextToken();
            }
            // Index signatures and computed property names are type members
            if (token() === 22 /* OpenBracketToken */) {
                return true;
            }
            // Try to get the first property-like token following all modifiers
            if (isLiteralPropertyName()) {
                idToken = true;
                nextToken();
            }
            // If we were able to get any potential identifier, check that it is
            // the start of a member declaration
            if (idToken) {
                return token() === 20 /* OpenParenToken */ ||
                    token() === 28 /* LessThanToken */ ||
                    token() === 56 /* QuestionToken */ ||
                    token() === 57 /* ColonToken */ ||
                    token() === 27 /* CommaToken */ ||
                    canParseSemicolon();
            }
            return false;
        }
        function parseTypeMember() {
            if (token() === 20 /* OpenParenToken */ || token() === 28 /* LessThanToken */) {
                return parseSignatureMember(161 /* CallSignature */);
            }
            if (token() === 96 /* NewKeyword */ && lookAhead(nextTokenIsOpenParenOrLessThan)) {
                return parseSignatureMember(162 /* ConstructSignature */);
            }
            var node = createNodeWithJSDoc(0 /* Unknown */);
            node.modifiers = parseModifiers();
            if (isIndexSignature()) {
                return parseIndexSignatureDeclaration(node);
            }
            return parsePropertyOrMethodSignature(node);
        }
        function nextTokenIsOpenParenOrLessThan() {
            nextToken();
            return token() === 20 /* OpenParenToken */ || token() === 28 /* LessThanToken */;
        }
        function nextTokenIsDot() {
            return nextToken() === 24 /* DotToken */;
        }
        function nextTokenIsOpenParenOrLessThanOrDot() {
            switch (nextToken()) {
                case 20 /* OpenParenToken */:
                case 28 /* LessThanToken */:
                case 24 /* DotToken */:
                    return true;
            }
            return false;
        }
        function parseTypeLiteral() {
            var node = createNode(169 /* TypeLiteral */);
            node.members = parseObjectTypeMembers();
            return finishNode(node);
        }
        function parseObjectTypeMembers() {
            var members;
            if (parseExpected(18 /* OpenBraceToken */)) {
                members = parseList(4 /* TypeMembers */, parseTypeMember);
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                members = createMissingList();
            }
            return members;
        }
        function isStartOfMappedType() {
            nextToken();
            if (token() === 38 /* PlusToken */ || token() === 39 /* MinusToken */) {
                return nextToken() === 134 /* ReadonlyKeyword */;
            }
            if (token() === 134 /* ReadonlyKeyword */) {
                nextToken();
            }
            return token() === 22 /* OpenBracketToken */ && nextTokenIsIdentifier() && nextToken() === 94 /* InKeyword */;
        }
        function parseMappedTypeParameter() {
            var node = createNode(151 /* TypeParameter */);
            node.name = parseIdentifier();
            parseExpected(94 /* InKeyword */);
            node.constraint = parseType();
            return finishNode(node);
        }
        function parseMappedType() {
            var node = createNode(182 /* MappedType */);
            parseExpected(18 /* OpenBraceToken */);
            if (token() === 134 /* ReadonlyKeyword */ || token() === 38 /* PlusToken */ || token() === 39 /* MinusToken */) {
                node.readonlyToken = parseTokenNode();
                if (node.readonlyToken.kind !== 134 /* ReadonlyKeyword */) {
                    parseExpectedToken(134 /* ReadonlyKeyword */);
                }
            }
            parseExpected(22 /* OpenBracketToken */);
            node.typeParameter = parseMappedTypeParameter();
            parseExpected(23 /* CloseBracketToken */);
            if (token() === 56 /* QuestionToken */ || token() === 38 /* PlusToken */ || token() === 39 /* MinusToken */) {
                node.questionToken = parseTokenNode();
                if (node.questionToken.kind !== 56 /* QuestionToken */) {
                    parseExpectedToken(56 /* QuestionToken */);
                }
            }
            node.type = parseTypeAnnotation();
            parseSemicolon();
            parseExpected(19 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseTupleElementType() {
            var pos = getNodePos();
            if (parseOptional(25 /* DotDotDotToken */)) {
                var node = createNode(173 /* RestType */, pos);
                node.type = parseType();
                return finishNode(node);
            }
            var type = parseType();
            if (!(contextFlags & 2097152 /* JSDoc */) && type.kind === 292 /* JSDocNullableType */ && type.pos === type.type.pos) {
                type.kind = 172 /* OptionalType */;
            }
            return type;
        }
        function parseTupleType() {
            var node = createNode(171 /* TupleType */);
            node.elementTypes = parseBracketedList(21 /* TupleElementTypes */, parseTupleElementType, 22 /* OpenBracketToken */, 23 /* CloseBracketToken */);
            return finishNode(node);
        }
        function parseParenthesizedType() {
            var node = createNode(178 /* ParenthesizedType */);
            parseExpected(20 /* OpenParenToken */);
            node.type = parseType();
            parseExpected(21 /* CloseParenToken */);
            return finishNode(node);
        }
        function parseFunctionOrConstructorType() {
            var pos = getNodePos();
            var kind = parseOptional(96 /* NewKeyword */) ? 167 /* ConstructorType */ : 166 /* FunctionType */;
            var node = createNodeWithJSDoc(kind, pos);
            fillSignature(37 /* EqualsGreaterThanToken */, 4 /* Type */, node);
            return finishNode(node);
        }
        function parseKeywordAndNoDot() {
            var node = parseTokenNode();
            return token() === 24 /* DotToken */ ? undefined : node;
        }
        function parseLiteralTypeNode(negative) {
            var node = createNode(183 /* LiteralType */);
            var unaryMinusExpression;
            if (negative) {
                unaryMinusExpression = createNode(203 /* PrefixUnaryExpression */);
                unaryMinusExpression.operator = 39 /* MinusToken */;
                nextToken();
            }
            var expression = token() === 103 /* TrueKeyword */ || token() === 88 /* FalseKeyword */
                ? parseTokenNode()
                : parseLiteralLikeNode(token());
            if (negative) {
                unaryMinusExpression.operand = expression;
                finishNode(unaryMinusExpression);
                expression = unaryMinusExpression;
            }
            node.literal = expression;
            return finishNode(node);
        }
        function isStartOfTypeOfImportType() {
            nextToken();
            return token() === 93 /* ImportKeyword */;
        }
        function parseImportType() {
            sourceFile.flags |= 524288 /* PossiblyContainsDynamicImport */;
            var node = createNode(184 /* ImportType */);
            if (parseOptional(105 /* TypeOfKeyword */)) {
                node.isTypeOf = true;
            }
            parseExpected(93 /* ImportKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.argument = parseType();
            parseExpected(21 /* CloseParenToken */);
            if (parseOptional(24 /* DotToken */)) {
                node.qualifier = parseEntityName(/*allowReservedWords*/ true, ts.Diagnostics.Type_expected);
            }
            if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === 28 /* LessThanToken */) {
                node.typeArguments = parseBracketedList(20 /* TypeArguments */, parseType, 28 /* LessThanToken */, 30 /* GreaterThanToken */);
            }
            return finishNode(node);
        }
        function nextTokenIsNumericOrBigIntLiteral() {
            nextToken();
            return token() === 8 /* NumericLiteral */ || token() === 9 /* BigIntLiteral */;
        }
        function parseNonArrayType() {
            switch (token()) {
                case 121 /* AnyKeyword */:
                case 144 /* UnknownKeyword */:
                case 139 /* StringKeyword */:
                case 136 /* NumberKeyword */:
                case 147 /* BigIntKeyword */:
                case 140 /* SymbolKeyword */:
                case 124 /* BooleanKeyword */:
                case 142 /* UndefinedKeyword */:
                case 133 /* NeverKeyword */:
                case 137 /* ObjectKeyword */:
                    // If these are followed by a dot, then parse these out as a dotted type reference instead.
                    return tryParse(parseKeywordAndNoDot) || parseTypeReference();
                case 40 /* AsteriskToken */:
                    return parseJSDocAllType(/*postfixEquals*/ false);
                case 63 /* AsteriskEqualsToken */:
                    return parseJSDocAllType(/*postfixEquals*/ true);
                case 56 /* QuestionToken */:
                    return parseJSDocUnknownOrNullableType();
                case 91 /* FunctionKeyword */:
                    return parseJSDocFunctionType();
                case 52 /* ExclamationToken */:
                    return parseJSDocNonNullableType();
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 103 /* TrueKeyword */:
                case 88 /* FalseKeyword */:
                    return parseLiteralTypeNode();
                case 39 /* MinusToken */:
                    return lookAhead(nextTokenIsNumericOrBigIntLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference();
                case 107 /* VoidKeyword */:
                case 97 /* NullKeyword */:
                    return parseTokenNode();
                case 101 /* ThisKeyword */: {
                    var thisKeyword = parseThisTypeNode();
                    if (token() === 129 /* IsKeyword */ && !scanner.hasPrecedingLineBreak()) {
                        return parseThisTypePredicate(thisKeyword);
                    }
                    else {
                        return thisKeyword;
                    }
                }
                case 105 /* TypeOfKeyword */:
                    return lookAhead(isStartOfTypeOfImportType) ? parseImportType() : parseTypeQuery();
                case 18 /* OpenBraceToken */:
                    return lookAhead(isStartOfMappedType) ? parseMappedType() : parseTypeLiteral();
                case 22 /* OpenBracketToken */:
                    return parseTupleType();
                case 20 /* OpenParenToken */:
                    return parseParenthesizedType();
                case 93 /* ImportKeyword */:
                    return parseImportType();
                default:
                    return parseTypeReference();
            }
        }
        function isStartOfType(inStartOfParameter) {
            switch (token()) {
                case 121 /* AnyKeyword */:
                case 144 /* UnknownKeyword */:
                case 139 /* StringKeyword */:
                case 136 /* NumberKeyword */:
                case 147 /* BigIntKeyword */:
                case 124 /* BooleanKeyword */:
                case 134 /* ReadonlyKeyword */:
                case 140 /* SymbolKeyword */:
                case 143 /* UniqueKeyword */:
                case 107 /* VoidKeyword */:
                case 142 /* UndefinedKeyword */:
                case 97 /* NullKeyword */:
                case 101 /* ThisKeyword */:
                case 105 /* TypeOfKeyword */:
                case 133 /* NeverKeyword */:
                case 18 /* OpenBraceToken */:
                case 22 /* OpenBracketToken */:
                case 28 /* LessThanToken */:
                case 50 /* BarToken */:
                case 49 /* AmpersandToken */:
                case 96 /* NewKeyword */:
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 103 /* TrueKeyword */:
                case 88 /* FalseKeyword */:
                case 137 /* ObjectKeyword */:
                case 40 /* AsteriskToken */:
                case 56 /* QuestionToken */:
                case 52 /* ExclamationToken */:
                case 25 /* DotDotDotToken */:
                case 128 /* InferKeyword */:
                case 93 /* ImportKeyword */:
                    return true;
                case 91 /* FunctionKeyword */:
                    return !inStartOfParameter;
                case 39 /* MinusToken */:
                    return !inStartOfParameter && lookAhead(nextTokenIsNumericOrBigIntLiteral);
                case 20 /* OpenParenToken */:
                    // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
                    // or something that starts a type. We don't want to consider things like '(1)' a type.
                    return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType);
                default:
                    return isIdentifier();
            }
        }
        function isStartOfParenthesizedOrFunctionType() {
            nextToken();
            return token() === 21 /* CloseParenToken */ || isStartOfParameter(/*isJSDocParameter*/ false) || isStartOfType();
        }
        function parsePostfixTypeOrHigher() {
            var type = parseNonArrayType();
            while (!scanner.hasPrecedingLineBreak()) {
                switch (token()) {
                    case 52 /* ExclamationToken */:
                        type = createPostfixType(293 /* JSDocNonNullableType */, type);
                        break;
                    case 56 /* QuestionToken */:
                        // If not in JSDoc and next token is start of a type we have a conditional type
                        if (!(contextFlags & 2097152 /* JSDoc */) && lookAhead(nextTokenIsStartOfType)) {
                            return type;
                        }
                        type = createPostfixType(292 /* JSDocNullableType */, type);
                        break;
                    case 22 /* OpenBracketToken */:
                        parseExpected(22 /* OpenBracketToken */);
                        if (isStartOfType()) {
                            var node = createNode(181 /* IndexedAccessType */, type.pos);
                            node.objectType = type;
                            node.indexType = parseType();
                            parseExpected(23 /* CloseBracketToken */);
                            type = finishNode(node);
                        }
                        else {
                            var node = createNode(170 /* ArrayType */, type.pos);
                            node.elementType = type;
                            parseExpected(23 /* CloseBracketToken */);
                            type = finishNode(node);
                        }
                        break;
                    default:
                        return type;
                }
            }
            return type;
        }
        function createPostfixType(kind, type) {
            nextToken();
            var postfix = createNode(kind, type.pos);
            postfix.type = type;
            return finishNode(postfix);
        }
        function parseTypeOperator(operator) {
            var node = createNode(180 /* TypeOperator */);
            parseExpected(operator);
            node.operator = operator;
            node.type = parseTypeOperatorOrHigher();
            return finishNode(node);
        }
        function parseInferType() {
            var node = createNode(177 /* InferType */);
            parseExpected(128 /* InferKeyword */);
            var typeParameter = createNode(151 /* TypeParameter */);
            typeParameter.name = parseIdentifier();
            node.typeParameter = finishNode(typeParameter);
            return finishNode(node);
        }
        function parseTypeOperatorOrHigher() {
            var operator = token();
            switch (operator) {
                case 130 /* KeyOfKeyword */:
                case 143 /* UniqueKeyword */:
                case 134 /* ReadonlyKeyword */:
                    return parseTypeOperator(operator);
                case 128 /* InferKeyword */:
                    return parseInferType();
            }
            return parsePostfixTypeOrHigher();
        }
        function parseUnionOrIntersectionType(kind, parseConstituentType, operator) {
            var start = scanner.getStartPos();
            var hasLeadingOperator = parseOptional(operator);
            var type = parseConstituentType();
            if (token() === operator || hasLeadingOperator) {
                var types = [type];
                while (parseOptional(operator)) {
                    types.push(parseConstituentType());
                }
                var node = createNode(kind, start);
                node.types = createNodeArray(types, start);
                type = finishNode(node);
            }
            return type;
        }
        function parseIntersectionTypeOrHigher() {
            return parseUnionOrIntersectionType(175 /* IntersectionType */, parseTypeOperatorOrHigher, 49 /* AmpersandToken */);
        }
        function parseUnionTypeOrHigher() {
            return parseUnionOrIntersectionType(174 /* UnionType */, parseIntersectionTypeOrHigher, 50 /* BarToken */);
        }
        function isStartOfFunctionType() {
            if (token() === 28 /* LessThanToken */) {
                return true;
            }
            return token() === 20 /* OpenParenToken */ && lookAhead(isUnambiguouslyStartOfFunctionType);
        }
        function skipParameterStart() {
            if (ts.isModifierKind(token())) {
                // Skip modifiers
                parseModifiers();
            }
            if (isIdentifier() || token() === 101 /* ThisKeyword */) {
                nextToken();
                return true;
            }
            if (token() === 22 /* OpenBracketToken */ || token() === 18 /* OpenBraceToken */) {
                // Return true if we can parse an array or object binding pattern with no errors
                var previousErrorCount = parseDiagnostics.length;
                parseIdentifierOrPattern();
                return previousErrorCount === parseDiagnostics.length;
            }
            return false;
        }
        function isUnambiguouslyStartOfFunctionType() {
            nextToken();
            if (token() === 21 /* CloseParenToken */ || token() === 25 /* DotDotDotToken */) {
                // ( )
                // ( ...
                return true;
            }
            if (skipParameterStart()) {
                // We successfully skipped modifiers (if any) and an identifier or binding pattern,
                // now see if we have something that indicates a parameter declaration
                if (token() === 57 /* ColonToken */ || token() === 27 /* CommaToken */ ||
                    token() === 56 /* QuestionToken */ || token() === 60 /* EqualsToken */) {
                    // ( xxx :
                    // ( xxx ,
                    // ( xxx ?
                    // ( xxx =
                    return true;
                }
                if (token() === 21 /* CloseParenToken */) {
                    nextToken();
                    if (token() === 37 /* EqualsGreaterThanToken */) {
                        // ( xxx ) =>
                        return true;
                    }
                }
            }
            return false;
        }
        function parseTypeOrTypePredicate() {
            var typePredicateVariable = isIdentifier() && tryParse(parseTypePredicatePrefix);
            var type = parseType();
            if (typePredicateVariable) {
                var node = createNode(164 /* TypePredicate */, typePredicateVariable.pos);
                node.parameterName = typePredicateVariable;
                node.type = type;
                return finishNode(node);
            }
            else {
                return type;
            }
        }
        function parseTypePredicatePrefix() {
            var id = parseIdentifier();
            if (token() === 129 /* IsKeyword */ && !scanner.hasPrecedingLineBreak()) {
                nextToken();
                return id;
            }
        }
        function parseType() {
            // The rules about 'yield' only apply to actual code/expression contexts.  They don't
            // apply to 'type' contexts.  So we disable these parameters here before moving on.
            return doOutsideOfContext(20480 /* TypeExcludesFlags */, parseTypeWorker);
        }
        function parseTypeWorker(noConditionalTypes) {
            if (isStartOfFunctionType() || token() === 96 /* NewKeyword */) {
                return parseFunctionOrConstructorType();
            }
            var type = parseUnionTypeOrHigher();
            if (!noConditionalTypes && !scanner.hasPrecedingLineBreak() && parseOptional(87 /* ExtendsKeyword */)) {
                var node = createNode(176 /* ConditionalType */, type.pos);
                node.checkType = type;
                // The type following 'extends' is not permitted to be another conditional type
                node.extendsType = parseTypeWorker(/*noConditionalTypes*/ true);
                parseExpected(56 /* QuestionToken */);
                node.trueType = parseTypeWorker();
                parseExpected(57 /* ColonToken */);
                node.falseType = parseTypeWorker();
                return finishNode(node);
            }
            return type;
        }
        function parseTypeAnnotation() {
            return parseOptional(57 /* ColonToken */) ? parseType() : undefined;
        }
        // EXPRESSIONS
        function isStartOfLeftHandSideExpression() {
            switch (token()) {
                case 101 /* ThisKeyword */:
                case 99 /* SuperKeyword */:
                case 97 /* NullKeyword */:
                case 103 /* TrueKeyword */:
                case 88 /* FalseKeyword */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 10 /* StringLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 15 /* TemplateHead */:
                case 20 /* OpenParenToken */:
                case 22 /* OpenBracketToken */:
                case 18 /* OpenBraceToken */:
                case 91 /* FunctionKeyword */:
                case 77 /* ClassKeyword */:
                case 96 /* NewKeyword */:
                case 42 /* SlashToken */:
                case 65 /* SlashEqualsToken */:
                case 73 /* Identifier */:
                    return true;
                case 93 /* ImportKeyword */:
                    return lookAhead(nextTokenIsOpenParenOrLessThanOrDot);
                default:
                    return isIdentifier();
            }
        }
        function isStartOfExpression() {
            if (isStartOfLeftHandSideExpression()) {
                return true;
            }
            switch (token()) {
                case 38 /* PlusToken */:
                case 39 /* MinusToken */:
                case 53 /* TildeToken */:
                case 52 /* ExclamationToken */:
                case 82 /* DeleteKeyword */:
                case 105 /* TypeOfKeyword */:
                case 107 /* VoidKeyword */:
                case 44 /* PlusPlusToken */:
                case 45 /* MinusMinusToken */:
                case 28 /* LessThanToken */:
                case 123 /* AwaitKeyword */:
                case 118 /* YieldKeyword */:
                    // Yield/await always starts an expression.  Either it is an identifier (in which case
                    // it is definitely an expression).  Or it's a keyword (either because we're in
                    // a generator or async function, or in strict mode (or both)) and it started a yield or await expression.
                    return true;
                default:
                    // Error tolerance.  If we see the start of some binary operator, we consider
                    // that the start of an expression.  That way we'll parse out a missing identifier,
                    // give a good message about an identifier being missing, and then consume the
                    // rest of the binary expression.
                    if (isBinaryOperator()) {
                        return true;
                    }
                    return isIdentifier();
            }
        }
        function isStartOfExpressionStatement() {
            // As per the grammar, none of '{' or 'function' or 'class' can start an expression statement.
            return token() !== 18 /* OpenBraceToken */ &&
                token() !== 91 /* FunctionKeyword */ &&
                token() !== 77 /* ClassKeyword */ &&
                token() !== 58 /* AtToken */ &&
                isStartOfExpression();
        }
        function parseExpression() {
            // Expression[in]:
            //      AssignmentExpression[in]
            //      Expression[in] , AssignmentExpression[in]
            // clear the decorator context when parsing Expression, as it should be unambiguous when parsing a decorator
            var saveDecoratorContext = inDecoratorContext();
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ false);
            }
            var expr = parseAssignmentExpressionOrHigher();
            var operatorToken;
            while ((operatorToken = parseOptionalToken(27 /* CommaToken */))) {
                expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher());
            }
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ true);
            }
            return expr;
        }
        function parseInitializer() {
            return parseOptional(60 /* EqualsToken */) ? parseAssignmentExpressionOrHigher() : undefined;
        }
        function parseAssignmentExpressionOrHigher() {
            //  AssignmentExpression[in,yield]:
            //      1) ConditionalExpression[?in,?yield]
            //      2) LeftHandSideExpression = AssignmentExpression[?in,?yield]
            //      3) LeftHandSideExpression AssignmentOperator AssignmentExpression[?in,?yield]
            //      4) ArrowFunctionExpression[?in,?yield]
            //      5) AsyncArrowFunctionExpression[in,yield,await]
            //      6) [+Yield] YieldExpression[?In]
            //
            // Note: for ease of implementation we treat productions '2' and '3' as the same thing.
            // (i.e. they're both BinaryExpressions with an assignment operator in it).
            // First, do the simple check if we have a YieldExpression (production '6').
            if (isYieldExpression()) {
                return parseYieldExpression();
            }
            // Then, check if we have an arrow function (production '4' and '5') that starts with a parenthesized
            // parameter list or is an async arrow function.
            // AsyncArrowFunctionExpression:
            //      1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In]
            //      2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In]
            // Production (1) of AsyncArrowFunctionExpression is parsed in "tryParseAsyncSimpleArrowFunctionExpression".
            // And production (2) is parsed in "tryParseParenthesizedArrowFunctionExpression".
            //
            // If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is
            // not a LeftHandSideExpression, nor does it start a ConditionalExpression.  So we are done
            // with AssignmentExpression if we see one.
            var arrowExpression = tryParseParenthesizedArrowFunctionExpression() || tryParseAsyncSimpleArrowFunctionExpression();
            if (arrowExpression) {
                return arrowExpression;
            }
            // Now try to see if we're in production '1', '2' or '3'.  A conditional expression can
            // start with a LogicalOrExpression, while the assignment productions can only start with
            // LeftHandSideExpressions.
            //
            // So, first, we try to just parse out a BinaryExpression.  If we get something that is a
            // LeftHandSide or higher, then we can try to parse out the assignment expression part.
            // Otherwise, we try to parse out the conditional expression bit.  We want to allow any
            // binary expression here, so we pass in the 'lowest' precedence here so that it matches
            // and consumes anything.
            var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
            // To avoid a look-ahead, we did not handle the case of an arrow function with a single un-parenthesized
            // parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single
            // identifier and the current token is an arrow.
            if (expr.kind === 73 /* Identifier */ && token() === 37 /* EqualsGreaterThanToken */) {
                return parseSimpleArrowFunctionExpression(expr);
            }
            // Now see if we might be in cases '2' or '3'.
            // If the expression was a LHS expression, and we have an assignment operator, then
            // we're in '2' or '3'. Consume the assignment and return.
            //
            // Note: we call reScanGreaterToken so that we get an appropriately merged token
            // for cases like `> > =` becoming `>>=`
            if (ts.isLeftHandSideExpression(expr) && ts.isAssignmentOperator(reScanGreaterToken())) {
                return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
            }
            // It wasn't an assignment or a lambda.  This is a conditional expression:
            return parseConditionalExpressionRest(expr);
        }
        function isYieldExpression() {
            if (token() === 118 /* YieldKeyword */) {
                // If we have a 'yield' keyword, and this is a context where yield expressions are
                // allowed, then definitely parse out a yield expression.
                if (inYieldContext()) {
                    return true;
                }
                // We're in a context where 'yield expr' is not allowed.  However, if we can
                // definitely tell that the user was trying to parse a 'yield expr' and not
                // just a normal expr that start with a 'yield' identifier, then parse out
                // a 'yield expr'.  We can then report an error later that they are only
                // allowed in generator expressions.
                //
                // for example, if we see 'yield(foo)', then we'll have to treat that as an
                // invocation expression of something called 'yield'.  However, if we have
                // 'yield foo' then that is not legal as a normal expression, so we can
                // definitely recognize this as a yield expression.
                //
                // for now we just check if the next token is an identifier.  More heuristics
                // can be added here later as necessary.  We just need to make sure that we
                // don't accidentally consume something legal.
                return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine);
            }
            return false;
        }
        function nextTokenIsIdentifierOnSameLine() {
            nextToken();
            return !scanner.hasPrecedingLineBreak() && isIdentifier();
        }
        function parseYieldExpression() {
            var node = createNode(208 /* YieldExpression */);
            // YieldExpression[In] :
            //      yield
            //      yield [no LineTerminator here] [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield]
            //      yield [no LineTerminator here] * [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield]
            nextToken();
            if (!scanner.hasPrecedingLineBreak() &&
                (token() === 40 /* AsteriskToken */ || isStartOfExpression())) {
                node.asteriskToken = parseOptionalToken(40 /* AsteriskToken */);
                node.expression = parseAssignmentExpressionOrHigher();
                return finishNode(node);
            }
            else {
                // if the next token is not on the same line as yield.  or we don't have an '*' or
                // the start of an expression, then this is just a simple "yield" expression.
                return finishNode(node);
            }
        }
        function parseSimpleArrowFunctionExpression(identifier, asyncModifier) {
            ts.Debug.assert(token() === 37 /* EqualsGreaterThanToken */, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");
            var node;
            if (asyncModifier) {
                node = createNode(198 /* ArrowFunction */, asyncModifier.pos);
                node.modifiers = asyncModifier;
            }
            else {
                node = createNode(198 /* ArrowFunction */, identifier.pos);
            }
            var parameter = createNode(152 /* Parameter */, identifier.pos);
            parameter.name = identifier;
            finishNode(parameter);
            node.parameters = createNodeArray([parameter], parameter.pos, parameter.end);
            node.equalsGreaterThanToken = parseExpectedToken(37 /* EqualsGreaterThanToken */);
            node.body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier);
            return addJSDocComment(finishNode(node));
        }
        function tryParseParenthesizedArrowFunctionExpression() {
            var triState = isParenthesizedArrowFunctionExpression();
            if (triState === 0 /* False */) {
                // It's definitely not a parenthesized arrow function expression.
                return undefined;
            }
            // If we definitely have an arrow function, then we can just parse one, not requiring a
            // following => or { token. Otherwise, we *might* have an arrow function.  Try to parse
            // it out, but don't allow any ambiguity, and return 'undefined' if this could be an
            // expression instead.
            var arrowFunction = triState === 1 /* True */
                ? parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ true)
                : tryParse(parsePossibleParenthesizedArrowFunctionExpressionHead);
            if (!arrowFunction) {
                // Didn't appear to actually be a parenthesized arrow function.  Just bail out.
                return undefined;
            }
            var isAsync = ts.hasModifier(arrowFunction, 256 /* Async */);
            // If we have an arrow, then try to parse the body. Even if not, try to parse if we
            // have an opening brace, just in case we're in an error state.
            var lastToken = token();
            arrowFunction.equalsGreaterThanToken = parseExpectedToken(37 /* EqualsGreaterThanToken */);
            arrowFunction.body = (lastToken === 37 /* EqualsGreaterThanToken */ || lastToken === 18 /* OpenBraceToken */)
                ? parseArrowFunctionExpressionBody(isAsync)
                : parseIdentifier();
            return finishNode(arrowFunction);
        }
        //  True        -> We definitely expect a parenthesized arrow function here.
        //  False       -> There *cannot* be a parenthesized arrow function here.
        //  Unknown     -> There *might* be a parenthesized arrow function here.
        //                 Speculatively look ahead to be sure, and rollback if not.
        function isParenthesizedArrowFunctionExpression() {
            if (token() === 20 /* OpenParenToken */ || token() === 28 /* LessThanToken */ || token() === 122 /* AsyncKeyword */) {
                return lookAhead(isParenthesizedArrowFunctionExpressionWorker);
            }
            if (token() === 37 /* EqualsGreaterThanToken */) {
                // ERROR RECOVERY TWEAK:
                // If we see a standalone => try to parse it as an arrow function expression as that's
                // likely what the user intended to write.
                return 1 /* True */;
            }
            // Definitely not a parenthesized arrow function.
            return 0 /* False */;
        }
        function isParenthesizedArrowFunctionExpressionWorker() {
            if (token() === 122 /* AsyncKeyword */) {
                nextToken();
                if (scanner.hasPrecedingLineBreak()) {
                    return 0 /* False */;
                }
                if (token() !== 20 /* OpenParenToken */ && token() !== 28 /* LessThanToken */) {
                    return 0 /* False */;
                }
            }
            var first = token();
            var second = nextToken();
            if (first === 20 /* OpenParenToken */) {
                if (second === 21 /* CloseParenToken */) {
                    // Simple cases: "() =>", "(): ", and "() {".
                    // This is an arrow function with no parameters.
                    // The last one is not actually an arrow function,
                    // but this is probably what the user intended.
                    var third = nextToken();
                    switch (third) {
                        case 37 /* EqualsGreaterThanToken */:
                        case 57 /* ColonToken */:
                        case 18 /* OpenBraceToken */:
                            return 1 /* True */;
                        default:
                            return 0 /* False */;
                    }
                }
                // If encounter "([" or "({", this could be the start of a binding pattern.
                // Examples:
                //      ([ x ]) => { }
                //      ({ x }) => { }
                //      ([ x ])
                //      ({ x })
                if (second === 22 /* OpenBracketToken */ || second === 18 /* OpenBraceToken */) {
                    return 2 /* Unknown */;
                }
                // Simple case: "(..."
                // This is an arrow function with a rest parameter.
                if (second === 25 /* DotDotDotToken */) {
                    return 1 /* True */;
                }
                // Check for "(xxx yyy", where xxx is a modifier and yyy is an identifier. This
                // isn't actually allowed, but we want to treat it as a lambda so we can provide
                // a good error message.
                if (ts.isModifierKind(second) && second !== 122 /* AsyncKeyword */ && lookAhead(nextTokenIsIdentifier)) {
                    return 1 /* True */;
                }
                // If we had "(" followed by something that's not an identifier,
                // then this definitely doesn't look like a lambda.  "this" is not
                // valid, but we want to parse it and then give a semantic error.
                if (!isIdentifier() && second !== 101 /* ThisKeyword */) {
                    return 0 /* False */;
                }
                switch (nextToken()) {
                    case 57 /* ColonToken */:
                        // If we have something like "(a:", then we must have a
                        // type-annotated parameter in an arrow function expression.
                        return 1 /* True */;
                    case 56 /* QuestionToken */:
                        nextToken();
                        // If we have "(a?:" or "(a?," or "(a?=" or "(a?)" then it is definitely a lambda.
                        if (token() === 57 /* ColonToken */ || token() === 27 /* CommaToken */ || token() === 60 /* EqualsToken */ || token() === 21 /* CloseParenToken */) {
                            return 1 /* True */;
                        }
                        // Otherwise it is definitely not a lambda.
                        return 0 /* False */;
                    case 27 /* CommaToken */:
                    case 60 /* EqualsToken */:
                    case 21 /* CloseParenToken */:
                        // If we have "(a," or "(a=" or "(a)" this *could* be an arrow function
                        return 2 /* Unknown */;
                }
                // It is definitely not an arrow function
                return 0 /* False */;
            }
            else {
                ts.Debug.assert(first === 28 /* LessThanToken */);
                // If we have "<" not followed by an identifier,
                // then this definitely is not an arrow function.
                if (!isIdentifier()) {
                    return 0 /* False */;
                }
                // JSX overrides
                if (sourceFile.languageVariant === 1 /* JSX */) {
                    var isArrowFunctionInJsx = lookAhead(function () {
                        var third = nextToken();
                        if (third === 87 /* ExtendsKeyword */) {
                            var fourth = nextToken();
                            switch (fourth) {
                                case 60 /* EqualsToken */:
                                case 30 /* GreaterThanToken */:
                                    return false;
                                default:
                                    return true;
                            }
                        }
                        else if (third === 27 /* CommaToken */) {
                            return true;
                        }
                        return false;
                    });
                    if (isArrowFunctionInJsx) {
                        return 1 /* True */;
                    }
                    return 0 /* False */;
                }
                // This *could* be a parenthesized arrow function.
                return 2 /* Unknown */;
            }
        }
        function parsePossibleParenthesizedArrowFunctionExpressionHead() {
            return parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ false);
        }
        function tryParseAsyncSimpleArrowFunctionExpression() {
            // We do a check here so that we won't be doing unnecessarily call to "lookAhead"
            if (token() === 122 /* AsyncKeyword */) {
                if (lookAhead(isUnParenthesizedAsyncArrowFunctionWorker) === 1 /* True */) {
                    var asyncModifier = parseModifiersForArrowFunction();
                    var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
                    return parseSimpleArrowFunctionExpression(expr, asyncModifier);
                }
            }
            return undefined;
        }
        function isUnParenthesizedAsyncArrowFunctionWorker() {
            // AsyncArrowFunctionExpression:
            //      1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In]
            //      2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In]
            if (token() === 122 /* AsyncKeyword */) {
                nextToken();
                // If the "async" is followed by "=>" token then it is not a beginning of an async arrow-function
                // but instead a simple arrow-function which will be parsed inside "parseAssignmentExpressionOrHigher"
                if (scanner.hasPrecedingLineBreak() || token() === 37 /* EqualsGreaterThanToken */) {
                    return 0 /* False */;
                }
                // Check for un-parenthesized AsyncArrowFunction
                var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
                if (!scanner.hasPrecedingLineBreak() && expr.kind === 73 /* Identifier */ && token() === 37 /* EqualsGreaterThanToken */) {
                    return 1 /* True */;
                }
            }
            return 0 /* False */;
        }
        function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity) {
            var node = createNodeWithJSDoc(198 /* ArrowFunction */);
            node.modifiers = parseModifiersForArrowFunction();
            var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */;
            // Arrow functions are never generators.
            //
            // If we're speculatively parsing a signature for a parenthesized arrow function, then
            // we have to have a complete parameter list.  Otherwise we might see something like
            // a => (b => c)
            // And think that "(b =>" was actually a parenthesized arrow function with a missing
            // close paren.
            if (!fillSignature(57 /* ColonToken */, isAsync, node) && !allowAmbiguity) {
                return undefined;
            }
            // Parsing a signature isn't enough.
            // Parenthesized arrow signatures often look like other valid expressions.
            // For instance:
            //  - "(x = 10)" is an assignment expression parsed as a signature with a default parameter value.
            //  - "(x,y)" is a comma expression parsed as a signature with two parameters.
            //  - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation.
            //  - "a ? (b): function() {}" will too, since function() is a valid JSDoc function type.
            //
            // So we need just a bit of lookahead to ensure that it can only be a signature.
            var hasJSDocFunctionType = node.type && ts.isJSDocFunctionType(node.type);
            if (!allowAmbiguity && token() !== 37 /* EqualsGreaterThanToken */ && (hasJSDocFunctionType || token() !== 18 /* OpenBraceToken */)) {
                // Returning undefined here will cause our caller to rewind to where we started from.
                return undefined;
            }
            return node;
        }
        function parseArrowFunctionExpressionBody(isAsync) {
            if (token() === 18 /* OpenBraceToken */) {
                return parseFunctionBlock(isAsync ? 2 /* Await */ : 0 /* None */);
            }
            if (token() !== 26 /* SemicolonToken */ &&
                token() !== 91 /* FunctionKeyword */ &&
                token() !== 77 /* ClassKeyword */ &&
                isStartOfStatement() &&
                !isStartOfExpressionStatement()) {
                // Check if we got a plain statement (i.e. no expression-statements, no function/class expressions/declarations)
                //
                // Here we try to recover from a potential error situation in the case where the
                // user meant to supply a block. For example, if the user wrote:
                //
                //  a =>
                //      let v = 0;
                //  }
                //
                // they may be missing an open brace.  Check to see if that's the case so we can
                // try to recover better.  If we don't do this, then the next close curly we see may end
                // up preemptively closing the containing construct.
                //
                // Note: even when 'IgnoreMissingOpenBrace' is passed, parseBody will still error.
                return parseFunctionBlock(16 /* IgnoreMissingOpenBrace */ | (isAsync ? 2 /* Await */ : 0 /* None */));
            }
            return isAsync
                ? doInAwaitContext(parseAssignmentExpressionOrHigher)
                : doOutsideOfAwaitContext(parseAssignmentExpressionOrHigher);
        }
        function parseConditionalExpressionRest(leftOperand) {
            // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher.
            var questionToken = parseOptionalToken(56 /* QuestionToken */);
            if (!questionToken) {
                return leftOperand;
            }
            // Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and
            // we do not that for the 'whenFalse' part.
            var node = createNode(206 /* ConditionalExpression */, leftOperand.pos);
            node.condition = leftOperand;
            node.questionToken = questionToken;
            node.whenTrue = doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher);
            node.colonToken = parseExpectedToken(57 /* ColonToken */);
            node.whenFalse = ts.nodeIsPresent(node.colonToken)
                ? parseAssignmentExpressionOrHigher()
                : createMissingNode(73 /* Identifier */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(57 /* ColonToken */));
            return finishNode(node);
        }
        function parseBinaryExpressionOrHigher(precedence) {
            var leftOperand = parseUnaryExpressionOrHigher();
            return parseBinaryExpressionRest(precedence, leftOperand);
        }
        function isInOrOfKeyword(t) {
            return t === 94 /* InKeyword */ || t === 148 /* OfKeyword */;
        }
        function parseBinaryExpressionRest(precedence, leftOperand) {
            while (true) {
                // We either have a binary operator here, or we're finished.  We call
                // reScanGreaterToken so that we merge token sequences like > and = into >=
                reScanGreaterToken();
                var newPrecedence = ts.getBinaryOperatorPrecedence(token());
                // Check the precedence to see if we should "take" this operator
                // - For left associative operator (all operator but **), consume the operator,
                //   recursively call the function below, and parse binaryExpression as a rightOperand
                //   of the caller if the new precedence of the operator is greater then or equal to the current precedence.
                //   For example:
                //      a - b - c;
                //            ^token; leftOperand = b. Return b to the caller as a rightOperand
                //      a * b - c
                //            ^token; leftOperand = b. Return b to the caller as a rightOperand
                //      a - b * c;
                //            ^token; leftOperand = b. Return b * c to the caller as a rightOperand
                // - For right associative operator (**), consume the operator, recursively call the function
                //   and parse binaryExpression as a rightOperand of the caller if the new precedence of
                //   the operator is strictly grater than the current precedence
                //   For example:
                //      a ** b ** c;
                //             ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
                //      a - b ** c;
                //            ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
                //      a ** b - c
                //             ^token; leftOperand = b. Return b to the caller as a rightOperand
                var consumeCurrentOperator = token() === 41 /* AsteriskAsteriskToken */ ?
                    newPrecedence >= precedence :
                    newPrecedence > precedence;
                if (!consumeCurrentOperator) {
                    break;
                }
                if (token() === 94 /* InKeyword */ && inDisallowInContext()) {
                    break;
                }
                if (token() === 120 /* AsKeyword */) {
                    // Make sure we *do* perform ASI for constructs like this:
                    //    var x = foo
                    //    as (Bar)
                    // This should be parsed as an initialized variable, followed
                    // by a function call to 'as' with the argument 'Bar'
                    if (scanner.hasPrecedingLineBreak()) {
                        break;
                    }
                    else {
                        nextToken();
                        leftOperand = makeAsExpression(leftOperand, parseType());
                    }
                }
                else {
                    leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
                }
            }
            return leftOperand;
        }
        function isBinaryOperator() {
            if (inDisallowInContext() && token() === 94 /* InKeyword */) {
                return false;
            }
            return ts.getBinaryOperatorPrecedence(token()) > 0;
        }
        function makeBinaryExpression(left, operatorToken, right) {
            var node = createNode(205 /* BinaryExpression */, left.pos);
            node.left = left;
            node.operatorToken = operatorToken;
            node.right = right;
            return finishNode(node);
        }
        function makeAsExpression(left, right) {
            var node = createNode(213 /* AsExpression */, left.pos);
            node.expression = left;
            node.type = right;
            return finishNode(node);
        }
        function parsePrefixUnaryExpression() {
            var node = createNode(203 /* PrefixUnaryExpression */);
            node.operator = token();
            nextToken();
            node.operand = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseDeleteExpression() {
            var node = createNode(199 /* DeleteExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseTypeOfExpression() {
            var node = createNode(200 /* TypeOfExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseVoidExpression() {
            var node = createNode(201 /* VoidExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function isAwaitExpression() {
            if (token() === 123 /* AwaitKeyword */) {
                if (inAwaitContext()) {
                    return true;
                }
                // here we are using similar heuristics as 'isYieldExpression'
                return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine);
            }
            return false;
        }
        function parseAwaitExpression() {
            var node = createNode(202 /* AwaitExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        /**
         * Parse ES7 exponential expression and await expression
         *
         * ES7 ExponentiationExpression:
         *      1) UnaryExpression[?Yield]
         *      2) UpdateExpression[?Yield] ** ExponentiationExpression[?Yield]
         *
         */
        function parseUnaryExpressionOrHigher() {
            /**
             * ES7 UpdateExpression:
             *      1) LeftHandSideExpression[?Yield]
             *      2) LeftHandSideExpression[?Yield][no LineTerminator here]++
             *      3) LeftHandSideExpression[?Yield][no LineTerminator here]--
             *      4) ++UnaryExpression[?Yield]
             *      5) --UnaryExpression[?Yield]
             */
            if (isUpdateExpression()) {
                var updateExpression = parseUpdateExpression();
                return token() === 41 /* AsteriskAsteriskToken */ ?
                    parseBinaryExpressionRest(ts.getBinaryOperatorPrecedence(token()), updateExpression) :
                    updateExpression;
            }
            /**
             * ES7 UnaryExpression:
             *      1) UpdateExpression[?yield]
             *      2) delete UpdateExpression[?yield]
             *      3) void UpdateExpression[?yield]
             *      4) typeof UpdateExpression[?yield]
             *      5) + UpdateExpression[?yield]
             *      6) - UpdateExpression[?yield]
             *      7) ~ UpdateExpression[?yield]
             *      8) ! UpdateExpression[?yield]
             */
            var unaryOperator = token();
            var simpleUnaryExpression = parseSimpleUnaryExpression();
            if (token() === 41 /* AsteriskAsteriskToken */) {
                var pos = ts.skipTrivia(sourceText, simpleUnaryExpression.pos);
                var end = simpleUnaryExpression.end;
                if (simpleUnaryExpression.kind === 195 /* TypeAssertionExpression */) {
                    parseErrorAt(pos, end, ts.Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses);
                }
                else {
                    parseErrorAt(pos, end, ts.Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, ts.tokenToString(unaryOperator));
                }
            }
            return simpleUnaryExpression;
        }
        /**
         * Parse ES7 simple-unary expression or higher:
         *
         * ES7 UnaryExpression:
         *      1) UpdateExpression[?yield]
         *      2) delete UnaryExpression[?yield]
         *      3) void UnaryExpression[?yield]
         *      4) typeof UnaryExpression[?yield]
         *      5) + UnaryExpression[?yield]
         *      6) - UnaryExpression[?yield]
         *      7) ~ UnaryExpression[?yield]
         *      8) ! UnaryExpression[?yield]
         *      9) [+Await] await UnaryExpression[?yield]
         */
        function parseSimpleUnaryExpression() {
            switch (token()) {
                case 38 /* PlusToken */:
                case 39 /* MinusToken */:
                case 53 /* TildeToken */:
                case 52 /* ExclamationToken */:
                    return parsePrefixUnaryExpression();
                case 82 /* DeleteKeyword */:
                    return parseDeleteExpression();
                case 105 /* TypeOfKeyword */:
                    return parseTypeOfExpression();
                case 107 /* VoidKeyword */:
                    return parseVoidExpression();
                case 28 /* LessThanToken */:
                    // This is modified UnaryExpression grammar in TypeScript
                    //  UnaryExpression (modified):
                    //      < type > UnaryExpression
                    return parseTypeAssertion();
                case 123 /* AwaitKeyword */:
                    if (isAwaitExpression()) {
                        return parseAwaitExpression();
                    }
                // falls through
                default:
                    return parseUpdateExpression();
            }
        }
        /**
         * Check if the current token can possibly be an ES7 increment expression.
         *
         * ES7 UpdateExpression:
         *      LeftHandSideExpression[?Yield]
         *      LeftHandSideExpression[?Yield][no LineTerminator here]++
         *      LeftHandSideExpression[?Yield][no LineTerminator here]--
         *      ++LeftHandSideExpression[?Yield]
         *      --LeftHandSideExpression[?Yield]
         */
        function isUpdateExpression() {
            // This function is called inside parseUnaryExpression to decide
            // whether to call parseSimpleUnaryExpression or call parseUpdateExpression directly
            switch (token()) {
                case 38 /* PlusToken */:
                case 39 /* MinusToken */:
                case 53 /* TildeToken */:
                case 52 /* ExclamationToken */:
                case 82 /* DeleteKeyword */:
                case 105 /* TypeOfKeyword */:
                case 107 /* VoidKeyword */:
                case 123 /* AwaitKeyword */:
                    return false;
                case 28 /* LessThanToken */:
                    // If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression
                    if (sourceFile.languageVariant !== 1 /* JSX */) {
                        return false;
                    }
                // We are in JSX context and the token is part of JSXElement.
                // falls through
                default:
                    return true;
            }
        }
        /**
         * Parse ES7 UpdateExpression. UpdateExpression is used instead of ES6's PostFixExpression.
         *
         * ES7 UpdateExpression[yield]:
         *      1) LeftHandSideExpression[?yield]
         *      2) LeftHandSideExpression[?yield] [[no LineTerminator here]]++
         *      3) LeftHandSideExpression[?yield] [[no LineTerminator here]]--
         *      4) ++LeftHandSideExpression[?yield]
         *      5) --LeftHandSideExpression[?yield]
         * In TypeScript (2), (3) are parsed as PostfixUnaryExpression. (4), (5) are parsed as PrefixUnaryExpression
         */
        function parseUpdateExpression() {
            if (token() === 44 /* PlusPlusToken */ || token() === 45 /* MinusMinusToken */) {
                var node = createNode(203 /* PrefixUnaryExpression */);
                node.operator = token();
                nextToken();
                node.operand = parseLeftHandSideExpressionOrHigher();
                return finishNode(node);
            }
            else if (sourceFile.languageVariant === 1 /* JSX */ && token() === 28 /* LessThanToken */ && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) {
                // JSXElement is part of primaryExpression
                return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true);
            }
            var expression = parseLeftHandSideExpressionOrHigher();
            ts.Debug.assert(ts.isLeftHandSideExpression(expression));
            if ((token() === 44 /* PlusPlusToken */ || token() === 45 /* MinusMinusToken */) && !scanner.hasPrecedingLineBreak()) {
                var node = createNode(204 /* PostfixUnaryExpression */, expression.pos);
                node.operand = expression;
                node.operator = token();
                nextToken();
                return finishNode(node);
            }
            return expression;
        }
        function parseLeftHandSideExpressionOrHigher() {
            // Original Ecma:
            // LeftHandSideExpression: See 11.2
            //      NewExpression
            //      CallExpression
            //
            // Our simplification:
            //
            // LeftHandSideExpression: See 11.2
            //      MemberExpression
            //      CallExpression
            //
            // See comment in parseMemberExpressionOrHigher on how we replaced NewExpression with
            // MemberExpression to make our lives easier.
            //
            // to best understand the below code, it's important to see how CallExpression expands
            // out into its own productions:
            //
            // CallExpression:
            //      MemberExpression Arguments
            //      CallExpression Arguments
            //      CallExpression[Expression]
            //      CallExpression.IdentifierName
            //      import (AssignmentExpression)
            //      super Arguments
            //      super.IdentifierName
            //
            // Because of the recursion in these calls, we need to bottom out first. There are three
            // bottom out states we can run into: 1) We see 'super' which must start either of
            // the last two CallExpression productions. 2) We see 'import' which must start import call.
            // 3)we have a MemberExpression which either completes the LeftHandSideExpression,
            // or starts the beginning of the first four CallExpression productions.
            var expression;
            if (token() === 93 /* ImportKeyword */) {
                if (lookAhead(nextTokenIsOpenParenOrLessThan)) {
                    // We don't want to eagerly consume all import keyword as import call expression so we look ahead to find "("
                    // For example:
                    //      var foo3 = require("subfolder
                    //      import * as foo1 from "module-from-node
                    // We want this import to be a statement rather than import call expression
                    sourceFile.flags |= 524288 /* PossiblyContainsDynamicImport */;
                    expression = parseTokenNode();
                }
                else if (lookAhead(nextTokenIsDot)) {
                    // This is an 'import.*' metaproperty (i.e. 'import.meta')
                    var fullStart = scanner.getStartPos();
                    nextToken(); // advance past the 'import'
                    nextToken(); // advance past the dot
                    var node = createNode(215 /* MetaProperty */, fullStart);
                    node.keywordToken = 93 /* ImportKeyword */;
                    node.name = parseIdentifierName();
                    expression = finishNode(node);
                    sourceFile.flags |= 1048576 /* PossiblyContainsImportMeta */;
                }
                else {
                    expression = parseMemberExpressionOrHigher();
                }
            }
            else {
                expression = token() === 99 /* SuperKeyword */ ? parseSuperExpression() : parseMemberExpressionOrHigher();
            }
            // Now, we *may* be complete.  However, we might have consumed the start of a
            // CallExpression.  As such, we need to consume the rest of it here to be complete.
            return parseCallExpressionRest(expression);
        }
        function parseMemberExpressionOrHigher() {
            // Note: to make our lives simpler, we decompose the NewExpression productions and
            // place ObjectCreationExpression and FunctionExpression into PrimaryExpression.
            // like so:
            //
            //   PrimaryExpression : See 11.1
            //      this
            //      Identifier
            //      Literal
            //      ArrayLiteral
            //      ObjectLiteral
            //      (Expression)
            //      FunctionExpression
            //      new MemberExpression Arguments?
            //
            //   MemberExpression : See 11.2
            //      PrimaryExpression
            //      MemberExpression[Expression]
            //      MemberExpression.IdentifierName
            //
            //   CallExpression : See 11.2
            //      MemberExpression
            //      CallExpression Arguments
            //      CallExpression[Expression]
            //      CallExpression.IdentifierName
            //
            // Technically this is ambiguous.  i.e. CallExpression defines:
            //
            //   CallExpression:
            //      CallExpression Arguments
            //
            // If you see: "new Foo()"
            //
            // Then that could be treated as a single ObjectCreationExpression, or it could be
            // treated as the invocation of "new Foo".  We disambiguate that in code (to match
            // the original grammar) by making sure that if we see an ObjectCreationExpression
            // we always consume arguments if they are there. So we treat "new Foo()" as an
            // object creation only, and not at all as an invocation.  Another way to think
            // about this is that for every "new" that we see, we will consume an argument list if
            // it is there as part of the *associated* object creation node.  Any additional
            // argument lists we see, will become invocation expressions.
            //
            // Because there are no other places in the grammar now that refer to FunctionExpression
            // or ObjectCreationExpression, it is safe to push down into the PrimaryExpression
            // production.
            //
            // Because CallExpression and MemberExpression are left recursive, we need to bottom out
            // of the recursion immediately.  So we parse out a primary expression to start with.
            var expression = parsePrimaryExpression();
            return parseMemberExpressionRest(expression);
        }
        function parseSuperExpression() {
            var expression = parseTokenNode();
            if (token() === 28 /* LessThanToken */) {
                var startPos = getNodePos();
                var typeArguments = tryParse(parseTypeArgumentsInExpression);
                if (typeArguments !== undefined) {
                    parseErrorAt(startPos, getNodePos(), ts.Diagnostics.super_may_not_use_type_arguments);
                }
            }
            if (token() === 20 /* OpenParenToken */ || token() === 24 /* DotToken */ || token() === 22 /* OpenBracketToken */) {
                return expression;
            }
            // If we have seen "super" it must be followed by '(' or '.'.
            // If it wasn't then just try to parse out a '.' and report an error.
            var node = createNode(190 /* PropertyAccessExpression */, expression.pos);
            node.expression = expression;
            parseExpectedToken(24 /* DotToken */, ts.Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access);
            node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
            return finishNode(node);
        }
        function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext) {
            var opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext);
            var result;
            if (opening.kind === 263 /* JsxOpeningElement */) {
                var node = createNode(261 /* JsxElement */, opening.pos);
                node.openingElement = opening;
                node.children = parseJsxChildren(node.openingElement);
                node.closingElement = parseJsxClosingElement(inExpressionContext);
                if (!tagNamesAreEquivalent(node.openingElement.tagName, node.closingElement.tagName)) {
                    parseErrorAtRange(node.closingElement, ts.Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, ts.getTextOfNodeFromSourceText(sourceText, node.openingElement.tagName));
                }
                result = finishNode(node);
            }
            else if (opening.kind === 266 /* JsxOpeningFragment */) {
                var node = createNode(265 /* JsxFragment */, opening.pos);
                node.openingFragment = opening;
                node.children = parseJsxChildren(node.openingFragment);
                node.closingFragment = parseJsxClosingFragment(inExpressionContext);
                result = finishNode(node);
            }
            else {
                ts.Debug.assert(opening.kind === 262 /* JsxSelfClosingElement */);
                // Nothing else to do for self-closing elements
                result = opening;
            }
            // If the user writes the invalid code '<div></div><div></div>' in an expression context (i.e. not wrapped in
            // an enclosing tag), we'll naively try to parse   ^ this as a 'less than' operator and the remainder of the tag
            // as garbage, which will cause the formatter to badly mangle the JSX. Perform a speculative parse of a JSX
            // element if we see a < token so that we can wrap it in a synthetic binary expression so the formatter
            // does less damage and we can report a better error.
            // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios
            // of one sort or another.
            if (inExpressionContext && token() === 28 /* LessThanToken */) {
                var invalidElement = tryParse(function () { return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true); });
                if (invalidElement) {
                    parseErrorAtCurrentToken(ts.Diagnostics.JSX_expressions_must_have_one_parent_element);
                    var badNode = createNode(205 /* BinaryExpression */, result.pos);
                    badNode.end = invalidElement.end;
                    badNode.left = result;
                    badNode.right = invalidElement;
                    badNode.operatorToken = createMissingNode(27 /* CommaToken */, /*reportAtCurrentPosition*/ false);
                    badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
                    return badNode;
                }
            }
            return result;
        }
        function parseJsxText() {
            var node = createNode(11 /* JsxText */);
            node.text = scanner.getTokenValue();
            node.containsOnlyTriviaWhiteSpaces = currentToken === 12 /* JsxTextAllWhiteSpaces */;
            currentToken = scanner.scanJsxToken();
            return finishNode(node);
        }
        function parseJsxChild(openingTag, token) {
            switch (token) {
                case 1 /* EndOfFileToken */:
                    // If we hit EOF, issue the error at the tag that lacks the closing element
                    // rather than at the end of the file (which is useless)
                    if (ts.isJsxOpeningFragment(openingTag)) {
                        parseErrorAtRange(openingTag, ts.Diagnostics.JSX_fragment_has_no_corresponding_closing_tag);
                    }
                    else {
                        parseErrorAtRange(openingTag.tagName, ts.Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, ts.getTextOfNodeFromSourceText(sourceText, openingTag.tagName));
                    }
                    return undefined;
                case 29 /* LessThanSlashToken */:
                case 7 /* ConflictMarkerTrivia */:
                    return undefined;
                case 11 /* JsxText */:
                case 12 /* JsxTextAllWhiteSpaces */:
                    return parseJsxText();
                case 18 /* OpenBraceToken */:
                    return parseJsxExpression(/*inExpressionContext*/ false);
                case 28 /* LessThanToken */:
                    return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ false);
                default:
                    return ts.Debug.assertNever(token);
            }
        }
        function parseJsxChildren(openingTag) {
            var list = [];
            var listPos = getNodePos();
            var saveParsingContext = parsingContext;
            parsingContext |= 1 << 14 /* JsxChildren */;
            while (true) {
                var child = parseJsxChild(openingTag, currentToken = scanner.reScanJsxToken());
                if (!child)
                    break;
                list.push(child);
            }
            parsingContext = saveParsingContext;
            return createNodeArray(list, listPos);
        }
        function parseJsxAttributes() {
            var jsxAttributes = createNode(269 /* JsxAttributes */);
            jsxAttributes.properties = parseList(13 /* JsxAttributes */, parseJsxAttribute);
            return finishNode(jsxAttributes);
        }
        function parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext) {
            var fullStart = scanner.getStartPos();
            parseExpected(28 /* LessThanToken */);
            if (token() === 30 /* GreaterThanToken */) {
                // See below for explanation of scanJsxText
                var node_1 = createNode(266 /* JsxOpeningFragment */, fullStart);
                scanJsxText();
                return finishNode(node_1);
            }
            var tagName = parseJsxElementName();
            var typeArguments = tryParseTypeArguments();
            var attributes = parseJsxAttributes();
            var node;
            if (token() === 30 /* GreaterThanToken */) {
                // Closing tag, so scan the immediately-following text with the JSX scanning instead
                // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate
                // scanning errors
                node = createNode(263 /* JsxOpeningElement */, fullStart);
                scanJsxText();
            }
            else {
                parseExpected(42 /* SlashToken */);
                if (inExpressionContext) {
                    parseExpected(30 /* GreaterThanToken */);
                }
                else {
                    parseExpected(30 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
                    scanJsxText();
                }
                node = createNode(262 /* JsxSelfClosingElement */, fullStart);
            }
            node.tagName = tagName;
            node.typeArguments = typeArguments;
            node.attributes = attributes;
            return finishNode(node);
        }
        function parseJsxElementName() {
            scanJsxIdentifier();
            // JsxElement can have name in the form of
            //      propertyAccessExpression
            //      primaryExpression in the form of an identifier and "this" keyword
            // We can't just simply use parseLeftHandSideExpressionOrHigher because then we will start consider class,function etc as a keyword
            // We only want to consider "this" as a primaryExpression
            var expression = token() === 101 /* ThisKeyword */ ?
                parseTokenNode() : parseIdentifierName();
            while (parseOptional(24 /* DotToken */)) {
                var propertyAccess = createNode(190 /* PropertyAccessExpression */, expression.pos);
                propertyAccess.expression = expression;
                propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
                expression = finishNode(propertyAccess);
            }
            return expression;
        }
        function parseJsxExpression(inExpressionContext) {
            var node = createNode(271 /* JsxExpression */);
            if (!parseExpected(18 /* OpenBraceToken */)) {
                return undefined;
            }
            if (token() !== 19 /* CloseBraceToken */) {
                node.dotDotDotToken = parseOptionalToken(25 /* DotDotDotToken */);
                node.expression = parseAssignmentExpressionOrHigher();
            }
            if (inExpressionContext) {
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                parseExpected(19 /* CloseBraceToken */, /*message*/ undefined, /*shouldAdvance*/ false);
                scanJsxText();
            }
            return finishNode(node);
        }
        function parseJsxAttribute() {
            if (token() === 18 /* OpenBraceToken */) {
                return parseJsxSpreadAttribute();
            }
            scanJsxIdentifier();
            var node = createNode(268 /* JsxAttribute */);
            node.name = parseIdentifierName();
            if (token() === 60 /* EqualsToken */) {
                switch (scanJsxAttributeValue()) {
                    case 10 /* StringLiteral */:
                        node.initializer = parseLiteralNode();
                        break;
                    default:
                        node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
                        break;
                }
            }
            return finishNode(node);
        }
        function parseJsxSpreadAttribute() {
            var node = createNode(270 /* JsxSpreadAttribute */);
            parseExpected(18 /* OpenBraceToken */);
            parseExpected(25 /* DotDotDotToken */);
            node.expression = parseExpression();
            parseExpected(19 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseJsxClosingElement(inExpressionContext) {
            var node = createNode(264 /* JsxClosingElement */);
            parseExpected(29 /* LessThanSlashToken */);
            node.tagName = parseJsxElementName();
            if (inExpressionContext) {
                parseExpected(30 /* GreaterThanToken */);
            }
            else {
                parseExpected(30 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
                scanJsxText();
            }
            return finishNode(node);
        }
        function parseJsxClosingFragment(inExpressionContext) {
            var node = createNode(267 /* JsxClosingFragment */);
            parseExpected(29 /* LessThanSlashToken */);
            if (ts.tokenIsIdentifierOrKeyword(token())) {
                parseErrorAtRange(parseJsxElementName(), ts.Diagnostics.Expected_corresponding_closing_tag_for_JSX_fragment);
            }
            if (inExpressionContext) {
                parseExpected(30 /* GreaterThanToken */);
            }
            else {
                parseExpected(30 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
                scanJsxText();
            }
            return finishNode(node);
        }
        function parseTypeAssertion() {
            var node = createNode(195 /* TypeAssertionExpression */);
            parseExpected(28 /* LessThanToken */);
            node.type = parseType();
            parseExpected(30 /* GreaterThanToken */);
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseMemberExpressionRest(expression) {
            while (true) {
                var dotToken = parseOptionalToken(24 /* DotToken */);
                if (dotToken) {
                    var propertyAccess = createNode(190 /* PropertyAccessExpression */, expression.pos);
                    propertyAccess.expression = expression;
                    propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
                    expression = finishNode(propertyAccess);
                    continue;
                }
                if (token() === 52 /* ExclamationToken */ && !scanner.hasPrecedingLineBreak()) {
                    nextToken();
                    var nonNullExpression = createNode(214 /* NonNullExpression */, expression.pos);
                    nonNullExpression.expression = expression;
                    expression = finishNode(nonNullExpression);
                    continue;
                }
                // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName
                if (!inDecoratorContext() && parseOptional(22 /* OpenBracketToken */)) {
                    var indexedAccess = createNode(191 /* ElementAccessExpression */, expression.pos);
                    indexedAccess.expression = expression;
                    if (token() === 23 /* CloseBracketToken */) {
                        indexedAccess.argumentExpression = createMissingNode(73 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.An_element_access_expression_should_take_an_argument);
                    }
                    else {
                        var argument = allowInAnd(parseExpression);
                        if (ts.isStringOrNumericLiteralLike(argument)) {
                            argument.text = internIdentifier(argument.text);
                        }
                        indexedAccess.argumentExpression = argument;
                    }
                    parseExpected(23 /* CloseBracketToken */);
                    expression = finishNode(indexedAccess);
                    continue;
                }
                if (isTemplateStartOfTaggedTemplate()) {
                    expression = parseTaggedTemplateRest(expression, /*typeArguments*/ undefined);
                    continue;
                }
                return expression;
            }
        }
        function isTemplateStartOfTaggedTemplate() {
            return token() === 14 /* NoSubstitutionTemplateLiteral */ || token() === 15 /* TemplateHead */;
        }
        function parseTaggedTemplateRest(tag, typeArguments) {
            var tagExpression = createNode(194 /* TaggedTemplateExpression */, tag.pos);
            tagExpression.tag = tag;
            tagExpression.typeArguments = typeArguments;
            tagExpression.template = token() === 14 /* NoSubstitutionTemplateLiteral */
                ? parseLiteralNode()
                : parseTemplateExpression();
            return finishNode(tagExpression);
        }
        function parseCallExpressionRest(expression) {
            while (true) {
                expression = parseMemberExpressionRest(expression);
                // handle 'foo<<T>()'
                if (token() === 28 /* LessThanToken */ || token() === 46 /* LessThanLessThanToken */) {
                    // See if this is the start of a generic invocation.  If so, consume it and
                    // keep checking for postfix expressions.  Otherwise, it's just a '<' that's
                    // part of an arithmetic expression.  Break out so we consume it higher in the
                    // stack.
                    var typeArguments = tryParse(parseTypeArgumentsInExpression);
                    if (!typeArguments) {
                        return expression;
                    }
                    if (isTemplateStartOfTaggedTemplate()) {
                        expression = parseTaggedTemplateRest(expression, typeArguments);
                        continue;
                    }
                    var callExpr = createNode(192 /* CallExpression */, expression.pos);
                    callExpr.expression = expression;
                    callExpr.typeArguments = typeArguments;
                    callExpr.arguments = parseArgumentList();
                    expression = finishNode(callExpr);
                    continue;
                }
                else if (token() === 20 /* OpenParenToken */) {
                    var callExpr = createNode(192 /* CallExpression */, expression.pos);
                    callExpr.expression = expression;
                    callExpr.arguments = parseArgumentList();
                    expression = finishNode(callExpr);
                    continue;
                }
                return expression;
            }
        }
        function parseArgumentList() {
            parseExpected(20 /* OpenParenToken */);
            var result = parseDelimitedList(11 /* ArgumentExpressions */, parseArgumentExpression);
            parseExpected(21 /* CloseParenToken */);
            return result;
        }
        function parseTypeArgumentsInExpression() {
            if (reScanLessThanToken() !== 28 /* LessThanToken */) {
                return undefined;
            }
            nextToken();
            var typeArguments = parseDelimitedList(20 /* TypeArguments */, parseType);
            if (!parseExpected(30 /* GreaterThanToken */)) {
                // If it doesn't have the closing `>` then it's definitely not an type argument list.
                return undefined;
            }
            // If we have a '<', then only parse this as a argument list if the type arguments
            // are complete and we have an open paren.  if we don't, rewind and return nothing.
            return typeArguments && canFollowTypeArgumentsInExpression()
                ? typeArguments
                : undefined;
        }
        function canFollowTypeArgumentsInExpression() {
            switch (token()) {
                case 20 /* OpenParenToken */: // foo<x>(
                case 14 /* NoSubstitutionTemplateLiteral */: // foo<T> `...`
                case 15 /* TemplateHead */: // foo<T> `...${100}...`
                // these are the only tokens can legally follow a type argument
                // list. So we definitely want to treat them as type arg lists.
                case 24 /* DotToken */: // foo<x>.
                case 21 /* CloseParenToken */: // foo<x>)
                case 23 /* CloseBracketToken */: // foo<x>]
                case 57 /* ColonToken */: // foo<x>:
                case 26 /* SemicolonToken */: // foo<x>;
                case 56 /* QuestionToken */: // foo<x>?
                case 33 /* EqualsEqualsToken */: // foo<x> ==
                case 35 /* EqualsEqualsEqualsToken */: // foo<x> ===
                case 34 /* ExclamationEqualsToken */: // foo<x> !=
                case 36 /* ExclamationEqualsEqualsToken */: // foo<x> !==
                case 54 /* AmpersandAmpersandToken */: // foo<x> &&
                case 55 /* BarBarToken */: // foo<x> ||
                case 51 /* CaretToken */: // foo<x> ^
                case 49 /* AmpersandToken */: // foo<x> &
                case 50 /* BarToken */: // foo<x> |
                case 19 /* CloseBraceToken */: // foo<x> }
                case 1 /* EndOfFileToken */: // foo<x>
                    // these cases can't legally follow a type arg list.  However, they're not legal
                    // expressions either.  The user is probably in the middle of a generic type. So
                    // treat it as such.
                    return true;
                case 27 /* CommaToken */: // foo<x>,
                case 18 /* OpenBraceToken */: // foo<x> {
                // We don't want to treat these as type arguments.  Otherwise we'll parse this
                // as an invocation expression.  Instead, we want to parse out the expression
                // in isolation from the type arguments.
                default:
                    // Anything else treat as an expression.
                    return false;
            }
        }
        function parsePrimaryExpression() {
            switch (token()) {
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 10 /* StringLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                    return parseLiteralNode();
                case 101 /* ThisKeyword */:
                case 99 /* SuperKeyword */:
                case 97 /* NullKeyword */:
                case 103 /* TrueKeyword */:
                case 88 /* FalseKeyword */:
                    return parseTokenNode();
                case 20 /* OpenParenToken */:
                    return parseParenthesizedExpression();
                case 22 /* OpenBracketToken */:
                    return parseArrayLiteralExpression();
                case 18 /* OpenBraceToken */:
                    return parseObjectLiteralExpression();
                case 122 /* AsyncKeyword */:
                    // Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher.
                    // If we encounter `async [no LineTerminator here] function` then this is an async
                    // function; otherwise, its an identifier.
                    if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) {
                        break;
                    }
                    return parseFunctionExpression();
                case 77 /* ClassKeyword */:
                    return parseClassExpression();
                case 91 /* FunctionKeyword */:
                    return parseFunctionExpression();
                case 96 /* NewKeyword */:
                    return parseNewExpressionOrNewDotTarget();
                case 42 /* SlashToken */:
                case 65 /* SlashEqualsToken */:
                    if (reScanSlashToken() === 13 /* RegularExpressionLiteral */) {
                        return parseLiteralNode();
                    }
                    break;
                case 15 /* TemplateHead */:
                    return parseTemplateExpression();
            }
            return parseIdentifier(ts.Diagnostics.Expression_expected);
        }
        function parseParenthesizedExpression() {
            var node = createNodeWithJSDoc(196 /* ParenthesizedExpression */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            return finishNode(node);
        }
        function parseSpreadElement() {
            var node = createNode(209 /* SpreadElement */);
            parseExpected(25 /* DotDotDotToken */);
            node.expression = parseAssignmentExpressionOrHigher();
            return finishNode(node);
        }
        function parseArgumentOrArrayLiteralElement() {
            return token() === 25 /* DotDotDotToken */ ? parseSpreadElement() :
                token() === 27 /* CommaToken */ ? createNode(211 /* OmittedExpression */) :
                    parseAssignmentExpressionOrHigher();
        }
        function parseArgumentExpression() {
            return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement);
        }
        function parseArrayLiteralExpression() {
            var node = createNode(188 /* ArrayLiteralExpression */);
            parseExpected(22 /* OpenBracketToken */);
            if (scanner.hasPrecedingLineBreak()) {
                node.multiLine = true;
            }
            node.elements = parseDelimitedList(15 /* ArrayLiteralMembers */, parseArgumentOrArrayLiteralElement);
            parseExpected(23 /* CloseBracketToken */);
            return finishNode(node);
        }
        function parseObjectLiteralElement() {
            var node = createNodeWithJSDoc(0 /* Unknown */);
            if (parseOptionalToken(25 /* DotDotDotToken */)) {
                node.kind = 278 /* SpreadAssignment */;
                node.expression = parseAssignmentExpressionOrHigher();
                return finishNode(node);
            }
            node.decorators = parseDecorators();
            node.modifiers = parseModifiers();
            if (parseContextualModifier(127 /* GetKeyword */)) {
                return parseAccessorDeclaration(node, 159 /* GetAccessor */);
            }
            if (parseContextualModifier(138 /* SetKeyword */)) {
                return parseAccessorDeclaration(node, 160 /* SetAccessor */);
            }
            var asteriskToken = parseOptionalToken(40 /* AsteriskToken */);
            var tokenIsIdentifier = isIdentifier();
            node.name = parsePropertyName();
            // Disallowing of optional property assignments and definite assignment assertion happens in the grammar checker.
            node.questionToken = parseOptionalToken(56 /* QuestionToken */);
            node.exclamationToken = parseOptionalToken(52 /* ExclamationToken */);
            if (asteriskToken || token() === 20 /* OpenParenToken */ || token() === 28 /* LessThanToken */) {
                return parseMethodDeclaration(node, asteriskToken);
            }
            // check if it is short-hand property assignment or normal property assignment
            // NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production
            // CoverInitializedName[Yield] :
            //     IdentifierReference[?Yield] Initializer[In, ?Yield]
            // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern
            var isShorthandPropertyAssignment = tokenIsIdentifier && (token() !== 57 /* ColonToken */);
            if (isShorthandPropertyAssignment) {
                node.kind = 277 /* ShorthandPropertyAssignment */;
                var equalsToken = parseOptionalToken(60 /* EqualsToken */);
                if (equalsToken) {
                    node.equalsToken = equalsToken;
                    node.objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher);
                }
            }
            else {
                node.kind = 276 /* PropertyAssignment */;
                parseExpected(57 /* ColonToken */);
                node.initializer = allowInAnd(parseAssignmentExpressionOrHigher);
            }
            return finishNode(node);
        }
        function parseObjectLiteralExpression() {
            var node = createNode(189 /* ObjectLiteralExpression */);
            parseExpected(18 /* OpenBraceToken */);
            if (scanner.hasPrecedingLineBreak()) {
                node.multiLine = true;
            }
            node.properties = parseDelimitedList(12 /* ObjectLiteralMembers */, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true);
            parseExpected(19 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseFunctionExpression() {
            // GeneratorExpression:
            //      function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody }
            //
            // FunctionExpression:
            //      function BindingIdentifier[opt](FormalParameters){ FunctionBody }
            var saveDecoratorContext = inDecoratorContext();
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ false);
            }
            var node = createNodeWithJSDoc(197 /* FunctionExpression */);
            node.modifiers = parseModifiers();
            parseExpected(91 /* FunctionKeyword */);
            node.asteriskToken = parseOptionalToken(40 /* AsteriskToken */);
            var isGenerator = node.asteriskToken ? 1 /* Yield */ : 0 /* None */;
            var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */;
            node.name =
                isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) :
                    isGenerator ? doInYieldContext(parseOptionalIdentifier) :
                        isAsync ? doInAwaitContext(parseOptionalIdentifier) :
                            parseOptionalIdentifier();
            fillSignature(57 /* ColonToken */, isGenerator | isAsync, node);
            node.body = parseFunctionBlock(isGenerator | isAsync);
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ true);
            }
            return finishNode(node);
        }
        function parseOptionalIdentifier() {
            return isIdentifier() ? parseIdentifier() : undefined;
        }
        function parseNewExpressionOrNewDotTarget() {
            var fullStart = scanner.getStartPos();
            parseExpected(96 /* NewKeyword */);
            if (parseOptional(24 /* DotToken */)) {
                var node_2 = createNode(215 /* MetaProperty */, fullStart);
                node_2.keywordToken = 96 /* NewKeyword */;
                node_2.name = parseIdentifierName();
                return finishNode(node_2);
            }
            var expression = parsePrimaryExpression();
            var typeArguments;
            while (true) {
                expression = parseMemberExpressionRest(expression);
                typeArguments = tryParse(parseTypeArgumentsInExpression);
                if (isTemplateStartOfTaggedTemplate()) {
                    ts.Debug.assert(!!typeArguments, "Expected a type argument list; all plain tagged template starts should be consumed in 'parseMemberExpressionRest'");
                    expression = parseTaggedTemplateRest(expression, typeArguments);
                    typeArguments = undefined;
                }
                break;
            }
            var node = createNode(193 /* NewExpression */, fullStart);
            node.expression = expression;
            node.typeArguments = typeArguments;
            if (node.typeArguments || token() === 20 /* OpenParenToken */) {
                node.arguments = parseArgumentList();
            }
            return finishNode(node);
        }
        // STATEMENTS
        function parseBlock(ignoreMissingOpenBrace, diagnosticMessage) {
            var node = createNode(219 /* Block */);
            if (parseExpected(18 /* OpenBraceToken */, diagnosticMessage) || ignoreMissingOpenBrace) {
                if (scanner.hasPrecedingLineBreak()) {
                    node.multiLine = true;
                }
                node.statements = parseList(1 /* BlockStatements */, parseStatement);
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                node.statements = createMissingList();
            }
            return finishNode(node);
        }
        function parseFunctionBlock(flags, diagnosticMessage) {
            var savedYieldContext = inYieldContext();
            setYieldContext(!!(flags & 1 /* Yield */));
            var savedAwaitContext = inAwaitContext();
            setAwaitContext(!!(flags & 2 /* Await */));
            // We may be in a [Decorator] context when parsing a function expression or
            // arrow function. The body of the function is not in [Decorator] context.
            var saveDecoratorContext = inDecoratorContext();
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ false);
            }
            var block = parseBlock(!!(flags & 16 /* IgnoreMissingOpenBrace */), diagnosticMessage);
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ true);
            }
            setYieldContext(savedYieldContext);
            setAwaitContext(savedAwaitContext);
            return block;
        }
        function parseEmptyStatement() {
            var node = createNode(221 /* EmptyStatement */);
            parseExpected(26 /* SemicolonToken */);
            return finishNode(node);
        }
        function parseIfStatement() {
            var node = createNode(223 /* IfStatement */);
            parseExpected(92 /* IfKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            node.thenStatement = parseStatement();
            node.elseStatement = parseOptional(84 /* ElseKeyword */) ? parseStatement() : undefined;
            return finishNode(node);
        }
        function parseDoStatement() {
            var node = createNode(224 /* DoStatement */);
            parseExpected(83 /* DoKeyword */);
            node.statement = parseStatement();
            parseExpected(108 /* WhileKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html
            // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in
            // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby
            //  do;while(0)x will have a semicolon inserted before x.
            parseOptional(26 /* SemicolonToken */);
            return finishNode(node);
        }
        function parseWhileStatement() {
            var node = createNode(225 /* WhileStatement */);
            parseExpected(108 /* WhileKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            node.statement = parseStatement();
            return finishNode(node);
        }
        function parseForOrForInOrForOfStatement() {
            var pos = getNodePos();
            parseExpected(90 /* ForKeyword */);
            var awaitToken = parseOptionalToken(123 /* AwaitKeyword */);
            parseExpected(20 /* OpenParenToken */);
            var initializer;
            if (token() !== 26 /* SemicolonToken */) {
                if (token() === 106 /* VarKeyword */ || token() === 112 /* LetKeyword */ || token() === 78 /* ConstKeyword */) {
                    initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true);
                }
                else {
                    initializer = disallowInAnd(parseExpression);
                }
            }
            var forOrForInOrForOfStatement;
            if (awaitToken ? parseExpected(148 /* OfKeyword */) : parseOptional(148 /* OfKeyword */)) {
                var forOfStatement = createNode(228 /* ForOfStatement */, pos);
                forOfStatement.awaitModifier = awaitToken;
                forOfStatement.initializer = initializer;
                forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
                parseExpected(21 /* CloseParenToken */);
                forOrForInOrForOfStatement = forOfStatement;
            }
            else if (parseOptional(94 /* InKeyword */)) {
                var forInStatement = createNode(227 /* ForInStatement */, pos);
                forInStatement.initializer = initializer;
                forInStatement.expression = allowInAnd(parseExpression);
                parseExpected(21 /* CloseParenToken */);
                forOrForInOrForOfStatement = forInStatement;
            }
            else {
                var forStatement = createNode(226 /* ForStatement */, pos);
                forStatement.initializer = initializer;
                parseExpected(26 /* SemicolonToken */);
                if (token() !== 26 /* SemicolonToken */ && token() !== 21 /* CloseParenToken */) {
                    forStatement.condition = allowInAnd(parseExpression);
                }
                parseExpected(26 /* SemicolonToken */);
                if (token() !== 21 /* CloseParenToken */) {
                    forStatement.incrementor = allowInAnd(parseExpression);
                }
                parseExpected(21 /* CloseParenToken */);
                forOrForInOrForOfStatement = forStatement;
            }
            forOrForInOrForOfStatement.statement = parseStatement();
            return finishNode(forOrForInOrForOfStatement);
        }
        function parseBreakOrContinueStatement(kind) {
            var node = createNode(kind);
            parseExpected(kind === 230 /* BreakStatement */ ? 74 /* BreakKeyword */ : 79 /* ContinueKeyword */);
            if (!canParseSemicolon()) {
                node.label = parseIdentifier();
            }
            parseSemicolon();
            return finishNode(node);
        }
        function parseReturnStatement() {
            var node = createNode(231 /* ReturnStatement */);
            parseExpected(98 /* ReturnKeyword */);
            if (!canParseSemicolon()) {
                node.expression = allowInAnd(parseExpression);
            }
            parseSemicolon();
            return finishNode(node);
        }
        function parseWithStatement() {
            var node = createNode(232 /* WithStatement */);
            parseExpected(109 /* WithKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            node.statement = doInsideOfContext(8388608 /* InWithStatement */, parseStatement);
            return finishNode(node);
        }
        function parseCaseClause() {
            var node = createNode(272 /* CaseClause */);
            parseExpected(75 /* CaseKeyword */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(57 /* ColonToken */);
            node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
            return finishNode(node);
        }
        function parseDefaultClause() {
            var node = createNode(273 /* DefaultClause */);
            parseExpected(81 /* DefaultKeyword */);
            parseExpected(57 /* ColonToken */);
            node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
            return finishNode(node);
        }
        function parseCaseOrDefaultClause() {
            return token() === 75 /* CaseKeyword */ ? parseCaseClause() : parseDefaultClause();
        }
        function parseSwitchStatement() {
            var node = createNode(233 /* SwitchStatement */);
            parseExpected(100 /* SwitchKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            var caseBlock = createNode(247 /* CaseBlock */);
            parseExpected(18 /* OpenBraceToken */);
            caseBlock.clauses = parseList(2 /* SwitchClauses */, parseCaseOrDefaultClause);
            parseExpected(19 /* CloseBraceToken */);
            node.caseBlock = finishNode(caseBlock);
            return finishNode(node);
        }
        function parseThrowStatement() {
            // ThrowStatement[Yield] :
            //      throw [no LineTerminator here]Expression[In, ?Yield];
            // Because of automatic semicolon insertion, we need to report error if this
            // throw could be terminated with a semicolon.  Note: we can't call 'parseExpression'
            // directly as that might consume an expression on the following line.
            // We just return 'undefined' in that case.  The actual error will be reported in the
            // grammar walker.
            var node = createNode(235 /* ThrowStatement */);
            parseExpected(102 /* ThrowKeyword */);
            node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression);
            parseSemicolon();
            return finishNode(node);
        }
        // TODO: Review for error recovery
        function parseTryStatement() {
            var node = createNode(236 /* TryStatement */);
            parseExpected(104 /* TryKeyword */);
            node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
            node.catchClause = token() === 76 /* CatchKeyword */ ? parseCatchClause() : undefined;
            // If we don't have a catch clause, then we must have a finally clause.  Try to parse
            // one out no matter what.
            if (!node.catchClause || token() === 89 /* FinallyKeyword */) {
                parseExpected(89 /* FinallyKeyword */);
                node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
            }
            return finishNode(node);
        }
        function parseCatchClause() {
            var result = createNode(275 /* CatchClause */);
            parseExpected(76 /* CatchKeyword */);
            if (parseOptional(20 /* OpenParenToken */)) {
                result.variableDeclaration = parseVariableDeclaration();
                parseExpected(21 /* CloseParenToken */);
            }
            else {
                // Keep shape of node to avoid degrading performance.
                result.variableDeclaration = undefined;
            }
            result.block = parseBlock(/*ignoreMissingOpenBrace*/ false);
            return finishNode(result);
        }
        function parseDebuggerStatement() {
            var node = createNode(237 /* DebuggerStatement */);
            parseExpected(80 /* DebuggerKeyword */);
            parseSemicolon();
            return finishNode(node);
        }
        function parseExpressionOrLabeledStatement() {
            // Avoiding having to do the lookahead for a labeled statement by just trying to parse
            // out an expression, seeing if it is identifier and then seeing if it is followed by
            // a colon.
            var node = createNodeWithJSDoc(0 /* Unknown */);
            var expression = allowInAnd(parseExpression);
            if (expression.kind === 73 /* Identifier */ && parseOptional(57 /* ColonToken */)) {
                node.kind = 234 /* LabeledStatement */;
                node.label = expression;
                node.statement = parseStatement();
            }
            else {
                node.kind = 222 /* ExpressionStatement */;
                node.expression = expression;
                parseSemicolon();
            }
            return finishNode(node);
        }
        function nextTokenIsIdentifierOrKeywordOnSameLine() {
            nextToken();
            return ts.tokenIsIdentifierOrKeyword(token()) && !scanner.hasPrecedingLineBreak();
        }
        function nextTokenIsClassKeywordOnSameLine() {
            nextToken();
            return token() === 77 /* ClassKeyword */ && !scanner.hasPrecedingLineBreak();
        }
        function nextTokenIsFunctionKeywordOnSameLine() {
            nextToken();
            return token() === 91 /* FunctionKeyword */ && !scanner.hasPrecedingLineBreak();
        }
        function nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine() {
            nextToken();
            return (ts.tokenIsIdentifierOrKeyword(token()) || token() === 8 /* NumericLiteral */ || token() === 9 /* BigIntLiteral */ || token() === 10 /* StringLiteral */) && !scanner.hasPrecedingLineBreak();
        }
        function isDeclaration() {
            while (true) {
                switch (token()) {
                    case 106 /* VarKeyword */:
                    case 112 /* LetKeyword */:
                    case 78 /* ConstKeyword */:
                    case 91 /* FunctionKeyword */:
                    case 77 /* ClassKeyword */:
                    case 85 /* EnumKeyword */:
                        return true;
                    // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers;
                    // however, an identifier cannot be followed by another identifier on the same line. This is what we
                    // count on to parse out the respective declarations. For instance, we exploit this to say that
                    //
                    //    namespace n
                    //
                    // can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees
                    //
                    //    namespace
                    //    n
                    //
                    // as the identifier 'namespace' on one line followed by the identifier 'n' on another.
                    // We need to look one token ahead to see if it permissible to try parsing a declaration.
                    //
                    // *Note*: 'interface' is actually a strict mode reserved word. So while
                    //
                    //   "use strict"
                    //   interface
                    //   I {}
                    //
                    // could be legal, it would add complexity for very little gain.
                    case 111 /* InterfaceKeyword */:
                    case 141 /* TypeKeyword */:
                        return nextTokenIsIdentifierOnSameLine();
                    case 131 /* ModuleKeyword */:
                    case 132 /* NamespaceKeyword */:
                        return nextTokenIsIdentifierOrStringLiteralOnSameLine();
                    case 119 /* AbstractKeyword */:
                    case 122 /* AsyncKeyword */:
                    case 126 /* DeclareKeyword */:
                    case 114 /* PrivateKeyword */:
                    case 115 /* ProtectedKeyword */:
                    case 116 /* PublicKeyword */:
                    case 134 /* ReadonlyKeyword */:
                        nextToken();
                        // ASI takes effect for this modifier.
                        if (scanner.hasPrecedingLineBreak()) {
                            return false;
                        }
                        continue;
                    case 146 /* GlobalKeyword */:
                        nextToken();
                        return token() === 18 /* OpenBraceToken */ || token() === 73 /* Identifier */ || token() === 86 /* ExportKeyword */;
                    case 93 /* ImportKeyword */:
                        nextToken();
                        return token() === 10 /* StringLiteral */ || token() === 40 /* AsteriskToken */ ||
                            token() === 18 /* OpenBraceToken */ || ts.tokenIsIdentifierOrKeyword(token());
                    case 86 /* ExportKeyword */:
                        nextToken();
                        if (token() === 60 /* EqualsToken */ || token() === 40 /* AsteriskToken */ ||
                            token() === 18 /* OpenBraceToken */ || token() === 81 /* DefaultKeyword */ ||
                            token() === 120 /* AsKeyword */) {
                            return true;
                        }
                        continue;
                    case 117 /* StaticKeyword */:
                        nextToken();
                        continue;
                    default:
                        return false;
                }
            }
        }
        function isStartOfDeclaration() {
            return lookAhead(isDeclaration);
        }
        function isStartOfStatement() {
            switch (token()) {
                case 58 /* AtToken */:
                case 26 /* SemicolonToken */:
                case 18 /* OpenBraceToken */:
                case 106 /* VarKeyword */:
                case 112 /* LetKeyword */:
                case 91 /* FunctionKeyword */:
                case 77 /* ClassKeyword */:
                case 85 /* EnumKeyword */:
                case 92 /* IfKeyword */:
                case 83 /* DoKeyword */:
                case 108 /* WhileKeyword */:
                case 90 /* ForKeyword */:
                case 79 /* ContinueKeyword */:
                case 74 /* BreakKeyword */:
                case 98 /* ReturnKeyword */:
                case 109 /* WithKeyword */:
                case 100 /* SwitchKeyword */:
                case 102 /* ThrowKeyword */:
                case 104 /* TryKeyword */:
                case 80 /* DebuggerKeyword */:
                // 'catch' and 'finally' do not actually indicate that the code is part of a statement,
                // however, we say they are here so that we may gracefully parse them and error later.
                case 76 /* CatchKeyword */:
                case 89 /* FinallyKeyword */:
                    return true;
                case 93 /* ImportKeyword */:
                    return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThanOrDot);
                case 78 /* ConstKeyword */:
                case 86 /* ExportKeyword */:
                    return isStartOfDeclaration();
                case 122 /* AsyncKeyword */:
                case 126 /* DeclareKeyword */:
                case 111 /* InterfaceKeyword */:
                case 131 /* ModuleKeyword */:
                case 132 /* NamespaceKeyword */:
                case 141 /* TypeKeyword */:
                case 146 /* GlobalKeyword */:
                    // When these don't start a declaration, they're an identifier in an expression statement
                    return true;
                case 116 /* PublicKeyword */:
                case 114 /* PrivateKeyword */:
                case 115 /* ProtectedKeyword */:
                case 117 /* StaticKeyword */:
                case 134 /* ReadonlyKeyword */:
                    // When these don't start a declaration, they may be the start of a class member if an identifier
                    // immediately follows. Otherwise they're an identifier in an expression statement.
                    return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
                default:
                    return isStartOfExpression();
            }
        }
        function nextTokenIsIdentifierOrStartOfDestructuring() {
            nextToken();
            return isIdentifier() || token() === 18 /* OpenBraceToken */ || token() === 22 /* OpenBracketToken */;
        }
        function isLetDeclaration() {
            // In ES6 'let' always starts a lexical declaration if followed by an identifier or {
            // or [.
            return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring);
        }
        function parseStatement() {
            switch (token()) {
                case 26 /* SemicolonToken */:
                    return parseEmptyStatement();
                case 18 /* OpenBraceToken */:
                    return parseBlock(/*ignoreMissingOpenBrace*/ false);
                case 106 /* VarKeyword */:
                    return parseVariableStatement(createNodeWithJSDoc(238 /* VariableDeclaration */));
                case 112 /* LetKeyword */:
                    if (isLetDeclaration()) {
                        return parseVariableStatement(createNodeWithJSDoc(238 /* VariableDeclaration */));
                    }
                    break;
                case 91 /* FunctionKeyword */:
                    return parseFunctionDeclaration(createNodeWithJSDoc(240 /* FunctionDeclaration */));
                case 77 /* ClassKeyword */:
                    return parseClassDeclaration(createNodeWithJSDoc(241 /* ClassDeclaration */));
                case 92 /* IfKeyword */:
                    return parseIfStatement();
                case 83 /* DoKeyword */:
                    return parseDoStatement();
                case 108 /* WhileKeyword */:
                    return parseWhileStatement();
                case 90 /* ForKeyword */:
                    return parseForOrForInOrForOfStatement();
                case 79 /* ContinueKeyword */:
                    return parseBreakOrContinueStatement(229 /* ContinueStatement */);
                case 74 /* BreakKeyword */:
                    return parseBreakOrContinueStatement(230 /* BreakStatement */);
                case 98 /* ReturnKeyword */:
                    return parseReturnStatement();
                case 109 /* WithKeyword */:
                    return parseWithStatement();
                case 100 /* SwitchKeyword */:
                    return parseSwitchStatement();
                case 102 /* ThrowKeyword */:
                    return parseThrowStatement();
                case 104 /* TryKeyword */:
                // Include 'catch' and 'finally' for error recovery.
                case 76 /* CatchKeyword */:
                case 89 /* FinallyKeyword */:
                    return parseTryStatement();
                case 80 /* DebuggerKeyword */:
                    return parseDebuggerStatement();
                case 58 /* AtToken */:
                    return parseDeclaration();
                case 122 /* AsyncKeyword */:
                case 111 /* InterfaceKeyword */:
                case 141 /* TypeKeyword */:
                case 131 /* ModuleKeyword */:
                case 132 /* NamespaceKeyword */:
                case 126 /* DeclareKeyword */:
                case 78 /* ConstKeyword */:
                case 85 /* EnumKeyword */:
                case 86 /* ExportKeyword */:
                case 93 /* ImportKeyword */:
                case 114 /* PrivateKeyword */:
                case 115 /* ProtectedKeyword */:
                case 116 /* PublicKeyword */:
                case 119 /* AbstractKeyword */:
                case 117 /* StaticKeyword */:
                case 134 /* ReadonlyKeyword */:
                case 146 /* GlobalKeyword */:
                    if (isStartOfDeclaration()) {
                        return parseDeclaration();
                    }
                    break;
            }
            return parseExpressionOrLabeledStatement();
        }
        function isDeclareModifier(modifier) {
            return modifier.kind === 126 /* DeclareKeyword */;
        }
        function parseDeclaration() {
            var node = createNodeWithJSDoc(0 /* Unknown */);
            node.decorators = parseDecorators();
            node.modifiers = parseModifiers();
            if (ts.some(node.modifiers, isDeclareModifier)) {
                for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
                    var m = _a[_i];
                    m.flags |= 4194304 /* Ambient */;
                }
                return doInsideOfContext(4194304 /* Ambient */, function () { return parseDeclarationWorker(node); });
            }
            else {
                return parseDeclarationWorker(node);
            }
        }
        function parseDeclarationWorker(node) {
            switch (token()) {
                case 106 /* VarKeyword */:
                case 112 /* LetKeyword */:
                case 78 /* ConstKeyword */:
                    return parseVariableStatement(node);
                case 91 /* FunctionKeyword */:
                    return parseFunctionDeclaration(node);
                case 77 /* ClassKeyword */:
                    return parseClassDeclaration(node);
                case 111 /* InterfaceKeyword */:
                    return parseInterfaceDeclaration(node);
                case 141 /* TypeKeyword */:
                    return parseTypeAliasDeclaration(node);
                case 85 /* EnumKeyword */:
                    return parseEnumDeclaration(node);
                case 146 /* GlobalKeyword */:
                case 131 /* ModuleKeyword */:
                case 132 /* NamespaceKeyword */:
                    return parseModuleDeclaration(node);
                case 93 /* ImportKeyword */:
                    return parseImportDeclarationOrImportEqualsDeclaration(node);
                case 86 /* ExportKeyword */:
                    nextToken();
                    switch (token()) {
                        case 81 /* DefaultKeyword */:
                        case 60 /* EqualsToken */:
                            return parseExportAssignment(node);
                        case 120 /* AsKeyword */:
                            return parseNamespaceExportDeclaration(node);
                        default:
                            return parseExportDeclaration(node);
                    }
                default:
                    if (node.decorators || node.modifiers) {
                        // We reached this point because we encountered decorators and/or modifiers and assumed a declaration
                        // would follow. For recovery and error reporting purposes, return an incomplete declaration.
                        var missing = createMissingNode(259 /* MissingDeclaration */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
                        missing.pos = node.pos;
                        missing.decorators = node.decorators;
                        missing.modifiers = node.modifiers;
                        return finishNode(missing);
                    }
                    return undefined; // TODO: GH#18217
            }
        }
        function nextTokenIsIdentifierOrStringLiteralOnSameLine() {
            nextToken();
            return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token() === 10 /* StringLiteral */);
        }
        function parseFunctionBlockOrSemicolon(flags, diagnosticMessage) {
            if (token() !== 18 /* OpenBraceToken */ && canParseSemicolon()) {
                parseSemicolon();
                return;
            }
            return parseFunctionBlock(flags, diagnosticMessage);
        }
        // DECLARATIONS
        function parseArrayBindingElement() {
            if (token() === 27 /* CommaToken */) {
                return createNode(211 /* OmittedExpression */);
            }
            var node = createNode(187 /* BindingElement */);
            node.dotDotDotToken = parseOptionalToken(25 /* DotDotDotToken */);
            node.name = parseIdentifierOrPattern();
            node.initializer = parseInitializer();
            return finishNode(node);
        }
        function parseObjectBindingElement() {
            var node = createNode(187 /* BindingElement */);
            node.dotDotDotToken = parseOptionalToken(25 /* DotDotDotToken */);
            var tokenIsIdentifier = isIdentifier();
            var propertyName = parsePropertyName();
            if (tokenIsIdentifier && token() !== 57 /* ColonToken */) {
                node.name = propertyName;
            }
            else {
                parseExpected(57 /* ColonToken */);
                node.propertyName = propertyName;
                node.name = parseIdentifierOrPattern();
            }
            node.initializer = parseInitializer();
            return finishNode(node);
        }
        function parseObjectBindingPattern() {
            var node = createNode(185 /* ObjectBindingPattern */);
            parseExpected(18 /* OpenBraceToken */);
            node.elements = parseDelimitedList(9 /* ObjectBindingElements */, parseObjectBindingElement);
            parseExpected(19 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseArrayBindingPattern() {
            var node = createNode(186 /* ArrayBindingPattern */);
            parseExpected(22 /* OpenBracketToken */);
            node.elements = parseDelimitedList(10 /* ArrayBindingElements */, parseArrayBindingElement);
            parseExpected(23 /* CloseBracketToken */);
            return finishNode(node);
        }
        function isIdentifierOrPattern() {
            return token() === 18 /* OpenBraceToken */ || token() === 22 /* OpenBracketToken */ || isIdentifier();
        }
        function parseIdentifierOrPattern() {
            if (token() === 22 /* OpenBracketToken */) {
                return parseArrayBindingPattern();
            }
            if (token() === 18 /* OpenBraceToken */) {
                return parseObjectBindingPattern();
            }
            return parseIdentifier();
        }
        function parseVariableDeclarationAllowExclamation() {
            return parseVariableDeclaration(/*allowExclamation*/ true);
        }
        function parseVariableDeclaration(allowExclamation) {
            var node = createNode(238 /* VariableDeclaration */);
            node.name = parseIdentifierOrPattern();
            if (allowExclamation && node.name.kind === 73 /* Identifier */ &&
                token() === 52 /* ExclamationToken */ && !scanner.hasPrecedingLineBreak()) {
                node.exclamationToken = parseTokenNode();
            }
            node.type = parseTypeAnnotation();
            if (!isInOrOfKeyword(token())) {
                node.initializer = parseInitializer();
            }
            return finishNode(node);
        }
        function parseVariableDeclarationList(inForStatementInitializer) {
            var node = createNode(239 /* VariableDeclarationList */);
            switch (token()) {
                case 106 /* VarKeyword */:
                    break;
                case 112 /* LetKeyword */:
                    node.flags |= 1 /* Let */;
                    break;
                case 78 /* ConstKeyword */:
                    node.flags |= 2 /* Const */;
                    break;
                default:
                    ts.Debug.fail();
            }
            nextToken();
            // The user may have written the following:
            //
            //    for (let of X) { }
            //
            // In this case, we want to parse an empty declaration list, and then parse 'of'
            // as a keyword. The reason this is not automatic is that 'of' is a valid identifier.
            // So we need to look ahead to determine if 'of' should be treated as a keyword in
            // this context.
            // The checker will then give an error that there is an empty declaration list.
            if (token() === 148 /* OfKeyword */ && lookAhead(canFollowContextualOfKeyword)) {
                node.declarations = createMissingList();
            }
            else {
                var savedDisallowIn = inDisallowInContext();
                setDisallowInContext(inForStatementInitializer);
                node.declarations = parseDelimitedList(8 /* VariableDeclarations */, inForStatementInitializer ? parseVariableDeclaration : parseVariableDeclarationAllowExclamation);
                setDisallowInContext(savedDisallowIn);
            }
            return finishNode(node);
        }
        function canFollowContextualOfKeyword() {
            return nextTokenIsIdentifier() && nextToken() === 21 /* CloseParenToken */;
        }
        function parseVariableStatement(node) {
            node.kind = 220 /* VariableStatement */;
            node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false);
            parseSemicolon();
            return finishNode(node);
        }
        function parseFunctionDeclaration(node) {
            node.kind = 240 /* FunctionDeclaration */;
            parseExpected(91 /* FunctionKeyword */);
            node.asteriskToken = parseOptionalToken(40 /* AsteriskToken */);
            node.name = ts.hasModifier(node, 512 /* Default */) ? parseOptionalIdentifier() : parseIdentifier();
            var isGenerator = node.asteriskToken ? 1 /* Yield */ : 0 /* None */;
            var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */;
            fillSignature(57 /* ColonToken */, isGenerator | isAsync, node);
            node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, ts.Diagnostics.or_expected);
            return finishNode(node);
        }
        function parseConstructorDeclaration(node) {
            node.kind = 158 /* Constructor */;
            parseExpected(125 /* ConstructorKeyword */);
            fillSignature(57 /* ColonToken */, 0 /* None */, node);
            node.body = parseFunctionBlockOrSemicolon(0 /* None */, ts.Diagnostics.or_expected);
            return finishNode(node);
        }
        function parseMethodDeclaration(node, asteriskToken, diagnosticMessage) {
            node.kind = 157 /* MethodDeclaration */;
            node.asteriskToken = asteriskToken;
            var isGenerator = asteriskToken ? 1 /* Yield */ : 0 /* None */;
            var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */;
            fillSignature(57 /* ColonToken */, isGenerator | isAsync, node);
            node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, diagnosticMessage);
            return finishNode(node);
        }
        function parsePropertyDeclaration(node) {
            node.kind = 155 /* PropertyDeclaration */;
            if (!node.questionToken && token() === 52 /* ExclamationToken */ && !scanner.hasPrecedingLineBreak()) {
                node.exclamationToken = parseTokenNode();
            }
            node.type = parseTypeAnnotation();
            // For instance properties specifically, since they are evaluated inside the constructor,
            // we do *not * want to parse yield expressions, so we specifically turn the yield context
            // off. The grammar would look something like this:
            //
            //    MemberVariableDeclaration[Yield]:
            //        AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initializer_opt[In];
            //        AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initializer_opt[In, ?Yield];
            //
            // The checker may still error in the static case to explicitly disallow the yield expression.
            node.initializer = ts.hasModifier(node, 32 /* Static */)
                ? allowInAnd(parseInitializer)
                : doOutsideOfContext(4096 /* YieldContext */ | 2048 /* DisallowInContext */, parseInitializer);
            parseSemicolon();
            return finishNode(node);
        }
        function parsePropertyOrMethodDeclaration(node) {
            var asteriskToken = parseOptionalToken(40 /* AsteriskToken */);
            node.name = parsePropertyName();
            // Note: this is not legal as per the grammar.  But we allow it in the parser and
            // report an error in the grammar checker.
            node.questionToken = parseOptionalToken(56 /* QuestionToken */);
            if (asteriskToken || token() === 20 /* OpenParenToken */ || token() === 28 /* LessThanToken */) {
                return parseMethodDeclaration(node, asteriskToken, ts.Diagnostics.or_expected);
            }
            return parsePropertyDeclaration(node);
        }
        function parseAccessorDeclaration(node, kind) {
            node.kind = kind;
            node.name = parsePropertyName();
            fillSignature(57 /* ColonToken */, 0 /* None */, node);
            node.body = parseFunctionBlockOrSemicolon(0 /* None */);
            return finishNode(node);
        }
        function isClassMemberStart() {
            var idToken;
            if (token() === 58 /* AtToken */) {
                return true;
            }
            // Eat up all modifiers, but hold on to the last one in case it is actually an identifier.
            while (ts.isModifierKind(token())) {
                idToken = token();
                // If the idToken is a class modifier (protected, private, public, and static), it is
                // certain that we are starting to parse class member. This allows better error recovery
                // Example:
                //      public foo() ...     // true
                //      public @dec blah ... // true; we will then report an error later
                //      export public ...    // true; we will then report an error later
                if (ts.isClassMemberModifier(idToken)) {
                    return true;
                }
                nextToken();
            }
            if (token() === 40 /* AsteriskToken */) {
                return true;
            }
            // Try to get the first property-like token following all modifiers.
            // This can either be an identifier or the 'get' or 'set' keywords.
            if (isLiteralPropertyName()) {
                idToken = token();
                nextToken();
            }
            // Index signatures and computed properties are class members; we can parse.
            if (token() === 22 /* OpenBracketToken */) {
                return true;
            }
            // If we were able to get any potential identifier...
            if (idToken !== undefined) {
                // If we have a non-keyword identifier, or if we have an accessor, then it's safe to parse.
                if (!ts.isKeyword(idToken) || idToken === 138 /* SetKeyword */ || idToken === 127 /* GetKeyword */) {
                    return true;
                }
                // If it *is* a keyword, but not an accessor, check a little farther along
                // to see if it should actually be parsed as a class member.
                switch (token()) {
                    case 20 /* OpenParenToken */: // Method declaration
                    case 28 /* LessThanToken */: // Generic Method declaration
                    case 52 /* ExclamationToken */: // Non-null assertion on property name
                    case 57 /* ColonToken */: // Type Annotation for declaration
                    case 60 /* EqualsToken */: // Initializer for declaration
                    case 56 /* QuestionToken */: // Not valid, but permitted so that it gets caught later on.
                        return true;
                    default:
                        // Covers
                        //  - Semicolons     (declaration termination)
                        //  - Closing braces (end-of-class, must be declaration)
                        //  - End-of-files   (not valid, but permitted so that it gets caught later on)
                        //  - Line-breaks    (enabling *automatic semicolon insertion*)
                        return canParseSemicolon();
                }
            }
            return false;
        }
        function parseDecorators() {
            var list;
            var listPos = getNodePos();
            while (true) {
                var decoratorStart = getNodePos();
                if (!parseOptional(58 /* AtToken */)) {
                    break;
                }
                var decorator = createNode(153 /* Decorator */, decoratorStart);
                decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
                finishNode(decorator);
                (list || (list = [])).push(decorator);
            }
            return list && createNodeArray(list, listPos);
        }
        /*
         * There are situations in which a modifier like 'const' will appear unexpectedly, such as on a class member.
         * In those situations, if we are entirely sure that 'const' is not valid on its own (such as when ASI takes effect
         * and turns it into a standalone declaration), then it is better to parse it and report an error later.
         *
         * In such situations, 'permitInvalidConstAsModifier' should be set to true.
         */
        function parseModifiers(permitInvalidConstAsModifier) {
            var list;
            var listPos = getNodePos();
            while (true) {
                var modifierStart = scanner.getStartPos();
                var modifierKind = token();
                if (token() === 78 /* ConstKeyword */ && permitInvalidConstAsModifier) {
                    // We need to ensure that any subsequent modifiers appear on the same line
                    // so that when 'const' is a standalone declaration, we don't issue an error.
                    if (!tryParse(nextTokenIsOnSameLineAndCanFollowModifier)) {
                        break;
                    }
                }
                else {
                    if (!parseAnyContextualModifier()) {
                        break;
                    }
                }
                var modifier = finishNode(createNode(modifierKind, modifierStart));
                (list || (list = [])).push(modifier);
            }
            return list && createNodeArray(list, listPos);
        }
        function parseModifiersForArrowFunction() {
            var modifiers;
            if (token() === 122 /* AsyncKeyword */) {
                var modifierStart = scanner.getStartPos();
                var modifierKind = token();
                nextToken();
                var modifier = finishNode(createNode(modifierKind, modifierStart));
                modifiers = createNodeArray([modifier], modifierStart);
            }
            return modifiers;
        }
        function parseClassElement() {
            if (token() === 26 /* SemicolonToken */) {
                var result = createNode(218 /* SemicolonClassElement */);
                nextToken();
                return finishNode(result);
            }
            var node = createNodeWithJSDoc(0 /* Unknown */);
            node.decorators = parseDecorators();
            node.modifiers = parseModifiers(/*permitInvalidConstAsModifier*/ true);
            if (parseContextualModifier(127 /* GetKeyword */)) {
                return parseAccessorDeclaration(node, 159 /* GetAccessor */);
            }
            if (parseContextualModifier(138 /* SetKeyword */)) {
                return parseAccessorDeclaration(node, 160 /* SetAccessor */);
            }
            if (token() === 125 /* ConstructorKeyword */) {
                return parseConstructorDeclaration(node);
            }
            if (isIndexSignature()) {
                return parseIndexSignatureDeclaration(node);
            }
            // It is very important that we check this *after* checking indexers because
            // the [ token can start an index signature or a computed property name
            if (ts.tokenIsIdentifierOrKeyword(token()) ||
                token() === 10 /* StringLiteral */ ||
                token() === 8 /* NumericLiteral */ ||
                token() === 40 /* AsteriskToken */ ||
                token() === 22 /* OpenBracketToken */) {
                return parsePropertyOrMethodDeclaration(node);
            }
            if (node.decorators || node.modifiers) {
                // treat this as a property declaration with a missing name.
                node.name = createMissingNode(73 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
                return parsePropertyDeclaration(node);
            }
            // 'isClassMemberStart' should have hinted not to attempt parsing.
            return ts.Debug.fail("Should not have attempted to parse class member declaration.");
        }
        function parseClassExpression() {
            return parseClassDeclarationOrExpression(createNodeWithJSDoc(0 /* Unknown */), 210 /* ClassExpression */);
        }
        function parseClassDeclaration(node) {
            return parseClassDeclarationOrExpression(node, 241 /* ClassDeclaration */);
        }
        function parseClassDeclarationOrExpression(node, kind) {
            node.kind = kind;
            parseExpected(77 /* ClassKeyword */);
            node.name = parseNameOfClassDeclarationOrExpression();
            node.typeParameters = parseTypeParameters();
            node.heritageClauses = parseHeritageClauses();
            if (parseExpected(18 /* OpenBraceToken */)) {
                // ClassTail[Yield,Await] : (Modified) See 14.5
                //      ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
                node.members = parseClassMembers();
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                node.members = createMissingList();
            }
            return finishNode(node);
        }
        function parseNameOfClassDeclarationOrExpression() {
            // implements is a future reserved word so
            // 'class implements' might mean either
            // - class expression with omitted name, 'implements' starts heritage clause
            // - class with name 'implements'
            // 'isImplementsClause' helps to disambiguate between these two cases
            return isIdentifier() && !isImplementsClause()
                ? parseIdentifier()
                : undefined;
        }
        function isImplementsClause() {
            return token() === 110 /* ImplementsKeyword */ && lookAhead(nextTokenIsIdentifierOrKeyword);
        }
        function parseHeritageClauses() {
            // ClassTail[Yield,Await] : (Modified) See 14.5
            //      ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
            if (isHeritageClause()) {
                return parseList(22 /* HeritageClauses */, parseHeritageClause);
            }
            return undefined;
        }
        function parseHeritageClause() {
            var tok = token();
            ts.Debug.assert(tok === 87 /* ExtendsKeyword */ || tok === 110 /* ImplementsKeyword */); // isListElement() should ensure this.
            var node = createNode(274 /* HeritageClause */);
            node.token = tok;
            nextToken();
            node.types = parseDelimitedList(7 /* HeritageClauseElement */, parseExpressionWithTypeArguments);
            return finishNode(node);
        }
        function parseExpressionWithTypeArguments() {
            var node = createNode(212 /* ExpressionWithTypeArguments */);
            node.expression = parseLeftHandSideExpressionOrHigher();
            node.typeArguments = tryParseTypeArguments();
            return finishNode(node);
        }
        function tryParseTypeArguments() {
            return token() === 28 /* LessThanToken */
                ? parseBracketedList(20 /* TypeArguments */, parseType, 28 /* LessThanToken */, 30 /* GreaterThanToken */)
                : undefined;
        }
        function isHeritageClause() {
            return token() === 87 /* ExtendsKeyword */ || token() === 110 /* ImplementsKeyword */;
        }
        function parseClassMembers() {
            return parseList(5 /* ClassMembers */, parseClassElement);
        }
        function parseInterfaceDeclaration(node) {
            node.kind = 242 /* InterfaceDeclaration */;
            parseExpected(111 /* InterfaceKeyword */);
            node.name = parseIdentifier();
            node.typeParameters = parseTypeParameters();
            node.heritageClauses = parseHeritageClauses();
            node.members = parseObjectTypeMembers();
            return finishNode(node);
        }
        function parseTypeAliasDeclaration(node) {
            node.kind = 243 /* TypeAliasDeclaration */;
            parseExpected(141 /* TypeKeyword */);
            node.name = parseIdentifier();
            node.typeParameters = parseTypeParameters();
            parseExpected(60 /* EqualsToken */);
            node.type = parseType();
            parseSemicolon();
            return finishNode(node);
        }
        // In an ambient declaration, the grammar only allows integer literals as initializers.
        // In a non-ambient declaration, the grammar allows uninitialized members only in a
        // ConstantEnumMemberSection, which starts at the beginning of an enum declaration
        // or any time an integer literal initializer is encountered.
        function parseEnumMember() {
            var node = createNodeWithJSDoc(279 /* EnumMember */);
            node.name = parsePropertyName();
            node.initializer = allowInAnd(parseInitializer);
            return finishNode(node);
        }
        function parseEnumDeclaration(node) {
            node.kind = 244 /* EnumDeclaration */;
            parseExpected(85 /* EnumKeyword */);
            node.name = parseIdentifier();
            if (parseExpected(18 /* OpenBraceToken */)) {
                node.members = parseDelimitedList(6 /* EnumMembers */, parseEnumMember);
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                node.members = createMissingList();
            }
            return finishNode(node);
        }
        function parseModuleBlock() {
            var node = createNode(246 /* ModuleBlock */);
            if (parseExpected(18 /* OpenBraceToken */)) {
                node.statements = parseList(1 /* BlockStatements */, parseStatement);
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                node.statements = createMissingList();
            }
            return finishNode(node);
        }
        function parseModuleOrNamespaceDeclaration(node, flags) {
            node.kind = 245 /* ModuleDeclaration */;
            // If we are parsing a dotted namespace name, we want to
            // propagate the 'Namespace' flag across the names if set.
            var namespaceFlag = flags & 16 /* Namespace */;
            node.flags |= flags;
            node.name = parseIdentifier();
            node.body = parseOptional(24 /* DotToken */)
                ? parseModuleOrNamespaceDeclaration(createNode(0 /* Unknown */), 4 /* NestedNamespace */ | namespaceFlag)
                : parseModuleBlock();
            return finishNode(node);
        }
        function parseAmbientExternalModuleDeclaration(node) {
            node.kind = 245 /* ModuleDeclaration */;
            if (token() === 146 /* GlobalKeyword */) {
                // parse 'global' as name of global scope augmentation
                node.name = parseIdentifier();
                node.flags |= 512 /* GlobalAugmentation */;
            }
            else {
                node.name = parseLiteralNode();
                node.name.text = internIdentifier(node.name.text);
            }
            if (token() === 18 /* OpenBraceToken */) {
                node.body = parseModuleBlock();
            }
            else {
                parseSemicolon();
            }
            return finishNode(node);
        }
        function parseModuleDeclaration(node) {
            var flags = 0;
            if (token() === 146 /* GlobalKeyword */) {
                // global augmentation
                return parseAmbientExternalModuleDeclaration(node);
            }
            else if (parseOptional(132 /* NamespaceKeyword */)) {
                flags |= 16 /* Namespace */;
            }
            else {
                parseExpected(131 /* ModuleKeyword */);
                if (token() === 10 /* StringLiteral */) {
                    return parseAmbientExternalModuleDeclaration(node);
                }
            }
            return parseModuleOrNamespaceDeclaration(node, flags);
        }
        function isExternalModuleReference() {
            return token() === 135 /* RequireKeyword */ &&
                lookAhead(nextTokenIsOpenParen);
        }
        function nextTokenIsOpenParen() {
            return nextToken() === 20 /* OpenParenToken */;
        }
        function nextTokenIsSlash() {
            return nextToken() === 42 /* SlashToken */;
        }
        function parseNamespaceExportDeclaration(node) {
            node.kind = 248 /* NamespaceExportDeclaration */;
            parseExpected(120 /* AsKeyword */);
            parseExpected(132 /* NamespaceKeyword */);
            node.name = parseIdentifier();
            parseSemicolon();
            return finishNode(node);
        }
        function parseImportDeclarationOrImportEqualsDeclaration(node) {
            parseExpected(93 /* ImportKeyword */);
            var afterImportPos = scanner.getStartPos();
            var identifier;
            if (isIdentifier()) {
                identifier = parseIdentifier();
                if (token() !== 27 /* CommaToken */ && token() !== 145 /* FromKeyword */) {
                    return parseImportEqualsDeclaration(node, identifier);
                }
            }
            // Import statement
            node.kind = 250 /* ImportDeclaration */;
            // ImportDeclaration:
            //  import ImportClause from ModuleSpecifier ;
            //  import ModuleSpecifier;
            if (identifier || // import id
                token() === 40 /* AsteriskToken */ || // import *
                token() === 18 /* OpenBraceToken */) { // import {
                node.importClause = parseImportClause(identifier, afterImportPos);
                parseExpected(145 /* FromKeyword */);
            }
            node.moduleSpecifier = parseModuleSpecifier();
            parseSemicolon();
            return finishNode(node);
        }
        function parseImportEqualsDeclaration(node, identifier) {
            node.kind = 249 /* ImportEqualsDeclaration */;
            node.name = identifier;
            parseExpected(60 /* EqualsToken */);
            node.moduleReference = parseModuleReference();
            parseSemicolon();
            return finishNode(node);
        }
        function parseImportClause(identifier, fullStart) {
            // ImportClause:
            //  ImportedDefaultBinding
            //  NameSpaceImport
            //  NamedImports
            //  ImportedDefaultBinding, NameSpaceImport
            //  ImportedDefaultBinding, NamedImports
            var importClause = createNode(251 /* ImportClause */, fullStart);
            if (identifier) {
                // ImportedDefaultBinding:
                //  ImportedBinding
                importClause.name = identifier;
            }
            // If there was no default import or if there is comma token after default import
            // parse namespace or named imports
            if (!importClause.name ||
                parseOptional(27 /* CommaToken */)) {
                importClause.namedBindings = token() === 40 /* AsteriskToken */ ? parseNamespaceImport() : parseNamedImportsOrExports(253 /* NamedImports */);
            }
            return finishNode(importClause);
        }
        function parseModuleReference() {
            return isExternalModuleReference()
                ? parseExternalModuleReference()
                : parseEntityName(/*allowReservedWords*/ false);
        }
        function parseExternalModuleReference() {
            var node = createNode(260 /* ExternalModuleReference */);
            parseExpected(135 /* RequireKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = parseModuleSpecifier();
            parseExpected(21 /* CloseParenToken */);
            return finishNode(node);
        }
        function parseModuleSpecifier() {
            if (token() === 10 /* StringLiteral */) {
                var result = parseLiteralNode();
                result.text = internIdentifier(result.text);
                return result;
            }
            else {
                // We allow arbitrary expressions here, even though the grammar only allows string
                // literals.  We check to ensure that it is only a string literal later in the grammar
                // check pass.
                return parseExpression();
            }
        }
        function parseNamespaceImport() {
            // NameSpaceImport:
            //  * as ImportedBinding
            var namespaceImport = createNode(252 /* NamespaceImport */);
            parseExpected(40 /* AsteriskToken */);
            parseExpected(120 /* AsKeyword */);
            namespaceImport.name = parseIdentifier();
            return finishNode(namespaceImport);
        }
        function parseNamedImportsOrExports(kind) {
            var node = createNode(kind);
            // NamedImports:
            //  { }
            //  { ImportsList }
            //  { ImportsList, }
            // ImportsList:
            //  ImportSpecifier
            //  ImportsList, ImportSpecifier
            node.elements = parseBracketedList(23 /* ImportOrExportSpecifiers */, kind === 253 /* NamedImports */ ? parseImportSpecifier : parseExportSpecifier, 18 /* OpenBraceToken */, 19 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseExportSpecifier() {
            return parseImportOrExportSpecifier(258 /* ExportSpecifier */);
        }
        function parseImportSpecifier() {
            return parseImportOrExportSpecifier(254 /* ImportSpecifier */);
        }
        function parseImportOrExportSpecifier(kind) {
            var node = createNode(kind);
            // ImportSpecifier:
            //   BindingIdentifier
            //   IdentifierName as BindingIdentifier
            // ExportSpecifier:
            //   IdentifierName
            //   IdentifierName as IdentifierName
            var checkIdentifierIsKeyword = ts.isKeyword(token()) && !isIdentifier();
            var checkIdentifierStart = scanner.getTokenPos();
            var checkIdentifierEnd = scanner.getTextPos();
            var identifierName = parseIdentifierName();
            if (token() === 120 /* AsKeyword */) {
                node.propertyName = identifierName;
                parseExpected(120 /* AsKeyword */);
                checkIdentifierIsKeyword = ts.isKeyword(token()) && !isIdentifier();
                checkIdentifierStart = scanner.getTokenPos();
                checkIdentifierEnd = scanner.getTextPos();
                node.name = parseIdentifierName();
            }
            else {
                node.name = identifierName;
            }
            if (kind === 254 /* ImportSpecifier */ && checkIdentifierIsKeyword) {
                parseErrorAt(checkIdentifierStart, checkIdentifierEnd, ts.Diagnostics.Identifier_expected);
            }
            return finishNode(node);
        }
        function parseExportDeclaration(node) {
            node.kind = 256 /* ExportDeclaration */;
            if (parseOptional(40 /* AsteriskToken */)) {
                parseExpected(145 /* FromKeyword */);
                node.moduleSpecifier = parseModuleSpecifier();
            }
            else {
                node.exportClause = parseNamedImportsOrExports(257 /* NamedExports */);
                // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios,
                // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`)
                // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect.
                if (token() === 145 /* FromKeyword */ || (token() === 10 /* StringLiteral */ && !scanner.hasPrecedingLineBreak())) {
                    parseExpected(145 /* FromKeyword */);
                    node.moduleSpecifier = parseModuleSpecifier();
                }
            }
            parseSemicolon();
            return finishNode(node);
        }
        function parseExportAssignment(node) {
            node.kind = 255 /* ExportAssignment */;
            if (parseOptional(60 /* EqualsToken */)) {
                node.isExportEquals = true;
            }
            else {
                parseExpected(81 /* DefaultKeyword */);
            }
            node.expression = parseAssignmentExpressionOrHigher();
            parseSemicolon();
            return finishNode(node);
        }
        function setExternalModuleIndicator(sourceFile) {
            // Try to use the first top-level import/export when available, then
            // fall back to looking for an 'import.meta' somewhere in the tree if necessary.
            sourceFile.externalModuleIndicator =
                ts.forEach(sourceFile.statements, isAnExternalModuleIndicatorNode) ||
                    getImportMetaIfNecessary(sourceFile);
        }
        function isAnExternalModuleIndicatorNode(node) {
            return ts.hasModifier(node, 1 /* Export */)
                || node.kind === 249 /* ImportEqualsDeclaration */ && node.moduleReference.kind === 260 /* ExternalModuleReference */
                || node.kind === 250 /* ImportDeclaration */
                || node.kind === 255 /* ExportAssignment */
                || node.kind === 256 /* ExportDeclaration */
                ? node
                : undefined;
        }
        function getImportMetaIfNecessary(sourceFile) {
            return sourceFile.flags & 1048576 /* PossiblyContainsImportMeta */ ?
                walkTreeForExternalModuleIndicators(sourceFile) :
                undefined;
        }
        function walkTreeForExternalModuleIndicators(node) {
            return isImportMeta(node) ? node : forEachChild(node, walkTreeForExternalModuleIndicators);
        }
        function isImportMeta(node) {
            return ts.isMetaProperty(node) && node.keywordToken === 93 /* ImportKeyword */ && node.name.escapedText === "meta";
        }
        var ParsingContext;
        (function (ParsingContext) {
            ParsingContext[ParsingContext["SourceElements"] = 0] = "SourceElements";
            ParsingContext[ParsingContext["BlockStatements"] = 1] = "BlockStatements";
            ParsingContext[ParsingContext["SwitchClauses"] = 2] = "SwitchClauses";
            ParsingContext[ParsingContext["SwitchClauseStatements"] = 3] = "SwitchClauseStatements";
            ParsingContext[ParsingContext["TypeMembers"] = 4] = "TypeMembers";
            ParsingContext[ParsingContext["ClassMembers"] = 5] = "ClassMembers";
            ParsingContext[ParsingContext["EnumMembers"] = 6] = "EnumMembers";
            ParsingContext[ParsingContext["HeritageClauseElement"] = 7] = "HeritageClauseElement";
            ParsingContext[ParsingContext["VariableDeclarations"] = 8] = "VariableDeclarations";
            ParsingContext[ParsingContext["ObjectBindingElements"] = 9] = "ObjectBindingElements";
            ParsingContext[ParsingContext["ArrayBindingElements"] = 10] = "ArrayBindingElements";
            ParsingContext[ParsingContext["ArgumentExpressions"] = 11] = "ArgumentExpressions";
            ParsingContext[ParsingContext["ObjectLiteralMembers"] = 12] = "ObjectLiteralMembers";
            ParsingContext[ParsingContext["JsxAttributes"] = 13] = "JsxAttributes";
            ParsingContext[ParsingContext["JsxChildren"] = 14] = "JsxChildren";
            ParsingContext[ParsingContext["ArrayLiteralMembers"] = 15] = "ArrayLiteralMembers";
            ParsingContext[ParsingContext["Parameters"] = 16] = "Parameters";
            ParsingContext[ParsingContext["JSDocParameters"] = 17] = "JSDocParameters";
            ParsingContext[ParsingContext["RestProperties"] = 18] = "RestProperties";
            ParsingContext[ParsingContext["TypeParameters"] = 19] = "TypeParameters";
            ParsingContext[ParsingContext["TypeArguments"] = 20] = "TypeArguments";
            ParsingContext[ParsingContext["TupleElementTypes"] = 21] = "TupleElementTypes";
            ParsingContext[ParsingContext["HeritageClauses"] = 22] = "HeritageClauses";
            ParsingContext[ParsingContext["ImportOrExportSpecifiers"] = 23] = "ImportOrExportSpecifiers";
            ParsingContext[ParsingContext["Count"] = 24] = "Count"; // Number of parsing contexts
        })(ParsingContext || (ParsingContext = {}));
        var Tristate;
        (function (Tristate) {
            Tristate[Tristate["False"] = 0] = "False";
            Tristate[Tristate["True"] = 1] = "True";
            Tristate[Tristate["Unknown"] = 2] = "Unknown";
        })(Tristate || (Tristate = {}));
        var JSDocParser;
        (function (JSDocParser) {
            function parseJSDocTypeExpressionForTests(content, start, length) {
                initializeState(content, 8 /* Latest */, /*_syntaxCursor:*/ undefined, 1 /* JS */);
                sourceFile = createSourceFile("file.js", 8 /* Latest */, 1 /* JS */, /*isDeclarationFile*/ false);
                scanner.setText(content, start, length);
                currentToken = scanner.scan();
                var jsDocTypeExpression = parseJSDocTypeExpression();
                var diagnostics = parseDiagnostics;
                clearState();
                return jsDocTypeExpression ? { jsDocTypeExpression: jsDocTypeExpression, diagnostics: diagnostics } : undefined;
            }
            JSDocParser.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests;
            // Parses out a JSDoc type expression.
            function parseJSDocTypeExpression(mayOmitBraces) {
                var result = createNode(289 /* JSDocTypeExpression */);
                var hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(18 /* OpenBraceToken */);
                result.type = doInsideOfContext(2097152 /* JSDoc */, parseJSDocType);
                if (!mayOmitBraces || hasBrace) {
                    parseExpectedJSDoc(19 /* CloseBraceToken */);
                }
                fixupParentReferences(result);
                return finishNode(result);
            }
            JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression;
            function parseIsolatedJSDocComment(content, start, length) {
                initializeState(content, 8 /* Latest */, /*_syntaxCursor:*/ undefined, 1 /* JS */);
                sourceFile = { languageVariant: 0 /* Standard */, text: content }; // tslint:disable-line no-object-literal-type-assertion
                var jsDoc = parseJSDocCommentWorker(start, length);
                var diagnostics = parseDiagnostics;
                clearState();
                return jsDoc ? { jsDoc: jsDoc, diagnostics: diagnostics } : undefined;
            }
            JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
            function parseJSDocComment(parent, start, length) {
                var _a;
                var saveToken = currentToken;
                var saveParseDiagnosticsLength = parseDiagnostics.length;
                var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
                var comment = parseJSDocCommentWorker(start, length);
                if (comment) {
                    comment.parent = parent;
                }
                if (contextFlags & 65536 /* JavaScriptFile */) {
                    if (!sourceFile.jsDocDiagnostics) {
                        sourceFile.jsDocDiagnostics = [];
                    }
                    (_a = sourceFile.jsDocDiagnostics).push.apply(_a, parseDiagnostics);
                }
                currentToken = saveToken;
                parseDiagnostics.length = saveParseDiagnosticsLength;
                parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode;
                return comment;
            }
            JSDocParser.parseJSDocComment = parseJSDocComment;
            var JSDocState;
            (function (JSDocState) {
                JSDocState[JSDocState["BeginningOfLine"] = 0] = "BeginningOfLine";
                JSDocState[JSDocState["SawAsterisk"] = 1] = "SawAsterisk";
                JSDocState[JSDocState["SavingComments"] = 2] = "SavingComments";
            })(JSDocState || (JSDocState = {}));
            var PropertyLikeParse;
            (function (PropertyLikeParse) {
                PropertyLikeParse[PropertyLikeParse["Property"] = 1] = "Property";
                PropertyLikeParse[PropertyLikeParse["Parameter"] = 2] = "Parameter";
                PropertyLikeParse[PropertyLikeParse["CallbackParameter"] = 4] = "CallbackParameter";
            })(PropertyLikeParse || (PropertyLikeParse = {}));
            function parseJSDocCommentWorker(start, length) {
                if (start === void 0) { start = 0; }
                var content = sourceText;
                var end = length === undefined ? content.length : start + length;
                length = end - start;
                ts.Debug.assert(start >= 0);
                ts.Debug.assert(start <= end);
                ts.Debug.assert(end <= content.length);
                // Check for /** (JSDoc opening part)
                if (!isJSDocLikeText(content, start)) {
                    return undefined;
                }
                var tags;
                var tagsPos;
                var tagsEnd;
                var comments = [];
                // + 3 for leading /**, - 5 in total for /** */
                return scanner.scanRange(start + 3, length - 5, function () {
                    // Initially we can parse out a tag.  We also have seen a starting asterisk.
                    // This is so that /** * @type */ doesn't parse.
                    var state = 1 /* SawAsterisk */;
                    var margin;
                    // + 4 for leading '/** '
                    var indent = start - Math.max(content.lastIndexOf("\n", start), 0) + 4;
                    function pushComment(text) {
                        if (!margin) {
                            margin = indent;
                        }
                        comments.push(text);
                        indent += text.length;
                    }
                    nextTokenJSDoc();
                    while (parseOptionalJsdoc(5 /* WhitespaceTrivia */))
                        ;
                    if (parseOptionalJsdoc(4 /* NewLineTrivia */)) {
                        state = 0 /* BeginningOfLine */;
                        indent = 0;
                    }
                    loop: while (true) {
                        switch (token()) {
                            case 58 /* AtToken */:
                                if (state === 0 /* BeginningOfLine */ || state === 1 /* SawAsterisk */) {
                                    removeTrailingWhitespace(comments);
                                    addTag(parseTag(indent));
                                    // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag.
                                    // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning
                                    // for malformed examples like `/** @param {string} x @returns {number} the length */`
                                    state = 0 /* BeginningOfLine */;
                                    margin = undefined;
                                }
                                else {
                                    pushComment(scanner.getTokenText());
                                }
                                break;
                            case 4 /* NewLineTrivia */:
                                comments.push(scanner.getTokenText());
                                state = 0 /* BeginningOfLine */;
                                indent = 0;
                                break;
                            case 40 /* AsteriskToken */:
                                var asterisk = scanner.getTokenText();
                                if (state === 1 /* SawAsterisk */ || state === 2 /* SavingComments */) {
                                    // If we've already seen an asterisk, then we can no longer parse a tag on this line
                                    state = 2 /* SavingComments */;
                                    pushComment(asterisk);
                                }
                                else {
                                    // Ignore the first asterisk on a line
                                    state = 1 /* SawAsterisk */;
                                    indent += asterisk.length;
                                }
                                break;
                            case 5 /* WhitespaceTrivia */:
                                // only collect whitespace if we're already saving comments or have just crossed the comment indent margin
                                var whitespace = scanner.getTokenText();
                                if (state === 2 /* SavingComments */) {
                                    comments.push(whitespace);
                                }
                                else if (margin !== undefined && indent + whitespace.length > margin) {
                                    comments.push(whitespace.slice(margin - indent - 1));
                                }
                                indent += whitespace.length;
                                break;
                            case 1 /* EndOfFileToken */:
                                break loop;
                            default:
                                // Anything else is doc comment text. We just save it. Because it
                                // wasn't a tag, we can no longer parse a tag on this line until we hit the next
                                // line break.
                                state = 2 /* SavingComments */;
                                pushComment(scanner.getTokenText());
                                break;
                        }
                        nextTokenJSDoc();
                    }
                    removeLeadingNewlines(comments);
                    removeTrailingWhitespace(comments);
                    return createJSDocComment();
                });
                function removeLeadingNewlines(comments) {
                    while (comments.length && (comments[0] === "\n" || comments[0] === "\r")) {
                        comments.shift();
                    }
                }
                function removeTrailingWhitespace(comments) {
                    while (comments.length && comments[comments.length - 1].trim() === "") {
                        comments.pop();
                    }
                }
                function createJSDocComment() {
                    var result = createNode(297 /* JSDocComment */, start);
                    result.tags = tags && createNodeArray(tags, tagsPos, tagsEnd);
                    result.comment = comments.length ? comments.join("") : undefined;
                    return finishNode(result, end);
                }
                function isNextNonwhitespaceTokenEndOfFile() {
                    // We must use infinite lookahead, as there could be any number of newlines :(
                    while (true) {
                        nextTokenJSDoc();
                        if (token() === 1 /* EndOfFileToken */) {
                            return true;
                        }
                        if (!(token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */)) {
                            return false;
                        }
                    }
                }
                function skipWhitespace() {
                    if (token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */) {
                        if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) {
                            return; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
                        }
                    }
                    while (token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */) {
                        nextTokenJSDoc();
                    }
                }
                function skipWhitespaceOrAsterisk() {
                    if (token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */) {
                        if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) {
                            return ""; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
                        }
                    }
                    var precedingLineBreak = scanner.hasPrecedingLineBreak();
                    var seenLineBreak = false;
                    var indentText = "";
                    while ((precedingLineBreak && token() === 40 /* AsteriskToken */) || token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */) {
                        indentText += scanner.getTokenText();
                        if (token() === 4 /* NewLineTrivia */) {
                            precedingLineBreak = true;
                            seenLineBreak = true;
                            indentText = "";
                        }
                        else if (token() === 40 /* AsteriskToken */) {
                            precedingLineBreak = false;
                        }
                        nextTokenJSDoc();
                    }
                    return seenLineBreak ? indentText : "";
                }
                function parseTag(margin) {
                    ts.Debug.assert(token() === 58 /* AtToken */);
                    var start = scanner.getTokenPos();
                    nextTokenJSDoc();
                    var tagName = parseJSDocIdentifierName(/*message*/ undefined);
                    var indentText = skipWhitespaceOrAsterisk();
                    var tag;
                    switch (tagName.escapedText) {
                        case "augments":
                        case "extends":
                            tag = parseAugmentsTag(start, tagName);
                            break;
                        case "class":
                        case "constructor":
                            tag = parseClassTag(start, tagName);
                            break;
                        case "this":
                            tag = parseThisTag(start, tagName);
                            break;
                        case "enum":
                            tag = parseEnumTag(start, tagName);
                            break;
                        case "arg":
                        case "argument":
                        case "param":
                            return parseParameterOrPropertyTag(start, tagName, 2 /* Parameter */, margin);
                        case "return":
                        case "returns":
                            tag = parseReturnTag(start, tagName);
                            break;
                        case "template":
                            tag = parseTemplateTag(start, tagName);
                            break;
                        case "type":
                            tag = parseTypeTag(start, tagName);
                            break;
                        case "typedef":
                            tag = parseTypedefTag(start, tagName, margin);
                            break;
                        case "callback":
                            tag = parseCallbackTag(start, tagName, margin);
                            break;
                        default:
                            tag = parseUnknownTag(start, tagName);
                            break;
                    }
                    if (!tag.comment) {
                        // some tags, like typedef and callback, have already parsed their comments earlier
                        if (!indentText) {
                            margin += tag.end - tag.pos;
                        }
                        tag.comment = parseTagComments(margin, indentText.slice(margin));
                    }
                    return tag;
                }
                function parseTagComments(indent, initialMargin) {
                    var comments = [];
                    var state = 0 /* BeginningOfLine */;
                    var margin;
                    function pushComment(text) {
                        if (!margin) {
                            margin = indent;
                        }
                        comments.push(text);
                        indent += text.length;
                    }
                    if (initialMargin) {
                        // jump straight to saving comments if there is some initial indentation
                        pushComment(initialMargin);
                        state = 2 /* SavingComments */;
                    }
                    var tok = token();
                    loop: while (true) {
                        switch (tok) {
                            case 4 /* NewLineTrivia */:
                                if (state >= 1 /* SawAsterisk */) {
                                    state = 0 /* BeginningOfLine */;
                                    comments.push(scanner.getTokenText());
                                }
                                indent = 0;
                                break;
                            case 58 /* AtToken */:
                                scanner.setTextPos(scanner.getTextPos() - 1);
                            // falls through
                            case 1 /* EndOfFileToken */:
                                // Done
                                break loop;
                            case 5 /* WhitespaceTrivia */:
                                if (state === 2 /* SavingComments */) {
                                    pushComment(scanner.getTokenText());
                                }
                                else {
                                    var whitespace = scanner.getTokenText();
                                    // if the whitespace crosses the margin, take only the whitespace that passes the margin
                                    if (margin !== undefined && indent + whitespace.length > margin) {
                                        comments.push(whitespace.slice(margin - indent));
                                    }
                                    indent += whitespace.length;
                                }
                                break;
                            case 18 /* OpenBraceToken */:
                                state = 2 /* SavingComments */;
                                if (lookAhead(function () { return nextTokenJSDoc() === 58 /* AtToken */ && ts.tokenIsIdentifierOrKeyword(nextTokenJSDoc()) && scanner.getTokenText() === "link"; })) {
                                    pushComment(scanner.getTokenText());
                                    nextTokenJSDoc();
                                    pushComment(scanner.getTokenText());
                                    nextTokenJSDoc();
                                }
                                pushComment(scanner.getTokenText());
                                break;
                            case 40 /* AsteriskToken */:
                                if (state === 0 /* BeginningOfLine */) {
                                    // leading asterisks start recording on the *next* (non-whitespace) token
                                    state = 1 /* SawAsterisk */;
                                    indent += 1;
                                    break;
                                }
                            // record the * as a comment
                            // falls through
                            default:
                                state = 2 /* SavingComments */; // leading identifiers start recording as well
                                pushComment(scanner.getTokenText());
                                break;
                        }
                        tok = nextTokenJSDoc();
                    }
                    removeLeadingNewlines(comments);
                    removeTrailingWhitespace(comments);
                    return comments.length === 0 ? undefined : comments.join("");
                }
                function parseUnknownTag(start, tagName) {
                    var result = createNode(300 /* JSDocTag */, start);
                    result.tagName = tagName;
                    return finishNode(result);
                }
                function addTag(tag) {
                    if (!tag) {
                        return;
                    }
                    if (!tags) {
                        tags = [tag];
                        tagsPos = tag.pos;
                    }
                    else {
                        tags.push(tag);
                    }
                    tagsEnd = tag.end;
                }
                function tryParseTypeExpression() {
                    skipWhitespaceOrAsterisk();
                    return token() === 18 /* OpenBraceToken */ ? parseJSDocTypeExpression() : undefined;
                }
                function parseBracketNameInPropertyAndParamTag() {
                    // Looking for something like '[foo]', 'foo', '[foo.bar]' or 'foo.bar'
                    var isBracketed = parseOptionalJsdoc(22 /* OpenBracketToken */);
                    if (isBracketed) {
                        skipWhitespace();
                    }
                    // a markdown-quoted name: `arg` is not legal jsdoc, but occurs in the wild
                    var isBackquoted = parseOptionalJsdoc(59 /* BacktickToken */);
                    var name = parseJSDocEntityName();
                    if (isBackquoted) {
                        parseExpectedTokenJSDoc(59 /* BacktickToken */);
                    }
                    if (isBracketed) {
                        skipWhitespace();
                        // May have an optional default, e.g. '[foo = 42]'
                        if (parseOptionalToken(60 /* EqualsToken */)) {
                            parseExpression();
                        }
                        parseExpected(23 /* CloseBracketToken */);
                    }
                    return { name: name, isBracketed: isBracketed };
                }
                function isObjectOrObjectArrayTypeReference(node) {
                    switch (node.kind) {
                        case 137 /* ObjectKeyword */:
                            return true;
                        case 170 /* ArrayType */:
                            return isObjectOrObjectArrayTypeReference(node.elementType);
                        default:
                            return ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.escapedText === "Object";
                    }
                }
                function parseParameterOrPropertyTag(start, tagName, target, indent) {
                    var typeExpression = tryParseTypeExpression();
                    var isNameFirst = !typeExpression;
                    skipWhitespaceOrAsterisk();
                    var _a = parseBracketNameInPropertyAndParamTag(), name = _a.name, isBracketed = _a.isBracketed;
                    skipWhitespace();
                    if (isNameFirst) {
                        typeExpression = tryParseTypeExpression();
                    }
                    var result = target === 1 /* Property */ ?
                        createNode(311 /* JSDocPropertyTag */, start) :
                        createNode(305 /* JSDocParameterTag */, start);
                    var comment = parseTagComments(indent + scanner.getStartPos() - start);
                    var nestedTypeLiteral = target !== 4 /* CallbackParameter */ && parseNestedTypeLiteral(typeExpression, name, target, indent);
                    if (nestedTypeLiteral) {
                        typeExpression = nestedTypeLiteral;
                        isNameFirst = true;
                    }
                    result.tagName = tagName;
                    result.typeExpression = typeExpression;
                    result.name = name;
                    result.isNameFirst = isNameFirst;
                    result.isBracketed = isBracketed;
                    result.comment = comment;
                    return finishNode(result);
                }
                function parseNestedTypeLiteral(typeExpression, name, target, indent) {
                    if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) {
                        var typeLiteralExpression = createNode(289 /* JSDocTypeExpression */, scanner.getTokenPos());
                        var child = void 0;
                        var jsdocTypeLiteral = void 0;
                        var start_2 = scanner.getStartPos();
                        var children = void 0;
                        while (child = tryParse(function () { return parseChildParameterOrPropertyTag(target, indent, name); })) {
                            if (child.kind === 305 /* JSDocParameterTag */ || child.kind === 311 /* JSDocPropertyTag */) {
                                children = ts.append(children, child);
                            }
                        }
                        if (children) {
                            jsdocTypeLiteral = createNode(298 /* JSDocTypeLiteral */, start_2);
                            jsdocTypeLiteral.jsDocPropertyTags = children;
                            if (typeExpression.type.kind === 170 /* ArrayType */) {
                                jsdocTypeLiteral.isArrayType = true;
                            }
                            typeLiteralExpression.type = finishNode(jsdocTypeLiteral);
                            return finishNode(typeLiteralExpression);
                        }
                    }
                }
                function parseReturnTag(start, tagName) {
                    if (ts.some(tags, ts.isJSDocReturnTag)) {
                        parseErrorAt(tagName.pos, scanner.getTokenPos(), ts.Diagnostics._0_tag_already_specified, tagName.escapedText);
                    }
                    var result = createNode(306 /* JSDocReturnTag */, start);
                    result.tagName = tagName;
                    result.typeExpression = tryParseTypeExpression();
                    return finishNode(result);
                }
                function parseTypeTag(start, tagName) {
                    if (ts.some(tags, ts.isJSDocTypeTag)) {
                        parseErrorAt(tagName.pos, scanner.getTokenPos(), ts.Diagnostics._0_tag_already_specified, tagName.escapedText);
                    }
                    var result = createNode(308 /* JSDocTypeTag */, start);
                    result.tagName = tagName;
                    result.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
                    return finishNode(result);
                }
                function parseAugmentsTag(start, tagName) {
                    var result = createNode(301 /* JSDocAugmentsTag */, start);
                    result.tagName = tagName;
                    result.class = parseExpressionWithTypeArgumentsForAugments();
                    return finishNode(result);
                }
                function parseExpressionWithTypeArgumentsForAugments() {
                    var usedBrace = parseOptional(18 /* OpenBraceToken */);
                    var node = createNode(212 /* ExpressionWithTypeArguments */);
                    node.expression = parsePropertyAccessEntityNameExpression();
                    node.typeArguments = tryParseTypeArguments();
                    var res = finishNode(node);
                    if (usedBrace) {
                        parseExpected(19 /* CloseBraceToken */);
                    }
                    return res;
                }
                function parsePropertyAccessEntityNameExpression() {
                    var node = parseJSDocIdentifierName();
                    while (parseOptional(24 /* DotToken */)) {
                        var prop = createNode(190 /* PropertyAccessExpression */, node.pos);
                        prop.expression = node;
                        prop.name = parseJSDocIdentifierName();
                        node = finishNode(prop);
                    }
                    return node;
                }
                function parseClassTag(start, tagName) {
                    var tag = createNode(302 /* JSDocClassTag */, start);
                    tag.tagName = tagName;
                    return finishNode(tag);
                }
                function parseThisTag(start, tagName) {
                    var tag = createNode(307 /* JSDocThisTag */, start);
                    tag.tagName = tagName;
                    tag.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
                    skipWhitespace();
                    return finishNode(tag);
                }
                function parseEnumTag(start, tagName) {
                    var tag = createNode(304 /* JSDocEnumTag */, start);
                    tag.tagName = tagName;
                    tag.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
                    skipWhitespace();
                    return finishNode(tag);
                }
                function parseTypedefTag(start, tagName, indent) {
                    var typeExpression = tryParseTypeExpression();
                    skipWhitespaceOrAsterisk();
                    var typedefTag = createNode(310 /* JSDocTypedefTag */, start);
                    typedefTag.tagName = tagName;
                    typedefTag.fullName = parseJSDocTypeNameWithNamespace();
                    typedefTag.name = getJSDocTypeAliasName(typedefTag.fullName);
                    skipWhitespace();
                    typedefTag.comment = parseTagComments(indent);
                    typedefTag.typeExpression = typeExpression;
                    var end;
                    if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) {
                        var child = void 0;
                        var jsdocTypeLiteral = void 0;
                        var childTypeTag = void 0;
                        while (child = tryParse(function () { return parseChildPropertyTag(indent); })) {
                            if (!jsdocTypeLiteral) {
                                jsdocTypeLiteral = createNode(298 /* JSDocTypeLiteral */, start);
                            }
                            if (child.kind === 308 /* JSDocTypeTag */) {
                                if (childTypeTag) {
                                    break;
                                }
                                else {
                                    childTypeTag = child;
                                }
                            }
                            else {
                                jsdocTypeLiteral.jsDocPropertyTags = ts.append(jsdocTypeLiteral.jsDocPropertyTags, child);
                            }
                        }
                        if (jsdocTypeLiteral) {
                            if (typeExpression && typeExpression.type.kind === 170 /* ArrayType */) {
                                jsdocTypeLiteral.isArrayType = true;
                            }
                            typedefTag.typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ?
                                childTypeTag.typeExpression :
                                finishNode(jsdocTypeLiteral);
                            end = typedefTag.typeExpression.end;
                        }
                    }
                    // Only include the characters between the name end and the next token if a comment was actually parsed out - otherwise it's just whitespace
                    return finishNode(typedefTag, end || typedefTag.comment !== undefined ? scanner.getStartPos() : (typedefTag.fullName || typedefTag.typeExpression || typedefTag.tagName).end);
                }
                function parseJSDocTypeNameWithNamespace(nested) {
                    var pos = scanner.getTokenPos();
                    if (!ts.tokenIsIdentifierOrKeyword(token())) {
                        return undefined;
                    }
                    var typeNameOrNamespaceName = parseJSDocIdentifierName();
                    if (parseOptional(24 /* DotToken */)) {
                        var jsDocNamespaceNode = createNode(245 /* ModuleDeclaration */, pos);
                        if (nested) {
                            jsDocNamespaceNode.flags |= 4 /* NestedNamespace */;
                        }
                        jsDocNamespaceNode.name = typeNameOrNamespaceName;
                        jsDocNamespaceNode.body = parseJSDocTypeNameWithNamespace(/*nested*/ true);
                        return finishNode(jsDocNamespaceNode);
                    }
                    if (nested) {
                        typeNameOrNamespaceName.isInJSDocNamespace = true;
                    }
                    return typeNameOrNamespaceName;
                }
                function parseCallbackTag(start, tagName, indent) {
                    var callbackTag = createNode(303 /* JSDocCallbackTag */, start);
                    callbackTag.tagName = tagName;
                    callbackTag.fullName = parseJSDocTypeNameWithNamespace();
                    callbackTag.name = getJSDocTypeAliasName(callbackTag.fullName);
                    skipWhitespace();
                    callbackTag.comment = parseTagComments(indent);
                    var child;
                    var jsdocSignature = createNode(299 /* JSDocSignature */, start);
                    jsdocSignature.parameters = [];
                    while (child = tryParse(function () { return parseChildParameterOrPropertyTag(4 /* CallbackParameter */, indent); })) {
                        jsdocSignature.parameters = ts.append(jsdocSignature.parameters, child);
                    }
                    var returnTag = tryParse(function () {
                        if (parseOptionalJsdoc(58 /* AtToken */)) {
                            var tag = parseTag(indent);
                            if (tag && tag.kind === 306 /* JSDocReturnTag */) {
                                return tag;
                            }
                        }
                    });
                    if (returnTag) {
                        jsdocSignature.type = returnTag;
                    }
                    callbackTag.typeExpression = finishNode(jsdocSignature);
                    return finishNode(callbackTag);
                }
                function getJSDocTypeAliasName(fullName) {
                    if (fullName) {
                        var rightNode = fullName;
                        while (true) {
                            if (ts.isIdentifier(rightNode) || !rightNode.body) {
                                return ts.isIdentifier(rightNode) ? rightNode : rightNode.name;
                            }
                            rightNode = rightNode.body;
                        }
                    }
                }
                function escapedTextsEqual(a, b) {
                    while (!ts.isIdentifier(a) || !ts.isIdentifier(b)) {
                        if (!ts.isIdentifier(a) && !ts.isIdentifier(b) && a.right.escapedText === b.right.escapedText) {
                            a = a.left;
                            b = b.left;
                        }
                        else {
                            return false;
                        }
                    }
                    return a.escapedText === b.escapedText;
                }
                function parseChildPropertyTag(indent) {
                    return parseChildParameterOrPropertyTag(1 /* Property */, indent);
                }
                function parseChildParameterOrPropertyTag(target, indent, name) {
                    var canParseTag = true;
                    var seenAsterisk = false;
                    while (true) {
                        switch (nextTokenJSDoc()) {
                            case 58 /* AtToken */:
                                if (canParseTag) {
                                    var child = tryParseChildTag(target, indent);
                                    if (child && (child.kind === 305 /* JSDocParameterTag */ || child.kind === 311 /* JSDocPropertyTag */) &&
                                        target !== 4 /* CallbackParameter */ &&
                                        name && (ts.isIdentifier(child.name) || !escapedTextsEqual(name, child.name.left))) {
                                        return false;
                                    }
                                    return child;
                                }
                                seenAsterisk = false;
                                break;
                            case 4 /* NewLineTrivia */:
                                canParseTag = true;
                                seenAsterisk = false;
                                break;
                            case 40 /* AsteriskToken */:
                                if (seenAsterisk) {
                                    canParseTag = false;
                                }
                                seenAsterisk = true;
                                break;
                            case 73 /* Identifier */:
                                canParseTag = false;
                                break;
                            case 1 /* EndOfFileToken */:
                                return false;
                        }
                    }
                }
                function tryParseChildTag(target, indent) {
                    ts.Debug.assert(token() === 58 /* AtToken */);
                    var start = scanner.getStartPos();
                    nextTokenJSDoc();
                    var tagName = parseJSDocIdentifierName();
                    skipWhitespace();
                    var t;
                    switch (tagName.escapedText) {
                        case "type":
                            return target === 1 /* Property */ && parseTypeTag(start, tagName);
                        case "prop":
                        case "property":
                            t = 1 /* Property */;
                            break;
                        case "arg":
                        case "argument":
                        case "param":
                            t = 2 /* Parameter */ | 4 /* CallbackParameter */;
                            break;
                        default:
                            return false;
                    }
                    if (!(target & t)) {
                        return false;
                    }
                    return parseParameterOrPropertyTag(start, tagName, target, indent);
                }
                function parseTemplateTag(start, tagName) {
                    // the template tag looks like '@template {Constraint} T,U,V'
                    var constraint;
                    if (token() === 18 /* OpenBraceToken */) {
                        constraint = parseJSDocTypeExpression();
                    }
                    var typeParameters = [];
                    var typeParametersPos = getNodePos();
                    do {
                        skipWhitespace();
                        var typeParameter = createNode(151 /* TypeParameter */);
                        typeParameter.name = parseJSDocIdentifierName(ts.Diagnostics.Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces);
                        finishNode(typeParameter);
                        skipWhitespace();
                        typeParameters.push(typeParameter);
                    } while (parseOptionalJsdoc(27 /* CommaToken */));
                    var result = createNode(309 /* JSDocTemplateTag */, start);
                    result.tagName = tagName;
                    result.constraint = constraint;
                    result.typeParameters = createNodeArray(typeParameters, typeParametersPos);
                    finishNode(result);
                    return result;
                }
                function parseOptionalJsdoc(t) {
                    if (token() === t) {
                        nextTokenJSDoc();
                        return true;
                    }
                    return false;
                }
                function parseJSDocEntityName() {
                    var entity = parseJSDocIdentifierName();
                    if (parseOptional(22 /* OpenBracketToken */)) {
                        parseExpected(23 /* CloseBracketToken */);
                        // Note that y[] is accepted as an entity name, but the postfix brackets are not saved for checking.
                        // Technically usejsdoc.org requires them for specifying a property of a type equivalent to Array<{ x: ...}>
                        // but it's not worth it to enforce that restriction.
                    }
                    while (parseOptional(24 /* DotToken */)) {
                        var name = parseJSDocIdentifierName();
                        if (parseOptional(22 /* OpenBracketToken */)) {
                            parseExpected(23 /* CloseBracketToken */);
                        }
                        entity = createQualifiedName(entity, name);
                    }
                    return entity;
                }
                function parseJSDocIdentifierName(message) {
                    if (!ts.tokenIsIdentifierOrKeyword(token())) {
                        return createMissingNode(73 /* Identifier */, /*reportAtCurrentPosition*/ !message, message || ts.Diagnostics.Identifier_expected);
                    }
                    var pos = scanner.getTokenPos();
                    var end = scanner.getTextPos();
                    var result = createNode(73 /* Identifier */, pos);
                    result.escapedText = ts.escapeLeadingUnderscores(scanner.getTokenText());
                    finishNode(result, end);
                    nextTokenJSDoc();
                    return result;
                }
            }
            JSDocParser.parseJSDocCommentWorker = parseJSDocCommentWorker;
        })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {}));
    })(Parser || (Parser = {}));
    var IncrementalParser;
    (function (IncrementalParser) {
        function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
            aggressiveChecks = aggressiveChecks || ts.Debug.shouldAssert(2 /* Aggressive */);
            checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks);
            if (ts.textChangeRangeIsUnchanged(textChangeRange)) {
                // if the text didn't change, then we can just return our current source file as-is.
                return sourceFile;
            }
            if (sourceFile.statements.length === 0) {
                // If we don't have any statements in the current source file, then there's no real
                // way to incrementally parse.  So just do a full parse instead.
                return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setParentNodes*/ true, sourceFile.scriptKind);
            }
            // Make sure we're not trying to incrementally update a source file more than once.  Once
            // we do an update the original source file is considered unusable from that point onwards.
            //
            // This is because we do incremental parsing in-place.  i.e. we take nodes from the old
            // tree and give them new positions and parents.  From that point on, trusting the old
            // tree at all is not possible as far too much of it may violate invariants.
            var incrementalSourceFile = sourceFile;
            ts.Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed);
            incrementalSourceFile.hasBeenIncrementallyParsed = true;
            var oldText = sourceFile.text;
            var syntaxCursor = createSyntaxCursor(sourceFile);
            // Make the actual change larger so that we know to reparse anything whose lookahead
            // might have intersected the change.
            var changeRange = extendToAffectedRange(sourceFile, textChangeRange);
            checkChangeRange(sourceFile, newText, changeRange, aggressiveChecks);
            // Ensure that extending the affected range only moved the start of the change range
            // earlier in the file.
            ts.Debug.assert(changeRange.span.start <= textChangeRange.span.start);
            ts.Debug.assert(ts.textSpanEnd(changeRange.span) === ts.textSpanEnd(textChangeRange.span));
            ts.Debug.assert(ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)) === ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)));
            // The is the amount the nodes after the edit range need to be adjusted.  It can be
            // positive (if the edit added characters), negative (if the edit deleted characters)
            // or zero (if this was a pure overwrite with nothing added/removed).
            var delta = ts.textChangeRangeNewSpan(changeRange).length - changeRange.span.length;
            // If we added or removed characters during the edit, then we need to go and adjust all
            // the nodes after the edit.  Those nodes may move forward (if we inserted chars) or they
            // may move backward (if we deleted chars).
            //
            // Doing this helps us out in two ways.  First, it means that any nodes/tokens we want
            // to reuse are already at the appropriate position in the new text.  That way when we
            // reuse them, we don't have to figure out if they need to be adjusted.  Second, it makes
            // it very easy to determine if we can reuse a node.  If the node's position is at where
            // we are in the text, then we can reuse it.  Otherwise we can't.  If the node's position
            // is ahead of us, then we'll need to rescan tokens.  If the node's position is behind
            // us, then we'll need to skip it or crumble it as appropriate
            //
            // We will also adjust the positions of nodes that intersect the change range as well.
            // By doing this, we ensure that all the positions in the old tree are consistent, not
            // just the positions of nodes entirely before/after the change range.  By being
            // consistent, we can then easily map from positions to nodes in the old tree easily.
            //
            // Also, mark any syntax elements that intersect the changed span.  We know, up front,
            // that we cannot reuse these elements.
            updateTokenPositionsAndMarkElements(incrementalSourceFile, changeRange.span.start, ts.textSpanEnd(changeRange.span), ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks);
            // Now that we've set up our internal incremental state just proceed and parse the
            // source file in the normal fashion.  When possible the parser will retrieve and
            // reuse nodes from the old tree.
            //
            // Note: passing in 'true' for setNodeParents is very important.  When incrementally
            // parsing, we will be reusing nodes from the old tree, and placing it into new
            // parents.  If we don't set the parents now, we'll end up with an observably
            // inconsistent tree.  Setting the parents on the new tree should be very fast.  We
            // will immediately bail out of walking any subtrees when we can see that their parents
            // are already correct.
            var result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /*setParentNodes*/ true, sourceFile.scriptKind);
            return result;
        }
        IncrementalParser.updateSourceFile = updateSourceFile;
        function moveElementEntirelyPastChangeRange(element, isArray, delta, oldText, newText, aggressiveChecks) {
            if (isArray) {
                visitArray(element);
            }
            else {
                visitNode(element);
            }
            return;
            function visitNode(node) {
                var text = "";
                if (aggressiveChecks && shouldCheckNode(node)) {
                    text = oldText.substring(node.pos, node.end);
                }
                // Ditch any existing LS children we may have created.  This way we can avoid
                // moving them forward.
                if (node._children) {
                    node._children = undefined;
                }
                node.pos += delta;
                node.end += delta;
                if (aggressiveChecks && shouldCheckNode(node)) {
                    ts.Debug.assert(text === newText.substring(node.pos, node.end));
                }
                forEachChild(node, visitNode, visitArray);
                if (ts.hasJSDocNodes(node)) {
                    for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                        var jsDocComment = _a[_i];
                        visitNode(jsDocComment);
                    }
                }
                checkNodePositions(node, aggressiveChecks);
            }
            function visitArray(array) {
                array._children = undefined;
                array.pos += delta;
                array.end += delta;
                for (var _i = 0, array_8 = array; _i < array_8.length; _i++) {
                    var node = array_8[_i];
                    visitNode(node);
                }
            }
        }
        function shouldCheckNode(node) {
            switch (node.kind) {
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 73 /* Identifier */:
                    return true;
            }
            return false;
        }
        function adjustIntersectingElement(element, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta) {
            ts.Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range");
            ts.Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range");
            ts.Debug.assert(element.pos <= element.end);
            // We have an element that intersects the change range in some way.  It may have its
            // start, or its end (or both) in the changed range.  We want to adjust any part
            // that intersects such that the final tree is in a consistent state.  i.e. all
            // children have spans within the span of their parent, and all siblings are ordered
            // properly.
            // We may need to update both the 'pos' and the 'end' of the element.
            // If the 'pos' is before the start of the change, then we don't need to touch it.
            // If it isn't, then the 'pos' must be inside the change.  How we update it will
            // depend if delta is positive or negative. If delta is positive then we have
            // something like:
            //
            //  -------------------AAA-----------------
            //  -------------------BBBCCCCCCC-----------------
            //
            // In this case, we consider any node that started in the change range to still be
            // starting at the same position.
            //
            // however, if the delta is negative, then we instead have something like this:
            //
            //  -------------------XXXYYYYYYY-----------------
            //  -------------------ZZZ-----------------
            //
            // In this case, any element that started in the 'X' range will keep its position.
            // However any element that started after that will have their pos adjusted to be
            // at the end of the new range.  i.e. any node that started in the 'Y' range will
            // be adjusted to have their start at the end of the 'Z' range.
            //
            // The element will keep its position if possible.  Or Move backward to the new-end
            // if it's in the 'Y' range.
            element.pos = Math.min(element.pos, changeRangeNewEnd);
            // If the 'end' is after the change range, then we always adjust it by the delta
            // amount.  However, if the end is in the change range, then how we adjust it
            // will depend on if delta is positive or negative.  If delta is positive then we
            // have something like:
            //
            //  -------------------AAA-----------------
            //  -------------------BBBCCCCCCC-----------------
            //
            // In this case, we consider any node that ended inside the change range to keep its
            // end position.
            //
            // however, if the delta is negative, then we instead have something like this:
            //
            //  -------------------XXXYYYYYYY-----------------
            //  -------------------ZZZ-----------------
            //
            // In this case, any element that ended in the 'X' range will keep its position.
            // However any element that ended after that will have their pos adjusted to be
            // at the end of the new range.  i.e. any node that ended in the 'Y' range will
            // be adjusted to have their end at the end of the 'Z' range.
            if (element.end >= changeRangeOldEnd) {
                // Element ends after the change range.  Always adjust the end pos.
                element.end += delta;
            }
            else {
                // Element ends in the change range.  The element will keep its position if
                // possible. Or Move backward to the new-end if it's in the 'Y' range.
                element.end = Math.min(element.end, changeRangeNewEnd);
            }
            ts.Debug.assert(element.pos <= element.end);
            if (element.parent) {
                ts.Debug.assert(element.pos >= element.parent.pos);
                ts.Debug.assert(element.end <= element.parent.end);
            }
        }
        function checkNodePositions(node, aggressiveChecks) {
            if (aggressiveChecks) {
                var pos_2 = node.pos;
                var visitNode_1 = function (child) {
                    ts.Debug.assert(child.pos >= pos_2);
                    pos_2 = child.end;
                };
                if (ts.hasJSDocNodes(node)) {
                    for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                        var jsDocComment = _a[_i];
                        visitNode_1(jsDocComment);
                    }
                }
                forEachChild(node, visitNode_1);
                ts.Debug.assert(pos_2 <= node.end);
            }
        }
        function updateTokenPositionsAndMarkElements(sourceFile, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta, oldText, newText, aggressiveChecks) {
            visitNode(sourceFile);
            return;
            function visitNode(child) {
                ts.Debug.assert(child.pos <= child.end);
                if (child.pos > changeRangeOldEnd) {
                    // Node is entirely past the change range.  We need to move both its pos and
                    // end, forward or backward appropriately.
                    moveElementEntirelyPastChangeRange(child, /*isArray*/ false, delta, oldText, newText, aggressiveChecks);
                    return;
                }
                // Check if the element intersects the change range.  If it does, then it is not
                // reusable.  Also, we'll need to recurse to see what constituent portions we may
                // be able to use.
                var fullEnd = child.end;
                if (fullEnd >= changeStart) {
                    child.intersectsChange = true;
                    child._children = undefined;
                    // Adjust the pos or end (or both) of the intersecting element accordingly.
                    adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
                    forEachChild(child, visitNode, visitArray);
                    if (ts.hasJSDocNodes(child)) {
                        for (var _i = 0, _a = child.jsDoc; _i < _a.length; _i++) {
                            var jsDocComment = _a[_i];
                            visitNode(jsDocComment);
                        }
                    }
                    checkNodePositions(child, aggressiveChecks);
                    return;
                }
                // Otherwise, the node is entirely before the change range.  No need to do anything with it.
                ts.Debug.assert(fullEnd < changeStart);
            }
            function visitArray(array) {
                ts.Debug.assert(array.pos <= array.end);
                if (array.pos > changeRangeOldEnd) {
                    // Array is entirely after the change range.  We need to move it, and move any of
                    // its children.
                    moveElementEntirelyPastChangeRange(array, /*isArray*/ true, delta, oldText, newText, aggressiveChecks);
                    return;
                }
                // Check if the element intersects the change range.  If it does, then it is not
                // reusable.  Also, we'll need to recurse to see what constituent portions we may
                // be able to use.
                var fullEnd = array.end;
                if (fullEnd >= changeStart) {
                    array.intersectsChange = true;
                    array._children = undefined;
                    // Adjust the pos or end (or both) of the intersecting array accordingly.
                    adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
                    for (var _i = 0, array_9 = array; _i < array_9.length; _i++) {
                        var node = array_9[_i];
                        visitNode(node);
                    }
                    return;
                }
                // Otherwise, the array is entirely before the change range.  No need to do anything with it.
                ts.Debug.assert(fullEnd < changeStart);
            }
        }
        function extendToAffectedRange(sourceFile, changeRange) {
            // Consider the following code:
            //      void foo() { /; }
            //
            // If the text changes with an insertion of / just before the semicolon then we end up with:
            //      void foo() { //; }
            //
            // If we were to just use the changeRange a is, then we would not rescan the { token
            // (as it does not intersect the actual original change range).  Because an edit may
            // change the token touching it, we actually need to look back *at least* one token so
            // that the prior token sees that change.
            var maxLookahead = 1;
            var start = changeRange.span.start;
            // the first iteration aligns us with the change start. subsequent iteration move us to
            // the left by maxLookahead tokens.  We only need to do this as long as we're not at the
            // start of the tree.
            for (var i = 0; start > 0 && i <= maxLookahead; i++) {
                var nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start);
                ts.Debug.assert(nearestNode.pos <= start);
                var position = nearestNode.pos;
                start = Math.max(0, position - 1);
            }
            var finalSpan = ts.createTextSpanFromBounds(start, ts.textSpanEnd(changeRange.span));
            var finalLength = changeRange.newLength + (changeRange.span.start - start);
            return ts.createTextChangeRange(finalSpan, finalLength);
        }
        function findNearestNodeStartingBeforeOrAtPosition(sourceFile, position) {
            var bestResult = sourceFile;
            var lastNodeEntirelyBeforePosition;
            forEachChild(sourceFile, visit);
            if (lastNodeEntirelyBeforePosition) {
                var lastChildOfLastEntireNodeBeforePosition = getLastDescendant(lastNodeEntirelyBeforePosition);
                if (lastChildOfLastEntireNodeBeforePosition.pos > bestResult.pos) {
                    bestResult = lastChildOfLastEntireNodeBeforePosition;
                }
            }
            return bestResult;
            function getLastDescendant(node) {
                while (true) {
                    var lastChild = ts.getLastChild(node);
                    if (lastChild) {
                        node = lastChild;
                    }
                    else {
                        return node;
                    }
                }
            }
            function visit(child) {
                if (ts.nodeIsMissing(child)) {
                    // Missing nodes are effectively invisible to us.  We never even consider them
                    // When trying to find the nearest node before us.
                    return;
                }
                // If the child intersects this position, then this node is currently the nearest
                // node that starts before the position.
                if (child.pos <= position) {
                    if (child.pos >= bestResult.pos) {
                        // This node starts before the position, and is closer to the position than
                        // the previous best node we found.  It is now the new best node.
                        bestResult = child;
                    }
                    // Now, the node may overlap the position, or it may end entirely before the
                    // position.  If it overlaps with the position, then either it, or one of its
                    // children must be the nearest node before the position.  So we can just
                    // recurse into this child to see if we can find something better.
                    if (position < child.end) {
                        // The nearest node is either this child, or one of the children inside
                        // of it.  We've already marked this child as the best so far.  Recurse
                        // in case one of the children is better.
                        forEachChild(child, visit);
                        // Once we look at the children of this node, then there's no need to
                        // continue any further.
                        return true;
                    }
                    else {
                        ts.Debug.assert(child.end <= position);
                        // The child ends entirely before this position.  Say you have the following
                        // (where $ is the position)
                        //
                        //      <complex expr 1> ? <complex expr 2> $ : <...> <...>
                        //
                        // We would want to find the nearest preceding node in "complex expr 2".
                        // To support that, we keep track of this node, and once we're done searching
                        // for a best node, we recurse down this node to see if we can find a good
                        // result in it.
                        //
                        // This approach allows us to quickly skip over nodes that are entirely
                        // before the position, while still allowing us to find any nodes in the
                        // last one that might be what we want.
                        lastNodeEntirelyBeforePosition = child;
                    }
                }
                else {
                    ts.Debug.assert(child.pos > position);
                    // We're now at a node that is entirely past the position we're searching for.
                    // This node (and all following nodes) could never contribute to the result,
                    // so just skip them by returning 'true' here.
                    return true;
                }
            }
        }
        function checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks) {
            var oldText = sourceFile.text;
            if (textChangeRange) {
                ts.Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length);
                if (aggressiveChecks || ts.Debug.shouldAssert(3 /* VeryAggressive */)) {
                    var oldTextPrefix = oldText.substr(0, textChangeRange.span.start);
                    var newTextPrefix = newText.substr(0, textChangeRange.span.start);
                    ts.Debug.assert(oldTextPrefix === newTextPrefix);
                    var oldTextSuffix = oldText.substring(ts.textSpanEnd(textChangeRange.span), oldText.length);
                    var newTextSuffix = newText.substring(ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)), newText.length);
                    ts.Debug.assert(oldTextSuffix === newTextSuffix);
                }
            }
        }
        function createSyntaxCursor(sourceFile) {
            var currentArray = sourceFile.statements;
            var currentArrayIndex = 0;
            ts.Debug.assert(currentArrayIndex < currentArray.length);
            var current = currentArray[currentArrayIndex];
            var lastQueriedPosition = -1 /* Value */;
            return {
                currentNode: function (position) {
                    // Only compute the current node if the position is different than the last time
                    // we were asked.  The parser commonly asks for the node at the same position
                    // twice.  Once to know if can read an appropriate list element at a certain point,
                    // and then to actually read and consume the node.
                    if (position !== lastQueriedPosition) {
                        // Much of the time the parser will need the very next node in the array that
                        // we just returned a node from.So just simply check for that case and move
                        // forward in the array instead of searching for the node again.
                        if (current && current.end === position && currentArrayIndex < (currentArray.length - 1)) {
                            currentArrayIndex++;
                            current = currentArray[currentArrayIndex];
                        }
                        // If we don't have a node, or the node we have isn't in the right position,
                        // then try to find a viable node at the position requested.
                        if (!current || current.pos !== position) {
                            findHighestListElementThatStartsAtPosition(position);
                        }
                    }
                    // Cache this query so that we don't do any extra work if the parser calls back
                    // into us.  Note: this is very common as the parser will make pairs of calls like
                    // 'isListElement -> parseListElement'.  If we were unable to find a node when
                    // called with 'isListElement', we don't want to redo the work when parseListElement
                    // is called immediately after.
                    lastQueriedPosition = position;
                    // Either we don'd have a node, or we have a node at the position being asked for.
                    ts.Debug.assert(!current || current.pos === position);
                    return current;
                }
            };
            // Finds the highest element in the tree we can find that starts at the provided position.
            // The element must be a direct child of some node list in the tree.  This way after we
            // return it, we can easily return its next sibling in the list.
            function findHighestListElementThatStartsAtPosition(position) {
                // Clear out any cached state about the last node we found.
                currentArray = undefined;
                currentArrayIndex = -1 /* Value */;
                current = undefined;
                // Recurse into the source file to find the highest node at this position.
                forEachChild(sourceFile, visitNode, visitArray);
                return;
                function visitNode(node) {
                    if (position >= node.pos && position < node.end) {
                        // Position was within this node.  Keep searching deeper to find the node.
                        forEachChild(node, visitNode, visitArray);
                        // don't proceed any further in the search.
                        return true;
                    }
                    // position wasn't in this node, have to keep searching.
                    return false;
                }
                function visitArray(array) {
                    if (position >= array.pos && position < array.end) {
                        // position was in this array.  Search through this array to see if we find a
                        // viable element.
                        for (var i = 0; i < array.length; i++) {
                            var child = array[i];
                            if (child) {
                                if (child.pos === position) {
                                    // Found the right node.  We're done.
                                    currentArray = array;
                                    currentArrayIndex = i;
                                    current = child;
                                    return true;
                                }
                                else {
                                    if (child.pos < position && position < child.end) {
                                        // Position in somewhere within this child.  Search in it and
                                        // stop searching in this array.
                                        forEachChild(child, visitNode, visitArray);
                                        return true;
                                    }
                                }
                            }
                        }
                    }
                    // position wasn't in this array, have to keep searching.
                    return false;
                }
            }
        }
        var InvalidPosition;
        (function (InvalidPosition) {
            InvalidPosition[InvalidPosition["Value"] = -1] = "Value";
        })(InvalidPosition || (InvalidPosition = {}));
    })(IncrementalParser || (IncrementalParser = {}));
    /** @internal */
    function isDeclarationFileName(fileName) {
        return ts.fileExtensionIs(fileName, ".d.ts" /* Dts */);
    }
    ts.isDeclarationFileName = isDeclarationFileName;
    /*@internal*/
    function processCommentPragmas(context, sourceText) {
        var pragmas = [];
        for (var _i = 0, _a = ts.getLeadingCommentRanges(sourceText, 0) || ts.emptyArray; _i < _a.length; _i++) {
            var range = _a[_i];
            var comment = sourceText.substring(range.pos, range.end);
            extractPragmas(pragmas, range, comment);
        }
        context.pragmas = ts.createMap();
        for (var _b = 0, pragmas_1 = pragmas; _b < pragmas_1.length; _b++) {
            var pragma = pragmas_1[_b];
            if (context.pragmas.has(pragma.name)) {
                var currentValue = context.pragmas.get(pragma.name);
                if (currentValue instanceof Array) {
                    currentValue.push(pragma.args);
                }
                else {
                    context.pragmas.set(pragma.name, [currentValue, pragma.args]);
                }
                continue;
            }
            context.pragmas.set(pragma.name, pragma.args);
        }
    }
    ts.processCommentPragmas = processCommentPragmas;
    /*@internal*/
    function processPragmasIntoFields(context, reportDiagnostic) {
        context.checkJsDirective = undefined;
        context.referencedFiles = [];
        context.typeReferenceDirectives = [];
        context.libReferenceDirectives = [];
        context.amdDependencies = [];
        context.hasNoDefaultLib = false;
        context.pragmas.forEach(function (entryOrList, key) {
            // TODO: The below should be strongly type-guarded and not need casts/explicit annotations, since entryOrList is related to
            // key and key is constrained to a union; but it's not (see GH#21483 for at least partial fix) :(
            switch (key) {
                case "reference": {
                    var referencedFiles_1 = context.referencedFiles;
                    var typeReferenceDirectives_1 = context.typeReferenceDirectives;
                    var libReferenceDirectives_1 = context.libReferenceDirectives;
                    ts.forEach(ts.toArray(entryOrList), function (arg) {
                        var _a = arg.arguments, types = _a.types, lib = _a.lib, path = _a.path;
                        if (arg.arguments["no-default-lib"]) {
                            context.hasNoDefaultLib = true;
                        }
                        else if (types) {
                            typeReferenceDirectives_1.push({ pos: types.pos, end: types.end, fileName: types.value });
                        }
                        else if (lib) {
                            libReferenceDirectives_1.push({ pos: lib.pos, end: lib.end, fileName: lib.value });
                        }
                        else if (path) {
                            referencedFiles_1.push({ pos: path.pos, end: path.end, fileName: path.value });
                        }
                        else {
                            reportDiagnostic(arg.range.pos, arg.range.end - arg.range.pos, ts.Diagnostics.Invalid_reference_directive_syntax);
                        }
                    });
                    break;
                }
                case "amd-dependency": {
                    context.amdDependencies = ts.map(ts.toArray(entryOrList), function (x) { return ({ name: x.arguments.name, path: x.arguments.path }); });
                    break;
                }
                case "amd-module": {
                    if (entryOrList instanceof Array) {
                        for (var _i = 0, entryOrList_1 = entryOrList; _i < entryOrList_1.length; _i++) {
                            var entry = entryOrList_1[_i];
                            if (context.moduleName) {
                                // TODO: It's probably fine to issue this diagnostic on all instances of the pragma
                                reportDiagnostic(entry.range.pos, entry.range.end - entry.range.pos, ts.Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments);
                            }
                            context.moduleName = entry.arguments.name;
                        }
                    }
                    else {
                        context.moduleName = entryOrList.arguments.name;
                    }
                    break;
                }
                case "ts-nocheck":
                case "ts-check": {
                    // _last_ of either nocheck or check in a file is the "winner"
                    ts.forEach(ts.toArray(entryOrList), function (entry) {
                        if (!context.checkJsDirective || entry.range.pos > context.checkJsDirective.pos) {
                            context.checkJsDirective = {
                                enabled: key === "ts-check",
                                end: entry.range.end,
                                pos: entry.range.pos
                            };
                        }
                    });
                    break;
                }
                case "jsx": return; // Accessed directly
                default: ts.Debug.fail("Unhandled pragma kind"); // Can this be made into an assertNever in the future?
            }
        });
    }
    ts.processPragmasIntoFields = processPragmasIntoFields;
    var namedArgRegExCache = ts.createMap();
    function getNamedArgRegEx(name) {
        if (namedArgRegExCache.has(name)) {
            return namedArgRegExCache.get(name);
        }
        var result = new RegExp("(\\s" + name + "\\s*=\\s*)('|\")(.+?)\\2", "im");
        namedArgRegExCache.set(name, result);
        return result;
    }
    var tripleSlashXMLCommentStartRegEx = /^\/\/\/\s*<(\S+)\s.*?\/>/im;
    var singleLinePragmaRegEx = /^\/\/\/?\s*@(\S+)\s*(.*)\s*$/im;
    function extractPragmas(pragmas, range, text) {
        var tripleSlash = range.kind === 2 /* SingleLineCommentTrivia */ && tripleSlashXMLCommentStartRegEx.exec(text);
        if (tripleSlash) {
            var name = tripleSlash[1].toLowerCase(); // Technically unsafe cast, but we do it so the below check to make it safe typechecks
            var pragma = ts.commentPragmas[name];
            if (!pragma || !(pragma.kind & 1 /* TripleSlashXML */)) {
                return;
            }
            if (pragma.args) {
                var argument = {};
                for (var _i = 0, _a = pragma.args; _i < _a.length; _i++) {
                    var arg = _a[_i];
                    var matcher = getNamedArgRegEx(arg.name);
                    var matchResult = matcher.exec(text);
                    if (!matchResult && !arg.optional) {
                        return; // Missing required argument, don't parse
                    }
                    else if (matchResult) {
                        if (arg.captureSpan) {
                            var startPos = range.pos + matchResult.index + matchResult[1].length + matchResult[2].length;
                            argument[arg.name] = {
                                value: matchResult[3],
                                pos: startPos,
                                end: startPos + matchResult[3].length
                            };
                        }
                        else {
                            argument[arg.name] = matchResult[3];
                        }
                    }
                }
                pragmas.push({ name: name, args: { arguments: argument, range: range } });
            }
            else {
                pragmas.push({ name: name, args: { arguments: {}, range: range } });
            }
            return;
        }
        var singleLine = range.kind === 2 /* SingleLineCommentTrivia */ && singleLinePragmaRegEx.exec(text);
        if (singleLine) {
            return addPragmaForMatch(pragmas, range, 2 /* SingleLine */, singleLine);
        }
        if (range.kind === 3 /* MultiLineCommentTrivia */) {
            var multiLinePragmaRegEx = /\s*@(\S+)\s*(.*)\s*$/gim; // Defined inline since it uses the "g" flag, which keeps a persistent index (for iterating)
            var multiLineMatch = void 0;
            while (multiLineMatch = multiLinePragmaRegEx.exec(text)) {
                addPragmaForMatch(pragmas, range, 4 /* MultiLine */, multiLineMatch);
            }
        }
    }
    function addPragmaForMatch(pragmas, range, kind, match) {
        if (!match)
            return;
        var name = match[1].toLowerCase(); // Technically unsafe cast, but we do it so they below check to make it safe typechecks
        var pragma = ts.commentPragmas[name];
        if (!pragma || !(pragma.kind & kind)) {
            return;
        }
        var args = match[2]; // Split on spaces and match up positionally with definition
        var argument = getNamedPragmaArguments(pragma, args);
        if (argument === "fail")
            return; // Missing required argument, fail to parse it
        pragmas.push({ name: name, args: { arguments: argument, range: range } });
        return;
    }
    function getNamedPragmaArguments(pragma, text) {
        if (!text)
            return {};
        if (!pragma.args)
            return {};
        var args = text.split(/\s+/);
        var argMap = {};
        for (var i = 0; i < pragma.args.length; i++) {
            var argument = pragma.args[i];
            if (!args[i] && !argument.optional) {
                return "fail";
            }
            if (argument.captureSpan) {
                return ts.Debug.fail("Capture spans not yet implemented for non-xml pragmas");
            }
            argMap[argument.name] = args[i];
        }
        return argMap;
    }
    /** @internal */
    function tagNamesAreEquivalent(lhs, rhs) {
        if (lhs.kind !== rhs.kind) {
            return false;
        }
        if (lhs.kind === 73 /* Identifier */) {
            return lhs.escapedText === rhs.escapedText;
        }
        if (lhs.kind === 101 /* ThisKeyword */) {
            return true;
        }
        // If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only
        // take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression
        // it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element
        return lhs.name.escapedText === rhs.name.escapedText &&
            tagNamesAreEquivalent(lhs.expression, rhs.expression);
    }
    ts.tagNamesAreEquivalent = tagNamesAreEquivalent;
})(ts || (ts = {}));
var ts;
(function (ts) {
    /* @internal */
    ts.compileOnSaveCommandLineOption = { name: "compileOnSave", type: "boolean" };
    // NOTE: The order here is important to default lib ordering as entries will have the same
    //       order in the generated program (see `getDefaultLibPriority` in program.ts). This
    //       order also affects overload resolution when a type declared in one lib is
    //       augmented in another lib.
    var libEntries = [
        // JavaScript only
        ["es5", "lib.es5.d.ts"],
        ["es6", "lib.es2015.d.ts"],
        ["es2015", "lib.es2015.d.ts"],
        ["es7", "lib.es2016.d.ts"],
        ["es2016", "lib.es2016.d.ts"],
        ["es2017", "lib.es2017.d.ts"],
        ["es2018", "lib.es2018.d.ts"],
        ["es2019", "lib.es2019.d.ts"],
        ["es2020", "lib.es2020.d.ts"],
        ["esnext", "lib.esnext.d.ts"],
        // Host only
        ["dom", "lib.dom.d.ts"],
        ["dom.iterable", "lib.dom.iterable.d.ts"],
        ["webworker", "lib.webworker.d.ts"],
        ["webworker.importscripts", "lib.webworker.importscripts.d.ts"],
        ["scripthost", "lib.scripthost.d.ts"],
        // ES2015 Or ESNext By-feature options
        ["es2015.core", "lib.es2015.core.d.ts"],
        ["es2015.collection", "lib.es2015.collection.d.ts"],
        ["es2015.generator", "lib.es2015.generator.d.ts"],
        ["es2015.iterable", "lib.es2015.iterable.d.ts"],
        ["es2015.promise", "lib.es2015.promise.d.ts"],
        ["es2015.proxy", "lib.es2015.proxy.d.ts"],
        ["es2015.reflect", "lib.es2015.reflect.d.ts"],
        ["es2015.symbol", "lib.es2015.symbol.d.ts"],
        ["es2015.symbol.wellknown", "lib.es2015.symbol.wellknown.d.ts"],
        ["es2016.array.include", "lib.es2016.array.include.d.ts"],
        ["es2017.object", "lib.es2017.object.d.ts"],
        ["es2017.sharedmemory", "lib.es2017.sharedmemory.d.ts"],
        ["es2017.string", "lib.es2017.string.d.ts"],
        ["es2017.intl", "lib.es2017.intl.d.ts"],
        ["es2017.typedarrays", "lib.es2017.typedarrays.d.ts"],
        ["es2018.asynciterable", "lib.es2018.asynciterable.d.ts"],
        ["es2018.intl", "lib.es2018.intl.d.ts"],
        ["es2018.promise", "lib.es2018.promise.d.ts"],
        ["es2018.regexp", "lib.es2018.regexp.d.ts"],
        ["es2019.array", "lib.es2019.array.d.ts"],
        ["es2019.object", "lib.es2019.object.d.ts"],
        ["es2019.string", "lib.es2019.string.d.ts"],
        ["es2019.symbol", "lib.es2019.symbol.d.ts"],
        ["es2020.string", "lib.es2020.string.d.ts"],
        ["es2020.symbol.wellknown", "lib.es2020.symbol.wellknown.d.ts"],
        ["esnext.array", "lib.es2019.array.d.ts"],
        ["esnext.symbol", "lib.es2019.symbol.d.ts"],
        ["esnext.asynciterable", "lib.es2018.asynciterable.d.ts"],
        ["esnext.intl", "lib.esnext.intl.d.ts"],
        ["esnext.bigint", "lib.esnext.bigint.d.ts"]
    ];
    /**
     * An array of supported "lib" reference file names used to determine the order for inclusion
     * when referenced, as well as for spelling suggestions. This ensures the correct ordering for
     * overload resolution when a type declared in one lib is extended by another.
     */
    /* @internal */
    ts.libs = libEntries.map(function (entry) { return entry[0]; });
    /**
     * A map of lib names to lib files. This map is used both for parsing the "lib" command line
     * option as well as for resolving lib reference directives.
     */
    /* @internal */
    ts.libMap = ts.createMapFromEntries(libEntries);
    /* @internal */
    ts.commonOptionsWithBuild = [
        {
            name: "help",
            shortName: "h",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Print_this_message,
        },
        {
            name: "help",
            shortName: "?",
            type: "boolean"
        },
        {
            name: "watch",
            shortName: "w",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Watch_input_files,
        },
        {
            name: "preserveWatchOutput",
            type: "boolean",
            showInSimplifiedHelpView: false,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen,
        },
        {
            name: "listFiles",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Print_names_of_files_part_of_the_compilation
        },
        {
            name: "listEmittedFiles",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Print_names_of_generated_files_part_of_the_compilation
        },
        {
            name: "pretty",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental
        },
        {
            name: "traceResolution",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Enable_tracing_of_the_name_resolution_process
        },
        {
            name: "diagnostics",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Show_diagnostic_information
        },
        {
            name: "extendedDiagnostics",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Show_verbose_diagnostic_information
        },
        {
            name: "incremental",
            shortName: "i",
            type: "boolean",
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Enable_incremental_compilation,
        },
    ];
    /* @internal */
    ts.optionDeclarations = ts.commonOptionsWithBuild.concat([
        {
            name: "all",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Show_all_compiler_options,
        },
        {
            name: "version",
            shortName: "v",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Print_the_compiler_s_version,
        },
        {
            name: "init",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file,
        },
        {
            name: "project",
            shortName: "p",
            type: "string",
            isFilePath: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            paramType: ts.Diagnostics.FILE_OR_DIRECTORY,
            description: ts.Diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json,
        },
        {
            name: "build",
            type: "boolean",
            shortName: "b",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Build_one_or_more_projects_and_their_dependencies_if_out_of_date
        },
        {
            name: "showConfig",
            type: "boolean",
            category: ts.Diagnostics.Command_line_Options,
            isCommandLineOnly: true,
            description: ts.Diagnostics.Print_the_final_configuration_instead_of_building
        },
        // Basic
        {
            name: "target",
            shortName: "t",
            type: ts.createMapFromTemplate({
                es3: 0 /* ES3 */,
                es5: 1 /* ES5 */,
                es6: 2 /* ES2015 */,
                es2015: 2 /* ES2015 */,
                es2016: 3 /* ES2016 */,
                es2017: 4 /* ES2017 */,
                es2018: 5 /* ES2018 */,
                es2019: 6 /* ES2019 */,
                es2020: 7 /* ES2020 */,
                esnext: 8 /* ESNext */,
            }),
            affectsSourceFile: true,
            affectsModuleResolution: true,
            affectsEmit: true,
            paramType: ts.Diagnostics.VERSION,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_ES2018_ES2019_or_ESNEXT,
        },
        {
            name: "module",
            shortName: "m",
            type: ts.createMapFromTemplate({
                none: ts.ModuleKind.None,
                commonjs: ts.ModuleKind.CommonJS,
                amd: ts.ModuleKind.AMD,
                system: ts.ModuleKind.System,
                umd: ts.ModuleKind.UMD,
                es6: ts.ModuleKind.ES2015,
                es2015: ts.ModuleKind.ES2015,
                esnext: ts.ModuleKind.ESNext
            }),
            affectsModuleResolution: true,
            paramType: ts.Diagnostics.KIND,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext,
        },
        {
            name: "lib",
            type: "list",
            element: {
                name: "lib",
                type: ts.libMap
            },
            affectsModuleResolution: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_library_files_to_be_included_in_the_compilation
        },
        {
            name: "allowJs",
            type: "boolean",
            affectsModuleResolution: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Allow_javascript_files_to_be_compiled
        },
        {
            name: "checkJs",
            type: "boolean",
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Report_errors_in_js_files
        },
        {
            name: "jsx",
            type: ts.createMapFromTemplate({
                "preserve": 1 /* Preserve */,
                "react-native": 3 /* ReactNative */,
                "react": 2 /* React */
            }),
            affectsSourceFile: true,
            paramType: ts.Diagnostics.KIND,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_JSX_code_generation_Colon_preserve_react_native_or_react,
        },
        {
            name: "declaration",
            shortName: "d",
            type: "boolean",
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Generates_corresponding_d_ts_file,
        },
        {
            name: "declarationMap",
            type: "boolean",
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Generates_a_sourcemap_for_each_corresponding_d_ts_file,
        },
        {
            name: "emitDeclarationOnly",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Only_emit_d_ts_declaration_files,
        },
        {
            name: "sourceMap",
            type: "boolean",
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Generates_corresponding_map_file,
        },
        {
            name: "outFile",
            type: "string",
            affectsEmit: true,
            isFilePath: true,
            paramType: ts.Diagnostics.FILE,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Concatenate_and_emit_output_to_single_file,
        },
        {
            name: "outDir",
            type: "string",
            affectsEmit: true,
            isFilePath: true,
            paramType: ts.Diagnostics.DIRECTORY,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Redirect_output_structure_to_the_directory,
        },
        {
            name: "rootDir",
            type: "string",
            affectsEmit: true,
            isFilePath: true,
            paramType: ts.Diagnostics.LOCATION,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir,
        },
        {
            name: "composite",
            type: "boolean",
            affectsEmit: true,
            isTSConfigOnly: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Enable_project_compilation,
        },
        {
            name: "tsBuildInfoFile",
            type: "string",
            affectsEmit: true,
            isFilePath: true,
            paramType: ts.Diagnostics.FILE,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_file_to_store_incremental_compilation_information,
        },
        {
            name: "removeComments",
            type: "boolean",
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Do_not_emit_comments_to_output,
        },
        {
            name: "noEmit",
            type: "boolean",
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Do_not_emit_outputs,
        },
        {
            name: "importHelpers",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Import_emit_helpers_from_tslib
        },
        {
            name: "downlevelIteration",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3
        },
        {
            name: "isolatedModules",
            type: "boolean",
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule
        },
        // Strict Type Checks
        {
            name: "strict",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_all_strict_type_checking_options
        },
        {
            name: "noImplicitAny",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type
        },
        {
            name: "strictNullChecks",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_strict_null_checks
        },
        {
            name: "strictFunctionTypes",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_strict_checking_of_function_types
        },
        {
            name: "strictBindCallApply",
            type: "boolean",
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_strict_bind_call_and_apply_methods_on_functions
        },
        {
            name: "strictPropertyInitialization",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_strict_checking_of_property_initialization_in_classes
        },
        {
            name: "noImplicitThis",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Raise_error_on_this_expressions_with_an_implied_any_type,
        },
        {
            name: "alwaysStrict",
            type: "boolean",
            affectsSourceFile: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file
        },
        // Additional Checks
        {
            name: "noUnusedLocals",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_errors_on_unused_locals,
        },
        {
            name: "noUnusedParameters",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_errors_on_unused_parameters,
        },
        {
            name: "noImplicitReturns",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_error_when_not_all_code_paths_in_function_return_a_value
        },
        {
            name: "noFallthroughCasesInSwitch",
            type: "boolean",
            affectsBindDiagnostics: true,
            affectsSemanticDiagnostics: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_errors_for_fallthrough_cases_in_switch_statement
        },
        // Module Resolution
        {
            name: "moduleResolution",
            type: ts.createMapFromTemplate({
                node: ts.ModuleResolutionKind.NodeJs,
                classic: ts.ModuleResolutionKind.Classic,
            }),
            affectsModuleResolution: true,
            paramType: ts.Diagnostics.STRATEGY,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6,
        },
        {
            name: "baseUrl",
            type: "string",
            affectsModuleResolution: true,
            isFilePath: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Base_directory_to_resolve_non_absolute_module_names
        },
        {
            // this option can only be specified in tsconfig.json
            // use type = object to copy the value as-is
            name: "paths",
            type: "object",
            affectsModuleResolution: true,
            isTSConfigOnly: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl
        },
        {
            // this option can only be specified in tsconfig.json
            // use type = object to copy the value as-is
            name: "rootDirs",
            type: "list",
            isTSConfigOnly: true,
            element: {
                name: "rootDirs",
                type: "string",
                isFilePath: true
            },
            affectsModuleResolution: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime
        },
        {
            name: "typeRoots",
            type: "list",
            element: {
                name: "typeRoots",
                type: "string",
                isFilePath: true
            },
            affectsModuleResolution: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.List_of_folders_to_include_type_definitions_from
        },
        {
            name: "types",
            type: "list",
            element: {
                name: "types",
                type: "string"
            },
            affectsModuleResolution: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Type_declaration_files_to_be_included_in_compilation
        },
        {
            name: "allowSyntheticDefaultImports",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
        },
        {
            name: "esModuleInterop",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for_all_imports_Implies_allowSyntheticDefaultImports
        },
        {
            name: "preserveSymlinks",
            type: "boolean",
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Do_not_resolve_the_real_path_of_symlinks,
        },
        {
            name: "allowUmdGlobalAccess",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Allow_accessing_UMD_globals_from_modules,
        },
        // Source Maps
        {
            name: "sourceRoot",
            type: "string",
            affectsEmit: true,
            paramType: ts.Diagnostics.LOCATION,
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations,
        },
        {
            name: "mapRoot",
            type: "string",
            affectsEmit: true,
            paramType: ts.Diagnostics.LOCATION,
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations,
        },
        {
            name: "inlineSourceMap",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file
        },
        {
            name: "inlineSources",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set
        },
        // Experimental
        {
            name: "experimentalDecorators",
            type: "boolean",
            category: ts.Diagnostics.Experimental_Options,
            description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators
        },
        {
            name: "emitDecoratorMetadata",
            type: "boolean",
            category: ts.Diagnostics.Experimental_Options,
            description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators
        },
        // Advanced
        {
            name: "jsxFactory",
            type: "string",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h
        },
        {
            name: "resolveJsonModule",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Include_modules_imported_with_json_extension
        },
        {
            name: "out",
            type: "string",
            affectsEmit: true,
            isFilePath: false,
            // for correct behaviour, please use outFile
            category: ts.Diagnostics.Advanced_Options,
            paramType: ts.Diagnostics.FILE,
            description: ts.Diagnostics.Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file,
        },
        {
            name: "reactNamespace",
            type: "string",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit
        },
        {
            name: "skipDefaultLibCheck",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files
        },
        {
            name: "charset",
            type: "string",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.The_character_set_of_the_input_files
        },
        {
            name: "emitBOM",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files
        },
        {
            name: "locale",
            type: "string",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.The_locale_used_when_displaying_messages_to_the_user_e_g_en_us
        },
        {
            name: "newLine",
            type: ts.createMapFromTemplate({
                crlf: 0 /* CarriageReturnLineFeed */,
                lf: 1 /* LineFeed */
            }),
            affectsEmit: true,
            paramType: ts.Diagnostics.NEWLINE,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix,
        },
        {
            name: "noErrorTruncation",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_truncate_error_messages
        },
        {
            name: "noLib",
            type: "boolean",
            affectsModuleResolution: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_include_the_default_library_file_lib_d_ts
        },
        {
            name: "noResolve",
            type: "boolean",
            affectsModuleResolution: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files
        },
        {
            name: "stripInternal",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_emit_declarations_for_code_that_has_an_internal_annotation,
        },
        {
            name: "disableSizeLimit",
            type: "boolean",
            affectsSourceFile: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disable_size_limitations_on_JavaScript_projects
        },
        {
            name: "noImplicitUseStrict",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_emit_use_strict_directives_in_module_output
        },
        {
            name: "noEmitHelpers",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_generate_custom_helper_functions_like_extends_in_compiled_output
        },
        {
            name: "noEmitOnError",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported,
        },
        {
            name: "preserveConstEnums",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code
        },
        {
            name: "declarationDir",
            type: "string",
            affectsEmit: true,
            isFilePath: true,
            paramType: ts.Diagnostics.DIRECTORY,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Output_directory_for_generated_declaration_files
        },
        {
            name: "skipLibCheck",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Skip_type_checking_of_declaration_files,
        },
        {
            name: "allowUnusedLabels",
            type: "boolean",
            affectsBindDiagnostics: true,
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_report_errors_on_unused_labels
        },
        {
            name: "allowUnreachableCode",
            type: "boolean",
            affectsBindDiagnostics: true,
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_report_errors_on_unreachable_code
        },
        {
            name: "suppressExcessPropertyErrors",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Suppress_excess_property_checks_for_object_literals,
        },
        {
            name: "suppressImplicitAnyIndexErrors",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures,
        },
        {
            name: "forceConsistentCasingInFileNames",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file
        },
        {
            name: "maxNodeModuleJsDepth",
            type: "number",
            affectsModuleResolution: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files
        },
        {
            name: "noStrictGenericChecks",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disable_strict_checking_of_generic_signatures_in_function_types,
        },
        {
            name: "keyofStringsOnly",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols,
        },
        {
            // A list of plugins to load in the language service
            name: "plugins",
            type: "list",
            isTSConfigOnly: true,
            element: {
                name: "plugin",
                type: "object"
            },
            description: ts.Diagnostics.List_of_language_service_plugins
        }
    ]);
    /* @internal */
    ts.semanticDiagnosticsOptionDeclarations = ts.optionDeclarations.filter(function (option) { return !!option.affectsSemanticDiagnostics; });
    /* @internal */
    ts.affectsEmitOptionDeclarations = ts.optionDeclarations.filter(function (option) { return !!option.affectsEmit; });
    /* @internal */
    ts.moduleResolutionOptionDeclarations = ts.optionDeclarations.filter(function (option) { return !!option.affectsModuleResolution; });
    /* @internal */
    ts.sourceFileAffectingCompilerOptions = ts.optionDeclarations.filter(function (option) {
        return !!option.affectsSourceFile || !!option.affectsModuleResolution || !!option.affectsBindDiagnostics;
    });
    /* @internal */
    ts.buildOpts = ts.commonOptionsWithBuild.concat([
        {
            name: "verbose",
            shortName: "v",
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Enable_verbose_logging,
            type: "boolean"
        },
        {
            name: "dry",
            shortName: "d",
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean,
            type: "boolean"
        },
        {
            name: "force",
            shortName: "f",
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date,
            type: "boolean"
        },
        {
            name: "clean",
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Delete_the_outputs_of_all_projects,
            type: "boolean"
        }
    ]);
    /* @internal */
    ts.typeAcquisitionDeclarations = [
        {
            /* @deprecated typingOptions.enableAutoDiscovery
             * Use typeAcquisition.enable instead.
             */
            name: "enableAutoDiscovery",
            type: "boolean",
        },
        {
            name: "enable",
            type: "boolean",
        },
        {
            name: "include",
            type: "list",
            element: {
                name: "include",
                type: "string"
            }
        },
        {
            name: "exclude",
            type: "list",
            element: {
                name: "exclude",
                type: "string"
            }
        }
    ];
    /* @internal */
    ts.defaultInitCompilerOptions = {
        module: ts.ModuleKind.CommonJS,
        target: 1 /* ES5 */,
        strict: true,
        esModuleInterop: true
    };
    var optionNameMapCache;
    /* @internal */
    function convertEnableAutoDiscoveryToEnable(typeAcquisition) {
        // Convert deprecated typingOptions.enableAutoDiscovery to typeAcquisition.enable
        if (typeAcquisition && typeAcquisition.enableAutoDiscovery !== undefined && typeAcquisition.enable === undefined) {
            return {
                enable: typeAcquisition.enableAutoDiscovery,
                include: typeAcquisition.include || [],
                exclude: typeAcquisition.exclude || []
            };
        }
        return typeAcquisition;
    }
    ts.convertEnableAutoDiscoveryToEnable = convertEnableAutoDiscoveryToEnable;
    function getOptionNameMap() {
        return optionNameMapCache || (optionNameMapCache = createOptionNameMap(ts.optionDeclarations));
    }
    /*@internal*/
    function createOptionNameMap(optionDeclarations) {
        var optionNameMap = ts.createMap();
        var shortOptionNames = ts.createMap();
        ts.forEach(optionDeclarations, function (option) {
            optionNameMap.set(option.name.toLowerCase(), option);
            if (option.shortName) {
                shortOptionNames.set(option.shortName, option.name);
            }
        });
        return { optionNameMap: optionNameMap, shortOptionNames: shortOptionNames };
    }
    ts.createOptionNameMap = createOptionNameMap;
    /* @internal */
    function createCompilerDiagnosticForInvalidCustomType(opt) {
        return createDiagnosticForInvalidCustomType(opt, ts.createCompilerDiagnostic);
    }
    ts.createCompilerDiagnosticForInvalidCustomType = createCompilerDiagnosticForInvalidCustomType;
    function createDiagnosticForInvalidCustomType(opt, createDiagnostic) {
        var namesOfType = ts.arrayFrom(opt.type.keys()).map(function (key) { return "'" + key + "'"; }).join(", ");
        return createDiagnostic(ts.Diagnostics.Argument_for_0_option_must_be_Colon_1, "--" + opt.name, namesOfType);
    }
    /* @internal */
    function parseCustomTypeOption(opt, value, errors) {
        return convertJsonOptionOfCustomType(opt, trimString(value || ""), errors);
    }
    ts.parseCustomTypeOption = parseCustomTypeOption;
    /* @internal */
    function parseListTypeOption(opt, value, errors) {
        if (value === void 0) { value = ""; }
        value = trimString(value);
        if (ts.startsWith(value, "-")) {
            return undefined;
        }
        if (value === "") {
            return [];
        }
        var values = value.split(",");
        switch (opt.element.type) {
            case "number":
                return ts.map(values, parseInt);
            case "string":
                return ts.map(values, function (v) { return v || ""; });
            default:
                return ts.mapDefined(values, function (v) { return parseCustomTypeOption(opt.element, v, errors); });
        }
    }
    ts.parseListTypeOption = parseListTypeOption;
    function parseCommandLineWorker(getOptionNameMap, _a, commandLine, readFile) {
        var unknownOptionDiagnostic = _a[0], optionTypeMismatchDiagnostic = _a[1];
        var options = {};
        var fileNames = [];
        var errors = [];
        parseStrings(commandLine);
        return {
            options: options,
            fileNames: fileNames,
            errors: errors
        };
        function parseStrings(args) {
            var i = 0;
            while (i < args.length) {
                var s = args[i];
                i++;
                if (s.charCodeAt(0) === 64 /* at */) {
                    parseResponseFile(s.slice(1));
                }
                else if (s.charCodeAt(0) === 45 /* minus */) {
                    var opt = getOptionDeclarationFromName(getOptionNameMap, s.slice(s.charCodeAt(1) === 45 /* minus */ ? 2 : 1), /*allowShort*/ true);
                    if (opt) {
                        if (opt.isTSConfigOnly) {
                            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file, opt.name));
                        }
                        else {
                            // Check to see if no argument was provided (e.g. "--locale" is the last command-line argument).
                            if (!args[i] && opt.type !== "boolean") {
                                errors.push(ts.createCompilerDiagnostic(optionTypeMismatchDiagnostic, opt.name));
                            }
                            switch (opt.type) {
                                case "number":
                                    options[opt.name] = parseInt(args[i]);
                                    i++;
                                    break;
                                case "boolean":
                                    // boolean flag has optional value true, false, others
                                    var optValue = args[i];
                                    options[opt.name] = optValue !== "false";
                                    // consume next argument as boolean flag value
                                    if (optValue === "false" || optValue === "true") {
                                        i++;
                                    }
                                    break;
                                case "string":
                                    options[opt.name] = args[i] || "";
                                    i++;
                                    break;
                                case "list":
                                    var result = parseListTypeOption(opt, args[i], errors);
                                    options[opt.name] = result || [];
                                    if (result) {
                                        i++;
                                    }
                                    break;
                                // If not a primitive, the possible types are specified in what is effectively a map of options.
                                default:
                                    options[opt.name] = parseCustomTypeOption(opt, args[i], errors);
                                    i++;
                                    break;
                            }
                        }
                    }
                    else {
                        errors.push(ts.createCompilerDiagnostic(unknownOptionDiagnostic, s));
                    }
                }
                else {
                    fileNames.push(s);
                }
            }
        }
        function parseResponseFile(fileName) {
            var text = readFile ? readFile(fileName) : ts.sys.readFile(fileName);
            if (!text) {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.File_0_not_found, fileName));
                return;
            }
            var args = [];
            var pos = 0;
            while (true) {
                while (pos < text.length && text.charCodeAt(pos) <= 32 /* space */)
                    pos++;
                if (pos >= text.length)
                    break;
                var start = pos;
                if (text.charCodeAt(start) === 34 /* doubleQuote */) {
                    pos++;
                    while (pos < text.length && text.charCodeAt(pos) !== 34 /* doubleQuote */)
                        pos++;
                    if (pos < text.length) {
                        args.push(text.substring(start + 1, pos));
                        pos++;
                    }
                    else {
                        errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unterminated_quoted_string_in_response_file_0, fileName));
                    }
                }
                else {
                    while (text.charCodeAt(pos) > 32 /* space */)
                        pos++;
                    args.push(text.substring(start, pos));
                }
            }
            parseStrings(args);
        }
    }
    function parseCommandLine(commandLine, readFile) {
        return parseCommandLineWorker(getOptionNameMap, [
            ts.Diagnostics.Unknown_compiler_option_0,
            ts.Diagnostics.Compiler_option_0_expects_an_argument
        ], commandLine, readFile);
    }
    ts.parseCommandLine = parseCommandLine;
    /** @internal */
    function getOptionFromName(optionName, allowShort) {
        return getOptionDeclarationFromName(getOptionNameMap, optionName, allowShort);
    }
    ts.getOptionFromName = getOptionFromName;
    function getOptionDeclarationFromName(getOptionNameMap, optionName, allowShort) {
        if (allowShort === void 0) { allowShort = false; }
        optionName = optionName.toLowerCase();
        var _a = getOptionNameMap(), optionNameMap = _a.optionNameMap, shortOptionNames = _a.shortOptionNames;
        // Try to translate short option names to their full equivalents.
        if (allowShort) {
            var short = shortOptionNames.get(optionName);
            if (short !== undefined) {
                optionName = short;
            }
        }
        return optionNameMap.get(optionName);
    }
    /*@internal*/
    function parseBuildCommand(args) {
        var buildOptionNameMap;
        var returnBuildOptionNameMap = function () { return (buildOptionNameMap || (buildOptionNameMap = createOptionNameMap(ts.buildOpts))); };
        var _a = parseCommandLineWorker(returnBuildOptionNameMap, [
            ts.Diagnostics.Unknown_build_option_0,
            ts.Diagnostics.Build_option_0_requires_a_value_of_type_1
        ], args), options = _a.options, projects = _a.fileNames, errors = _a.errors;
        var buildOptions = options;
        if (projects.length === 0) {
            // tsc -b invoked with no extra arguments; act as if invoked with "tsc -b ."
            projects.push(".");
        }
        // Nonsensical combinations
        if (buildOptions.clean && buildOptions.force) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force"));
        }
        if (buildOptions.clean && buildOptions.verbose) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose"));
        }
        if (buildOptions.clean && buildOptions.watch) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch"));
        }
        if (buildOptions.watch && buildOptions.dry) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry"));
        }
        return { buildOptions: buildOptions, projects: projects, errors: errors };
    }
    ts.parseBuildCommand = parseBuildCommand;
    function getDiagnosticText(_message) {
        var _args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            _args[_i - 1] = arguments[_i];
        }
        var diagnostic = ts.createCompilerDiagnostic.apply(undefined, arguments);
        return diagnostic.messageText;
    }
    /* @internal */
    function printVersion() {
        ts.sys.write(getDiagnosticText(ts.Diagnostics.Version_0, ts.version) + ts.sys.newLine);
    }
    ts.printVersion = printVersion;
    /* @internal */
    function printHelp(optionsList, syntaxPrefix) {
        if (syntaxPrefix === void 0) { syntaxPrefix = ""; }
        var output = [];
        // We want to align our "syntax" and "examples" commands to a certain margin.
        var syntaxLength = getDiagnosticText(ts.Diagnostics.Syntax_Colon_0, "").length;
        var examplesLength = getDiagnosticText(ts.Diagnostics.Examples_Colon_0, "").length;
        var marginLength = Math.max(syntaxLength, examplesLength);
        // Build up the syntactic skeleton.
        var syntax = makePadding(marginLength - syntaxLength);
        syntax += "tsc " + syntaxPrefix + "[" + getDiagnosticText(ts.Diagnostics.options) + "] [" + getDiagnosticText(ts.Diagnostics.file) + "...]";
        output.push(getDiagnosticText(ts.Diagnostics.Syntax_Colon_0, syntax));
        output.push(ts.sys.newLine + ts.sys.newLine);
        // Build up the list of examples.
        var padding = makePadding(marginLength);
        output.push(getDiagnosticText(ts.Diagnostics.Examples_Colon_0, makePadding(marginLength - examplesLength) + "tsc hello.ts") + ts.sys.newLine);
        output.push(padding + "tsc --outFile file.js file.ts" + ts.sys.newLine);
        output.push(padding + "tsc @args.txt" + ts.sys.newLine);
        output.push(padding + "tsc --build tsconfig.json" + ts.sys.newLine);
        output.push(ts.sys.newLine);
        output.push(getDiagnosticText(ts.Diagnostics.Options_Colon) + ts.sys.newLine);
        // We want our descriptions to align at the same column in our output,
        // so we keep track of the longest option usage string.
        marginLength = 0;
        var usageColumn = []; // Things like "-d, --declaration" go in here.
        var descriptionColumn = [];
        var optionsDescriptionMap = ts.createMap(); // Map between option.description and list of option.type if it is a kind
        for (var _i = 0, optionsList_1 = optionsList; _i < optionsList_1.length; _i++) {
            var option = optionsList_1[_i];
            // If an option lacks a description,
            // it is not officially supported.
            if (!option.description) {
                continue;
            }
            var usageText_1 = " ";
            if (option.shortName) {
                usageText_1 += "-" + option.shortName;
                usageText_1 += getParamType(option);
                usageText_1 += ", ";
            }
            usageText_1 += "--" + option.name;
            usageText_1 += getParamType(option);
            usageColumn.push(usageText_1);
            var description = void 0;
            if (option.name === "lib") {
                description = getDiagnosticText(option.description);
                var element = option.element;
                var typeMap = element.type;
                optionsDescriptionMap.set(description, ts.arrayFrom(typeMap.keys()).map(function (key) { return "'" + key + "'"; }));
            }
            else {
                description = getDiagnosticText(option.description);
            }
            descriptionColumn.push(description);
            // Set the new margin for the description column if necessary.
            marginLength = Math.max(usageText_1.length, marginLength);
        }
        // Special case that can't fit in the loop.
        var usageText = " @<" + getDiagnosticText(ts.Diagnostics.file) + ">";
        usageColumn.push(usageText);
        descriptionColumn.push(getDiagnosticText(ts.Diagnostics.Insert_command_line_options_and_files_from_a_file));
        marginLength = Math.max(usageText.length, marginLength);
        // Print out each row, aligning all the descriptions on the same column.
        for (var i = 0; i < usageColumn.length; i++) {
            var usage = usageColumn[i];
            var description = descriptionColumn[i];
            var kindsList = optionsDescriptionMap.get(description);
            output.push(usage + makePadding(marginLength - usage.length + 2) + description + ts.sys.newLine);
            if (kindsList) {
                output.push(makePadding(marginLength + 4));
                for (var _a = 0, kindsList_1 = kindsList; _a < kindsList_1.length; _a++) {
                    var kind = kindsList_1[_a];
                    output.push(kind + " ");
                }
                output.push(ts.sys.newLine);
            }
        }
        for (var _b = 0, output_1 = output; _b < output_1.length; _b++) {
            var line = output_1[_b];
            ts.sys.write(line);
        }
        return;
        function getParamType(option) {
            if (option.paramType !== undefined) {
                return " " + getDiagnosticText(option.paramType);
            }
            return "";
        }
        function makePadding(paddingLength) {
            return Array(paddingLength + 1).join(" ");
        }
    }
    ts.printHelp = printHelp;
    /**
     * Reads the config file, reports errors if any and exits if the config file cannot be found
     */
    function getParsedCommandLineOfConfigFile(configFileName, optionsToExtend, host, extendedConfigCache) {
        var configFileText;
        try {
            configFileText = host.readFile(configFileName);
        }
        catch (e) {
            var error = ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, configFileName, e.message);
            host.onUnRecoverableConfigFileDiagnostic(error);
            return undefined;
        }
        if (!configFileText) {
            var error = ts.createCompilerDiagnostic(ts.Diagnostics.File_0_not_found, configFileName);
            host.onUnRecoverableConfigFileDiagnostic(error);
            return undefined;
        }
        var result = ts.parseJsonText(configFileName, configFileText);
        var cwd = host.getCurrentDirectory();
        result.path = ts.toPath(configFileName, cwd, ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames));
        result.resolvedPath = result.path;
        result.originalFileName = result.fileName;
        return parseJsonSourceFileConfigFileContent(result, host, ts.getNormalizedAbsolutePath(ts.getDirectoryPath(configFileName), cwd), optionsToExtend, ts.getNormalizedAbsolutePath(configFileName, cwd), 
        /*resolutionStack*/ undefined, 
        /*extraFileExtension*/ undefined, extendedConfigCache);
    }
    ts.getParsedCommandLineOfConfigFile = getParsedCommandLineOfConfigFile;
    /**
     * Read tsconfig.json file
     * @param fileName The path to the config file
     */
    function readConfigFile(fileName, readFile) {
        var textOrDiagnostic = tryReadFile(fileName, readFile);
        return ts.isString(textOrDiagnostic) ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic };
    }
    ts.readConfigFile = readConfigFile;
    /**
     * Parse the text of the tsconfig.json file
     * @param fileName The path to the config file
     * @param jsonText The text of the config file
     */
    function parseConfigFileTextToJson(fileName, jsonText) {
        var jsonSourceFile = ts.parseJsonText(fileName, jsonText);
        return {
            config: convertToObject(jsonSourceFile, jsonSourceFile.parseDiagnostics),
            error: jsonSourceFile.parseDiagnostics.length ? jsonSourceFile.parseDiagnostics[0] : undefined
        };
    }
    ts.parseConfigFileTextToJson = parseConfigFileTextToJson;
    /**
     * Read tsconfig.json file
     * @param fileName The path to the config file
     */
    function readJsonConfigFile(fileName, readFile) {
        var textOrDiagnostic = tryReadFile(fileName, readFile);
        return ts.isString(textOrDiagnostic) ? ts.parseJsonText(fileName, textOrDiagnostic) : { parseDiagnostics: [textOrDiagnostic] };
    }
    ts.readJsonConfigFile = readJsonConfigFile;
    function tryReadFile(fileName, readFile) {
        var text;
        try {
            text = readFile(fileName);
        }
        catch (e) {
            return ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message);
        }
        return text === undefined ? ts.createCompilerDiagnostic(ts.Diagnostics.The_specified_path_does_not_exist_Colon_0, fileName) : text;
    }
    function commandLineOptionsToMap(options) {
        return ts.arrayToMap(options, function (option) { return option.name; });
    }
    var _tsconfigRootOptions;
    function getTsconfigRootOptionsMap() {
        if (_tsconfigRootOptions === undefined) {
            _tsconfigRootOptions = {
                name: undefined,
                type: "object",
                elementOptions: commandLineOptionsToMap([
                    {
                        name: "compilerOptions",
                        type: "object",
                        elementOptions: commandLineOptionsToMap(ts.optionDeclarations),
                        extraKeyDiagnosticMessage: ts.Diagnostics.Unknown_compiler_option_0
                    },
                    {
                        name: "typingOptions",
                        type: "object",
                        elementOptions: commandLineOptionsToMap(ts.typeAcquisitionDeclarations),
                        extraKeyDiagnosticMessage: ts.Diagnostics.Unknown_type_acquisition_option_0
                    },
                    {
                        name: "typeAcquisition",
                        type: "object",
                        elementOptions: commandLineOptionsToMap(ts.typeAcquisitionDeclarations),
                        extraKeyDiagnosticMessage: ts.Diagnostics.Unknown_type_acquisition_option_0
                    },
                    {
                        name: "extends",
                        type: "string"
                    },
                    {
                        name: "references",
                        type: "list",
                        element: {
                            name: "references",
                            type: "object"
                        }
                    },
                    {
                        name: "files",
                        type: "list",
                        element: {
                            name: "files",
                            type: "string"
                        }
                    },
                    {
                        name: "include",
                        type: "list",
                        element: {
                            name: "include",
                            type: "string"
                        }
                    },
                    {
                        name: "exclude",
                        type: "list",
                        element: {
                            name: "exclude",
                            type: "string"
                        }
                    },
                    ts.compileOnSaveCommandLineOption
                ])
            };
        }
        return _tsconfigRootOptions;
    }
    /**
     * Convert the json syntax tree into the json value
     */
    function convertToObject(sourceFile, errors) {
        return convertToObjectWorker(sourceFile, errors, /*returnValue*/ true, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
    }
    ts.convertToObject = convertToObject;
    /**
     * Convert the json syntax tree into the json value and report errors
     * This returns the json value (apart from checking errors) only if returnValue provided is true.
     * Otherwise it just checks the errors and returns undefined
     */
    /*@internal*/
    function convertToObjectWorker(sourceFile, errors, returnValue, knownRootOptions, jsonConversionNotifier) {
        if (!sourceFile.statements.length) {
            return returnValue ? {} : undefined;
        }
        return convertPropertyValueToJson(sourceFile.statements[0].expression, knownRootOptions);
        function isRootOptionMap(knownOptions) {
            return knownRootOptions && knownRootOptions.elementOptions === knownOptions;
        }
        function convertObjectLiteralExpressionToJson(node, knownOptions, extraKeyDiagnosticMessage, parentOption) {
            var result = returnValue ? {} : undefined;
            for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                var element = _a[_i];
                if (element.kind !== 276 /* PropertyAssignment */) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element, ts.Diagnostics.Property_assignment_expected));
                    continue;
                }
                if (element.questionToken) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.questionToken, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, "?"));
                }
                if (!isDoubleQuotedString(element.name)) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, ts.Diagnostics.String_literal_with_double_quotes_expected));
                }
                var textOfKey = ts.getTextOfPropertyName(element.name);
                var keyText = textOfKey && ts.unescapeLeadingUnderscores(textOfKey);
                var option = keyText && knownOptions ? knownOptions.get(keyText) : undefined;
                if (keyText && extraKeyDiagnosticMessage && !option) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, extraKeyDiagnosticMessage, keyText));
                }
                var value = convertPropertyValueToJson(element.initializer, option);
                if (typeof keyText !== "undefined") {
                    if (returnValue) {
                        result[keyText] = value;
                    }
                    // Notify key value set, if user asked for it
                    if (jsonConversionNotifier &&
                        // Current callbacks are only on known parent option or if we are setting values in the root
                        (parentOption || isRootOptionMap(knownOptions))) {
                        var isValidOptionValue = isCompilerOptionsValue(option, value);
                        if (parentOption) {
                            if (isValidOptionValue) {
                                // Notify option set in the parent if its a valid option value
                                jsonConversionNotifier.onSetValidOptionKeyValueInParent(parentOption, option, value);
                            }
                        }
                        else if (isRootOptionMap(knownOptions)) {
                            if (isValidOptionValue) {
                                // Notify about the valid root key value being set
                                jsonConversionNotifier.onSetValidOptionKeyValueInRoot(keyText, element.name, value, element.initializer);
                            }
                            else if (!option) {
                                // Notify about the unknown root key value being set
                                jsonConversionNotifier.onSetUnknownOptionKeyValueInRoot(keyText, element.name, value, element.initializer);
                            }
                        }
                    }
                }
            }
            return result;
        }
        function convertArrayLiteralExpressionToJson(elements, elementOption) {
            if (!returnValue) {
                return elements.forEach(function (element) { return convertPropertyValueToJson(element, elementOption); });
            }
            // Filter out invalid values
            return ts.filter(elements.map(function (element) { return convertPropertyValueToJson(element, elementOption); }), function (v) { return v !== undefined; });
        }
        function convertPropertyValueToJson(valueExpression, option) {
            switch (valueExpression.kind) {
                case 103 /* TrueKeyword */:
                    reportInvalidOptionValue(option && option.type !== "boolean");
                    return true;
                case 88 /* FalseKeyword */:
                    reportInvalidOptionValue(option && option.type !== "boolean");
                    return false;
                case 97 /* NullKeyword */:
                    reportInvalidOptionValue(option && option.name === "extends"); // "extends" is the only option we don't allow null/undefined for
                    return null; // tslint:disable-line:no-null-keyword
                case 10 /* StringLiteral */:
                    if (!isDoubleQuotedString(valueExpression)) {
                        errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.String_literal_with_double_quotes_expected));
                    }
                    reportInvalidOptionValue(option && (ts.isString(option.type) && option.type !== "string"));
                    var text = valueExpression.text;
                    if (option && !ts.isString(option.type)) {
                        var customOption = option;
                        // Validate custom option type
                        if (!customOption.type.has(text.toLowerCase())) {
                            errors.push(createDiagnosticForInvalidCustomType(customOption, function (message, arg0, arg1) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, message, arg0, arg1); }));
                        }
                    }
                    return text;
                case 8 /* NumericLiteral */:
                    reportInvalidOptionValue(option && option.type !== "number");
                    return Number(valueExpression.text);
                case 203 /* PrefixUnaryExpression */:
                    if (valueExpression.operator !== 39 /* MinusToken */ || valueExpression.operand.kind !== 8 /* NumericLiteral */) {
                        break; // not valid JSON syntax
                    }
                    reportInvalidOptionValue(option && option.type !== "number");
                    return -Number(valueExpression.operand.text);
                case 189 /* ObjectLiteralExpression */:
                    reportInvalidOptionValue(option && option.type !== "object");
                    var objectLiteralExpression = valueExpression;
                    // Currently having element option declaration in the tsconfig with type "object"
                    // determines if it needs onSetValidOptionKeyValueInParent callback or not
                    // At moment there are only "compilerOptions", "typeAcquisition" and "typingOptions"
                    // that satifies it and need it to modify options set in them (for normalizing file paths)
                    // vs what we set in the json
                    // If need arises, we can modify this interface and callbacks as needed
                    if (option) {
                        var _a = option, elementOptions = _a.elementOptions, extraKeyDiagnosticMessage = _a.extraKeyDiagnosticMessage, optionName = _a.name;
                        return convertObjectLiteralExpressionToJson(objectLiteralExpression, elementOptions, extraKeyDiagnosticMessage, optionName);
                    }
                    else {
                        return convertObjectLiteralExpressionToJson(objectLiteralExpression, /* knownOptions*/ undefined, 
                        /*extraKeyDiagnosticMessage */ undefined, /*parentOption*/ undefined);
                    }
                case 188 /* ArrayLiteralExpression */:
                    reportInvalidOptionValue(option && option.type !== "list");
                    return convertArrayLiteralExpressionToJson(valueExpression.elements, option && option.element);
            }
            // Not in expected format
            if (option) {
                reportInvalidOptionValue(/*isError*/ true);
            }
            else {
                errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_literal));
            }
            return undefined;
            function reportInvalidOptionValue(isError) {
                if (isError) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, option.name, getCompilerOptionValueTypeString(option)));
                }
            }
        }
        function isDoubleQuotedString(node) {
            return ts.isStringLiteral(node) && ts.isStringDoubleQuoted(node, sourceFile);
        }
    }
    ts.convertToObjectWorker = convertToObjectWorker;
    function getCompilerOptionValueTypeString(option) {
        return option.type === "list" ?
            "Array" :
            ts.isString(option.type) ? option.type : "string";
    }
    function isCompilerOptionsValue(option, value) {
        if (option) {
            if (isNullOrUndefined(value))
                return true; // All options are undefinable/nullable
            if (option.type === "list") {
                return ts.isArray(value);
            }
            var expectedType = ts.isString(option.type) ? option.type : "string";
            return typeof value === expectedType;
        }
        return false;
    }
    /**
     * Generate an uncommented, complete tsconfig for use with "--showConfig"
     * @param configParseResult options to be generated into tsconfig.json
     * @param configFileName name of the parsed config file - output paths will be generated relative to this
     * @param host provides current directory and case sensitivity services
     */
    /** @internal */
    function convertToTSConfig(configParseResult, configFileName, host) {
        var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames);
        var files = ts.map(ts.filter(configParseResult.fileNames, (!configParseResult.configFileSpecs || !configParseResult.configFileSpecs.validatedIncludeSpecs) ? function (_) { return true; } : matchesSpecs(configFileName, configParseResult.configFileSpecs.validatedIncludeSpecs, configParseResult.configFileSpecs.validatedExcludeSpecs)), function (f) { return ts.getRelativePathFromFile(ts.getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), ts.getNormalizedAbsolutePath(f, host.getCurrentDirectory()), getCanonicalFileName); });
        var optionMap = serializeCompilerOptions(configParseResult.options, { configFilePath: ts.getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), useCaseSensitiveFileNames: host.useCaseSensitiveFileNames });
        var config = __assign({ compilerOptions: __assign({}, ts.arrayFrom(optionMap.entries()).reduce(function (prev, cur) {
                var _a;
                return (__assign({}, prev, (_a = {}, _a[cur[0]] = cur[1], _a)));
            }, {}), { showConfig: undefined, configFile: undefined, configFilePath: undefined, help: undefined, init: undefined, listFiles: undefined, listEmittedFiles: undefined, project: undefined, build: undefined, version: undefined }), references: ts.map(configParseResult.projectReferences, function (r) { return (__assign({}, r, { path: r.originalPath, originalPath: undefined })); }), files: ts.length(files) ? files : undefined }, (configParseResult.configFileSpecs ? {
            include: filterSameAsDefaultInclude(configParseResult.configFileSpecs.validatedIncludeSpecs),
            exclude: configParseResult.configFileSpecs.validatedExcludeSpecs
        } : {}), { compilerOnSave: !!configParseResult.compileOnSave ? true : undefined });
        return config;
    }
    ts.convertToTSConfig = convertToTSConfig;
    function filterSameAsDefaultInclude(specs) {
        if (!ts.length(specs))
            return undefined;
        if (ts.length(specs) !== 1)
            return specs;
        if (specs[0] === "**/*")
            return undefined;
        return specs;
    }
    function matchesSpecs(path, includeSpecs, excludeSpecs) {
        if (!includeSpecs)
            return function (_) { return true; };
        var patterns = ts.getFileMatcherPatterns(path, excludeSpecs, includeSpecs, ts.sys.useCaseSensitiveFileNames, ts.sys.getCurrentDirectory());
        var excludeRe = patterns.excludePattern && ts.getRegexFromPattern(patterns.excludePattern, ts.sys.useCaseSensitiveFileNames);
        var includeRe = patterns.includeFilePattern && ts.getRegexFromPattern(patterns.includeFilePattern, ts.sys.useCaseSensitiveFileNames);
        if (includeRe) {
            if (excludeRe) {
                return function (path) { return !(includeRe.test(path) && !excludeRe.test(path)); };
            }
            return function (path) { return !includeRe.test(path); };
        }
        if (excludeRe) {
            return function (path) { return excludeRe.test(path); };
        }
        return function (_) { return true; };
    }
    function getCustomTypeMapOfCommandLineOption(optionDefinition) {
        if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean" || optionDefinition.type === "object") {
            // this is of a type CommandLineOptionOfPrimitiveType
            return undefined;
        }
        else if (optionDefinition.type === "list") {
            return getCustomTypeMapOfCommandLineOption(optionDefinition.element);
        }
        else {
            return optionDefinition.type;
        }
    }
    function getNameOfCompilerOptionValue(value, customTypeMap) {
        // There is a typeMap associated with this command-line option so use it to map value back to its name
        return ts.forEachEntry(customTypeMap, function (mapValue, key) {
            if (mapValue === value) {
                return key;
            }
        });
    }
    function serializeCompilerOptions(options, pathOptions) {
        var result = ts.createMap();
        var optionsNameMap = getOptionNameMap().optionNameMap;
        var getCanonicalFileName = pathOptions && ts.createGetCanonicalFileName(pathOptions.useCaseSensitiveFileNames);
        var _loop_3 = function (name) {
            if (ts.hasProperty(options, name)) {
                // tsconfig only options cannot be specified via command line,
                // so we can assume that only types that can appear here string | number | boolean
                if (optionsNameMap.has(name) && optionsNameMap.get(name).category === ts.Diagnostics.Command_line_Options) {
                    return "continue";
                }
                var value = options[name];
                var optionDefinition = optionsNameMap.get(name.toLowerCase());
                if (optionDefinition) {
                    var customTypeMap_1 = getCustomTypeMapOfCommandLineOption(optionDefinition);
                    if (!customTypeMap_1) {
                        // There is no map associated with this compiler option then use the value as-is
                        // This is the case if the value is expect to be string, number, boolean or list of string
                        if (pathOptions && optionDefinition.isFilePath) {
                            result.set(name, ts.getRelativePathFromFile(pathOptions.configFilePath, ts.getNormalizedAbsolutePath(value, ts.getDirectoryPath(pathOptions.configFilePath)), getCanonicalFileName));
                        }
                        else {
                            result.set(name, value);
                        }
                    }
                    else {
                        if (optionDefinition.type === "list") {
                            result.set(name, value.map(function (element) { return getNameOfCompilerOptionValue(element, customTypeMap_1); })); // TODO: GH#18217
                        }
                        else {
                            // There is a typeMap associated with this command-line option so use it to map value back to its name
                            result.set(name, getNameOfCompilerOptionValue(value, customTypeMap_1));
                        }
                    }
                }
            }
        };
        for (var name in options) {
            _loop_3(name);
        }
        return result;
    }
    /**
     * Generate tsconfig configuration when running command line "--init"
     * @param options commandlineOptions to be generated into tsconfig.json
     * @param fileNames array of filenames to be generated into tsconfig.json
     */
    /* @internal */
    function generateTSConfig(options, fileNames, newLine) {
        var compilerOptions = ts.extend(options, ts.defaultInitCompilerOptions);
        var compilerOptionsMap = serializeCompilerOptions(compilerOptions);
        return writeConfigurations();
        function getDefaultValueForOption(option) {
            switch (option.type) {
                case "number":
                    return 1;
                case "boolean":
                    return true;
                case "string":
                    return option.isFilePath ? "./" : "";
                case "list":
                    return [];
                case "object":
                    return {};
                default:
                    return option.type.keys().next().value;
            }
        }
        function makePadding(paddingLength) {
            return Array(paddingLength + 1).join(" ");
        }
        function isAllowedOption(_a) {
            var category = _a.category, name = _a.name;
            // Skip options which do not have a category or have category `Command_line_Options`
            // Exclude all possible `Advanced_Options` in tsconfig.json which were NOT defined in command line
            return category !== undefined
                && category !== ts.Diagnostics.Command_line_Options
                && (category !== ts.Diagnostics.Advanced_Options || compilerOptionsMap.has(name));
        }
        function writeConfigurations() {
            // Filter applicable options to place in the file
            var categorizedOptions = ts.createMultiMap();
            for (var _i = 0, optionDeclarations_1 = ts.optionDeclarations; _i < optionDeclarations_1.length; _i++) {
                var option = optionDeclarations_1[_i];
                var category = option.category;
                if (isAllowedOption(option)) {
                    categorizedOptions.add(ts.getLocaleSpecificMessage(category), option);
                }
            }
            // Serialize all options and their descriptions
            var marginLength = 0;
            var seenKnownKeys = 0;
            var nameColumn = [];
            var descriptionColumn = [];
            categorizedOptions.forEach(function (options, category) {
                if (nameColumn.length !== 0) {
                    nameColumn.push("");
                    descriptionColumn.push("");
                }
                nameColumn.push("/* " + category + " */");
                descriptionColumn.push("");
                for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
                    var option = options_1[_i];
                    var optionName = void 0;
                    if (compilerOptionsMap.has(option.name)) {
                        optionName = "\"" + option.name + "\": " + JSON.stringify(compilerOptionsMap.get(option.name)) + ((seenKnownKeys += 1) === compilerOptionsMap.size ? "" : ",");
                    }
                    else {
                        optionName = "// \"" + option.name + "\": " + JSON.stringify(getDefaultValueForOption(option)) + ",";
                    }
                    nameColumn.push(optionName);
                    descriptionColumn.push("/* " + (option.description && ts.getLocaleSpecificMessage(option.description) || option.name) + " */");
                    marginLength = Math.max(optionName.length, marginLength);
                }
            });
            // Write the output
            var tab = makePadding(2);
            var result = [];
            result.push("{");
            result.push(tab + "\"compilerOptions\": {");
            // Print out each row, aligning all the descriptions on the same column.
            for (var i = 0; i < nameColumn.length; i++) {
                var optionName = nameColumn[i];
                var description = descriptionColumn[i];
                result.push(optionName && "" + tab + tab + optionName + (description && (makePadding(marginLength - optionName.length + 2) + description)));
            }
            if (fileNames.length) {
                result.push(tab + "},");
                result.push(tab + "\"files\": [");
                for (var i = 0; i < fileNames.length; i++) {
                    result.push("" + tab + tab + JSON.stringify(fileNames[i]) + (i === fileNames.length - 1 ? "" : ","));
                }
                result.push(tab + "]");
            }
            else {
                result.push(tab + "}");
            }
            result.push("}");
            return result.join(newLine) + newLine;
        }
    }
    ts.generateTSConfig = generateTSConfig;
    /**
     * Parse the contents of a config file (tsconfig.json).
     * @param json The contents of the config file to parse
     * @param host Instance of ParseConfigHost used to enumerate files in folder.
     * @param basePath A root directory to resolve relative path entries in the config
     *    file to. e.g. outDir
     */
    function parseJsonConfigFileContent(json, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache) {
        return parseJsonConfigFileContentWorker(json, /*sourceFile*/ undefined, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache);
    }
    ts.parseJsonConfigFileContent = parseJsonConfigFileContent;
    /**
     * Parse the contents of a config file (tsconfig.json).
     * @param jsonNode The contents of the config file to parse
     * @param host Instance of ParseConfigHost used to enumerate files in folder.
     * @param basePath A root directory to resolve relative path entries in the config
     *    file to. e.g. outDir
     */
    function parseJsonSourceFileConfigFileContent(sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache) {
        return parseJsonConfigFileContentWorker(/*json*/ undefined, sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache);
    }
    ts.parseJsonSourceFileConfigFileContent = parseJsonSourceFileConfigFileContent;
    /*@internal*/
    function setConfigFileInOptions(options, configFile) {
        if (configFile) {
            Object.defineProperty(options, "configFile", { enumerable: false, writable: false, value: configFile });
        }
    }
    ts.setConfigFileInOptions = setConfigFileInOptions;
    function isNullOrUndefined(x) {
        // tslint:disable-next-line:no-null-keyword
        return x === undefined || x === null;
    }
    function directoryOfCombinedPath(fileName, basePath) {
        // Use the `getNormalizedAbsolutePath` function to avoid canonicalizing the path, as it must remain noncanonical
        // until consistent casing errors are reported
        return ts.getDirectoryPath(ts.getNormalizedAbsolutePath(fileName, basePath));
    }
    /**
     * Parse the contents of a config file from json or json source file (tsconfig.json).
     * @param json The contents of the config file to parse
     * @param sourceFile sourceFile corresponding to the Json
     * @param host Instance of ParseConfigHost used to enumerate files in folder.
     * @param basePath A root directory to resolve relative path entries in the config
     *    file to. e.g. outDir
     * @param resolutionStack Only present for backwards-compatibility. Should be empty.
     */
    function parseJsonConfigFileContentWorker(json, sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache) {
        if (existingOptions === void 0) { existingOptions = {}; }
        if (resolutionStack === void 0) { resolutionStack = []; }
        if (extraFileExtensions === void 0) { extraFileExtensions = []; }
        ts.Debug.assert((json === undefined && sourceFile !== undefined) || (json !== undefined && sourceFile === undefined));
        var errors = [];
        var parsedConfig = parseConfig(json, sourceFile, host, basePath, configFileName, resolutionStack, errors, extendedConfigCache);
        var raw = parsedConfig.raw;
        var options = ts.extend(existingOptions, parsedConfig.options || {});
        options.configFilePath = configFileName && ts.normalizeSlashes(configFileName);
        setConfigFileInOptions(options, sourceFile);
        var projectReferences;
        var _a = getFileNames(), fileNames = _a.fileNames, wildcardDirectories = _a.wildcardDirectories, spec = _a.spec;
        return {
            options: options,
            fileNames: fileNames,
            projectReferences: projectReferences,
            typeAcquisition: parsedConfig.typeAcquisition || getDefaultTypeAcquisition(),
            raw: raw,
            errors: errors,
            wildcardDirectories: wildcardDirectories,
            compileOnSave: !!raw.compileOnSave,
            configFileSpecs: spec
        };
        function getFileNames() {
            var filesSpecs;
            if (ts.hasProperty(raw, "files") && !isNullOrUndefined(raw.files)) {
                if (ts.isArray(raw.files)) {
                    filesSpecs = raw.files;
                    var hasReferences = ts.hasProperty(raw, "references") && !isNullOrUndefined(raw.references);
                    var hasZeroOrNoReferences = !hasReferences || raw.references.length === 0;
                    var hasExtends = ts.hasProperty(raw, "extends");
                    if (filesSpecs.length === 0 && hasZeroOrNoReferences && !hasExtends) {
                        if (sourceFile) {
                            var fileName = configFileName || "tsconfig.json";
                            var diagnosticMessage = ts.Diagnostics.The_files_list_in_config_file_0_is_empty;
                            var nodeValue = ts.firstDefined(ts.getTsConfigPropArray(sourceFile, "files"), function (property) { return property.initializer; });
                            var error = nodeValue
                                ? ts.createDiagnosticForNodeInSourceFile(sourceFile, nodeValue, diagnosticMessage, fileName)
                                : ts.createCompilerDiagnostic(diagnosticMessage, fileName);
                            errors.push(error);
                        }
                        else {
                            createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json");
                        }
                    }
                }
                else {
                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "files", "Array");
                }
            }
            var includeSpecs;
            if (ts.hasProperty(raw, "include") && !isNullOrUndefined(raw.include)) {
                if (ts.isArray(raw.include)) {
                    includeSpecs = raw.include;
                }
                else {
                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "include", "Array");
                }
            }
            var excludeSpecs;
            if (ts.hasProperty(raw, "exclude") && !isNullOrUndefined(raw.exclude)) {
                if (ts.isArray(raw.exclude)) {
                    excludeSpecs = raw.exclude;
                }
                else {
                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "exclude", "Array");
                }
            }
            else if (raw.compilerOptions) {
                var outDir = raw.compilerOptions.outDir;
                var declarationDir = raw.compilerOptions.declarationDir;
                if (outDir || declarationDir) {
                    excludeSpecs = [outDir, declarationDir].filter(function (d) { return !!d; });
                }
            }
            if (filesSpecs === undefined && includeSpecs === undefined) {
                includeSpecs = ["**/*"];
            }
            var result = matchFileNames(filesSpecs, includeSpecs, excludeSpecs, configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath, options, host, errors, extraFileExtensions, sourceFile);
            if (shouldReportNoInputFiles(result, canJsonReportNoInutFiles(raw), resolutionStack)) {
                errors.push(getErrorForNoInputFiles(result.spec, configFileName));
            }
            if (ts.hasProperty(raw, "references") && !isNullOrUndefined(raw.references)) {
                if (ts.isArray(raw.references)) {
                    for (var _i = 0, _a = raw.references; _i < _a.length; _i++) {
                        var ref = _a[_i];
                        if (typeof ref.path !== "string") {
                            createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "reference.path", "string");
                        }
                        else {
                            (projectReferences || (projectReferences = [])).push({
                                path: ts.getNormalizedAbsolutePath(ref.path, basePath),
                                originalPath: ref.path,
                                prepend: ref.prepend,
                                circular: ref.circular
                            });
                        }
                    }
                }
                else {
                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "references", "Array");
                }
            }
            return result;
        }
        function createCompilerDiagnosticOnlyIfJson(message, arg0, arg1) {
            if (!sourceFile) {
                errors.push(ts.createCompilerDiagnostic(message, arg0, arg1));
            }
        }
    }
    function isErrorNoInputFiles(error) {
        return error.code === ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code;
    }
    function getErrorForNoInputFiles(_a, configFileName) {
        var includeSpecs = _a.includeSpecs, excludeSpecs = _a.excludeSpecs;
        return ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, configFileName || "tsconfig.json", JSON.stringify(includeSpecs || []), JSON.stringify(excludeSpecs || []));
    }
    function shouldReportNoInputFiles(result, canJsonReportNoInutFiles, resolutionStack) {
        return result.fileNames.length === 0 && canJsonReportNoInutFiles && (!resolutionStack || resolutionStack.length === 0);
    }
    /*@internal*/
    function canJsonReportNoInutFiles(raw) {
        return !ts.hasProperty(raw, "files") && !ts.hasProperty(raw, "references");
    }
    ts.canJsonReportNoInutFiles = canJsonReportNoInutFiles;
    /*@internal*/
    function updateErrorForNoInputFiles(result, configFileName, configFileSpecs, configParseDiagnostics, canJsonReportNoInutFiles) {
        var existingErrors = configParseDiagnostics.length;
        if (shouldReportNoInputFiles(result, canJsonReportNoInutFiles)) {
            configParseDiagnostics.push(getErrorForNoInputFiles(configFileSpecs, configFileName));
        }
        else {
            ts.filterMutate(configParseDiagnostics, function (error) { return !isErrorNoInputFiles(error); });
        }
        return existingErrors !== configParseDiagnostics.length;
    }
    ts.updateErrorForNoInputFiles = updateErrorForNoInputFiles;
    function isSuccessfulParsedTsconfig(value) {
        return !!value.options;
    }
    /**
     * This *just* extracts options/include/exclude/files out of a config file.
     * It does *not* resolve the included files.
     */
    function parseConfig(json, sourceFile, host, basePath, configFileName, resolutionStack, errors, extendedConfigCache) {
        basePath = ts.normalizeSlashes(basePath);
        var resolvedPath = ts.getNormalizedAbsolutePath(configFileName || "", basePath);
        if (resolutionStack.indexOf(resolvedPath) >= 0) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Circularity_detected_while_resolving_configuration_Colon_0, resolutionStack.concat([resolvedPath]).join(" -> ")));
            return { raw: json || convertToObject(sourceFile, errors) };
        }
        var ownConfig = json ?
            parseOwnConfigOfJson(json, host, basePath, configFileName, errors) :
            parseOwnConfigOfJsonSourceFile(sourceFile, host, basePath, configFileName, errors);
        if (ownConfig.extendedConfigPath) {
            // copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios.
            resolutionStack = resolutionStack.concat([resolvedPath]);
            var extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, basePath, resolutionStack, errors, extendedConfigCache);
            if (extendedConfig && isSuccessfulParsedTsconfig(extendedConfig)) {
                var baseRaw_1 = extendedConfig.raw;
                var raw_1 = ownConfig.raw;
                var setPropertyInRawIfNotUndefined = function (propertyName) {
                    var value = raw_1[propertyName] || baseRaw_1[propertyName];
                    if (value) {
                        raw_1[propertyName] = value;
                    }
                };
                setPropertyInRawIfNotUndefined("include");
                setPropertyInRawIfNotUndefined("exclude");
                setPropertyInRawIfNotUndefined("files");
                if (raw_1.compileOnSave === undefined) {
                    raw_1.compileOnSave = baseRaw_1.compileOnSave;
                }
                ownConfig.options = ts.assign({}, extendedConfig.options, ownConfig.options);
                // TODO extend type typeAcquisition
            }
        }
        return ownConfig;
    }
    function parseOwnConfigOfJson(json, host, basePath, configFileName, errors) {
        if (ts.hasProperty(json, "excludes")) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
        }
        var options = convertCompilerOptionsFromJsonWorker(json.compilerOptions, basePath, errors, configFileName);
        // typingOptions has been deprecated and is only supported for backward compatibility purposes.
        // It should be removed in future releases - use typeAcquisition instead.
        var typeAcquisition = convertTypeAcquisitionFromJsonWorker(json.typeAcquisition || json.typingOptions, basePath, errors, configFileName);
        json.compileOnSave = convertCompileOnSaveOptionFromJson(json, basePath, errors);
        var extendedConfigPath;
        if (json.extends) {
            if (!ts.isString(json.extends)) {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "extends", "string"));
            }
            else {
                var newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath;
                extendedConfigPath = getExtendsConfigPath(json.extends, host, newBase, errors, ts.createCompilerDiagnostic);
            }
        }
        return { raw: json, options: options, typeAcquisition: typeAcquisition, extendedConfigPath: extendedConfigPath };
    }
    function parseOwnConfigOfJsonSourceFile(sourceFile, host, basePath, configFileName, errors) {
        var options = getDefaultCompilerOptions(configFileName);
        var typeAcquisition, typingOptionstypeAcquisition;
        var extendedConfigPath;
        var optionsIterator = {
            onSetValidOptionKeyValueInParent: function (parentOption, option, value) {
                ts.Debug.assert(parentOption === "compilerOptions" || parentOption === "typeAcquisition" || parentOption === "typingOptions");
                var currentOption = parentOption === "compilerOptions" ?
                    options :
                    parentOption === "typeAcquisition" ?
                        (typeAcquisition || (typeAcquisition = getDefaultTypeAcquisition(configFileName))) :
                        (typingOptionstypeAcquisition || (typingOptionstypeAcquisition = getDefaultTypeAcquisition(configFileName)));
                currentOption[option.name] = normalizeOptionValue(option, basePath, value);
            },
            onSetValidOptionKeyValueInRoot: function (key, _keyNode, value, valueNode) {
                switch (key) {
                    case "extends":
                        var newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath;
                        extendedConfigPath = getExtendsConfigPath(value, host, newBase, errors, function (message, arg0) {
                            return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueNode, message, arg0);
                        });
                        return;
                }
            },
            onSetUnknownOptionKeyValueInRoot: function (key, keyNode, _value, _valueNode) {
                if (key === "excludes") {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, keyNode, ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
                }
            }
        };
        var json = convertToObjectWorker(sourceFile, errors, /*returnValue*/ true, getTsconfigRootOptionsMap(), optionsIterator);
        if (!typeAcquisition) {
            if (typingOptionstypeAcquisition) {
                typeAcquisition = (typingOptionstypeAcquisition.enableAutoDiscovery !== undefined) ?
                    {
                        enable: typingOptionstypeAcquisition.enableAutoDiscovery,
                        include: typingOptionstypeAcquisition.include,
                        exclude: typingOptionstypeAcquisition.exclude
                    } :
                    typingOptionstypeAcquisition;
            }
            else {
                typeAcquisition = getDefaultTypeAcquisition(configFileName);
            }
        }
        return { raw: json, options: options, typeAcquisition: typeAcquisition, extendedConfigPath: extendedConfigPath };
    }
    function getExtendsConfigPath(extendedConfig, host, basePath, errors, createDiagnostic) {
        extendedConfig = ts.normalizeSlashes(extendedConfig);
        if (ts.isRootedDiskPath(extendedConfig) || ts.startsWith(extendedConfig, "./") || ts.startsWith(extendedConfig, "../")) {
            var extendedConfigPath = ts.getNormalizedAbsolutePath(extendedConfig, basePath);
            if (!host.fileExists(extendedConfigPath) && !ts.endsWith(extendedConfigPath, ".json" /* Json */)) {
                extendedConfigPath = extendedConfigPath + ".json";
                if (!host.fileExists(extendedConfigPath)) {
                    errors.push(createDiagnostic(ts.Diagnostics.File_0_not_found, extendedConfig));
                    return undefined;
                }
            }
            return extendedConfigPath;
        }
        // If the path isn't a rooted or relative path, resolve like a module
        var resolved = ts.nodeModuleNameResolver(extendedConfig, ts.combinePaths(basePath, "tsconfig.json"), { moduleResolution: ts.ModuleResolutionKind.NodeJs }, host, /*cache*/ undefined, /*projectRefs*/ undefined, /*lookupConfig*/ true);
        if (resolved.resolvedModule) {
            return resolved.resolvedModule.resolvedFileName;
        }
        errors.push(createDiagnostic(ts.Diagnostics.File_0_not_found, extendedConfig));
        return undefined;
    }
    function getExtendedConfig(sourceFile, extendedConfigPath, host, basePath, resolutionStack, errors, extendedConfigCache) {
        var _a;
        var path = host.useCaseSensitiveFileNames ? extendedConfigPath : ts.toLowerCase(extendedConfigPath);
        var value;
        var extendedResult;
        var extendedConfig;
        if (extendedConfigCache && (value = extendedConfigCache.get(path))) {
            (extendedResult = value.extendedResult, extendedConfig = value.extendedConfig);
        }
        else {
            extendedResult = readJsonConfigFile(extendedConfigPath, function (path) { return host.readFile(path); });
            if (!extendedResult.parseDiagnostics.length) {
                var extendedDirname = ts.getDirectoryPath(extendedConfigPath);
                extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, extendedDirname, ts.getBaseFileName(extendedConfigPath), resolutionStack, errors, extendedConfigCache);
                if (isSuccessfulParsedTsconfig(extendedConfig)) {
                    // Update the paths to reflect base path
                    var relativeDifference_1 = ts.convertToRelativePath(extendedDirname, basePath, ts.identity);
                    var updatePath_1 = function (path) { return ts.isRootedDiskPath(path) ? path : ts.combinePaths(relativeDifference_1, path); };
                    var mapPropertiesInRawIfNotUndefined = function (propertyName) {
                        if (raw_2[propertyName]) {
                            raw_2[propertyName] = ts.map(raw_2[propertyName], updatePath_1);
                        }
                    };
                    var raw_2 = extendedConfig.raw;
                    mapPropertiesInRawIfNotUndefined("include");
                    mapPropertiesInRawIfNotUndefined("exclude");
                    mapPropertiesInRawIfNotUndefined("files");
                }
            }
            if (extendedConfigCache) {
                extendedConfigCache.set(path, { extendedResult: extendedResult, extendedConfig: extendedConfig });
            }
        }
        if (sourceFile) {
            sourceFile.extendedSourceFiles = [extendedResult.fileName];
            if (extendedResult.extendedSourceFiles) {
                (_a = sourceFile.extendedSourceFiles).push.apply(_a, extendedResult.extendedSourceFiles);
            }
        }
        if (extendedResult.parseDiagnostics.length) {
            errors.push.apply(errors, extendedResult.parseDiagnostics);
            return undefined;
        }
        return extendedConfig;
    }
    function convertCompileOnSaveOptionFromJson(jsonOption, basePath, errors) {
        if (!ts.hasProperty(jsonOption, ts.compileOnSaveCommandLineOption.name)) {
            return false;
        }
        var result = convertJsonOption(ts.compileOnSaveCommandLineOption, jsonOption.compileOnSave, basePath, errors);
        return typeof result === "boolean" && result;
    }
    function convertCompilerOptionsFromJson(jsonOptions, basePath, configFileName) {
        var errors = [];
        var options = convertCompilerOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName);
        return { options: options, errors: errors };
    }
    ts.convertCompilerOptionsFromJson = convertCompilerOptionsFromJson;
    function convertTypeAcquisitionFromJson(jsonOptions, basePath, configFileName) {
        var errors = [];
        var options = convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName);
        return { options: options, errors: errors };
    }
    ts.convertTypeAcquisitionFromJson = convertTypeAcquisitionFromJson;
    function getDefaultCompilerOptions(configFileName) {
        var options = configFileName && ts.getBaseFileName(configFileName) === "jsconfig.json"
            ? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true, noEmit: true }
            : {};
        return options;
    }
    function convertCompilerOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName) {
        var options = getDefaultCompilerOptions(configFileName);
        convertOptionsFromJson(ts.optionDeclarations, jsonOptions, basePath, options, ts.Diagnostics.Unknown_compiler_option_0, errors);
        if (configFileName) {
            options.configFilePath = ts.normalizeSlashes(configFileName);
        }
        return options;
    }
    function getDefaultTypeAcquisition(configFileName) {
        return { enable: !!configFileName && ts.getBaseFileName(configFileName) === "jsconfig.json", include: [], exclude: [] };
    }
    function convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName) {
        var options = getDefaultTypeAcquisition(configFileName);
        var typeAcquisition = convertEnableAutoDiscoveryToEnable(jsonOptions);
        convertOptionsFromJson(ts.typeAcquisitionDeclarations, typeAcquisition, basePath, options, ts.Diagnostics.Unknown_type_acquisition_option_0, errors);
        return options;
    }
    function convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, defaultOptions, diagnosticMessage, errors) {
        if (!jsonOptions) {
            return;
        }
        var optionNameMap = commandLineOptionsToMap(optionDeclarations);
        for (var id in jsonOptions) {
            var opt = optionNameMap.get(id);
            if (opt) {
                defaultOptions[opt.name] = convertJsonOption(opt, jsonOptions[id], basePath, errors);
            }
            else {
                errors.push(ts.createCompilerDiagnostic(diagnosticMessage, id));
            }
        }
    }
    function convertJsonOption(opt, value, basePath, errors) {
        if (isCompilerOptionsValue(opt, value)) {
            var optType = opt.type;
            if (optType === "list" && ts.isArray(value)) {
                return convertJsonOptionOfListType(opt, value, basePath, errors);
            }
            else if (!ts.isString(optType)) {
                return convertJsonOptionOfCustomType(opt, value, errors);
            }
            return normalizeNonListOptionValue(opt, basePath, value);
        }
        else {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, opt.name, getCompilerOptionValueTypeString(opt)));
        }
    }
    function normalizeOptionValue(option, basePath, value) {
        if (isNullOrUndefined(value))
            return undefined;
        if (option.type === "list") {
            var listOption_1 = option;
            if (listOption_1.element.isFilePath || !ts.isString(listOption_1.element.type)) {
                return ts.filter(ts.map(value, function (v) { return normalizeOptionValue(listOption_1.element, basePath, v); }), function (v) { return !!v; });
            }
            return value;
        }
        else if (!ts.isString(option.type)) {
            return option.type.get(ts.isString(value) ? value.toLowerCase() : value);
        }
        return normalizeNonListOptionValue(option, basePath, value);
    }
    function normalizeNonListOptionValue(option, basePath, value) {
        if (option.isFilePath) {
            value = ts.normalizePath(ts.combinePaths(basePath, value));
            if (value === "") {
                value = ".";
            }
        }
        return value;
    }
    function convertJsonOptionOfCustomType(opt, value, errors) {
        if (isNullOrUndefined(value))
            return undefined;
        var key = value.toLowerCase();
        var val = opt.type.get(key);
        if (val !== undefined) {
            return val;
        }
        else {
            errors.push(createCompilerDiagnosticForInvalidCustomType(opt));
        }
    }
    function convertJsonOptionOfListType(option, values, basePath, errors) {
        return ts.filter(ts.map(values, function (v) { return convertJsonOption(option.element, v, basePath, errors); }), function (v) { return !!v; });
    }
    function trimString(s) {
        return typeof s.trim === "function" ? s.trim() : s.replace(/^[\s]+|[\s]+$/g, "");
    }
    /**
     * Tests for a path that ends in a recursive directory wildcard.
     * Matches **, \**, **\, and \**\, but not a**b.
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  (^|\/)      # matches either the beginning of the string or a directory separator.
     *  \*\*        # matches the recursive directory wildcard "**".
     *  \/?$        # matches an optional trailing directory separator at the end of the string.
     */
    var invalidTrailingRecursionPattern = /(^|\/)\*\*\/?$/;
    /**
     * Tests for a path where .. appears after a recursive directory wildcard.
     * Matches **\..\*, **\a\..\*, and **\.., but not ..\**\*
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  (^|\/)      # matches either the beginning of the string or a directory separator.
     *  \*\*\/      # matches a recursive directory wildcard "**" followed by a directory separator.
     *  (.*\/)?     # optionally matches any number of characters followed by a directory separator.
     *  \.\.        # matches a parent directory path component ".."
     *  ($|\/)      # matches either the end of the string or a directory separator.
     */
    var invalidDotDotAfterRecursiveWildcardPattern = /(^|\/)\*\*\/(.*\/)?\.\.($|\/)/;
    /**
     * Tests for a path containing a wildcard character in a directory component of the path.
     * Matches \*\, \?\, and \a*b\, but not \a\ or \a\*.
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  \/          # matches a directory separator.
     *  [^/]*?      # matches any number of characters excluding directory separators (non-greedy).
     *  [*?]        # matches either a wildcard character (* or ?)
     *  [^/]*       # matches any number of characters excluding directory separators (greedy).
     *  \/          # matches a directory separator.
     */
    var watchRecursivePattern = /\/[^/]*?[*?][^/]*\//;
    /**
     * Matches the portion of a wildcard path that does not contain wildcards.
     * Matches \a of \a\*, or \a\b\c of \a\b\c\?\d.
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  ^                   # matches the beginning of the string
     *  [^*?]*              # matches any number of non-wildcard characters
     *  (?=\/[^/]*[*?])     # lookahead that matches a directory separator followed by
     *                      # a path component that contains at least one wildcard character (* or ?).
     */
    var wildcardDirectoryPattern = /^[^*?]*(?=\/[^/]*[*?])/;
    /**
     * Expands an array of file specifications.
     *
     * @param filesSpecs The literal file names to include.
     * @param includeSpecs The wildcard file specifications to include.
     * @param excludeSpecs The wildcard file specifications to exclude.
     * @param basePath The base path for any relative file specifications.
     * @param options Compiler options.
     * @param host The host used to resolve files and directories.
     * @param errors An array for diagnostic reporting.
     */
    function matchFileNames(filesSpecs, includeSpecs, excludeSpecs, basePath, options, host, errors, extraFileExtensions, jsonSourceFile) {
        basePath = ts.normalizePath(basePath);
        var validatedIncludeSpecs, validatedExcludeSpecs;
        // The exclude spec list is converted into a regular expression, which allows us to quickly
        // test whether a file or directory should be excluded before recursively traversing the
        // file system.
        if (includeSpecs) {
            validatedIncludeSpecs = validateSpecs(includeSpecs, errors, /*allowTrailingRecursion*/ false, jsonSourceFile, "include");
        }
        if (excludeSpecs) {
            validatedExcludeSpecs = validateSpecs(excludeSpecs, errors, /*allowTrailingRecursion*/ true, jsonSourceFile, "exclude");
        }
        // Wildcard directories (provided as part of a wildcard path) are stored in a
        // file map that marks whether it was a regular wildcard match (with a `*` or `?` token),
        // or a recursive directory. This information is used by filesystem watchers to monitor for
        // new entries in these paths.
        var wildcardDirectories = getWildcardDirectories(validatedIncludeSpecs, validatedExcludeSpecs, basePath, host.useCaseSensitiveFileNames);
        var spec = { filesSpecs: filesSpecs, includeSpecs: includeSpecs, excludeSpecs: excludeSpecs, validatedIncludeSpecs: validatedIncludeSpecs, validatedExcludeSpecs: validatedExcludeSpecs, wildcardDirectories: wildcardDirectories };
        return getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions);
    }
    /**
     * Gets the file names from the provided config file specs that contain, files, include, exclude and
     * other properties needed to resolve the file names
     * @param spec The config file specs extracted with file names to include, wildcards to include/exclude and other details
     * @param basePath The base path for any relative file specifications.
     * @param options Compiler options.
     * @param host The host used to resolve files and directories.
     * @param extraFileExtensions optionaly file extra file extension information from host
     */
    /* @internal */
    function getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions) {
        if (extraFileExtensions === void 0) { extraFileExtensions = []; }
        basePath = ts.normalizePath(basePath);
        var keyMapper = host.useCaseSensitiveFileNames ? ts.identity : ts.toLowerCase;
        // Literal file names (provided via the "files" array in tsconfig.json) are stored in a
        // file map with a possibly case insensitive key. We use this map later when when including
        // wildcard paths.
        var literalFileMap = ts.createMap();
        // Wildcard paths (provided via the "includes" array in tsconfig.json) are stored in a
        // file map with a possibly case insensitive key. We use this map to store paths matched
        // via wildcard, and to handle extension priority.
        var wildcardFileMap = ts.createMap();
        // Wildcard paths of json files (provided via the "includes" array in tsconfig.json) are stored in a
        // file map with a possibly case insensitive key. We use this map to store paths matched
        // via wildcard of *.json kind
        var wildCardJsonFileMap = ts.createMap();
        var filesSpecs = spec.filesSpecs, validatedIncludeSpecs = spec.validatedIncludeSpecs, validatedExcludeSpecs = spec.validatedExcludeSpecs, wildcardDirectories = spec.wildcardDirectories;
        // Rather than requery this for each file and filespec, we query the supported extensions
        // once and store it on the expansion context.
        var supportedExtensions = ts.getSupportedExtensions(options, extraFileExtensions);
        var supportedExtensionsWithJsonIfResolveJsonModule = ts.getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions);
        // Literal files are always included verbatim. An "include" or "exclude" specification cannot
        // remove a literal file.
        if (filesSpecs) {
            for (var _i = 0, filesSpecs_1 = filesSpecs; _i < filesSpecs_1.length; _i++) {
                var fileName = filesSpecs_1[_i];
                var file = ts.getNormalizedAbsolutePath(fileName, basePath);
                literalFileMap.set(keyMapper(file), file);
            }
        }
        var jsonOnlyIncludeRegexes;
        if (validatedIncludeSpecs && validatedIncludeSpecs.length > 0) {
            var _loop_4 = function (file) {
                if (ts.fileExtensionIs(file, ".json" /* Json */)) {
                    // Valid only if *.json specified
                    if (!jsonOnlyIncludeRegexes) {
                        var includes = validatedIncludeSpecs.filter(function (s) { return ts.endsWith(s, ".json" /* Json */); });
                        var includeFilePatterns = ts.map(ts.getRegularExpressionsForWildcards(includes, basePath, "files"), function (pattern) { return "^" + pattern + "$"; });
                        jsonOnlyIncludeRegexes = includeFilePatterns ? includeFilePatterns.map(function (pattern) { return ts.getRegexFromPattern(pattern, host.useCaseSensitiveFileNames); }) : ts.emptyArray;
                    }
                    var includeIndex = ts.findIndex(jsonOnlyIncludeRegexes, function (re) { return re.test(file); });
                    if (includeIndex !== -1) {
                        var key_1 = keyMapper(file);
                        if (!literalFileMap.has(key_1) && !wildCardJsonFileMap.has(key_1)) {
                            wildCardJsonFileMap.set(key_1, file);
                        }
                    }
                    return "continue";
                }
                // If we have already included a literal or wildcard path with a
                // higher priority extension, we should skip this file.
                //
                // This handles cases where we may encounter both <file>.ts and
                // <file>.d.ts (or <file>.js if "allowJs" is enabled) in the same
                // directory when they are compilation outputs.
                if (hasFileWithHigherPriorityExtension(file, literalFileMap, wildcardFileMap, supportedExtensions, keyMapper)) {
                    return "continue";
                }
                // We may have included a wildcard path with a lower priority
                // extension due to the user-defined order of entries in the
                // "include" array. If there is a lower priority extension in the
                // same directory, we should remove it.
                removeWildcardFilesWithLowerPriorityExtension(file, wildcardFileMap, supportedExtensions, keyMapper);
                var key = keyMapper(file);
                if (!literalFileMap.has(key) && !wildcardFileMap.has(key)) {
                    wildcardFileMap.set(key, file);
                }
            };
            for (var _a = 0, _b = host.readDirectory(basePath, supportedExtensionsWithJsonIfResolveJsonModule, validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined); _a < _b.length; _a++) {
                var file = _b[_a];
                _loop_4(file);
            }
        }
        var literalFiles = ts.arrayFrom(literalFileMap.values());
        var wildcardFiles = ts.arrayFrom(wildcardFileMap.values());
        return {
            fileNames: literalFiles.concat(wildcardFiles, ts.arrayFrom(wildCardJsonFileMap.values())),
            wildcardDirectories: wildcardDirectories,
            spec: spec
        };
    }
    ts.getFileNamesFromConfigSpecs = getFileNamesFromConfigSpecs;
    function validateSpecs(specs, errors, allowTrailingRecursion, jsonSourceFile, specKey) {
        return specs.filter(function (spec) {
            var diag = specToDiagnostic(spec, allowTrailingRecursion);
            if (diag !== undefined) {
                errors.push(createDiagnostic(diag, spec));
            }
            return diag === undefined;
        });
        function createDiagnostic(message, spec) {
            var element = ts.getTsConfigPropArrayElementValue(jsonSourceFile, specKey, spec);
            return element ?
                ts.createDiagnosticForNodeInSourceFile(jsonSourceFile, element, message, spec) :
                ts.createCompilerDiagnostic(message, spec);
        }
    }
    function specToDiagnostic(spec, allowTrailingRecursion) {
        if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) {
            return ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0;
        }
        else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) {
            return ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0;
        }
    }
    /**
     * Gets directories in a set of include patterns that should be watched for changes.
     */
    function getWildcardDirectories(include, exclude, path, useCaseSensitiveFileNames) {
        // We watch a directory recursively if it contains a wildcard anywhere in a directory segment
        // of the pattern:
        //
        //  /a/b/**/d   - Watch /a/b recursively to catch changes to any d in any subfolder recursively
        //  /a/b/*/d    - Watch /a/b recursively to catch any d in any immediate subfolder, even if a new subfolder is added
        //  /a/b        - Watch /a/b recursively to catch changes to anything in any recursive subfoler
        //
        // We watch a directory without recursion if it contains a wildcard in the file segment of
        // the pattern:
        //
        //  /a/b/*      - Watch /a/b directly to catch any new file
        //  /a/b/a?z    - Watch /a/b directly to catch any new file matching a?z
        var rawExcludeRegex = ts.getRegularExpressionForWildcard(exclude, path, "exclude");
        var excludeRegex = rawExcludeRegex && new RegExp(rawExcludeRegex, useCaseSensitiveFileNames ? "" : "i");
        var wildcardDirectories = {};
        if (include !== undefined) {
            var recursiveKeys = [];
            for (var _i = 0, include_1 = include; _i < include_1.length; _i++) {
                var file = include_1[_i];
                var spec = ts.normalizePath(ts.combinePaths(path, file));
                if (excludeRegex && excludeRegex.test(spec)) {
                    continue;
                }
                var match = getWildcardDirectoryFromSpec(spec, useCaseSensitiveFileNames);
                if (match) {
                    var key = match.key, flags = match.flags;
                    var existingFlags = wildcardDirectories[key];
                    if (existingFlags === undefined || existingFlags < flags) {
                        wildcardDirectories[key] = flags;
                        if (flags === 1 /* Recursive */) {
                            recursiveKeys.push(key);
                        }
                    }
                }
            }
            // Remove any subpaths under an existing recursively watched directory.
            for (var key in wildcardDirectories) {
                if (ts.hasProperty(wildcardDirectories, key)) {
                    for (var _a = 0, recursiveKeys_1 = recursiveKeys; _a < recursiveKeys_1.length; _a++) {
                        var recursiveKey = recursiveKeys_1[_a];
                        if (key !== recursiveKey && ts.containsPath(recursiveKey, key, path, !useCaseSensitiveFileNames)) {
                            delete wildcardDirectories[key];
                        }
                    }
                }
            }
        }
        return wildcardDirectories;
    }
    function getWildcardDirectoryFromSpec(spec, useCaseSensitiveFileNames) {
        var match = wildcardDirectoryPattern.exec(spec);
        if (match) {
            return {
                key: useCaseSensitiveFileNames ? match[0] : match[0].toLowerCase(),
                flags: watchRecursivePattern.test(spec) ? 1 /* Recursive */ : 0 /* None */
            };
        }
        if (ts.isImplicitGlob(spec)) {
            return { key: spec, flags: 1 /* Recursive */ };
        }
        return undefined;
    }
    /**
     * Determines whether a literal or wildcard file has already been included that has a higher
     * extension priority.
     *
     * @param file The path to the file.
     * @param extensionPriority The priority of the extension.
     * @param context The expansion context.
     */
    function hasFileWithHigherPriorityExtension(file, literalFiles, wildcardFiles, extensions, keyMapper) {
        var extensionPriority = ts.getExtensionPriority(file, extensions);
        var adjustedExtensionPriority = ts.adjustExtensionPriority(extensionPriority, extensions);
        for (var i = 0 /* Highest */; i < adjustedExtensionPriority; i++) {
            var higherPriorityExtension = extensions[i];
            var higherPriorityPath = keyMapper(ts.changeExtension(file, higherPriorityExtension));
            if (literalFiles.has(higherPriorityPath) || wildcardFiles.has(higherPriorityPath)) {
                return true;
            }
        }
        return false;
    }
    /**
     * Removes files included via wildcard expansion with a lower extension priority that have
     * already been included.
     *
     * @param file The path to the file.
     * @param extensionPriority The priority of the extension.
     * @param context The expansion context.
     */
    function removeWildcardFilesWithLowerPriorityExtension(file, wildcardFiles, extensions, keyMapper) {
        var extensionPriority = ts.getExtensionPriority(file, extensions);
        var nextExtensionPriority = ts.getNextLowestExtensionPriority(extensionPriority, extensions);
        for (var i = nextExtensionPriority; i < extensions.length; i++) {
            var lowerPriorityExtension = extensions[i];
            var lowerPriorityPath = keyMapper(ts.changeExtension(file, lowerPriorityExtension));
            wildcardFiles.delete(lowerPriorityPath);
        }
    }
    /**
     * Produces a cleaned version of compiler options with personally identifying info (aka, paths) removed.
     * Also converts enum values back to strings.
     */
    /* @internal */
    function convertCompilerOptionsForTelemetry(opts) {
        var out = {};
        for (var key in opts) {
            if (opts.hasOwnProperty(key)) {
                var type = getOptionFromName(key);
                if (type !== undefined) { // Ignore unknown options
                    out[key] = getOptionValueWithEmptyStrings(opts[key], type);
                }
            }
        }
        return out;
    }
    ts.convertCompilerOptionsForTelemetry = convertCompilerOptionsForTelemetry;
    function getOptionValueWithEmptyStrings(value, option) {
        switch (option.type) {
            case "object": // "paths". Can't get any useful information from the value since we blank out strings, so just return "".
                return "";
            case "string": // Could be any arbitrary string -- use empty string instead.
                return "";
            case "number": // Allow numbers, but be sure to check it's actually a number.
                return typeof value === "number" ? value : "";
            case "boolean":
                return typeof value === "boolean" ? value : "";
            case "list":
                var elementType_1 = option.element;
                return ts.isArray(value) ? value.map(function (v) { return getOptionValueWithEmptyStrings(v, elementType_1); }) : "";
            default:
                return ts.forEachEntry(option.type, function (optionEnumValue, optionStringValue) {
                    if (optionEnumValue === value) {
                        return optionStringValue;
                    }
                }); // TODO: GH#18217
        }
    }
})(ts || (ts = {}));
var ts;
(function (ts) {
    function trace(host) {
        host.trace(ts.formatMessage.apply(undefined, arguments));
    }
    ts.trace = trace;
    /* @internal */
    function isTraceEnabled(compilerOptions, host) {
        return !!compilerOptions.traceResolution && host.trace !== undefined;
    }
    ts.isTraceEnabled = isTraceEnabled;
    function withPackageId(packageInfo, r) {
        var packageId;
        if (r && packageInfo) {
            var packageJsonContent = packageInfo.packageJsonContent;
            if (typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string") {
                packageId = {
                    name: packageJsonContent.name,
                    subModuleName: r.path.slice(packageInfo.packageDirectory.length + ts.directorySeparator.length),
                    version: packageJsonContent.version
                };
            }
        }
        return r && { path: r.path, extension: r.ext, packageId: packageId };
    }
    function noPackageId(r) {
        return withPackageId(/*packageInfo*/ undefined, r);
    }
    function removeIgnoredPackageId(r) {
        if (r) {
            ts.Debug.assert(r.packageId === undefined);
            return { path: r.path, ext: r.extension };
        }
    }
    /**
     * Kinds of file that we are currently looking for.
     * Typically there is one pass with Extensions.TypeScript, then a second pass with Extensions.JavaScript.
     */
    var Extensions;
    (function (Extensions) {
        Extensions[Extensions["TypeScript"] = 0] = "TypeScript";
        Extensions[Extensions["JavaScript"] = 1] = "JavaScript";
        Extensions[Extensions["Json"] = 2] = "Json";
        Extensions[Extensions["TSConfig"] = 3] = "TSConfig";
        Extensions[Extensions["DtsOnly"] = 4] = "DtsOnly"; /** Only '.d.ts' */
    })(Extensions || (Extensions = {}));
    /** Used with `Extensions.DtsOnly` to extract the path from TypeScript results. */
    function resolvedTypeScriptOnly(resolved) {
        if (!resolved) {
            return undefined;
        }
        ts.Debug.assert(ts.extensionIsTS(resolved.extension));
        return { fileName: resolved.path, packageId: resolved.packageId };
    }
    function createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations) {
        return {
            resolvedModule: resolved && { resolvedFileName: resolved.path, originalPath: resolved.originalPath === true ? undefined : resolved.originalPath, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport, packageId: resolved.packageId },
            failedLookupLocations: failedLookupLocations
        };
    }
    function readPackageJsonField(jsonContent, fieldName, typeOfTag, state) {
        if (!ts.hasProperty(jsonContent, fieldName)) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.package_json_does_not_have_a_0_field, fieldName);
            }
            return;
        }
        var value = jsonContent[fieldName];
        if (typeof value !== typeOfTag || value === null) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, fieldName, typeOfTag, value === null ? "null" : typeof value);
            }
            return;
        }
        return value;
    }
    function readPackageJsonPathField(jsonContent, fieldName, baseDirectory, state) {
        var fileName = readPackageJsonField(jsonContent, fieldName, "string", state);
        if (fileName === undefined) {
            return;
        }
        if (!fileName) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.package_json_had_a_falsy_0_field, fieldName);
            }
            return;
        }
        var path = ts.normalizePath(ts.combinePaths(baseDirectory, fileName));
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path);
        }
        return path;
    }
    function readPackageJsonTypesFields(jsonContent, baseDirectory, state) {
        return readPackageJsonPathField(jsonContent, "typings", baseDirectory, state)
            || readPackageJsonPathField(jsonContent, "types", baseDirectory, state);
    }
    function readPackageJsonTSConfigField(jsonContent, baseDirectory, state) {
        return readPackageJsonPathField(jsonContent, "tsconfig", baseDirectory, state);
    }
    function readPackageJsonMainField(jsonContent, baseDirectory, state) {
        return readPackageJsonPathField(jsonContent, "main", baseDirectory, state);
    }
    function readPackageJsonTypesVersionsField(jsonContent, state) {
        var typesVersions = readPackageJsonField(jsonContent, "typesVersions", "object", state);
        if (typesVersions === undefined)
            return;
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_field_with_version_specific_path_mappings);
        }
        return typesVersions;
    }
    function readPackageJsonTypesVersionPaths(jsonContent, state) {
        var typesVersions = readPackageJsonTypesVersionsField(jsonContent, state);
        if (typesVersions === undefined)
            return;
        if (state.traceEnabled) {
            for (var key in typesVersions) {
                if (ts.hasProperty(typesVersions, key) && !ts.VersionRange.tryParse(key)) {
                    trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range, key);
                }
            }
        }
        var result = getPackageJsonTypesVersionsPaths(typesVersions);
        if (!result) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.package_json_does_not_have_a_typesVersions_entry_that_matches_version_0, ts.versionMajorMinor);
            }
            return;
        }
        var bestVersionKey = result.version, bestVersionPaths = result.paths;
        if (typeof bestVersionPaths !== "object") {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, "typesVersions['" + bestVersionKey + "']", "object", typeof bestVersionPaths);
            }
            return;
        }
        return result;
    }
    var typeScriptVersion;
    /* @internal */
    function getPackageJsonTypesVersionsPaths(typesVersions) {
        if (!typeScriptVersion)
            typeScriptVersion = new ts.Version(ts.version);
        for (var key in typesVersions) {
            if (!ts.hasProperty(typesVersions, key))
                continue;
            var keyRange = ts.VersionRange.tryParse(key);
            if (keyRange === undefined) {
                continue;
            }
            // return the first entry whose range matches the current compiler version.
            if (keyRange.test(typeScriptVersion)) {
                return { version: key, paths: typesVersions[key] };
            }
        }
    }
    ts.getPackageJsonTypesVersionsPaths = getPackageJsonTypesVersionsPaths;
    function getEffectiveTypeRoots(options, host) {
        if (options.typeRoots) {
            return options.typeRoots;
        }
        var currentDirectory;
        if (options.configFilePath) {
            currentDirectory = ts.getDirectoryPath(options.configFilePath);
        }
        else if (host.getCurrentDirectory) {
            currentDirectory = host.getCurrentDirectory();
        }
        if (currentDirectory !== undefined) {
            return getDefaultTypeRoots(currentDirectory, host);
        }
    }
    ts.getEffectiveTypeRoots = getEffectiveTypeRoots;
    /**
     * Returns the path to every node_modules/@types directory from some ancestor directory.
     * Returns undefined if there are none.
     */
    function getDefaultTypeRoots(currentDirectory, host) {
        if (!host.directoryExists) {
            return [ts.combinePaths(currentDirectory, nodeModulesAtTypes)];
            // And if it doesn't exist, tough.
        }
        var typeRoots;
        ts.forEachAncestorDirectory(ts.normalizePath(currentDirectory), function (directory) {
            var atTypes = ts.combinePaths(directory, nodeModulesAtTypes);
            if (host.directoryExists(atTypes)) {
                (typeRoots || (typeRoots = [])).push(atTypes);
            }
            return undefined;
        });
        return typeRoots;
    }
    var nodeModulesAtTypes = ts.combinePaths("node_modules", "@types");
    /**
     * @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
     * This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
     * is assumed to be the same as root directory of the project.
     */
    function resolveTypeReferenceDirective(typeReferenceDirectiveName, containingFile, options, host, redirectedReference) {
        var traceEnabled = isTraceEnabled(options, host);
        if (redirectedReference) {
            options = redirectedReference.commandLine.options;
        }
        var failedLookupLocations = [];
        var moduleResolutionState = { compilerOptions: options, host: host, traceEnabled: traceEnabled, failedLookupLocations: failedLookupLocations };
        var typeRoots = getEffectiveTypeRoots(options, host);
        if (traceEnabled) {
            if (containingFile === undefined) {
                if (typeRoots === undefined) {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set, typeReferenceDirectiveName);
                }
                else {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1, typeReferenceDirectiveName, typeRoots);
                }
            }
            else {
                if (typeRoots === undefined) {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set, typeReferenceDirectiveName, containingFile);
                }
                else {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_2, typeReferenceDirectiveName, containingFile, typeRoots);
                }
            }
            if (redirectedReference) {
                trace(host, ts.Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName);
            }
        }
        var resolved = primaryLookup();
        var primary = true;
        if (!resolved) {
            resolved = secondaryLookup();
            primary = false;
        }
        var resolvedTypeReferenceDirective;
        if (resolved) {
            var fileName = resolved.fileName, packageId = resolved.packageId;
            var resolvedFileName = options.preserveSymlinks ? fileName : realPath(fileName, host, traceEnabled);
            if (traceEnabled) {
                if (packageId) {
                    trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3, typeReferenceDirectiveName, resolvedFileName, ts.packageIdToString(packageId), primary);
                }
                else {
                    trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFileName, primary);
                }
            }
            resolvedTypeReferenceDirective = { primary: primary, resolvedFileName: resolvedFileName, packageId: packageId, isExternalLibraryImport: pathContainsNodeModules(fileName) };
        }
        return { resolvedTypeReferenceDirective: resolvedTypeReferenceDirective, failedLookupLocations: failedLookupLocations };
        function primaryLookup() {
            // Check primary library paths
            if (typeRoots && typeRoots.length) {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(", "));
                }
                return ts.firstDefined(typeRoots, function (typeRoot) {
                    var candidate = ts.combinePaths(typeRoot, typeReferenceDirectiveName);
                    var candidateDirectory = ts.getDirectoryPath(candidate);
                    var directoryExists = ts.directoryProbablyExists(candidateDirectory, host);
                    if (!directoryExists && traceEnabled) {
                        trace(host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidateDirectory);
                    }
                    return resolvedTypeScriptOnly(loadNodeModuleFromDirectory(Extensions.DtsOnly, candidate, !directoryExists, moduleResolutionState));
                });
            }
            else {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Root_directory_cannot_be_determined_skipping_primary_search_paths);
                }
            }
        }
        function secondaryLookup() {
            var initialLocationForSecondaryLookup = containingFile && ts.getDirectoryPath(containingFile);
            if (initialLocationForSecondaryLookup !== undefined) {
                // check secondary locations
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup);
                }
                var result = void 0;
                if (!ts.isExternalModuleNameRelative(typeReferenceDirectiveName)) {
                    var searchResult = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
                    result = searchResult && searchResult.value;
                }
                else {
                    var candidate = ts.normalizePathAndParts(ts.combinePaths(initialLocationForSecondaryLookup, typeReferenceDirectiveName)).path;
                    result = nodeLoadModuleByRelativeName(Extensions.DtsOnly, candidate, /*onlyRecordFailures*/ false, moduleResolutionState, /*considerPackageJson*/ true);
                }
                var resolvedFile = resolvedTypeScriptOnly(result);
                if (!resolvedFile && traceEnabled) {
                    trace(host, ts.Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName);
                }
                return resolvedFile;
            }
            else {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder);
                }
            }
        }
    }
    ts.resolveTypeReferenceDirective = resolveTypeReferenceDirective;
    /**
     * Given a set of options, returns the set of type directive names
     *   that should be included for this program automatically.
     * This list could either come from the config file,
     *   or from enumerating the types root + initial secondary types lookup location.
     * More type directives might appear in the program later as a result of loading actual source files;
     *   this list is only the set of defaults that are implicitly included.
     */
    function getAutomaticTypeDirectiveNames(options, host) {
        // Use explicit type list from tsconfig.json
        if (options.types) {
            return options.types;
        }
        // Walk the primary type lookup locations
        var result = [];
        if (host.directoryExists && host.getDirectories) {
            var typeRoots = getEffectiveTypeRoots(options, host);
            if (typeRoots) {
                for (var _i = 0, typeRoots_1 = typeRoots; _i < typeRoots_1.length; _i++) {
                    var root = typeRoots_1[_i];
                    if (host.directoryExists(root)) {
                        for (var _a = 0, _b = host.getDirectories(root); _a < _b.length; _a++) {
                            var typeDirectivePath = _b[_a];
                            var normalized = ts.normalizePath(typeDirectivePath);
                            var packageJsonPath = ts.combinePaths(root, normalized, "package.json");
                            // `types-publisher` sometimes creates packages with `"typings": null` for packages that don't provide their own types.
                            // See `createNotNeededPackageJSON` in the types-publisher` repo.
                            // tslint:disable-next-line:no-null-keyword
                            var isNotNeededPackage = host.fileExists(packageJsonPath) && ts.readJson(packageJsonPath, host).typings === null;
                            if (!isNotNeededPackage) {
                                var baseFileName = ts.getBaseFileName(normalized);
                                // At this stage, skip results with leading dot.
                                if (baseFileName.charCodeAt(0) !== 46 /* dot */) {
                                    // Return just the type directive names
                                    result.push(baseFileName);
                                }
                            }
                        }
                    }
                }
            }
        }
        return result;
    }
    ts.getAutomaticTypeDirectiveNames = getAutomaticTypeDirectiveNames;
    function createModuleResolutionCache(currentDirectory, getCanonicalFileName, options) {
        return createModuleResolutionCacheWithMaps(createCacheWithRedirects(options), createCacheWithRedirects(options), currentDirectory, getCanonicalFileName);
    }
    ts.createModuleResolutionCache = createModuleResolutionCache;
    /*@internal*/
    function createCacheWithRedirects(options) {
        var ownMap = ts.createMap();
        var redirectsMap = ts.createMap();
        return {
            ownMap: ownMap,
            redirectsMap: redirectsMap,
            getOrCreateMapOfCacheRedirects: getOrCreateMapOfCacheRedirects,
            clear: clear,
            setOwnOptions: setOwnOptions,
            setOwnMap: setOwnMap
        };
        function setOwnOptions(newOptions) {
            options = newOptions;
        }
        function setOwnMap(newOwnMap) {
            ownMap = newOwnMap;
        }
        function getOrCreateMapOfCacheRedirects(redirectedReference) {
            if (!redirectedReference) {
                return ownMap;
            }
            var path = redirectedReference.sourceFile.path;
            var redirects = redirectsMap.get(path);
            if (!redirects) {
                // Reuse map if redirected reference map uses same resolution
                redirects = !options || ts.optionsHaveModuleResolutionChanges(options, redirectedReference.commandLine.options) ? ts.createMap() : ownMap;
                redirectsMap.set(path, redirects);
            }
            return redirects;
        }
        function clear() {
            ownMap.clear();
            redirectsMap.clear();
        }
    }
    ts.createCacheWithRedirects = createCacheWithRedirects;
    /*@internal*/
    function createModuleResolutionCacheWithMaps(directoryToModuleNameMap, moduleNameToDirectoryMap, currentDirectory, getCanonicalFileName) {
        return { getOrCreateCacheForDirectory: getOrCreateCacheForDirectory, getOrCreateCacheForModuleName: getOrCreateCacheForModuleName, directoryToModuleNameMap: directoryToModuleNameMap, moduleNameToDirectoryMap: moduleNameToDirectoryMap };
        function getOrCreateCacheForDirectory(directoryName, redirectedReference) {
            var path = ts.toPath(directoryName, currentDirectory, getCanonicalFileName);
            return getOrCreateCache(directoryToModuleNameMap, redirectedReference, path, ts.createMap);
        }
        function getOrCreateCacheForModuleName(nonRelativeModuleName, redirectedReference) {
            ts.Debug.assert(!ts.isExternalModuleNameRelative(nonRelativeModuleName));
            return getOrCreateCache(moduleNameToDirectoryMap, redirectedReference, nonRelativeModuleName, createPerModuleNameCache);
        }
        function getOrCreateCache(cacheWithRedirects, redirectedReference, key, create) {
            var cache = cacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference);
            var result = cache.get(key);
            if (!result) {
                result = create();
                cache.set(key, result);
            }
            return result;
        }
        function createPerModuleNameCache() {
            var directoryPathMap = ts.createMap();
            return { get: get, set: set };
            function get(directory) {
                return directoryPathMap.get(ts.toPath(directory, currentDirectory, getCanonicalFileName));
            }
            /**
             * At first this function add entry directory -> module resolution result to the table.
             * Then it computes the set of parent folders for 'directory' that should have the same module resolution result
             * and for every parent folder in set it adds entry: parent -> module resolution. .
             * Lets say we first directory name: /a/b/c/d/e and resolution result is: /a/b/bar.ts.
             * Set of parent folders that should have the same result will be:
             * [
             *     /a/b/c/d, /a/b/c, /a/b
             * ]
             * this means that request for module resolution from file in any of these folder will be immediately found in cache.
             */
            function set(directory, result) {
                var path = ts.toPath(directory, currentDirectory, getCanonicalFileName);
                // if entry is already in cache do nothing
                if (directoryPathMap.has(path)) {
                    return;
                }
                directoryPathMap.set(path, result);
                var resolvedFileName = result.resolvedModule &&
                    (result.resolvedModule.originalPath || result.resolvedModule.resolvedFileName);
                // find common prefix between directory and resolved file name
                // this common prefix should be the shortest path that has the same resolution
                // directory: /a/b/c/d/e
                // resolvedFileName: /a/b/foo.d.ts
                // commonPrefix: /a/b
                // for failed lookups cache the result for every directory up to root
                var commonPrefix = resolvedFileName && getCommonPrefix(path, resolvedFileName);
                var current = path;
                while (current !== commonPrefix) {
                    var parent = ts.getDirectoryPath(current);
                    if (parent === current || directoryPathMap.has(parent)) {
                        break;
                    }
                    directoryPathMap.set(parent, result);
                    current = parent;
                }
            }
            function getCommonPrefix(directory, resolution) {
                var resolutionDirectory = ts.toPath(ts.getDirectoryPath(resolution), currentDirectory, getCanonicalFileName);
                // find first position where directory and resolution differs
                var i = 0;
                var limit = Math.min(directory.length, resolutionDirectory.length);
                while (i < limit && directory.charCodeAt(i) === resolutionDirectory.charCodeAt(i)) {
                    i++;
                }
                if (i === directory.length && (resolutionDirectory.length === i || resolutionDirectory[i] === ts.directorySeparator)) {
                    return directory;
                }
                var rootLength = ts.getRootLength(directory);
                if (i < rootLength) {
                    return undefined;
                }
                var sep = directory.lastIndexOf(ts.directorySeparator, i - 1);
                if (sep === -1) {
                    return undefined;
                }
                return directory.substr(0, Math.max(sep, rootLength));
            }
        }
    }
    ts.createModuleResolutionCacheWithMaps = createModuleResolutionCacheWithMaps;
    function resolveModuleNameFromCache(moduleName, containingFile, cache) {
        var containingDirectory = ts.getDirectoryPath(containingFile);
        var perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory);
        return perFolderCache && perFolderCache.get(moduleName);
    }
    ts.resolveModuleNameFromCache = resolveModuleNameFromCache;
    function resolveModuleName(moduleName, containingFile, compilerOptions, host, cache, redirectedReference) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        if (redirectedReference) {
            compilerOptions = redirectedReference.commandLine.options;
        }
        if (traceEnabled) {
            trace(host, ts.Diagnostics.Resolving_module_0_from_1, moduleName, containingFile);
            if (redirectedReference) {
                trace(host, ts.Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName);
            }
        }
        var containingDirectory = ts.getDirectoryPath(containingFile);
        var perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference);
        var result = perFolderCache && perFolderCache.get(moduleName);
        if (result) {
            if (traceEnabled) {
                trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory);
            }
        }
        else {
            var moduleResolution = compilerOptions.moduleResolution;
            if (moduleResolution === undefined) {
                moduleResolution = ts.getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS ? ts.ModuleResolutionKind.NodeJs : ts.ModuleResolutionKind.Classic;
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Module_resolution_kind_is_not_specified_using_0, ts.ModuleResolutionKind[moduleResolution]);
                }
            }
            else {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Explicitly_specified_module_resolution_kind_Colon_0, ts.ModuleResolutionKind[moduleResolution]);
                }
            }
            switch (moduleResolution) {
                case ts.ModuleResolutionKind.NodeJs:
                    result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference);
                    break;
                case ts.ModuleResolutionKind.Classic:
                    result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference);
                    break;
                default:
                    return ts.Debug.fail("Unexpected moduleResolution: " + moduleResolution);
            }
            if (perFolderCache) {
                perFolderCache.set(moduleName, result);
                if (!ts.isExternalModuleNameRelative(moduleName)) {
                    // put result in per-module name cache
                    cache.getOrCreateCacheForModuleName(moduleName, redirectedReference).set(containingDirectory, result);
                }
            }
        }
        if (traceEnabled) {
            if (result.resolvedModule) {
                if (result.resolvedModule.packageId) {
                    trace(host, ts.Diagnostics.Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2, moduleName, result.resolvedModule.resolvedFileName, ts.packageIdToString(result.resolvedModule.packageId));
                }
                else {
                    trace(host, ts.Diagnostics.Module_name_0_was_successfully_resolved_to_1, moduleName, result.resolvedModule.resolvedFileName);
                }
            }
            else {
                trace(host, ts.Diagnostics.Module_name_0_was_not_resolved, moduleName);
            }
        }
        return result;
    }
    ts.resolveModuleName = resolveModuleName;
    /**
     * Any module resolution kind can be augmented with optional settings: 'baseUrl', 'paths' and 'rootDirs' - they are used to
     * mitigate differences between design time structure of the project and its runtime counterpart so the same import name
     * can be resolved successfully by TypeScript compiler and runtime module loader.
     * If these settings are set then loading procedure will try to use them to resolve module name and it can of failure it will
     * fallback to standard resolution routine.
     *
     * - baseUrl - this setting controls how non-relative module names are resolved. If this setting is specified then non-relative
     * names will be resolved relative to baseUrl: i.e. if baseUrl is '/a/b' then candidate location to resolve module name 'c/d' will
     * be '/a/b/c/d'
     * - paths - this setting can only be used when baseUrl is specified. allows to tune how non-relative module names
     * will be resolved based on the content of the module name.
     * Structure of 'paths' compiler options
     * 'paths': {
     *    pattern-1: [...substitutions],
     *    pattern-2: [...substitutions],
     *    ...
     *    pattern-n: [...substitutions]
     * }
     * Pattern here is a string that can contain zero or one '*' character. During module resolution module name will be matched against
     * all patterns in the list. Matching for patterns that don't contain '*' means that module name must be equal to pattern respecting the case.
     * If pattern contains '*' then to match pattern "<prefix>*<suffix>" module name must start with the <prefix> and end with <suffix>.
     * <MatchedStar> denotes part of the module name between <prefix> and <suffix>.
     * If module name can be matches with multiple patterns then pattern with the longest prefix will be picked.
     * After selecting pattern we'll use list of substitutions to get candidate locations of the module and the try to load module
     * from the candidate location.
     * Substitution is a string that can contain zero or one '*'. To get candidate location from substitution we'll pick every
     * substitution in the list and replace '*' with <MatchedStar> string. If candidate location is not rooted it
     * will be converted to absolute using baseUrl.
     * For example:
     * baseUrl: /a/b/c
     * "paths": {
     *     // match all module names
     *     "*": [
     *         "*",        // use matched name as is,
     *                     // <matched name> will be looked as /a/b/c/<matched name>
     *
     *         "folder1/*" // substitution will convert matched name to 'folder1/<matched name>',
     *                     // since it is not rooted then final candidate location will be /a/b/c/folder1/<matched name>
     *     ],
     *     // match module names that start with 'components/'
     *     "components/*": [ "/root/components/*" ] // substitution will convert /components/folder1/<matched name> to '/root/components/folder1/<matched name>',
     *                                              // it is rooted so it will be final candidate location
     * }
     *
     * 'rootDirs' allows the project to be spreaded across multiple locations and resolve modules with relative names as if
     * they were in the same location. For example lets say there are two files
     * '/local/src/content/file1.ts'
     * '/shared/components/contracts/src/content/protocols/file2.ts'
     * After bundling content of '/shared/components/contracts/src' will be merged with '/local/src' so
     * if file1 has the following import 'import {x} from "./protocols/file2"' it will be resolved successfully in runtime.
     * 'rootDirs' provides the way to tell compiler that in order to get the whole project it should behave as if content of all
     * root dirs were merged together.
     * I.e. for the example above 'rootDirs' will have two entries: [ '/local/src', '/shared/components/contracts/src' ].
     * Compiler will first convert './protocols/file2' into absolute path relative to the location of containing file:
     * '/local/src/content/protocols/file2' and try to load it - failure.
     * Then it will search 'rootDirs' looking for a longest matching prefix of this absolute path and if such prefix is found - absolute path will
     * be converted to a path relative to found rootDir entry './content/protocols/file2' (*). As a last step compiler will check all remaining
     * entries in 'rootDirs', use them to build absolute path out of (*) and try to resolve module from this location.
     */
    function tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, state) {
        var resolved = tryLoadModuleUsingPathsIfEligible(extensions, moduleName, loader, state);
        if (resolved)
            return resolved.value;
        if (!ts.isExternalModuleNameRelative(moduleName)) {
            return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, state);
        }
        else {
            return tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, state);
        }
    }
    function tryLoadModuleUsingPathsIfEligible(extensions, moduleName, loader, state) {
        var _a = state.compilerOptions, baseUrl = _a.baseUrl, paths = _a.paths;
        if (baseUrl && paths && !ts.pathIsRelative(moduleName)) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName);
                trace(state.host, ts.Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName);
            }
            return tryLoadModuleUsingPaths(extensions, moduleName, baseUrl, paths, loader, /*onlyRecordFailures*/ false, state);
        }
    }
    function tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, state) {
        if (!state.compilerOptions.rootDirs) {
            return undefined;
        }
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0, moduleName);
        }
        var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
        var matchedRootDir;
        var matchedNormalizedPrefix;
        for (var _i = 0, _a = state.compilerOptions.rootDirs; _i < _a.length; _i++) {
            var rootDir = _a[_i];
            // rootDirs are expected to be absolute
            // in case of tsconfig.json this will happen automatically - compiler will expand relative names
            // using location of tsconfig.json as base location
            var normalizedRoot = ts.normalizePath(rootDir);
            if (!ts.endsWith(normalizedRoot, ts.directorySeparator)) {
                normalizedRoot += ts.directorySeparator;
            }
            var isLongestMatchingPrefix = ts.startsWith(candidate, normalizedRoot) &&
                (matchedNormalizedPrefix === undefined || matchedNormalizedPrefix.length < normalizedRoot.length);
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Checking_if_0_is_the_longest_matching_prefix_for_1_2, normalizedRoot, candidate, isLongestMatchingPrefix);
            }
            if (isLongestMatchingPrefix) {
                matchedNormalizedPrefix = normalizedRoot;
                matchedRootDir = rootDir;
            }
        }
        if (matchedNormalizedPrefix) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Longest_matching_prefix_for_0_is_1, candidate, matchedNormalizedPrefix);
            }
            var suffix = candidate.substr(matchedNormalizedPrefix.length);
            // first - try to load from a initial location
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, matchedNormalizedPrefix, candidate);
            }
            var resolvedFileName = loader(extensions, candidate, !ts.directoryProbablyExists(containingDirectory, state.host), state);
            if (resolvedFileName) {
                return resolvedFileName;
            }
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Trying_other_entries_in_rootDirs);
            }
            // then try to resolve using remaining entries in rootDirs
            for (var _b = 0, _c = state.compilerOptions.rootDirs; _b < _c.length; _b++) {
                var rootDir = _c[_b];
                if (rootDir === matchedRootDir) {
                    // skip the initially matched entry
                    continue;
                }
                var candidate_1 = ts.combinePaths(ts.normalizePath(rootDir), suffix);
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, rootDir, candidate_1);
                }
                var baseDirectory = ts.getDirectoryPath(candidate_1);
                var resolvedFileName_1 = loader(extensions, candidate_1, !ts.directoryProbablyExists(baseDirectory, state.host), state);
                if (resolvedFileName_1) {
                    return resolvedFileName_1;
                }
            }
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Module_resolution_using_rootDirs_has_failed);
            }
        }
        return undefined;
    }
    function tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, state) {
        var baseUrl = state.compilerOptions.baseUrl;
        if (!baseUrl) {
            return undefined;
        }
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName);
        }
        var candidate = ts.normalizePath(ts.combinePaths(baseUrl, moduleName));
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, baseUrl, candidate);
        }
        return loader(extensions, candidate, !ts.directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state);
    }
    /**
     * Expose resolution logic to allow us to use Node module resolution logic from arbitrary locations.
     * No way to do this with `require()`: https://github.com/nodejs/node/issues/5963
     * Throws an error if the module can't be resolved.
     */
    /* @internal */
    function resolveJSModule(moduleName, initialDir, host) {
        var _a = tryResolveJSModuleWorker(moduleName, initialDir, host), resolvedModule = _a.resolvedModule, failedLookupLocations = _a.failedLookupLocations;
        if (!resolvedModule) {
            throw new Error("Could not resolve JS module '" + moduleName + "' starting at '" + initialDir + "'. Looked in: " + failedLookupLocations.join(", "));
        }
        return resolvedModule.resolvedFileName;
    }
    ts.resolveJSModule = resolveJSModule;
    /* @internal */
    function tryResolveJSModule(moduleName, initialDir, host) {
        var resolvedModule = tryResolveJSModuleWorker(moduleName, initialDir, host).resolvedModule;
        return resolvedModule && resolvedModule.resolvedFileName;
    }
    ts.tryResolveJSModule = tryResolveJSModule;
    var jsOnlyExtensions = [Extensions.JavaScript];
    var tsExtensions = [Extensions.TypeScript, Extensions.JavaScript];
    var tsPlusJsonExtensions = tsExtensions.concat([Extensions.Json]);
    var tsconfigExtensions = [Extensions.TSConfig];
    function tryResolveJSModuleWorker(moduleName, initialDir, host) {
        return nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, jsOnlyExtensions, /*redirectedReferences*/ undefined);
    }
    function nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, lookupConfig) {
        return nodeModuleNameResolverWorker(moduleName, ts.getDirectoryPath(containingFile), compilerOptions, host, cache, lookupConfig ? tsconfigExtensions : (compilerOptions.resolveJsonModule ? tsPlusJsonExtensions : tsExtensions), redirectedReference);
    }
    ts.nodeModuleNameResolver = nodeModuleNameResolver;
    function nodeModuleNameResolverWorker(moduleName, containingDirectory, compilerOptions, host, cache, extensions, redirectedReference) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        var failedLookupLocations = [];
        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled, failedLookupLocations: failedLookupLocations };
        var result = ts.forEach(extensions, function (ext) { return tryResolve(ext); });
        if (result && result.value) {
            var _a = result.value, resolved = _a.resolved, isExternalLibraryImport = _a.isExternalLibraryImport;
            return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations);
        }
        return { resolvedModule: undefined, failedLookupLocations: failedLookupLocations };
        function tryResolve(extensions) {
            var loader = function (extensions, candidate, onlyRecordFailures, state) { return nodeLoadModuleByRelativeName(extensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ true); };
            var resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, state);
            if (resolved) {
                return toSearchResult({ resolved: resolved, isExternalLibraryImport: pathContainsNodeModules(resolved.path) });
            }
            if (!ts.isExternalModuleNameRelative(moduleName)) {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
                }
                var resolved_1 = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
                if (!resolved_1)
                    return undefined;
                var resolvedValue = resolved_1.value;
                if (!compilerOptions.preserveSymlinks && resolvedValue && !resolvedValue.originalPath) {
                    var path = realPath(resolvedValue.path, host, traceEnabled);
                    var originalPath = path === resolvedValue.path ? undefined : resolvedValue.path;
                    resolvedValue = __assign({}, resolvedValue, { path: path, originalPath: originalPath });
                }
                // For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files.
                return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } };
            }
            else {
                var _a = ts.normalizePathAndParts(ts.combinePaths(containingDirectory, moduleName)), candidate = _a.path, parts = _a.parts;
                var resolved_2 = nodeLoadModuleByRelativeName(extensions, candidate, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true);
                // Treat explicit "node_modules" import as an external library import.
                return resolved_2 && toSearchResult({ resolved: resolved_2, isExternalLibraryImport: ts.contains(parts, "node_modules") });
            }
        }
    }
    function realPath(path, host, traceEnabled) {
        if (!host.realpath) {
            return path;
        }
        var real = ts.normalizePath(host.realpath(path));
        if (traceEnabled) {
            trace(host, ts.Diagnostics.Resolving_real_path_for_0_result_1, path, real);
        }
        ts.Debug.assert(host.fileExists(real), path + " linked to nonexistent file " + real); // tslint:disable-line
        return real;
    }
    function nodeLoadModuleByRelativeName(extensions, candidate, onlyRecordFailures, state, considerPackageJson) {
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1, candidate, Extensions[extensions]);
        }
        if (!ts.hasTrailingDirectorySeparator(candidate)) {
            if (!onlyRecordFailures) {
                var parentOfCandidate = ts.getDirectoryPath(candidate);
                if (!ts.directoryProbablyExists(parentOfCandidate, state.host)) {
                    if (state.traceEnabled) {
                        trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, parentOfCandidate);
                    }
                    onlyRecordFailures = true;
                }
            }
            var resolvedFromFile = loadModuleFromFile(extensions, candidate, onlyRecordFailures, state);
            if (resolvedFromFile) {
                var packageDirectory = considerPackageJson ? parseNodeModuleFromPath(resolvedFromFile) : undefined;
                var packageInfo = packageDirectory ? getPackageJsonInfo(packageDirectory, /*onlyRecordFailures*/ false, state) : undefined;
                return withPackageId(packageInfo, resolvedFromFile);
            }
        }
        if (!onlyRecordFailures) {
            var candidateExists = ts.directoryProbablyExists(candidate, state.host);
            if (!candidateExists) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidate);
                }
                onlyRecordFailures = true;
            }
        }
        return loadNodeModuleFromDirectory(extensions, candidate, onlyRecordFailures, state, considerPackageJson);
    }
    /*@internal*/
    ts.nodeModulesPathPart = "/node_modules/";
    /*@internal*/
    function pathContainsNodeModules(path) {
        return ts.stringContains(path, ts.nodeModulesPathPart);
    }
    ts.pathContainsNodeModules = pathContainsNodeModules;
    /**
     * This will be called on the successfully resolved path from `loadModuleFromFile`.
     * (Not neeeded for `loadModuleFromNodeModules` as that looks up the `package.json` as part of resolution.)
     *
     * packageDirectory is the directory of the package itself.
     *   For `blah/node_modules/foo/index.d.ts` this is packageDirectory: "foo"
     *   For `/node_modules/foo/bar.d.ts` this is packageDirectory: "foo"
     *   For `/node_modules/@types/foo/bar/index.d.ts` this is packageDirectory: "@types/foo"
     *   For `/node_modules/foo/bar/index.d.ts` this is packageDirectory: "foo"
     */
    function parseNodeModuleFromPath(resolved) {
        var path = ts.normalizePath(resolved.path);
        var idx = path.lastIndexOf(ts.nodeModulesPathPart);
        if (idx === -1) {
            return undefined;
        }
        var indexAfterNodeModules = idx + ts.nodeModulesPathPart.length;
        var indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterNodeModules);
        if (path.charCodeAt(indexAfterNodeModules) === 64 /* at */) {
            indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterPackageName);
        }
        return path.slice(0, indexAfterPackageName);
    }
    function moveToNextDirectorySeparatorIfAvailable(path, prevSeparatorIndex) {
        var nextSeparatorIndex = path.indexOf(ts.directorySeparator, prevSeparatorIndex + 1);
        return nextSeparatorIndex === -1 ? prevSeparatorIndex : nextSeparatorIndex;
    }
    function loadModuleFromFileNoPackageId(extensions, candidate, onlyRecordFailures, state) {
        return noPackageId(loadModuleFromFile(extensions, candidate, onlyRecordFailures, state));
    }
    /**
     * @param {boolean} onlyRecordFailures - if true then function won't try to actually load files but instead record all attempts as failures. This flag is necessary
     * in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations.
     */
    function loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) {
        if (extensions === Extensions.Json || extensions === Extensions.TSConfig) {
            var extensionLess = ts.tryRemoveExtension(candidate, ".json" /* Json */);
            return (extensionLess === undefined && extensions === Extensions.Json) ? undefined : tryAddingExtensions(extensionLess || candidate, extensions, onlyRecordFailures, state);
        }
        // First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts"
        var resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, onlyRecordFailures, state);
        if (resolvedByAddingExtension) {
            return resolvedByAddingExtension;
        }
        // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one;
        // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts"
        if (ts.hasJSFileExtension(candidate)) {
            var extensionless = ts.removeFileExtension(candidate);
            if (state.traceEnabled) {
                var extension = candidate.substring(extensionless.length);
                trace(state.host, ts.Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension);
            }
            return tryAddingExtensions(extensionless, extensions, onlyRecordFailures, state);
        }
    }
    /** Try to return an existing file that adds one of the `extensions` to `candidate`. */
    function tryAddingExtensions(candidate, extensions, onlyRecordFailures, state) {
        if (!onlyRecordFailures) {
            // check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing
            var directory = ts.getDirectoryPath(candidate);
            if (directory) {
                onlyRecordFailures = !ts.directoryProbablyExists(directory, state.host);
            }
        }
        switch (extensions) {
            case Extensions.DtsOnly:
                return tryExtension(".d.ts" /* Dts */);
            case Extensions.TypeScript:
                return tryExtension(".ts" /* Ts */) || tryExtension(".tsx" /* Tsx */) || tryExtension(".d.ts" /* Dts */);
            case Extensions.JavaScript:
                return tryExtension(".js" /* Js */) || tryExtension(".jsx" /* Jsx */);
            case Extensions.TSConfig:
            case Extensions.Json:
                return tryExtension(".json" /* Json */);
        }
        function tryExtension(ext) {
            var path = tryFile(candidate + ext, onlyRecordFailures, state);
            return path === undefined ? undefined : { path: path, ext: ext };
        }
    }
    /** Return the file if it exists. */
    function tryFile(fileName, onlyRecordFailures, state) {
        if (!onlyRecordFailures) {
            if (state.host.fileExists(fileName)) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName);
                }
                return fileName;
            }
            else {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName);
                }
            }
        }
        state.failedLookupLocations.push(fileName);
        return undefined;
    }
    function loadNodeModuleFromDirectory(extensions, candidate, onlyRecordFailures, state, considerPackageJson) {
        if (considerPackageJson === void 0) { considerPackageJson = true; }
        var packageInfo = considerPackageJson ? getPackageJsonInfo(candidate, onlyRecordFailures, state) : undefined;
        var packageJsonContent = packageInfo && packageInfo.packageJsonContent;
        var versionPaths = packageInfo && packageInfo.versionPaths;
        return withPackageId(packageInfo, loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageJsonContent, versionPaths));
    }
    function getPackageJsonInfo(packageDirectory, onlyRecordFailures, state) {
        var host = state.host, traceEnabled = state.traceEnabled;
        var directoryExists = !onlyRecordFailures && ts.directoryProbablyExists(packageDirectory, host);
        var packageJsonPath = ts.combinePaths(packageDirectory, "package.json");
        if (directoryExists && host.fileExists(packageJsonPath)) {
            var packageJsonContent = ts.readJson(packageJsonPath, host);
            if (traceEnabled) {
                trace(host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath);
            }
            var versionPaths = readPackageJsonTypesVersionPaths(packageJsonContent, state);
            return { packageDirectory: packageDirectory, packageJsonContent: packageJsonContent, versionPaths: versionPaths };
        }
        else {
            if (directoryExists && traceEnabled) {
                trace(host, ts.Diagnostics.File_0_does_not_exist, packageJsonPath);
            }
            // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
            state.failedLookupLocations.push(packageJsonPath);
        }
    }
    function loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, jsonContent, versionPaths) {
        var packageFile;
        if (jsonContent) {
            switch (extensions) {
                case Extensions.JavaScript:
                case Extensions.Json:
                    packageFile = readPackageJsonMainField(jsonContent, candidate, state);
                    break;
                case Extensions.TypeScript:
                    // When resolving typescript modules, try resolving using main field as well
                    packageFile = readPackageJsonTypesFields(jsonContent, candidate, state) || readPackageJsonMainField(jsonContent, candidate, state);
                    break;
                case Extensions.DtsOnly:
                    packageFile = readPackageJsonTypesFields(jsonContent, candidate, state);
                    break;
                case Extensions.TSConfig:
                    packageFile = readPackageJsonTSConfigField(jsonContent, candidate, state);
                    break;
                default:
                    return ts.Debug.assertNever(extensions);
            }
        }
        var loader = function (extensions, candidate, onlyRecordFailures, state) {
            var fromFile = tryFile(candidate, onlyRecordFailures, state);
            if (fromFile) {
                var resolved = resolvedIfExtensionMatches(extensions, fromFile);
                if (resolved) {
                    return noPackageId(resolved);
                }
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromFile);
                }
            }
            // Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types"
            var nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions;
            // Don't do package.json lookup recursively, because Node.js' package lookup doesn't.
            return nodeLoadModuleByRelativeName(nextExtensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ false);
        };
        var onlyRecordFailuresForPackageFile = packageFile ? !ts.directoryProbablyExists(ts.getDirectoryPath(packageFile), state.host) : undefined;
        var onlyRecordFailuresForIndex = onlyRecordFailures || !ts.directoryProbablyExists(candidate, state.host);
        var indexPath = ts.combinePaths(candidate, extensions === Extensions.TSConfig ? "tsconfig" : "index");
        if (versionPaths && (!packageFile || ts.containsPath(candidate, packageFile))) {
            var moduleName = ts.getRelativePathFromDirectory(candidate, packageFile || indexPath, /*ignoreCase*/ false);
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, versionPaths.version, ts.version, moduleName);
            }
            var result = tryLoadModuleUsingPaths(extensions, moduleName, candidate, versionPaths.paths, loader, onlyRecordFailuresForPackageFile || onlyRecordFailuresForIndex, state);
            if (result) {
                return removeIgnoredPackageId(result.value);
            }
        }
        // It won't have a `packageId` set, because we disabled `considerPackageJson`.
        var packageFileResult = packageFile && removeIgnoredPackageId(loader(extensions, packageFile, onlyRecordFailuresForPackageFile, state));
        if (packageFileResult)
            return packageFileResult;
        return loadModuleFromFile(extensions, indexPath, onlyRecordFailuresForIndex, state);
    }
    /** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */
    function resolvedIfExtensionMatches(extensions, path) {
        var ext = ts.tryGetExtensionFromPath(path);
        return ext !== undefined && extensionIsOk(extensions, ext) ? { path: path, ext: ext } : undefined;
    }
    /** True if `extension` is one of the supported `extensions`. */
    function extensionIsOk(extensions, extension) {
        switch (extensions) {
            case Extensions.JavaScript:
                return extension === ".js" /* Js */ || extension === ".jsx" /* Jsx */;
            case Extensions.TSConfig:
            case Extensions.Json:
                return extension === ".json" /* Json */;
            case Extensions.TypeScript:
                return extension === ".ts" /* Ts */ || extension === ".tsx" /* Tsx */ || extension === ".d.ts" /* Dts */;
            case Extensions.DtsOnly:
                return extension === ".d.ts" /* Dts */;
        }
    }
    /* @internal */
    function parsePackageName(moduleName) {
        var idx = moduleName.indexOf(ts.directorySeparator);
        if (moduleName[0] === "@") {
            idx = moduleName.indexOf(ts.directorySeparator, idx + 1);
        }
        return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) };
    }
    ts.parsePackageName = parsePackageName;
    function loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, directory, state, cache, redirectedReference) {
        return loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, /*typesScopeOnly*/ false, cache, redirectedReference);
    }
    function loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName, directory, state) {
        // Extensions parameter here doesn't actually matter, because typesOnly ensures we're just doing @types lookup, which is always DtsOnly.
        return loadModuleFromNearestNodeModulesDirectoryWorker(Extensions.DtsOnly, moduleName, directory, state, /*typesScopeOnly*/ true, /*cache*/ undefined, /*redirectedReference*/ undefined);
    }
    function loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, typesScopeOnly, cache, redirectedReference) {
        var perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, redirectedReference);
        return ts.forEachAncestorDirectory(ts.normalizeSlashes(directory), function (ancestorDirectory) {
            if (ts.getBaseFileName(ancestorDirectory) !== "node_modules") {
                var resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state);
                if (resolutionFromCache) {
                    return resolutionFromCache;
                }
                return toSearchResult(loadModuleFromImmediateNodeModulesDirectory(extensions, moduleName, ancestorDirectory, state, typesScopeOnly));
            }
        });
    }
    function loadModuleFromImmediateNodeModulesDirectory(extensions, moduleName, directory, state, typesScopeOnly) {
        var nodeModulesFolder = ts.combinePaths(directory, "node_modules");
        var nodeModulesFolderExists = ts.directoryProbablyExists(nodeModulesFolder, state.host);
        if (!nodeModulesFolderExists && state.traceEnabled) {
            trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesFolder);
        }
        var packageResult = typesScopeOnly ? undefined : loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, state);
        if (packageResult) {
            return packageResult;
        }
        if (extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) {
            var nodeModulesAtTypes_1 = ts.combinePaths(nodeModulesFolder, "@types");
            var nodeModulesAtTypesExists = nodeModulesFolderExists;
            if (nodeModulesFolderExists && !ts.directoryProbablyExists(nodeModulesAtTypes_1, state.host)) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesAtTypes_1);
                }
                nodeModulesAtTypesExists = false;
            }
            return loadModuleFromSpecificNodeModulesDirectory(Extensions.DtsOnly, mangleScopedPackageNameWithTrace(moduleName, state), nodeModulesAtTypes_1, nodeModulesAtTypesExists, state);
        }
    }
    function loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state) {
        var candidate = ts.normalizePath(ts.combinePaths(nodeModulesDirectory, moduleName));
        // First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
        var packageInfo = getPackageJsonInfo(candidate, !nodeModulesDirectoryExists, state);
        if (packageInfo) {
            var fromFile = loadModuleFromFile(extensions, candidate, !nodeModulesDirectoryExists, state);
            if (fromFile) {
                return noPackageId(fromFile);
            }
            var fromDirectory = loadNodeModuleFromDirectoryWorker(extensions, candidate, !nodeModulesDirectoryExists, state, packageInfo.packageJsonContent, packageInfo.versionPaths);
            return withPackageId(packageInfo, fromDirectory);
        }
        var loader = function (extensions, candidate, onlyRecordFailures, state) {
            var pathAndExtension = loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) ||
                loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageInfo && packageInfo.packageJsonContent, packageInfo && packageInfo.versionPaths);
            return withPackageId(packageInfo, pathAndExtension);
        };
        var _a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
        if (rest !== "") { // If "rest" is empty, we just did this search above.
            var packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName);
            // Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId and path mappings.
            packageInfo = getPackageJsonInfo(packageDirectory, !nodeModulesDirectoryExists, state);
            if (packageInfo && packageInfo.versionPaths) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, packageInfo.versionPaths.version, ts.version, rest);
                }
                var packageDirectoryExists = nodeModulesDirectoryExists && ts.directoryProbablyExists(packageDirectory, state.host);
                var fromPaths = tryLoadModuleUsingPaths(extensions, rest, packageDirectory, packageInfo.versionPaths.paths, loader, !packageDirectoryExists, state);
                if (fromPaths) {
                    return fromPaths.value;
                }
            }
        }
        return loader(extensions, candidate, !nodeModulesDirectoryExists, state);
    }
    function tryLoadModuleUsingPaths(extensions, moduleName, baseDirectory, paths, loader, onlyRecordFailures, state) {
        var matchedPattern = ts.matchPatternOrExact(ts.getOwnKeys(paths), moduleName);
        if (matchedPattern) {
            var matchedStar_1 = ts.isString(matchedPattern) ? undefined : ts.matchedText(matchedPattern, moduleName);
            var matchedPatternText = ts.isString(matchedPattern) ? matchedPattern : ts.patternText(matchedPattern);
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText);
            }
            var resolved = ts.forEach(paths[matchedPatternText], function (subst) {
                var path = matchedStar_1 ? subst.replace("*", matchedStar_1) : subst;
                var candidate = ts.normalizePath(ts.combinePaths(baseDirectory, path));
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path);
                }
                // A path mapping may have an extension, in contrast to an import, which should omit it.
                var extension = ts.tryGetExtensionFromPath(candidate);
                if (extension !== undefined) {
                    var path_1 = tryFile(candidate, onlyRecordFailures, state);
                    if (path_1 !== undefined) {
                        return noPackageId({ path: path_1, ext: extension });
                    }
                }
                return loader(extensions, candidate, onlyRecordFailures || !ts.directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state);
            });
            return { value: resolved };
        }
    }
    /** Double underscores are used in DefinitelyTyped to delimit scoped packages. */
    var mangledScopedPackageSeparator = "__";
    /** For a scoped package, we must look in `@types/foo__bar` instead of `@types/@foo/bar`. */
    function mangleScopedPackageNameWithTrace(packageName, state) {
        var mangled = mangleScopedPackageName(packageName);
        if (state.traceEnabled && mangled !== packageName) {
            trace(state.host, ts.Diagnostics.Scoped_package_detected_looking_in_0, mangled);
        }
        return mangled;
    }
    /* @internal */
    function getTypesPackageName(packageName) {
        return "@types/" + mangleScopedPackageName(packageName);
    }
    ts.getTypesPackageName = getTypesPackageName;
    /* @internal */
    function mangleScopedPackageName(packageName) {
        if (ts.startsWith(packageName, "@")) {
            var replaceSlash = packageName.replace(ts.directorySeparator, mangledScopedPackageSeparator);
            if (replaceSlash !== packageName) {
                return replaceSlash.slice(1); // Take off the "@"
            }
        }
        return packageName;
    }
    ts.mangleScopedPackageName = mangleScopedPackageName;
    /* @internal */
    function getPackageNameFromTypesPackageName(mangledName) {
        var withoutAtTypePrefix = ts.removePrefix(mangledName, "@types/");
        if (withoutAtTypePrefix !== mangledName) {
            return unmangleScopedPackageName(withoutAtTypePrefix);
        }
        return mangledName;
    }
    ts.getPackageNameFromTypesPackageName = getPackageNameFromTypesPackageName;
    /* @internal */
    function unmangleScopedPackageName(typesPackageName) {
        return ts.stringContains(typesPackageName, mangledScopedPackageSeparator) ?
            "@" + typesPackageName.replace(mangledScopedPackageSeparator, ts.directorySeparator) :
            typesPackageName;
    }
    ts.unmangleScopedPackageName = unmangleScopedPackageName;
    function tryFindNonRelativeModuleNameInCache(cache, moduleName, containingDirectory, state) {
        var _a;
        var result = cache && cache.get(containingDirectory);
        if (result) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory);
            }
            (_a = state.failedLookupLocations).push.apply(_a, result.failedLookupLocations);
            return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, originalPath: result.resolvedModule.originalPath || true, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } };
        }
    }
    function classicNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        var failedLookupLocations = [];
        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled, failedLookupLocations: failedLookupLocations };
        var containingDirectory = ts.getDirectoryPath(containingFile);
        var resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
        // No originalPath because classic resolution doesn't resolve realPath
        return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations);
        function tryResolve(extensions) {
            var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, state);
            if (resolvedUsingSettings) {
                return { value: resolvedUsingSettings };
            }
            if (!ts.isExternalModuleNameRelative(moduleName)) {
                var perModuleNameCache_1 = cache && cache.getOrCreateCacheForModuleName(moduleName, redirectedReference);
                // Climb up parent directories looking for a module.
                var resolved_3 = ts.forEachAncestorDirectory(containingDirectory, function (directory) {
                    var resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache_1, moduleName, directory, state);
                    if (resolutionFromCache) {
                        return resolutionFromCache;
                    }
                    var searchName = ts.normalizePath(ts.combinePaths(directory, moduleName));
                    return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, /*onlyRecordFailures*/ false, state));
                });
                if (resolved_3) {
                    return resolved_3;
                }
                if (extensions === Extensions.TypeScript) {
                    // If we didn't find the file normally, look it up in @types.
                    return loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName, containingDirectory, state);
                }
            }
            else {
                var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
                return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, /*onlyRecordFailures*/ false, state));
            }
        }
    }
    ts.classicNameResolver = classicNameResolver;
    /**
     * LSHost may load a module from a global cache of typings.
     * This is the minumum code needed to expose that functionality; the rest is in LSHost.
     */
    /* @internal */
    function loadModuleFromGlobalCache(moduleName, projectName, compilerOptions, host, globalCache) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        if (traceEnabled) {
            trace(host, ts.Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache);
        }
        var failedLookupLocations = [];
        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled, failedLookupLocations: failedLookupLocations };
        var resolved = loadModuleFromImmediateNodeModulesDirectory(Extensions.DtsOnly, moduleName, globalCache, state, /*typesScopeOnly*/ false);
        return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations);
    }
    ts.loadModuleFromGlobalCache = loadModuleFromGlobalCache;
    /**
     * Wraps value to SearchResult.
     * @returns undefined if value is undefined or { value } otherwise
     */
    function toSearchResult(value) {
        return value !== undefined ? { value: value } : undefined;
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var ModuleInstanceState;
    (function (ModuleInstanceState) {
        ModuleInstanceState[ModuleInstanceState["NonInstantiated"] = 0] = "NonInstantiated";
        ModuleInstanceState[ModuleInstanceState["Instantiated"] = 1] = "Instantiated";
        ModuleInstanceState[ModuleInstanceState["ConstEnumOnly"] = 2] = "ConstEnumOnly";
    })(ModuleInstanceState = ts.ModuleInstanceState || (ts.ModuleInstanceState = {}));
    function getModuleInstanceState(node) {
        return node.body ? getModuleInstanceStateWorker(node.body) : 1 /* Instantiated */;
    }
    ts.getModuleInstanceState = getModuleInstanceState;
    function getModuleInstanceStateWorker(node) {
        // A module is uninstantiated if it contains only
        switch (node.kind) {
            // 1. interface declarations, type alias declarations
            case 242 /* InterfaceDeclaration */:
            case 243 /* TypeAliasDeclaration */:
                return 0 /* NonInstantiated */;
            // 2. const enum declarations
            case 244 /* EnumDeclaration */:
                if (ts.isEnumConst(node)) {
                    return 2 /* ConstEnumOnly */;
                }
                break;
            // 3. non-exported import declarations
            case 250 /* ImportDeclaration */:
            case 249 /* ImportEqualsDeclaration */:
                if (!(ts.hasModifier(node, 1 /* Export */))) {
                    return 0 /* NonInstantiated */;
                }
                break;
            // 4. other uninstantiated module declarations.
            case 246 /* ModuleBlock */: {
                var state_1 = 0 /* NonInstantiated */;
                ts.forEachChild(node, function (n) {
                    var childState = getModuleInstanceStateWorker(n);
                    switch (childState) {
                        case 0 /* NonInstantiated */:
                            // child is non-instantiated - continue searching
                            return;
                        case 2 /* ConstEnumOnly */:
                            // child is const enum only - record state and continue searching
                            state_1 = 2 /* ConstEnumOnly */;
                            return;
                        case 1 /* Instantiated */:
                            // child is instantiated - record state and stop
                            state_1 = 1 /* Instantiated */;
                            return true;
                        default:
                            ts.Debug.assertNever(childState);
                    }
                });
                return state_1;
            }
            case 245 /* ModuleDeclaration */:
                return getModuleInstanceState(node);
            case 73 /* Identifier */:
                // Only jsdoc typedef definition can exist in jsdoc namespace, and it should
                // be considered the same as type alias
                if (node.isInJSDocNamespace) {
                    return 0 /* NonInstantiated */;
                }
        }
        return 1 /* Instantiated */;
    }
    var ContainerFlags;
    (function (ContainerFlags) {
        // The current node is not a container, and no container manipulation should happen before
        // recursing into it.
        ContainerFlags[ContainerFlags["None"] = 0] = "None";
        // The current node is a container.  It should be set as the current container (and block-
        // container) before recursing into it.  The current node does not have locals.  Examples:
        //
        //      Classes, ObjectLiterals, TypeLiterals, Interfaces...
        ContainerFlags[ContainerFlags["IsContainer"] = 1] = "IsContainer";
        // The current node is a block-scoped-container.  It should be set as the current block-
        // container before recursing into it.  Examples:
        //
        //      Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements...
        ContainerFlags[ContainerFlags["IsBlockScopedContainer"] = 2] = "IsBlockScopedContainer";
        // The current node is the container of a control flow path. The current control flow should
        // be saved and restored, and a new control flow initialized within the container.
        ContainerFlags[ContainerFlags["IsControlFlowContainer"] = 4] = "IsControlFlowContainer";
        ContainerFlags[ContainerFlags["IsFunctionLike"] = 8] = "IsFunctionLike";
        ContainerFlags[ContainerFlags["IsFunctionExpression"] = 16] = "IsFunctionExpression";
        ContainerFlags[ContainerFlags["HasLocals"] = 32] = "HasLocals";
        ContainerFlags[ContainerFlags["IsInterface"] = 64] = "IsInterface";
        ContainerFlags[ContainerFlags["IsObjectLiteralOrClassExpressionMethod"] = 128] = "IsObjectLiteralOrClassExpressionMethod";
    })(ContainerFlags || (ContainerFlags = {}));
    var flowNodeCreated = ts.identity;
    var binder = createBinder();
    function bindSourceFile(file, options) {
        ts.performance.mark("beforeBind");
        binder(file, options);
        ts.performance.mark("afterBind");
        ts.performance.measure("Bind", "beforeBind", "afterBind");
    }
    ts.bindSourceFile = bindSourceFile;
    function createBinder() {
        var file;
        var options;
        var languageVersion;
        var parent;
        var container;
        var thisParentContainer; // Container one level up
        var blockScopeContainer;
        var lastContainer;
        var delayedTypeAliases;
        var seenThisKeyword;
        // state used by control flow analysis
        var currentFlow;
        var currentBreakTarget;
        var currentContinueTarget;
        var currentReturnTarget;
        var currentTrueTarget;
        var currentFalseTarget;
        var preSwitchCaseFlow;
        var activeLabels;
        var hasExplicitReturn;
        // state used for emit helpers
        var emitFlags;
        // If this file is an external module, then it is automatically in strict-mode according to
        // ES6.  If it is not an external module, then we'll determine if it is in strict mode or
        // not depending on if we see "use strict" in certain places or if we hit a class/namespace
        // or if compiler options contain alwaysStrict.
        var inStrictMode;
        var symbolCount = 0;
        var Symbol; // tslint:disable-line variable-name
        var classifiableNames;
        var unreachableFlow = { flags: 1 /* Unreachable */ };
        var reportedUnreachableFlow = { flags: 1 /* Unreachable */ };
        // state used to aggregate transform flags during bind.
        var subtreeTransformFlags = 0 /* None */;
        var skipTransformFlagAggregation;
        /**
         * Inside the binder, we may create a diagnostic for an as-yet unbound node (with potentially no parent pointers, implying no accessible source file)
         * If so, the node _must_ be in the current file (as that's the only way anything could have traversed to it to yield it as the error node)
         * This version of `createDiagnosticForNode` uses the binder's context to account for this, and always yields correct diagnostics even in these situations.
         */
        function createDiagnosticForNode(node, message, arg0, arg1, arg2) {
            return ts.createDiagnosticForNodeInSourceFile(ts.getSourceFileOfNode(node) || file, node, message, arg0, arg1, arg2);
        }
        function bindSourceFile(f, opts) {
            file = f;
            options = opts;
            languageVersion = ts.getEmitScriptTarget(options);
            inStrictMode = bindInStrictMode(file, opts);
            classifiableNames = ts.createUnderscoreEscapedMap();
            symbolCount = 0;
            skipTransformFlagAggregation = file.isDeclarationFile;
            Symbol = ts.objectAllocator.getSymbolConstructor();
            if (!file.locals) {
                bind(file);
                file.symbolCount = symbolCount;
                file.classifiableNames = classifiableNames;
                delayedBindJSDocTypedefTag();
            }
            file = undefined;
            options = undefined;
            languageVersion = undefined;
            parent = undefined;
            container = undefined;
            thisParentContainer = undefined;
            blockScopeContainer = undefined;
            lastContainer = undefined;
            delayedTypeAliases = undefined;
            seenThisKeyword = false;
            currentFlow = undefined;
            currentBreakTarget = undefined;
            currentContinueTarget = undefined;
            currentReturnTarget = undefined;
            currentTrueTarget = undefined;
            currentFalseTarget = undefined;
            activeLabels = undefined;
            hasExplicitReturn = false;
            emitFlags = 0 /* None */;
            subtreeTransformFlags = 0 /* None */;
        }
        return bindSourceFile;
        function bindInStrictMode(file, opts) {
            if (ts.getStrictOptionValue(opts, "alwaysStrict") && !file.isDeclarationFile) {
                // bind in strict mode source files with alwaysStrict option
                return true;
            }
            else {
                return !!file.externalModuleIndicator;
            }
        }
        function createSymbol(flags, name) {
            symbolCount++;
            return new Symbol(flags, name);
        }
        function addDeclarationToSymbol(symbol, node, symbolFlags) {
            symbol.flags |= symbolFlags;
            node.symbol = symbol;
            symbol.declarations = ts.append(symbol.declarations, node);
            if (symbolFlags & (32 /* Class */ | 384 /* Enum */ | 1536 /* Module */ | 3 /* Variable */) && !symbol.exports) {
                symbol.exports = ts.createSymbolTable();
            }
            if (symbolFlags & (32 /* Class */ | 64 /* Interface */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) && !symbol.members) {
                symbol.members = ts.createSymbolTable();
            }
            // On merge of const enum module with class or function, reset const enum only flag (namespaces will already recalculate)
            if (symbol.constEnumOnlyModule && (symbol.flags & (16 /* Function */ | 32 /* Class */ | 256 /* RegularEnum */))) {
                symbol.constEnumOnlyModule = false;
            }
            if (symbolFlags & 67220415 /* Value */) {
                setValueDeclaration(symbol, node);
            }
        }
        function setValueDeclaration(symbol, node) {
            var valueDeclaration = symbol.valueDeclaration;
            if (!valueDeclaration ||
                (ts.isAssignmentDeclaration(valueDeclaration) && !ts.isAssignmentDeclaration(node)) ||
                (valueDeclaration.kind !== node.kind && ts.isEffectiveModuleDeclaration(valueDeclaration))) {
                // other kinds of value declarations take precedence over modules and assignment declarations
                symbol.valueDeclaration = node;
            }
        }
        // Should not be called on a declaration with a computed property name,
        // unless it is a well known Symbol.
        function getDeclarationName(node) {
            if (node.kind === 255 /* ExportAssignment */) {
                return node.isExportEquals ? "export=" /* ExportEquals */ : "default" /* Default */;
            }
            var name = ts.getNameOfDeclaration(node);
            if (name) {
                if (ts.isAmbientModule(node)) {
                    var moduleName = ts.getTextOfIdentifierOrLiteral(name);
                    return (ts.isGlobalScopeAugmentation(node) ? "__global" : "\"" + moduleName + "\"");
                }
                if (name.kind === 150 /* ComputedPropertyName */) {
                    var nameExpression = name.expression;
                    // treat computed property names where expression is string/numeric literal as just string/numeric literal
                    if (ts.isStringOrNumericLiteralLike(nameExpression)) {
                        return ts.escapeLeadingUnderscores(nameExpression.text);
                    }
                    ts.Debug.assert(ts.isWellKnownSymbolSyntactically(nameExpression));
                    return ts.getPropertyNameForKnownSymbolName(ts.idText(nameExpression.name));
                }
                return ts.isPropertyNameLiteral(name) ? ts.getEscapedTextOfIdentifierOrLiteral(name) : undefined;
            }
            switch (node.kind) {
                case 158 /* Constructor */:
                    return "__constructor" /* Constructor */;
                case 166 /* FunctionType */:
                case 161 /* CallSignature */:
                case 299 /* JSDocSignature */:
                    return "__call" /* Call */;
                case 167 /* ConstructorType */:
                case 162 /* ConstructSignature */:
                    return "__new" /* New */;
                case 163 /* IndexSignature */:
                    return "__index" /* Index */;
                case 256 /* ExportDeclaration */:
                    return "__export" /* ExportStar */;
                case 285 /* SourceFile */:
                    // json file should behave as
                    // module.exports = ...
                    return "export=" /* ExportEquals */;
                case 205 /* BinaryExpression */:
                    if (ts.getAssignmentDeclarationKind(node) === 2 /* ModuleExports */) {
                        // module.exports = ...
                        return "export=" /* ExportEquals */;
                    }
                    ts.Debug.fail("Unknown binary declaration kind");
                    break;
                case 295 /* JSDocFunctionType */:
                    return (ts.isJSDocConstructSignature(node) ? "__new" /* New */ : "__call" /* Call */);
                case 152 /* Parameter */:
                    // Parameters with names are handled at the top of this function.  Parameters
                    // without names can only come from JSDocFunctionTypes.
                    ts.Debug.assert(node.parent.kind === 295 /* JSDocFunctionType */, "Impossible parameter parent kind", function () { return "parent is: " + (ts.SyntaxKind ? ts.SyntaxKind[node.parent.kind] : node.parent.kind) + ", expected JSDocFunctionType"; });
                    var functionType = node.parent;
                    var index = functionType.parameters.indexOf(node);
                    return "arg" + index;
            }
        }
        function getDisplayName(node) {
            return ts.isNamedDeclaration(node) ? ts.declarationNameToString(node.name) : ts.unescapeLeadingUnderscores(ts.Debug.assertDefined(getDeclarationName(node)));
        }
        /**
         * Declares a Symbol for the node and adds it to symbols. Reports errors for conflicting identifier names.
         * @param symbolTable - The symbol table which node will be added to.
         * @param parent - node's parent declaration.
         * @param node - The declaration to be added to the symbol table
         * @param includes - The SymbolFlags that node has in addition to its declaration type (eg: export, ambient, etc.)
         * @param excludes - The flags which node cannot be declared alongside in a symbol table. Used to report forbidden declarations.
         */
        function declareSymbol(symbolTable, parent, node, includes, excludes, isReplaceableByMethod) {
            ts.Debug.assert(!ts.hasDynamicName(node));
            var isDefaultExport = ts.hasModifier(node, 512 /* Default */);
            // The exported symbol for an export default function/class node is always named "default"
            var name = isDefaultExport && parent ? "default" /* Default */ : getDeclarationName(node);
            var symbol;
            if (name === undefined) {
                symbol = createSymbol(0 /* None */, "__missing" /* Missing */);
            }
            else {
                // Check and see if the symbol table already has a symbol with this name.  If not,
                // create a new symbol with this name and add it to the table.  Note that we don't
                // give the new symbol any flags *yet*.  This ensures that it will not conflict
                // with the 'excludes' flags we pass in.
                //
                // If we do get an existing symbol, see if it conflicts with the new symbol we're
                // creating.  For example, a 'var' symbol and a 'class' symbol will conflict within
                // the same symbol table.  If we have a conflict, report the issue on each
                // declaration we have for this symbol, and then create a new symbol for this
                // declaration.
                //
                // Note that when properties declared in Javascript constructors
                // (marked by isReplaceableByMethod) conflict with another symbol, the property loses.
                // Always. This allows the common Javascript pattern of overwriting a prototype method
                // with an bound instance method of the same type: `this.method = this.method.bind(this)`
                //
                // If we created a new symbol, either because we didn't have a symbol with this name
                // in the symbol table, or we conflicted with an existing symbol, then just add this
                // node as the sole declaration of the new symbol.
                //
                // Otherwise, we'll be merging into a compatible existing symbol (for example when
                // you have multiple 'vars' with the same name in the same container).  In this case
                // just add this node into the declarations list of the symbol.
                symbol = symbolTable.get(name);
                if (includes & 2885600 /* Classifiable */) {
                    classifiableNames.set(name, true);
                }
                if (!symbol) {
                    symbolTable.set(name, symbol = createSymbol(0 /* None */, name));
                    if (isReplaceableByMethod)
                        symbol.isReplaceableByMethod = true;
                }
                else if (isReplaceableByMethod && !symbol.isReplaceableByMethod) {
                    // A symbol already exists, so don't add this as a declaration.
                    return symbol;
                }
                else if (symbol.flags & excludes) {
                    if (symbol.isReplaceableByMethod) {
                        // Javascript constructor-declared symbols can be discarded in favor of
                        // prototype symbols like methods.
                        symbolTable.set(name, symbol = createSymbol(0 /* None */, name));
                    }
                    else if (!(includes & 3 /* Variable */ && symbol.flags & 67108864 /* Assignment */)) {
                        // Assignment declarations are allowed to merge with variables, no matter what other flags they have.
                        if (ts.isNamedDeclaration(node)) {
                            node.name.parent = node;
                        }
                        // Report errors every position with duplicate declaration
                        // Report errors on previous encountered declarations
                        var message_1 = symbol.flags & 2 /* BlockScopedVariable */
                            ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0
                            : ts.Diagnostics.Duplicate_identifier_0;
                        var messageNeedsName_1 = true;
                        if (symbol.flags & 384 /* Enum */ || includes & 384 /* Enum */) {
                            message_1 = ts.Diagnostics.Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations;
                            messageNeedsName_1 = false;
                        }
                        var multipleDefaultExports_1 = false;
                        if (ts.length(symbol.declarations)) {
                            // If the current node is a default export of some sort, then check if
                            // there are any other default exports that we need to error on.
                            // We'll know whether we have other default exports depending on if `symbol` already has a declaration list set.
                            if (isDefaultExport) {
                                message_1 = ts.Diagnostics.A_module_cannot_have_multiple_default_exports;
                                messageNeedsName_1 = false;
                                multipleDefaultExports_1 = true;
                            }
                            else {
                                // This is to properly report an error in the case "export default { }" is after export default of class declaration or function declaration.
                                // Error on multiple export default in the following case:
                                // 1. multiple export default of class declaration or function declaration by checking NodeFlags.Default
                                // 2. multiple export default of export assignment. This one doesn't have NodeFlags.Default on (as export default doesn't considered as modifiers)
                                if (symbol.declarations && symbol.declarations.length &&
                                    (node.kind === 255 /* ExportAssignment */ && !node.isExportEquals)) {
                                    message_1 = ts.Diagnostics.A_module_cannot_have_multiple_default_exports;
                                    messageNeedsName_1 = false;
                                    multipleDefaultExports_1 = true;
                                }
                            }
                        }
                        var declarationName_1 = ts.getNameOfDeclaration(node) || node;
                        var relatedInformation_1 = [];
                        ts.forEach(symbol.declarations, function (declaration, index) {
                            var decl = ts.getNameOfDeclaration(declaration) || declaration;
                            var diag = createDiagnosticForNode(decl, message_1, messageNeedsName_1 ? getDisplayName(declaration) : undefined);
                            file.bindDiagnostics.push(multipleDefaultExports_1 ? ts.addRelatedInfo(diag, createDiagnosticForNode(declarationName_1, index === 0 ? ts.Diagnostics.Another_export_default_is_here : ts.Diagnostics.and_here)) : diag);
                            if (multipleDefaultExports_1) {
                                relatedInformation_1.push(createDiagnosticForNode(decl, ts.Diagnostics.The_first_export_default_is_here));
                            }
                        });
                        var diag = createDiagnosticForNode(declarationName_1, message_1, messageNeedsName_1 ? getDisplayName(node) : undefined);
                        file.bindDiagnostics.push(multipleDefaultExports_1 ? ts.addRelatedInfo.apply(void 0, [diag].concat(relatedInformation_1)) : diag);
                        symbol = createSymbol(0 /* None */, name);
                    }
                }
            }
            addDeclarationToSymbol(symbol, node, includes);
            if (symbol.parent) {
                ts.Debug.assert(symbol.parent === parent, "Existing symbol parent should match new one");
            }
            else {
                symbol.parent = parent;
            }
            return symbol;
        }
        function declareModuleMember(node, symbolFlags, symbolExcludes) {
            var hasExportModifier = ts.getCombinedModifierFlags(node) & 1 /* Export */;
            if (symbolFlags & 2097152 /* Alias */) {
                if (node.kind === 258 /* ExportSpecifier */ || (node.kind === 249 /* ImportEqualsDeclaration */ && hasExportModifier)) {
                    return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
                }
                else {
                    return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
                }
            }
            else {
                // Exported module members are given 2 symbols: A local symbol that is classified with an ExportValue flag,
                // and an associated export symbol with all the correct flags set on it. There are 2 main reasons:
                //
                //   1. We treat locals and exports of the same name as mutually exclusive within a container.
                //      That means the binder will issue a Duplicate Identifier error if you mix locals and exports
                //      with the same name in the same container.
                //      TODO: Make this a more specific error and decouple it from the exclusion logic.
                //   2. When we checkIdentifier in the checker, we set its resolved symbol to the local symbol,
                //      but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way
                //      when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope.
                // NOTE: Nested ambient modules always should go to to 'locals' table to prevent their automatic merge
                //       during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation
                //       and this case is specially handled. Module augmentations should only be merged with original module definition
                //       and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
                if (ts.isJSDocTypeAlias(node))
                    ts.Debug.assert(ts.isInJSFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file.
                if ((!ts.isAmbientModule(node) && (hasExportModifier || container.flags & 32 /* ExportContext */)) || ts.isJSDocTypeAlias(node)) {
                    if (ts.hasModifier(node, 512 /* Default */) && !getDeclarationName(node)) {
                        return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); // No local symbol for an unnamed default!
                    }
                    var exportKind = symbolFlags & 67220415 /* Value */ ? 1048576 /* ExportValue */ : 0;
                    var local = declareSymbol(container.locals, /*parent*/ undefined, node, exportKind, symbolExcludes);
                    local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
                    node.localSymbol = local;
                    return local;
                }
                else {
                    return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
                }
            }
        }
        // All container nodes are kept on a linked list in declaration order. This list is used by
        // the getLocalNameOfContainer function in the type checker to validate that the local name
        // used for a container is unique.
        function bindContainer(node, containerFlags) {
            // Before we recurse into a node's children, we first save the existing parent, container
            // and block-container.  Then after we pop out of processing the children, we restore
            // these saved values.
            var saveContainer = container;
            var saveThisParentContainer = thisParentContainer;
            var savedBlockScopeContainer = blockScopeContainer;
            // Depending on what kind of node this is, we may have to adjust the current container
            // and block-container.   If the current node is a container, then it is automatically
            // considered the current block-container as well.  Also, for containers that we know
            // may contain locals, we eagerly initialize the .locals field. We do this because
            // it's highly likely that the .locals will be needed to place some child in (for example,
            // a parameter, or variable declaration).
            //
            // However, we do not proactively create the .locals for block-containers because it's
            // totally normal and common for block-containers to never actually have a block-scoped
            // variable in them.  We don't want to end up allocating an object for every 'block' we
            // run into when most of them won't be necessary.
            //
            // Finally, if this is a block-container, then we clear out any existing .locals object
            // it may contain within it.  This happens in incremental scenarios.  Because we can be
            // reusing a node from a previous compilation, that node may have had 'locals' created
            // for it.  We must clear this so we don't accidentally move any stale data forward from
            // a previous compilation.
            if (containerFlags & 1 /* IsContainer */) {
                if (node.kind !== 198 /* ArrowFunction */) {
                    thisParentContainer = container;
                }
                container = blockScopeContainer = node;
                if (containerFlags & 32 /* HasLocals */) {
                    container.locals = ts.createSymbolTable();
                }
                addToContainerChain(container);
            }
            else if (containerFlags & 2 /* IsBlockScopedContainer */) {
                blockScopeContainer = node;
                blockScopeContainer.locals = undefined;
            }
            if (containerFlags & 4 /* IsControlFlowContainer */) {
                var saveFlowNodeCreated = flowNodeCreated;
                var saveCurrentFlow = currentFlow;
                var saveBreakTarget = currentBreakTarget;
                var saveContinueTarget = currentContinueTarget;
                var saveReturnTarget = currentReturnTarget;
                var saveActiveLabels = activeLabels;
                var saveHasExplicitReturn = hasExplicitReturn;
                var isIIFE = containerFlags & 16 /* IsFunctionExpression */ && !ts.hasModifier(node, 256 /* Async */) &&
                    !node.asteriskToken && !!ts.getImmediatelyInvokedFunctionExpression(node);
                // A non-async, non-generator IIFE is considered part of the containing control flow. Return statements behave
                // similarly to break statements that exit to a label just past the statement body.
                if (!isIIFE) {
                    currentFlow = { flags: 2 /* Start */ };
                    if (containerFlags & (16 /* IsFunctionExpression */ | 128 /* IsObjectLiteralOrClassExpressionMethod */)) {
                        currentFlow.container = node;
                    }
                }
                // We create a return control flow graph for IIFEs and constructors. For constructors
                // we use the return control flow graph in strict property initialization checks.
                currentReturnTarget = isIIFE || node.kind === 158 /* Constructor */ ? createBranchLabel() : undefined;
                currentBreakTarget = undefined;
                currentContinueTarget = undefined;
                activeLabels = undefined;
                hasExplicitReturn = false;
                flowNodeCreated = ts.identity;
                bindChildren(node);
                // Reset all reachability check related flags on node (for incremental scenarios)
                node.flags &= ~1408 /* ReachabilityAndEmitFlags */;
                if (!(currentFlow.flags & 1 /* Unreachable */) && containerFlags & 8 /* IsFunctionLike */ && ts.nodeIsPresent(node.body)) {
                    node.flags |= 128 /* HasImplicitReturn */;
                    if (hasExplicitReturn)
                        node.flags |= 256 /* HasExplicitReturn */;
                }
                if (node.kind === 285 /* SourceFile */) {
                    node.flags |= emitFlags;
                }
                if (currentReturnTarget) {
                    addAntecedent(currentReturnTarget, currentFlow);
                    currentFlow = finishFlowLabel(currentReturnTarget);
                    if (node.kind === 158 /* Constructor */) {
                        node.returnFlowNode = currentFlow;
                    }
                }
                if (!isIIFE) {
                    currentFlow = saveCurrentFlow;
                }
                currentBreakTarget = saveBreakTarget;
                currentContinueTarget = saveContinueTarget;
                currentReturnTarget = saveReturnTarget;
                activeLabels = saveActiveLabels;
                hasExplicitReturn = saveHasExplicitReturn;
                flowNodeCreated = saveFlowNodeCreated;
            }
            else if (containerFlags & 64 /* IsInterface */) {
                seenThisKeyword = false;
                bindChildren(node);
                node.flags = seenThisKeyword ? node.flags | 64 /* ContainsThis */ : node.flags & ~64 /* ContainsThis */;
            }
            else {
                bindChildren(node);
            }
            container = saveContainer;
            thisParentContainer = saveThisParentContainer;
            blockScopeContainer = savedBlockScopeContainer;
        }
        function bindChildren(node) {
            if (skipTransformFlagAggregation) {
                bindChildrenWorker(node);
            }
            else if (node.transformFlags & 536870912 /* HasComputedFlags */) {
                skipTransformFlagAggregation = true;
                bindChildrenWorker(node);
                skipTransformFlagAggregation = false;
                subtreeTransformFlags |= node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind);
            }
            else {
                var savedSubtreeTransformFlags = subtreeTransformFlags;
                subtreeTransformFlags = 0;
                bindChildrenWorker(node);
                subtreeTransformFlags = savedSubtreeTransformFlags | computeTransformFlagsForNode(node, subtreeTransformFlags);
            }
        }
        function bindEachFunctionsFirst(nodes) {
            bindEach(nodes, function (n) { return n.kind === 240 /* FunctionDeclaration */ ? bind(n) : undefined; });
            bindEach(nodes, function (n) { return n.kind !== 240 /* FunctionDeclaration */ ? bind(n) : undefined; });
        }
        function bindEach(nodes, bindFunction) {
            if (bindFunction === void 0) { bindFunction = bind; }
            if (nodes === undefined) {
                return;
            }
            if (skipTransformFlagAggregation) {
                ts.forEach(nodes, bindFunction);
            }
            else {
                var savedSubtreeTransformFlags = subtreeTransformFlags;
                subtreeTransformFlags = 0 /* None */;
                var nodeArrayFlags = 0 /* None */;
                for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
                    var node = nodes_2[_i];
                    bindFunction(node);
                    nodeArrayFlags |= node.transformFlags & ~536870912 /* HasComputedFlags */;
                }
                nodes.transformFlags = nodeArrayFlags | 536870912 /* HasComputedFlags */;
                subtreeTransformFlags |= savedSubtreeTransformFlags;
            }
        }
        function bindEachChild(node) {
            ts.forEachChild(node, bind, bindEach);
        }
        function bindChildrenWorker(node) {
            if (checkUnreachable(node)) {
                bindEachChild(node);
                bindJSDoc(node);
                return;
            }
            switch (node.kind) {
                case 225 /* WhileStatement */:
                    bindWhileStatement(node);
                    break;
                case 224 /* DoStatement */:
                    bindDoStatement(node);
                    break;
                case 226 /* ForStatement */:
                    bindForStatement(node);
                    break;
                case 227 /* ForInStatement */:
                case 228 /* ForOfStatement */:
                    bindForInOrForOfStatement(node);
                    break;
                case 223 /* IfStatement */:
                    bindIfStatement(node);
                    break;
                case 231 /* ReturnStatement */:
                case 235 /* ThrowStatement */:
                    bindReturnOrThrow(node);
                    break;
                case 230 /* BreakStatement */:
                case 229 /* ContinueStatement */:
                    bindBreakOrContinueStatement(node);
                    break;
                case 236 /* TryStatement */:
                    bindTryStatement(node);
                    break;
                case 233 /* SwitchStatement */:
                    bindSwitchStatement(node);
                    break;
                case 247 /* CaseBlock */:
                    bindCaseBlock(node);
                    break;
                case 272 /* CaseClause */:
                    bindCaseClause(node);
                    break;
                case 234 /* LabeledStatement */:
                    bindLabeledStatement(node);
                    break;
                case 203 /* PrefixUnaryExpression */:
                    bindPrefixUnaryExpressionFlow(node);
                    break;
                case 204 /* PostfixUnaryExpression */:
                    bindPostfixUnaryExpressionFlow(node);
                    break;
                case 205 /* BinaryExpression */:
                    bindBinaryExpressionFlow(node);
                    break;
                case 199 /* DeleteExpression */:
                    bindDeleteExpressionFlow(node);
                    break;
                case 206 /* ConditionalExpression */:
                    bindConditionalExpressionFlow(node);
                    break;
                case 238 /* VariableDeclaration */:
                    bindVariableDeclarationFlow(node);
                    break;
                case 192 /* CallExpression */:
                    bindCallExpressionFlow(node);
                    break;
                case 310 /* JSDocTypedefTag */:
                case 303 /* JSDocCallbackTag */:
                    bindJSDocTypeAlias(node);
                    break;
                // In source files and blocks, bind functions first to match hoisting that occurs at runtime
                case 285 /* SourceFile */: {
                    bindEachFunctionsFirst(node.statements);
                    bind(node.endOfFileToken);
                    break;
                }
                case 219 /* Block */:
                case 246 /* ModuleBlock */:
                    bindEachFunctionsFirst(node.statements);
                    break;
                default:
                    bindEachChild(node);
                    break;
            }
            bindJSDoc(node);
        }
        function isNarrowingExpression(expr) {
            switch (expr.kind) {
                case 73 /* Identifier */:
                case 101 /* ThisKeyword */:
                case 190 /* PropertyAccessExpression */:
                case 191 /* ElementAccessExpression */:
                    return isNarrowableReference(expr);
                case 192 /* CallExpression */:
                    return hasNarrowableArgument(expr);
                case 196 /* ParenthesizedExpression */:
                    return isNarrowingExpression(expr.expression);
                case 205 /* BinaryExpression */:
                    return isNarrowingBinaryExpression(expr);
                case 203 /* PrefixUnaryExpression */:
                    return expr.operator === 52 /* ExclamationToken */ && isNarrowingExpression(expr.operand);
                case 200 /* TypeOfExpression */:
                    return isNarrowingExpression(expr.expression);
            }
            return false;
        }
        function isNarrowableReference(expr) {
            return expr.kind === 73 /* Identifier */ || expr.kind === 101 /* ThisKeyword */ || expr.kind === 99 /* SuperKeyword */ ||
                (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) ||
                ts.isElementAccessExpression(expr) && expr.argumentExpression &&
                    (ts.isStringLiteral(expr.argumentExpression) || ts.isNumericLiteral(expr.argumentExpression)) &&
                    isNarrowableReference(expr.expression);
        }
        function hasNarrowableArgument(expr) {
            if (expr.arguments) {
                for (var _i = 0, _a = expr.arguments; _i < _a.length; _i++) {
                    var argument = _a[_i];
                    if (isNarrowableReference(argument)) {
                        return true;
                    }
                }
            }
            if (expr.expression.kind === 190 /* PropertyAccessExpression */ &&
                isNarrowableReference(expr.expression.expression)) {
                return true;
            }
            return false;
        }
        function isNarrowingTypeofOperands(expr1, expr2) {
            return ts.isTypeOfExpression(expr1) && isNarrowableOperand(expr1.expression) && ts.isStringLiteralLike(expr2);
        }
        function isNarrowableInOperands(left, right) {
            return ts.isStringLiteralLike(left) && isNarrowingExpression(right);
        }
        function isNarrowingBinaryExpression(expr) {
            switch (expr.operatorToken.kind) {
                case 60 /* EqualsToken */:
                    return isNarrowableReference(expr.left);
                case 33 /* EqualsEqualsToken */:
                case 34 /* ExclamationEqualsToken */:
                case 35 /* EqualsEqualsEqualsToken */:
                case 36 /* ExclamationEqualsEqualsToken */:
                    return isNarrowableOperand(expr.left) || isNarrowableOperand(expr.right) ||
                        isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right);
                case 95 /* InstanceOfKeyword */:
                    return isNarrowableOperand(expr.left);
                case 94 /* InKeyword */:
                    return isNarrowableInOperands(expr.left, expr.right);
                case 27 /* CommaToken */:
                    return isNarrowingExpression(expr.right);
            }
            return false;
        }
        function isNarrowableOperand(expr) {
            switch (expr.kind) {
                case 196 /* ParenthesizedExpression */:
                    return isNarrowableOperand(expr.expression);
                case 205 /* BinaryExpression */:
                    switch (expr.operatorToken.kind) {
                        case 60 /* EqualsToken */:
                            return isNarrowableOperand(expr.left);
                        case 27 /* CommaToken */:
                            return isNarrowableOperand(expr.right);
                    }
            }
            return isNarrowableReference(expr);
        }
        function createBranchLabel() {
            return {
                flags: 4 /* BranchLabel */,
                antecedents: undefined
            };
        }
        function createLoopLabel() {
            return {
                flags: 8 /* LoopLabel */,
                antecedents: undefined
            };
        }
        function setFlowNodeReferenced(flow) {
            // On first reference we set the Referenced flag, thereafter we set the Shared flag
            flow.flags |= flow.flags & 512 /* Referenced */ ? 1024 /* Shared */ : 512 /* Referenced */;
        }
        function addAntecedent(label, antecedent) {
            if (!(antecedent.flags & 1 /* Unreachable */) && !ts.contains(label.antecedents, antecedent)) {
                (label.antecedents || (label.antecedents = [])).push(antecedent);
                setFlowNodeReferenced(antecedent);
            }
        }
        function createFlowCondition(flags, antecedent, expression) {
            if (antecedent.flags & 1 /* Unreachable */) {
                return antecedent;
            }
            if (!expression) {
                return flags & 32 /* TrueCondition */ ? antecedent : unreachableFlow;
            }
            if (expression.kind === 103 /* TrueKeyword */ && flags & 64 /* FalseCondition */ ||
                expression.kind === 88 /* FalseKeyword */ && flags & 32 /* TrueCondition */) {
                return unreachableFlow;
            }
            if (!isNarrowingExpression(expression)) {
                return antecedent;
            }
            setFlowNodeReferenced(antecedent);
            return flowNodeCreated({ flags: flags, expression: expression, antecedent: antecedent });
        }
        function createFlowSwitchClause(antecedent, switchStatement, clauseStart, clauseEnd) {
            if (!isNarrowingExpression(switchStatement.expression)) {
                return antecedent;
            }
            setFlowNodeReferenced(antecedent);
            return flowNodeCreated({ flags: 128 /* SwitchClause */, switchStatement: switchStatement, clauseStart: clauseStart, clauseEnd: clauseEnd, antecedent: antecedent });
        }
        function createFlowAssignment(antecedent, node) {
            setFlowNodeReferenced(antecedent);
            return flowNodeCreated({ flags: 16 /* Assignment */, antecedent: antecedent, node: node });
        }
        function createFlowArrayMutation(antecedent, node) {
            setFlowNodeReferenced(antecedent);
            var res = flowNodeCreated({ flags: 256 /* ArrayMutation */, antecedent: antecedent, node: node });
            return res;
        }
        function finishFlowLabel(flow) {
            var antecedents = flow.antecedents;
            if (!antecedents) {
                return unreachableFlow;
            }
            if (antecedents.length === 1) {
                return antecedents[0];
            }
            return flow;
        }
        function isStatementCondition(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 223 /* IfStatement */:
                case 225 /* WhileStatement */:
                case 224 /* DoStatement */:
                    return parent.expression === node;
                case 226 /* ForStatement */:
                case 206 /* ConditionalExpression */:
                    return parent.condition === node;
            }
            return false;
        }
        function isLogicalExpression(node) {
            while (true) {
                if (node.kind === 196 /* ParenthesizedExpression */) {
                    node = node.expression;
                }
                else if (node.kind === 203 /* PrefixUnaryExpression */ && node.operator === 52 /* ExclamationToken */) {
                    node = node.operand;
                }
                else {
                    return node.kind === 205 /* BinaryExpression */ && (node.operatorToken.kind === 54 /* AmpersandAmpersandToken */ ||
                        node.operatorToken.kind === 55 /* BarBarToken */);
                }
            }
        }
        function isTopLevelLogicalExpression(node) {
            while (node.parent.kind === 196 /* ParenthesizedExpression */ ||
                node.parent.kind === 203 /* PrefixUnaryExpression */ &&
                    node.parent.operator === 52 /* ExclamationToken */) {
                node = node.parent;
            }
            return !isStatementCondition(node) && !isLogicalExpression(node.parent);
        }
        function bindCondition(node, trueTarget, falseTarget) {
            var saveTrueTarget = currentTrueTarget;
            var saveFalseTarget = currentFalseTarget;
            currentTrueTarget = trueTarget;
            currentFalseTarget = falseTarget;
            bind(node);
            currentTrueTarget = saveTrueTarget;
            currentFalseTarget = saveFalseTarget;
            if (!node || !isLogicalExpression(node)) {
                addAntecedent(trueTarget, createFlowCondition(32 /* TrueCondition */, currentFlow, node));
                addAntecedent(falseTarget, createFlowCondition(64 /* FalseCondition */, currentFlow, node));
            }
        }
        function bindIterativeStatement(node, breakTarget, continueTarget) {
            var saveBreakTarget = currentBreakTarget;
            var saveContinueTarget = currentContinueTarget;
            currentBreakTarget = breakTarget;
            currentContinueTarget = continueTarget;
            bind(node);
            currentBreakTarget = saveBreakTarget;
            currentContinueTarget = saveContinueTarget;
        }
        function bindWhileStatement(node) {
            var preWhileLabel = createLoopLabel();
            var preBodyLabel = createBranchLabel();
            var postWhileLabel = createBranchLabel();
            addAntecedent(preWhileLabel, currentFlow);
            currentFlow = preWhileLabel;
            bindCondition(node.expression, preBodyLabel, postWhileLabel);
            currentFlow = finishFlowLabel(preBodyLabel);
            bindIterativeStatement(node.statement, postWhileLabel, preWhileLabel);
            addAntecedent(preWhileLabel, currentFlow);
            currentFlow = finishFlowLabel(postWhileLabel);
        }
        function bindDoStatement(node) {
            var preDoLabel = createLoopLabel();
            var enclosingLabeledStatement = node.parent.kind === 234 /* LabeledStatement */
                ? ts.lastOrUndefined(activeLabels)
                : undefined;
            // if do statement is wrapped in labeled statement then target labels for break/continue with or without
            // label should be the same
            var preConditionLabel = enclosingLabeledStatement ? enclosingLabeledStatement.continueTarget : createBranchLabel();
            var postDoLabel = enclosingLabeledStatement ? enclosingLabeledStatement.breakTarget : createBranchLabel();
            addAntecedent(preDoLabel, currentFlow);
            currentFlow = preDoLabel;
            bindIterativeStatement(node.statement, postDoLabel, preConditionLabel);
            addAntecedent(preConditionLabel, currentFlow);
            currentFlow = finishFlowLabel(preConditionLabel);
            bindCondition(node.expression, preDoLabel, postDoLabel);
            currentFlow = finishFlowLabel(postDoLabel);
        }
        function bindForStatement(node) {
            var preLoopLabel = createLoopLabel();
            var preBodyLabel = createBranchLabel();
            var postLoopLabel = createBranchLabel();
            bind(node.initializer);
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = preLoopLabel;
            bindCondition(node.condition, preBodyLabel, postLoopLabel);
            currentFlow = finishFlowLabel(preBodyLabel);
            bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel);
            bind(node.incrementor);
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = finishFlowLabel(postLoopLabel);
        }
        function bindForInOrForOfStatement(node) {
            var preLoopLabel = createLoopLabel();
            var postLoopLabel = createBranchLabel();
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = preLoopLabel;
            if (node.kind === 228 /* ForOfStatement */) {
                bind(node.awaitModifier);
            }
            bind(node.expression);
            addAntecedent(postLoopLabel, currentFlow);
            bind(node.initializer);
            if (node.initializer.kind !== 239 /* VariableDeclarationList */) {
                bindAssignmentTargetFlow(node.initializer);
            }
            bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel);
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = finishFlowLabel(postLoopLabel);
        }
        function bindIfStatement(node) {
            var thenLabel = createBranchLabel();
            var elseLabel = createBranchLabel();
            var postIfLabel = createBranchLabel();
            bindCondition(node.expression, thenLabel, elseLabel);
            currentFlow = finishFlowLabel(thenLabel);
            bind(node.thenStatement);
            addAntecedent(postIfLabel, currentFlow);
            currentFlow = finishFlowLabel(elseLabel);
            bind(node.elseStatement);
            addAntecedent(postIfLabel, currentFlow);
            currentFlow = finishFlowLabel(postIfLabel);
        }
        function bindReturnOrThrow(node) {
            bind(node.expression);
            if (node.kind === 231 /* ReturnStatement */) {
                hasExplicitReturn = true;
                if (currentReturnTarget) {
                    addAntecedent(currentReturnTarget, currentFlow);
                }
            }
            currentFlow = unreachableFlow;
        }
        function findActiveLabel(name) {
            if (activeLabels) {
                for (var _i = 0, activeLabels_1 = activeLabels; _i < activeLabels_1.length; _i++) {
                    var label = activeLabels_1[_i];
                    if (label.name === name) {
                        return label;
                    }
                }
            }
            return undefined;
        }
        function bindBreakOrContinueFlow(node, breakTarget, continueTarget) {
            var flowLabel = node.kind === 230 /* BreakStatement */ ? breakTarget : continueTarget;
            if (flowLabel) {
                addAntecedent(flowLabel, currentFlow);
                currentFlow = unreachableFlow;
            }
        }
        function bindBreakOrContinueStatement(node) {
            bind(node.label);
            if (node.label) {
                var activeLabel = findActiveLabel(node.label.escapedText);
                if (activeLabel) {
                    activeLabel.referenced = true;
                    bindBreakOrContinueFlow(node, activeLabel.breakTarget, activeLabel.continueTarget);
                }
            }
            else {
                bindBreakOrContinueFlow(node, currentBreakTarget, currentContinueTarget);
            }
        }
        function bindTryStatement(node) {
            var preFinallyLabel = createBranchLabel();
            var preTryFlow = currentFlow;
            var tryPriors = [];
            var oldFlowNodeCreated = flowNodeCreated;
            // We hook the creation of all flow nodes within the `try` scope and store them so we can add _all_ of them
            // as possible antecedents of the start of the `catch` or `finally` blocks.
            // Don't bother intercepting the call if there's no finally or catch block that needs the information
            if (node.catchClause || node.finallyBlock) {
                flowNodeCreated = function (node) { return (tryPriors.push(node), node); };
            }
            bind(node.tryBlock);
            flowNodeCreated = oldFlowNodeCreated;
            addAntecedent(preFinallyLabel, currentFlow);
            var flowAfterTry = currentFlow;
            var flowAfterCatch = unreachableFlow;
            if (node.catchClause) {
                currentFlow = preTryFlow;
                if (tryPriors.length) {
                    var preCatchFlow = createBranchLabel();
                    addAntecedent(preCatchFlow, currentFlow);
                    for (var _i = 0, tryPriors_1 = tryPriors; _i < tryPriors_1.length; _i++) {
                        var p = tryPriors_1[_i];
                        addAntecedent(preCatchFlow, p);
                    }
                    currentFlow = finishFlowLabel(preCatchFlow);
                }
                bind(node.catchClause);
                addAntecedent(preFinallyLabel, currentFlow);
                flowAfterCatch = currentFlow;
            }
            if (node.finallyBlock) {
                // We add the nodes within the `try` block to the `finally`'s antecedents if there's no catch block
                // (If there is a `catch` block, it will have all these antecedents instead, and the `finally` will
                // have the end of the `try` block and the end of the `catch` block)
                var preFinallyPrior = preTryFlow;
                if (!node.catchClause) {
                    if (tryPriors.length) {
                        var preFinallyFlow_1 = createBranchLabel();
                        addAntecedent(preFinallyFlow_1, preTryFlow);
                        for (var _a = 0, tryPriors_2 = tryPriors; _a < tryPriors_2.length; _a++) {
                            var p = tryPriors_2[_a];
                            addAntecedent(preFinallyFlow_1, p);
                        }
                        preFinallyPrior = finishFlowLabel(preFinallyFlow_1);
                    }
                }
                // in finally flow is combined from pre-try/flow from try/flow from catch
                // pre-flow is necessary to make sure that finally is reachable even if finally flows in both try and finally blocks are unreachable
                // also for finally blocks we inject two extra edges into the flow graph.
                // first -> edge that connects pre-try flow with the label at the beginning of the finally block, it has lock associated with it
                // second -> edge that represents post-finally flow.
                // these edges are used in following scenario:
                // let a; (1)
                // try { a = someOperation(); (2)}
                // finally { (3) console.log(a) } (4)
                // (5) a
                // flow graph for this case looks roughly like this (arrows show ):
                // (1-pre-try-flow) <--.. <-- (2-post-try-flow)
                //  ^                                ^
                //  |*****(3-pre-finally-label) -----|
                //                ^
                //                |-- ... <-- (4-post-finally-label) <--- (5)
                // In case when we walk the flow starting from inside the finally block we want to take edge '*****' into account
                // since it ensures that finally is always reachable. However when we start outside the finally block and go through label (5)
                // then edge '*****' should be discarded because label 4 is only reachable if post-finally label-4 is reachable
                // Simply speaking code inside finally block is treated as reachable as pre-try-flow
                // since we conservatively assume that any line in try block can throw or return in which case we'll enter finally.
                // However code after finally is reachable only if control flow was not abrupted in try/catch or finally blocks - it should be composed from
                // final flows of these blocks without taking pre-try flow into account.
                //
                // extra edges that we inject allows to control this behavior
                // if when walking the flow we step on post-finally edge - we can mark matching pre-finally edge as locked so it will be skipped.
                var preFinallyFlow = { flags: 2048 /* PreFinally */, antecedent: preFinallyPrior, lock: {} };
                addAntecedent(preFinallyLabel, preFinallyFlow);
                currentFlow = finishFlowLabel(preFinallyLabel);
                bind(node.finallyBlock);
                // if flow after finally is unreachable - keep it
                // otherwise check if flows after try and after catch are unreachable
                // if yes - convert current flow to unreachable
                // i.e.
                // try { return "1" } finally { console.log(1); }
                // console.log(2); // this line should be unreachable even if flow falls out of finally block
                if (!(currentFlow.flags & 1 /* Unreachable */)) {
                    if ((flowAfterTry.flags & 1 /* Unreachable */) && (flowAfterCatch.flags & 1 /* Unreachable */)) {
                        currentFlow = flowAfterTry === reportedUnreachableFlow || flowAfterCatch === reportedUnreachableFlow
                            ? reportedUnreachableFlow
                            : unreachableFlow;
                    }
                }
                if (!(currentFlow.flags & 1 /* Unreachable */)) {
                    var afterFinallyFlow = flowNodeCreated({ flags: 4096 /* AfterFinally */, antecedent: currentFlow });
                    preFinallyFlow.lock = afterFinallyFlow;
                    currentFlow = afterFinallyFlow;
                }
            }
            else {
                currentFlow = finishFlowLabel(preFinallyLabel);
            }
        }
        function bindSwitchStatement(node) {
            var postSwitchLabel = createBranchLabel();
            bind(node.expression);
            var saveBreakTarget = currentBreakTarget;
            var savePreSwitchCaseFlow = preSwitchCaseFlow;
            currentBreakTarget = postSwitchLabel;
            preSwitchCaseFlow = currentFlow;
            bind(node.caseBlock);
            addAntecedent(postSwitchLabel, currentFlow);
            var hasDefault = ts.forEach(node.caseBlock.clauses, function (c) { return c.kind === 273 /* DefaultClause */; });
            // We mark a switch statement as possibly exhaustive if it has no default clause and if all
            // case clauses have unreachable end points (e.g. they all return).
            node.possiblyExhaustive = !hasDefault && !postSwitchLabel.antecedents;
            if (!hasDefault) {
                addAntecedent(postSwitchLabel, createFlowSwitchClause(preSwitchCaseFlow, node, 0, 0));
            }
            currentBreakTarget = saveBreakTarget;
            preSwitchCaseFlow = savePreSwitchCaseFlow;
            currentFlow = finishFlowLabel(postSwitchLabel);
        }
        function bindCaseBlock(node) {
            var savedSubtreeTransformFlags = subtreeTransformFlags;
            subtreeTransformFlags = 0;
            var clauses = node.clauses;
            var fallthroughFlow = unreachableFlow;
            for (var i = 0; i < clauses.length; i++) {
                var clauseStart = i;
                while (!clauses[i].statements.length && i + 1 < clauses.length) {
                    bind(clauses[i]);
                    i++;
                }
                var preCaseLabel = createBranchLabel();
                addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow, node.parent, clauseStart, i + 1));
                addAntecedent(preCaseLabel, fallthroughFlow);
                currentFlow = finishFlowLabel(preCaseLabel);
                var clause = clauses[i];
                bind(clause);
                fallthroughFlow = currentFlow;
                if (!(currentFlow.flags & 1 /* Unreachable */) && i !== clauses.length - 1 && options.noFallthroughCasesInSwitch) {
                    errorOnFirstToken(clause, ts.Diagnostics.Fallthrough_case_in_switch);
                }
            }
            clauses.transformFlags = subtreeTransformFlags | 536870912 /* HasComputedFlags */;
            subtreeTransformFlags |= savedSubtreeTransformFlags;
        }
        function bindCaseClause(node) {
            var saveCurrentFlow = currentFlow;
            currentFlow = preSwitchCaseFlow;
            bind(node.expression);
            currentFlow = saveCurrentFlow;
            bindEach(node.statements);
        }
        function pushActiveLabel(name, breakTarget, continueTarget) {
            var activeLabel = {
                name: name,
                breakTarget: breakTarget,
                continueTarget: continueTarget,
                referenced: false
            };
            (activeLabels || (activeLabels = [])).push(activeLabel);
            return activeLabel;
        }
        function popActiveLabel() {
            activeLabels.pop();
        }
        function bindLabeledStatement(node) {
            var preStatementLabel = createLoopLabel();
            var postStatementLabel = createBranchLabel();
            bind(node.label);
            addAntecedent(preStatementLabel, currentFlow);
            var activeLabel = pushActiveLabel(node.label.escapedText, postStatementLabel, preStatementLabel);
            bind(node.statement);
            popActiveLabel();
            if (!activeLabel.referenced && !options.allowUnusedLabels) {
                errorOrSuggestionOnNode(ts.unusedLabelIsError(options), node.label, ts.Diagnostics.Unused_label);
            }
            if (!node.statement || node.statement.kind !== 224 /* DoStatement */) {
                // do statement sets current flow inside bindDoStatement
                addAntecedent(postStatementLabel, currentFlow);
                currentFlow = finishFlowLabel(postStatementLabel);
            }
        }
        function bindDestructuringTargetFlow(node) {
            if (node.kind === 205 /* BinaryExpression */ && node.operatorToken.kind === 60 /* EqualsToken */) {
                bindAssignmentTargetFlow(node.left);
            }
            else {
                bindAssignmentTargetFlow(node);
            }
        }
        function bindAssignmentTargetFlow(node) {
            if (isNarrowableReference(node)) {
                currentFlow = createFlowAssignment(currentFlow, node);
            }
            else if (node.kind === 188 /* ArrayLiteralExpression */) {
                for (var _i = 0, _a = node.elements; _i < _a.length; _i++) {
                    var e = _a[_i];
                    if (e.kind === 209 /* SpreadElement */) {
                        bindAssignmentTargetFlow(e.expression);
                    }
                    else {
                        bindDestructuringTargetFlow(e);
                    }
                }
            }
            else if (node.kind === 189 /* ObjectLiteralExpression */) {
                for (var _b = 0, _c = node.properties; _b < _c.length; _b++) {
                    var p = _c[_b];
                    if (p.kind === 276 /* PropertyAssignment */) {
                        bindDestructuringTargetFlow(p.initializer);
                    }
                    else if (p.kind === 277 /* ShorthandPropertyAssignment */) {
                        bindAssignmentTargetFlow(p.name);
                    }
                    else if (p.kind === 278 /* SpreadAssignment */) {
                        bindAssignmentTargetFlow(p.expression);
                    }
                }
            }
        }
        function bindLogicalExpression(node, trueTarget, falseTarget) {
            var preRightLabel = createBranchLabel();
            if (node.operatorToken.kind === 54 /* AmpersandAmpersandToken */) {
                bindCondition(node.left, preRightLabel, falseTarget);
            }
            else {
                bindCondition(node.left, trueTarget, preRightLabel);
            }
            currentFlow = finishFlowLabel(preRightLabel);
            bind(node.operatorToken);
            bindCondition(node.right, trueTarget, falseTarget);
        }
        function bindPrefixUnaryExpressionFlow(node) {
            if (node.operator === 52 /* ExclamationToken */) {
                var saveTrueTarget = currentTrueTarget;
                currentTrueTarget = currentFalseTarget;
                currentFalseTarget = saveTrueTarget;
                bindEachChild(node);
                currentFalseTarget = currentTrueTarget;
                currentTrueTarget = saveTrueTarget;
            }
            else {
                bindEachChild(node);
                if (node.operator === 44 /* PlusPlusToken */ || node.operator === 45 /* MinusMinusToken */) {
                    bindAssignmentTargetFlow(node.operand);
                }
            }
        }
        function bindPostfixUnaryExpressionFlow(node) {
            bindEachChild(node);
            if (node.operator === 44 /* PlusPlusToken */ || node.operator === 45 /* MinusMinusToken */) {
                bindAssignmentTargetFlow(node.operand);
            }
        }
        function bindBinaryExpressionFlow(node) {
            var operator = node.operatorToken.kind;
            if (operator === 54 /* AmpersandAmpersandToken */ || operator === 55 /* BarBarToken */) {
                if (isTopLevelLogicalExpression(node)) {
                    var postExpressionLabel = createBranchLabel();
                    bindLogicalExpression(node, postExpressionLabel, postExpressionLabel);
                    currentFlow = finishFlowLabel(postExpressionLabel);
                }
                else {
                    bindLogicalExpression(node, currentTrueTarget, currentFalseTarget);
                }
            }
            else {
                bindEachChild(node);
                if (ts.isAssignmentOperator(operator) && !ts.isAssignmentTarget(node)) {
                    bindAssignmentTargetFlow(node.left);
                    if (operator === 60 /* EqualsToken */ && node.left.kind === 191 /* ElementAccessExpression */) {
                        var elementAccess = node.left;
                        if (isNarrowableOperand(elementAccess.expression)) {
                            currentFlow = createFlowArrayMutation(currentFlow, node);
                        }
                    }
                }
            }
        }
        function bindDeleteExpressionFlow(node) {
            bindEachChild(node);
            if (node.expression.kind === 190 /* PropertyAccessExpression */) {
                bindAssignmentTargetFlow(node.expression);
            }
        }
        function bindConditionalExpressionFlow(node) {
            var trueLabel = createBranchLabel();
            var falseLabel = createBranchLabel();
            var postExpressionLabel = createBranchLabel();
            bindCondition(node.condition, trueLabel, falseLabel);
            currentFlow = finishFlowLabel(trueLabel);
            bind(node.questionToken);
            bind(node.whenTrue);
            addAntecedent(postExpressionLabel, currentFlow);
            currentFlow = finishFlowLabel(falseLabel);
            bind(node.colonToken);
            bind(node.whenFalse);
            addAntecedent(postExpressionLabel, currentFlow);
            currentFlow = finishFlowLabel(postExpressionLabel);
        }
        function bindInitializedVariableFlow(node) {
            var name = !ts.isOmittedExpression(node) ? node.name : undefined;
            if (ts.isBindingPattern(name)) {
                for (var _i = 0, _a = name.elements; _i < _a.length; _i++) {
                    var child = _a[_i];
                    bindInitializedVariableFlow(child);
                }
            }
            else {
                currentFlow = createFlowAssignment(currentFlow, node);
            }
        }
        function bindVariableDeclarationFlow(node) {
            bindEachChild(node);
            if (node.initializer || ts.isForInOrOfStatement(node.parent.parent)) {
                bindInitializedVariableFlow(node);
            }
        }
        function bindJSDocTypeAlias(node) {
            node.tagName.parent = node;
            if (node.fullName) {
                setParentPointers(node, node.fullName);
            }
        }
        function bindCallExpressionFlow(node) {
            // If the target of the call expression is a function expression or arrow function we have
            // an immediately invoked function expression (IIFE). Initialize the flowNode property to
            // the current control flow (which includes evaluation of the IIFE arguments).
            var expr = node.expression;
            while (expr.kind === 196 /* ParenthesizedExpression */) {
                expr = expr.expression;
            }
            if (expr.kind === 197 /* FunctionExpression */ || expr.kind === 198 /* ArrowFunction */) {
                bindEach(node.typeArguments);
                bindEach(node.arguments);
                bind(node.expression);
            }
            else {
                bindEachChild(node);
            }
            if (node.expression.kind === 190 /* PropertyAccessExpression */) {
                var propertyAccess = node.expression;
                if (isNarrowableOperand(propertyAccess.expression) && ts.isPushOrUnshiftIdentifier(propertyAccess.name)) {
                    currentFlow = createFlowArrayMutation(currentFlow, node);
                }
            }
        }
        function getContainerFlags(node) {
            switch (node.kind) {
                case 210 /* ClassExpression */:
                case 241 /* ClassDeclaration */:
                case 244 /* EnumDeclaration */:
                case 189 /* ObjectLiteralExpression */:
                case 169 /* TypeLiteral */:
                case 298 /* JSDocTypeLiteral */:
                case 269 /* JsxAttributes */:
                    return 1 /* IsContainer */;
                case 242 /* InterfaceDeclaration */:
                    return 1 /* IsContainer */ | 64 /* IsInterface */;
                case 245 /* ModuleDeclaration */:
                case 243 /* TypeAliasDeclaration */:
                case 182 /* MappedType */:
                    return 1 /* IsContainer */ | 32 /* HasLocals */;
                case 285 /* SourceFile */:
                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */;
                case 157 /* MethodDeclaration */:
                    if (ts.isObjectLiteralOrClassExpressionMethod(node)) {
                        return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */ | 128 /* IsObjectLiteralOrClassExpressionMethod */;
                    }
                // falls through
                case 158 /* Constructor */:
                case 240 /* FunctionDeclaration */:
                case 156 /* MethodSignature */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                case 161 /* CallSignature */:
                case 299 /* JSDocSignature */:
                case 295 /* JSDocFunctionType */:
                case 166 /* FunctionType */:
                case 162 /* ConstructSignature */:
                case 163 /* IndexSignature */:
                case 167 /* ConstructorType */:
                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */;
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */:
                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */ | 16 /* IsFunctionExpression */;
                case 246 /* ModuleBlock */:
                    return 4 /* IsControlFlowContainer */;
                case 155 /* PropertyDeclaration */:
                    return node.initializer ? 4 /* IsControlFlowContainer */ : 0;
                case 275 /* CatchClause */:
                case 226 /* ForStatement */:
                case 227 /* ForInStatement */:
                case 228 /* ForOfStatement */:
                case 247 /* CaseBlock */:
                    return 2 /* IsBlockScopedContainer */;
                case 219 /* Block */:
                    // do not treat blocks directly inside a function as a block-scoped-container.
                    // Locals that reside in this block should go to the function locals. Otherwise 'x'
                    // would not appear to be a redeclaration of a block scoped local in the following
                    // example:
                    //
                    //      function foo() {
                    //          var x;
                    //          let x;
                    //      }
                    //
                    // If we placed 'var x' into the function locals and 'let x' into the locals of
                    // the block, then there would be no collision.
                    //
                    // By not creating a new block-scoped-container here, we ensure that both 'var x'
                    // and 'let x' go into the Function-container's locals, and we do get a collision
                    // conflict.
                    return ts.isFunctionLike(node.parent) ? 0 /* None */ : 2 /* IsBlockScopedContainer */;
            }
            return 0 /* None */;
        }
        function addToContainerChain(next) {
            if (lastContainer) {
                lastContainer.nextContainer = next;
            }
            lastContainer = next;
        }
        function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) {
            switch (container.kind) {
                // Modules, source files, and classes need specialized handling for how their
                // members are declared (for example, a member of a class will go into a specific
                // symbol table depending on if it is static or not). We defer to specialized
                // handlers to take care of declaring these child members.
                case 245 /* ModuleDeclaration */:
                    return declareModuleMember(node, symbolFlags, symbolExcludes);
                case 285 /* SourceFile */:
                    return declareSourceFileMember(node, symbolFlags, symbolExcludes);
                case 210 /* ClassExpression */:
                case 241 /* ClassDeclaration */:
                    return declareClassMember(node, symbolFlags, symbolExcludes);
                case 244 /* EnumDeclaration */:
                    return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
                case 169 /* TypeLiteral */:
                case 298 /* JSDocTypeLiteral */:
                case 189 /* ObjectLiteralExpression */:
                case 242 /* InterfaceDeclaration */:
                case 269 /* JsxAttributes */:
                    // Interface/Object-types always have their children added to the 'members' of
                    // their container. They are only accessible through an instance of their
                    // container, and are never in scope otherwise (even inside the body of the
                    // object / type / interface declaring them). An exception is type parameters,
                    // which are in scope without qualification (similar to 'locals').
                    return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
                case 166 /* FunctionType */:
                case 167 /* ConstructorType */:
                case 161 /* CallSignature */:
                case 162 /* ConstructSignature */:
                case 299 /* JSDocSignature */:
                case 163 /* IndexSignature */:
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                case 158 /* Constructor */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                case 240 /* FunctionDeclaration */:
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */:
                case 295 /* JSDocFunctionType */:
                case 310 /* JSDocTypedefTag */:
                case 303 /* JSDocCallbackTag */:
                case 243 /* TypeAliasDeclaration */:
                case 182 /* MappedType */:
                    // All the children of these container types are never visible through another
                    // symbol (i.e. through another symbol's 'exports' or 'members').  Instead,
                    // they're only accessed 'lexically' (i.e. from code that exists underneath
                    // their container in the tree). To accomplish this, we simply add their declared
                    // symbol to the 'locals' of the container.  These symbols can then be found as
                    // the type checker walks up the containers, checking them for matching names.
                    return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
            }
        }
        function declareClassMember(node, symbolFlags, symbolExcludes) {
            return ts.hasModifier(node, 32 /* Static */)
                ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes)
                : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
        }
        function declareSourceFileMember(node, symbolFlags, symbolExcludes) {
            return ts.isExternalModule(file)
                ? declareModuleMember(node, symbolFlags, symbolExcludes)
                : declareSymbol(file.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
        }
        function hasExportDeclarations(node) {
            var body = ts.isSourceFile(node) ? node : ts.tryCast(node.body, ts.isModuleBlock);
            return !!body && body.statements.some(function (s) { return ts.isExportDeclaration(s) || ts.isExportAssignment(s); });
        }
        function setExportContextFlag(node) {
            // A declaration source file or ambient module declaration that contains no export declarations (but possibly regular
            // declarations with export modifiers) is an export context in which declarations are implicitly exported.
            if (node.flags & 4194304 /* Ambient */ && !hasExportDeclarations(node)) {
                node.flags |= 32 /* ExportContext */;
            }
            else {
                node.flags &= ~32 /* ExportContext */;
            }
        }
        function bindModuleDeclaration(node) {
            setExportContextFlag(node);
            if (ts.isAmbientModule(node)) {
                if (ts.hasModifier(node, 1 /* Export */)) {
                    errorOnFirstToken(node, ts.Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible);
                }
                if (ts.isModuleAugmentationExternal(node)) {
                    declareModuleSymbol(node);
                }
                else {
                    var pattern = void 0;
                    if (node.name.kind === 10 /* StringLiteral */) {
                        var text = node.name.text;
                        if (ts.hasZeroOrOneAsteriskCharacter(text)) {
                            pattern = ts.tryParsePattern(text);
                        }
                        else {
                            errorOnFirstToken(node.name, ts.Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, text);
                        }
                    }
                    var symbol = declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 110735 /* ValueModuleExcludes */);
                    file.patternAmbientModules = ts.append(file.patternAmbientModules, pattern && { pattern: pattern, symbol: symbol });
                }
            }
            else {
                var state = declareModuleSymbol(node);
                if (state !== 0 /* NonInstantiated */) {
                    var symbol = node.symbol;
                    // if module was already merged with some function, class or non-const enum, treat it as non-const-enum-only
                    symbol.constEnumOnlyModule = (!(symbol.flags & (16 /* Function */ | 32 /* Class */ | 256 /* RegularEnum */)))
                        // Current must be `const enum` only
                        && state === 2 /* ConstEnumOnly */
                        // Can't have been set to 'false' in a previous merged symbol. ('undefined' OK)
                        && symbol.constEnumOnlyModule !== false;
                }
            }
        }
        function declareModuleSymbol(node) {
            var state = getModuleInstanceState(node);
            var instantiated = state !== 0 /* NonInstantiated */;
            declareSymbolAndAddToSymbolTable(node, instantiated ? 512 /* ValueModule */ : 1024 /* NamespaceModule */, instantiated ? 110735 /* ValueModuleExcludes */ : 0 /* NamespaceModuleExcludes */);
            return state;
        }
        function bindFunctionOrConstructorType(node) {
            // For a given function symbol "<...>(...) => T" we want to generate a symbol identical
            // to the one we would get for: { <...>(...): T }
            //
            // We do that by making an anonymous type literal symbol, and then setting the function
            // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable
            // from an actual type literal symbol you would have gotten had you used the long form.
            var symbol = createSymbol(131072 /* Signature */, getDeclarationName(node)); // TODO: GH#18217
            addDeclarationToSymbol(symbol, node, 131072 /* Signature */);
            var typeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */);
            addDeclarationToSymbol(typeLiteralSymbol, node, 2048 /* TypeLiteral */);
            typeLiteralSymbol.members = ts.createSymbolTable();
            typeLiteralSymbol.members.set(symbol.escapedName, symbol);
        }
        function bindObjectLiteralExpression(node) {
            var ElementKind;
            (function (ElementKind) {
                ElementKind[ElementKind["Property"] = 1] = "Property";
                ElementKind[ElementKind["Accessor"] = 2] = "Accessor";
            })(ElementKind || (ElementKind = {}));
            if (inStrictMode) {
                var seen = ts.createUnderscoreEscapedMap();
                for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (prop.kind === 278 /* SpreadAssignment */ || prop.name.kind !== 73 /* Identifier */) {
                        continue;
                    }
                    var identifier = prop.name;
                    // ECMA-262 11.1.5 Object Initializer
                    // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
                    // a.This production is contained in strict code and IsDataDescriptor(previous) is true and
                    // IsDataDescriptor(propId.descriptor) is true.
                    //    b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
                    //    c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
                    //    d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
                    // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
                    var currentKind = prop.kind === 276 /* PropertyAssignment */ || prop.kind === 277 /* ShorthandPropertyAssignment */ || prop.kind === 157 /* MethodDeclaration */
                        ? 1 /* Property */
                        : 2 /* Accessor */;
                    var existingKind = seen.get(identifier.escapedText);
                    if (!existingKind) {
                        seen.set(identifier.escapedText, currentKind);
                        continue;
                    }
                    if (currentKind === 1 /* Property */ && existingKind === 1 /* Property */) {
                        var span = ts.getErrorSpanForNode(file, identifier);
                        file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode));
                    }
                }
            }
            return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object" /* Object */);
        }
        function bindJsxAttributes(node) {
            return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__jsxAttributes" /* JSXAttributes */);
        }
        function bindJsxAttribute(node, symbolFlags, symbolExcludes) {
            return declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
        }
        function bindAnonymousDeclaration(node, symbolFlags, name) {
            var symbol = createSymbol(symbolFlags, name);
            if (symbolFlags & (8 /* EnumMember */ | 106500 /* ClassMember */)) {
                symbol.parent = container.symbol;
            }
            addDeclarationToSymbol(symbol, node, symbolFlags);
            return symbol;
        }
        function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) {
            switch (blockScopeContainer.kind) {
                case 245 /* ModuleDeclaration */:
                    declareModuleMember(node, symbolFlags, symbolExcludes);
                    break;
                case 285 /* SourceFile */:
                    if (ts.isExternalOrCommonJsModule(container)) {
                        declareModuleMember(node, symbolFlags, symbolExcludes);
                        break;
                    }
                // falls through
                default:
                    if (!blockScopeContainer.locals) {
                        blockScopeContainer.locals = ts.createSymbolTable();
                        addToContainerChain(blockScopeContainer);
                    }
                    declareSymbol(blockScopeContainer.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
            }
        }
        function delayedBindJSDocTypedefTag() {
            if (!delayedTypeAliases) {
                return;
            }
            var saveContainer = container;
            var saveLastContainer = lastContainer;
            var saveBlockScopeContainer = blockScopeContainer;
            var saveParent = parent;
            var saveCurrentFlow = currentFlow;
            for (var _i = 0, delayedTypeAliases_1 = delayedTypeAliases; _i < delayedTypeAliases_1.length; _i++) {
                var typeAlias = delayedTypeAliases_1[_i];
                var host = ts.getJSDocHost(typeAlias);
                container = ts.findAncestor(host.parent, function (n) { return !!(getContainerFlags(n) & 1 /* IsContainer */); }) || file;
                blockScopeContainer = ts.getEnclosingBlockScopeContainer(host) || file;
                currentFlow = { flags: 2 /* Start */ };
                parent = typeAlias;
                bind(typeAlias.typeExpression);
                if (!typeAlias.fullName || typeAlias.fullName.kind === 73 /* Identifier */) {
                    parent = typeAlias.parent;
                    bindBlockScopedDeclaration(typeAlias, 524288 /* TypeAlias */, 67897832 /* TypeAliasExcludes */);
                }
                else {
                    bind(typeAlias.fullName);
                }
            }
            container = saveContainer;
            lastContainer = saveLastContainer;
            blockScopeContainer = saveBlockScopeContainer;
            parent = saveParent;
            currentFlow = saveCurrentFlow;
        }
        // The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
        // check for reserved words used as identifiers in strict mode code.
        function checkStrictModeIdentifier(node) {
            if (inStrictMode &&
                node.originalKeywordKind >= 110 /* FirstFutureReservedWord */ &&
                node.originalKeywordKind <= 118 /* LastFutureReservedWord */ &&
                !ts.isIdentifierName(node) &&
                !(node.flags & 4194304 /* Ambient */)) {
                // Report error only if there are no parse errors in file
                if (!file.parseDiagnostics.length) {
                    file.bindDiagnostics.push(createDiagnosticForNode(node, getStrictModeIdentifierMessage(node), ts.declarationNameToString(node)));
                }
            }
        }
        function getStrictModeIdentifierMessage(node) {
            // Provide specialized messages to help the user understand why we think they're in
            // strict mode.
            if (ts.getContainingClass(node)) {
                return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
            }
            if (file.externalModuleIndicator) {
                return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode;
            }
            return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
        }
        function checkStrictModeBinaryExpression(node) {
            if (inStrictMode && ts.isLeftHandSideExpression(node.left) && ts.isAssignmentOperator(node.operatorToken.kind)) {
                // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
                // Assignment operator(11.13) or of a PostfixExpression(11.3)
                checkStrictModeEvalOrArguments(node, node.left);
            }
        }
        function checkStrictModeCatchClause(node) {
            // It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the
            // Catch production is eval or arguments
            if (inStrictMode && node.variableDeclaration) {
                checkStrictModeEvalOrArguments(node, node.variableDeclaration.name);
            }
        }
        function checkStrictModeDeleteExpression(node) {
            // Grammar checking
            if (inStrictMode && node.expression.kind === 73 /* Identifier */) {
                // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
                // UnaryExpression is a direct reference to a variable, function argument, or function name
                var span = ts.getErrorSpanForNode(file, node.expression);
                file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode));
            }
        }
        function isEvalOrArgumentsIdentifier(node) {
            return ts.isIdentifier(node) && (node.escapedText === "eval" || node.escapedText === "arguments");
        }
        function checkStrictModeEvalOrArguments(contextNode, name) {
            if (name && name.kind === 73 /* Identifier */) {
                var identifier = name;
                if (isEvalOrArgumentsIdentifier(identifier)) {
                    // We check first if the name is inside class declaration or class expression; if so give explicit message
                    // otherwise report generic error message.
                    var span = ts.getErrorSpanForNode(file, name);
                    file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, getStrictModeEvalOrArgumentsMessage(contextNode), ts.idText(identifier)));
                }
            }
        }
        function getStrictModeEvalOrArgumentsMessage(node) {
            // Provide specialized messages to help the user understand why we think they're in
            // strict mode.
            if (ts.getContainingClass(node)) {
                return ts.Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode;
            }
            if (file.externalModuleIndicator) {
                return ts.Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode;
            }
            return ts.Diagnostics.Invalid_use_of_0_in_strict_mode;
        }
        function checkStrictModeFunctionName(node) {
            if (inStrictMode) {
                // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1))
                checkStrictModeEvalOrArguments(node, node.name);
            }
        }
        function getStrictModeBlockScopeFunctionDeclarationMessage(node) {
            // Provide specialized messages to help the user understand why we think they're in
            // strict mode.
            if (ts.getContainingClass(node)) {
                return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_definitions_are_automatically_in_strict_mode;
            }
            if (file.externalModuleIndicator) {
                return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_are_automatically_in_strict_mode;
            }
            return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5;
        }
        function checkStrictModeFunctionDeclaration(node) {
            if (languageVersion < 2 /* ES2015 */) {
                // Report error if function is not top level function declaration
                if (blockScopeContainer.kind !== 285 /* SourceFile */ &&
                    blockScopeContainer.kind !== 245 /* ModuleDeclaration */ &&
                    !ts.isFunctionLike(blockScopeContainer)) {
                    // We check first if the name is inside class declaration or class expression; if so give explicit message
                    // otherwise report generic error message.
                    var errorSpan = ts.getErrorSpanForNode(file, node);
                    file.bindDiagnostics.push(ts.createFileDiagnostic(file, errorSpan.start, errorSpan.length, getStrictModeBlockScopeFunctionDeclarationMessage(node)));
                }
            }
        }
        function checkStrictModeNumericLiteral(node) {
            if (inStrictMode && node.numericLiteralFlags & 32 /* Octal */) {
                file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Octal_literals_are_not_allowed_in_strict_mode));
            }
        }
        function checkStrictModePostfixUnaryExpression(node) {
            // Grammar checking
            // The identifier eval or arguments may not appear as the LeftHandSideExpression of an
            // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
            // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator.
            if (inStrictMode) {
                checkStrictModeEvalOrArguments(node, node.operand);
            }
        }
        function checkStrictModePrefixUnaryExpression(node) {
            // Grammar checking
            if (inStrictMode) {
                if (node.operator === 44 /* PlusPlusToken */ || node.operator === 45 /* MinusMinusToken */) {
                    checkStrictModeEvalOrArguments(node, node.operand);
                }
            }
        }
        function checkStrictModeWithStatement(node) {
            // Grammar checking for withStatement
            if (inStrictMode) {
                errorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_strict_mode);
            }
        }
        function checkStrictModeLabeledStatement(node) {
            // Grammar checking for labeledStatement
            if (inStrictMode && options.target >= 2 /* ES2015 */) {
                if (ts.isDeclarationStatement(node.statement) || ts.isVariableStatement(node.statement)) {
                    errorOnFirstToken(node.label, ts.Diagnostics.A_label_is_not_allowed_here);
                }
            }
        }
        function errorOnFirstToken(node, message, arg0, arg1, arg2) {
            var span = ts.getSpanOfTokenAtPosition(file, node.pos);
            file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
        }
        function errorOrSuggestionOnNode(isError, node, message) {
            errorOrSuggestionOnRange(isError, node, node, message);
        }
        function errorOrSuggestionOnRange(isError, startNode, endNode, message) {
            addErrorOrSuggestionDiagnostic(isError, { pos: ts.getTokenPosOfNode(startNode, file), end: endNode.end }, message);
        }
        function addErrorOrSuggestionDiagnostic(isError, range, message) {
            var diag = ts.createFileDiagnostic(file, range.pos, range.end - range.pos, message);
            if (isError) {
                file.bindDiagnostics.push(diag);
            }
            else {
                file.bindSuggestionDiagnostics = ts.append(file.bindSuggestionDiagnostics, __assign({}, diag, { category: ts.DiagnosticCategory.Suggestion }));
            }
        }
        function bind(node) {
            if (!node) {
                return;
            }
            node.parent = parent;
            var saveInStrictMode = inStrictMode;
            // Even though in the AST the jsdoc @typedef node belongs to the current node,
            // its symbol might be in the same scope with the current node's symbol. Consider:
            //
            //     /** @typedef {string | number} MyType */
            //     function foo();
            //
            // Here the current node is "foo", which is a container, but the scope of "MyType" should
            // not be inside "foo". Therefore we always bind @typedef before bind the parent node,
            // and skip binding this tag later when binding all the other jsdoc tags.
            // First we bind declaration nodes to a symbol if possible. We'll both create a symbol
            // and then potentially add the symbol to an appropriate symbol table. Possible
            // destination symbol tables are:
            //
            //  1) The 'exports' table of the current container's symbol.
            //  2) The 'members' table of the current container's symbol.
            //  3) The 'locals' table of the current container.
            //
            // However, not all symbols will end up in any of these tables. 'Anonymous' symbols
            // (like TypeLiterals for example) will not be put in any table.
            bindWorker(node);
            // Then we recurse into the children of the node to bind them as well. For certain
            // symbols we do specialized work when we recurse. For example, we'll keep track of
            // the current 'container' node when it changes. This helps us know which symbol table
            // a local should go into for example. Since terminal nodes are known not to have
            // children, as an optimization we don't process those.
            if (node.kind > 148 /* LastToken */) {
                var saveParent = parent;
                parent = node;
                var containerFlags = getContainerFlags(node);
                if (containerFlags === 0 /* None */) {
                    bindChildren(node);
                }
                else {
                    bindContainer(node, containerFlags);
                }
                parent = saveParent;
            }
            else if (!skipTransformFlagAggregation && (node.transformFlags & 536870912 /* HasComputedFlags */) === 0) {
                subtreeTransformFlags |= computeTransformFlagsForNode(node, 0);
                var saveParent = parent;
                if (node.kind === 1 /* EndOfFileToken */)
                    parent = node;
                bindJSDoc(node);
                parent = saveParent;
            }
            inStrictMode = saveInStrictMode;
        }
        function bindJSDoc(node) {
            if (ts.hasJSDocNodes(node)) {
                if (ts.isInJSFile(node)) {
                    for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                        var j = _a[_i];
                        bind(j);
                    }
                }
                else {
                    for (var _b = 0, _c = node.jsDoc; _b < _c.length; _b++) {
                        var j = _c[_b];
                        setParentPointers(node, j);
                    }
                }
            }
        }
        function updateStrictModeStatementList(statements) {
            if (!inStrictMode) {
                for (var _i = 0, statements_1 = statements; _i < statements_1.length; _i++) {
                    var statement = statements_1[_i];
                    if (!ts.isPrologueDirective(statement)) {
                        return;
                    }
                    if (isUseStrictPrologueDirective(statement)) {
                        inStrictMode = true;
                        return;
                    }
                }
            }
        }
        /// Should be called only on prologue directives (isPrologueDirective(node) should be true)
        function isUseStrictPrologueDirective(node) {
            var nodeText = ts.getSourceTextOfNodeFromSourceFile(file, node.expression);
            // Note: the node text must be exactly "use strict" or 'use strict'.  It is not ok for the
            // string to contain unicode escapes (as per ES5).
            return nodeText === '"use strict"' || nodeText === "'use strict'";
        }
        function bindWorker(node) {
            switch (node.kind) {
                /* Strict mode checks */
                case 73 /* Identifier */:
                    // for typedef type names with namespaces, bind the new jsdoc type symbol here
                    // because it requires all containing namespaces to be in effect, namely the
                    // current "blockScopeContainer" needs to be set to its immediate namespace parent.
                    if (node.isInJSDocNamespace) {
                        var parentNode = node.parent;
                        while (parentNode && !ts.isJSDocTypeAlias(parentNode)) {
                            parentNode = parentNode.parent;
                        }
                        bindBlockScopedDeclaration(parentNode, 524288 /* TypeAlias */, 67897832 /* TypeAliasExcludes */);
                        break;
                    }
                // falls through
                case 101 /* ThisKeyword */:
                    if (currentFlow && (ts.isExpression(node) || parent.kind === 277 /* ShorthandPropertyAssignment */)) {
                        node.flowNode = currentFlow;
                    }
                    return checkStrictModeIdentifier(node);
                case 190 /* PropertyAccessExpression */:
                case 191 /* ElementAccessExpression */:
                    if (currentFlow && isNarrowableReference(node)) {
                        node.flowNode = currentFlow;
                    }
                    if (ts.isSpecialPropertyDeclaration(node)) {
                        bindSpecialPropertyDeclaration(node);
                    }
                    if (ts.isInJSFile(node) &&
                        file.commonJsModuleIndicator &&
                        ts.isModuleExportsPropertyAccessExpression(node) &&
                        !lookupSymbolForNameWorker(blockScopeContainer, "module")) {
                        declareSymbol(file.locals, /*parent*/ undefined, node.expression, 1 /* FunctionScopedVariable */ | 134217728 /* ModuleExports */, 67220414 /* FunctionScopedVariableExcludes */);
                    }
                    break;
                case 205 /* BinaryExpression */:
                    var specialKind = ts.getAssignmentDeclarationKind(node);
                    switch (specialKind) {
                        case 1 /* ExportsProperty */:
                            bindExportsPropertyAssignment(node);
                            break;
                        case 2 /* ModuleExports */:
                            bindModuleExportsAssignment(node);
                            break;
                        case 3 /* PrototypeProperty */:
                            bindPrototypePropertyAssignment(node.left, node);
                            break;
                        case 6 /* Prototype */:
                            bindPrototypeAssignment(node);
                            break;
                        case 4 /* ThisProperty */:
                            bindThisPropertyAssignment(node);
                            break;
                        case 5 /* Property */:
                            bindSpecialPropertyAssignment(node);
                            break;
                        case 0 /* None */:
                            // Nothing to do
                            break;
                        default:
                            ts.Debug.fail("Unknown binary expression special property assignment kind");
                    }
                    return checkStrictModeBinaryExpression(node);
                case 275 /* CatchClause */:
                    return checkStrictModeCatchClause(node);
                case 199 /* DeleteExpression */:
                    return checkStrictModeDeleteExpression(node);
                case 8 /* NumericLiteral */:
                    return checkStrictModeNumericLiteral(node);
                case 204 /* PostfixUnaryExpression */:
                    return checkStrictModePostfixUnaryExpression(node);
                case 203 /* PrefixUnaryExpression */:
                    return checkStrictModePrefixUnaryExpression(node);
                case 232 /* WithStatement */:
                    return checkStrictModeWithStatement(node);
                case 234 /* LabeledStatement */:
                    return checkStrictModeLabeledStatement(node);
                case 179 /* ThisType */:
                    seenThisKeyword = true;
                    return;
                case 164 /* TypePredicate */:
                    break; // Binding the children will handle everything
                case 151 /* TypeParameter */:
                    return bindTypeParameter(node);
                case 152 /* Parameter */:
                    return bindParameter(node);
                case 238 /* VariableDeclaration */:
                    return bindVariableDeclarationOrBindingElement(node);
                case 187 /* BindingElement */:
                    node.flowNode = currentFlow;
                    return bindVariableDeclarationOrBindingElement(node);
                case 155 /* PropertyDeclaration */:
                case 154 /* PropertySignature */:
                    return bindPropertyWorker(node);
                case 276 /* PropertyAssignment */:
                case 277 /* ShorthandPropertyAssignment */:
                    return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 0 /* PropertyExcludes */);
                case 279 /* EnumMember */:
                    return bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 68008959 /* EnumMemberExcludes */);
                case 161 /* CallSignature */:
                case 162 /* ConstructSignature */:
                case 163 /* IndexSignature */:
                    return declareSymbolAndAddToSymbolTable(node, 131072 /* Signature */, 0 /* None */);
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                    // If this is an ObjectLiteralExpression method, then it sits in the same space
                    // as other properties in the object literal.  So we use SymbolFlags.PropertyExcludes
                    // so that it will conflict with any other object literal members with the same
                    // name.
                    return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 0 /* PropertyExcludes */ : 67212223 /* MethodExcludes */);
                case 240 /* FunctionDeclaration */:
                    return bindFunctionDeclaration(node);
                case 158 /* Constructor */:
                    return declareSymbolAndAddToSymbolTable(node, 16384 /* Constructor */, /*symbolExcludes:*/ 0 /* None */);
                case 159 /* GetAccessor */:
                    return bindPropertyOrMethodOrAccessor(node, 32768 /* GetAccessor */, 67154879 /* GetAccessorExcludes */);
                case 160 /* SetAccessor */:
                    return bindPropertyOrMethodOrAccessor(node, 65536 /* SetAccessor */, 67187647 /* SetAccessorExcludes */);
                case 166 /* FunctionType */:
                case 295 /* JSDocFunctionType */:
                case 299 /* JSDocSignature */:
                case 167 /* ConstructorType */:
                    return bindFunctionOrConstructorType(node);
                case 169 /* TypeLiteral */:
                case 298 /* JSDocTypeLiteral */:
                case 182 /* MappedType */:
                    return bindAnonymousTypeWorker(node);
                case 189 /* ObjectLiteralExpression */:
                    return bindObjectLiteralExpression(node);
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */:
                    return bindFunctionExpression(node);
                case 192 /* CallExpression */:
                    var assignmentKind = ts.getAssignmentDeclarationKind(node);
                    switch (assignmentKind) {
                        case 7 /* ObjectDefinePropertyValue */:
                            return bindObjectDefinePropertyAssignment(node);
                        case 8 /* ObjectDefinePropertyExports */:
                            return bindObjectDefinePropertyExport(node);
                        case 9 /* ObjectDefinePrototypeProperty */:
                            return bindObjectDefinePrototypeProperty(node);
                        case 0 /* None */:
                            break; // Nothing to do
                        default:
                            return ts.Debug.fail("Unknown call expression assignment declaration kind");
                    }
                    if (ts.isInJSFile(node)) {
                        bindCallExpression(node);
                    }
                    break;
                // Members of classes, interfaces, and modules
                case 210 /* ClassExpression */:
                case 241 /* ClassDeclaration */:
                    // All classes are automatically in strict mode in ES6.
                    inStrictMode = true;
                    return bindClassLikeDeclaration(node);
                case 242 /* InterfaceDeclaration */:
                    return bindBlockScopedDeclaration(node, 64 /* Interface */, 67897736 /* InterfaceExcludes */);
                case 243 /* TypeAliasDeclaration */:
                    return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 67897832 /* TypeAliasExcludes */);
                case 244 /* EnumDeclaration */:
                    return bindEnumDeclaration(node);
                case 245 /* ModuleDeclaration */:
                    return bindModuleDeclaration(node);
                // Jsx-attributes
                case 269 /* JsxAttributes */:
                    return bindJsxAttributes(node);
                case 268 /* JsxAttribute */:
                    return bindJsxAttribute(node, 4 /* Property */, 0 /* PropertyExcludes */);
                // Imports and exports
                case 249 /* ImportEqualsDeclaration */:
                case 252 /* NamespaceImport */:
                case 254 /* ImportSpecifier */:
                case 258 /* ExportSpecifier */:
                    return declareSymbolAndAddToSymbolTable(node, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
                case 248 /* NamespaceExportDeclaration */:
                    return bindNamespaceExportDeclaration(node);
                case 251 /* ImportClause */:
                    return bindImportClause(node);
                case 256 /* ExportDeclaration */:
                    return bindExportDeclaration(node);
                case 255 /* ExportAssignment */:
                    return bindExportAssignment(node);
                case 285 /* SourceFile */:
                    updateStrictModeStatementList(node.statements);
                    return bindSourceFileIfExternalModule();
                case 219 /* Block */:
                    if (!ts.isFunctionLike(node.parent)) {
                        return;
                    }
                // falls through
                case 246 /* ModuleBlock */:
                    return updateStrictModeStatementList(node.statements);
                case 305 /* JSDocParameterTag */:
                    if (node.parent.kind === 299 /* JSDocSignature */) {
                        return bindParameter(node);
                    }
                    if (node.parent.kind !== 298 /* JSDocTypeLiteral */) {
                        break;
                    }
                // falls through
                case 311 /* JSDocPropertyTag */:
                    var propTag = node;
                    var flags = propTag.isBracketed || propTag.typeExpression && propTag.typeExpression.type.kind === 294 /* JSDocOptionalType */ ?
                        4 /* Property */ | 16777216 /* Optional */ :
                        4 /* Property */;
                    return declareSymbolAndAddToSymbolTable(propTag, flags, 0 /* PropertyExcludes */);
                case 310 /* JSDocTypedefTag */:
                case 303 /* JSDocCallbackTag */:
                    return (delayedTypeAliases || (delayedTypeAliases = [])).push(node);
            }
        }
        function bindPropertyWorker(node) {
            return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */);
        }
        function bindAnonymousTypeWorker(node) {
            return bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type" /* Type */);
        }
        function bindSourceFileIfExternalModule() {
            setExportContextFlag(file);
            if (ts.isExternalModule(file)) {
                bindSourceFileAsExternalModule();
            }
            else if (ts.isJsonSourceFile(file)) {
                bindSourceFileAsExternalModule();
                // Create symbol equivalent for the module.exports = {}
                var originalSymbol = file.symbol;
                declareSymbol(file.symbol.exports, file.symbol, file, 4 /* Property */, 67108863 /* All */);
                file.symbol = originalSymbol;
            }
        }
        function bindSourceFileAsExternalModule() {
            bindAnonymousDeclaration(file, 512 /* ValueModule */, "\"" + ts.removeFileExtension(file.fileName) + "\"");
        }
        function bindExportAssignment(node) {
            if (!container.symbol || !container.symbol.exports) {
                // Export assignment in some sort of block construct
                bindAnonymousDeclaration(node, 2097152 /* Alias */, getDeclarationName(node));
            }
            else {
                var flags = ts.exportAssignmentIsAlias(node)
                    // An export default clause with an EntityNameExpression or a class expression exports all meanings of that identifier or expression;
                    ? 2097152 /* Alias */
                    // An export default clause with any other expression exports a value
                    : 4 /* Property */;
                // If there is an `export default x;` alias declaration, can't `export default` anything else.
                // (In contrast, you can still have `export default function f() {}` and `export default interface I {}`.)
                var symbol = declareSymbol(container.symbol.exports, container.symbol, node, flags, 67108863 /* All */);
                if (node.isExportEquals) {
                    // Will be an error later, since the module already has other exports. Just make sure this has a valueDeclaration set.
                    setValueDeclaration(symbol, node);
                }
            }
        }
        function bindNamespaceExportDeclaration(node) {
            if (node.modifiers && node.modifiers.length) {
                file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Modifiers_cannot_appear_here));
            }
            var diag = !ts.isSourceFile(node.parent) ? ts.Diagnostics.Global_module_exports_may_only_appear_at_top_level
                : !ts.isExternalModule(node.parent) ? ts.Diagnostics.Global_module_exports_may_only_appear_in_module_files
                    : !node.parent.isDeclarationFile ? ts.Diagnostics.Global_module_exports_may_only_appear_in_declaration_files
                        : undefined;
            if (diag) {
                file.bindDiagnostics.push(createDiagnosticForNode(node, diag));
            }
            else {
                file.symbol.globalExports = file.symbol.globalExports || ts.createSymbolTable();
                declareSymbol(file.symbol.globalExports, file.symbol, node, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
            }
        }
        function bindExportDeclaration(node) {
            if (!container.symbol || !container.symbol.exports) {
                // Export * in some sort of block construct
                bindAnonymousDeclaration(node, 8388608 /* ExportStar */, getDeclarationName(node));
            }
            else if (!node.exportClause) {
                // All export * declarations are collected in an __export symbol
                declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* ExportStar */, 0 /* None */);
            }
        }
        function bindImportClause(node) {
            if (node.name) {
                declareSymbolAndAddToSymbolTable(node, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
            }
        }
        function setCommonJsModuleIndicator(node) {
            if (file.externalModuleIndicator) {
                return false;
            }
            if (!file.commonJsModuleIndicator) {
                file.commonJsModuleIndicator = node;
                bindSourceFileAsExternalModule();
            }
            return true;
        }
        function bindObjectDefinePropertyExport(node) {
            if (!setCommonJsModuleIndicator(node)) {
                return;
            }
            var symbol = forEachIdentifierInEntityName(node.arguments[0], /*parent*/ undefined, function (id, symbol) {
                if (symbol) {
                    addDeclarationToSymbol(symbol, id, 1536 /* Module */ | 67108864 /* Assignment */);
                }
                return symbol;
            });
            if (symbol) {
                var flags = 4 /* Property */ | 1048576 /* ExportValue */;
                declareSymbol(symbol.exports, symbol, node, flags, 0 /* None */);
            }
        }
        function bindExportsPropertyAssignment(node) {
            // When we create a property via 'exports.foo = bar', the 'exports.foo' property access
            // expression is the declaration
            if (!setCommonJsModuleIndicator(node)) {
                return;
            }
            var lhs = node.left;
            var symbol = forEachIdentifierInEntityName(lhs.expression, /*parent*/ undefined, function (id, symbol) {
                if (symbol) {
                    addDeclarationToSymbol(symbol, id, 1536 /* Module */ | 67108864 /* Assignment */);
                }
                return symbol;
            });
            if (symbol) {
                var flags = ts.isClassExpression(node.right) ?
                    4 /* Property */ | 1048576 /* ExportValue */ | 32 /* Class */ :
                    4 /* Property */ | 1048576 /* ExportValue */;
                declareSymbol(symbol.exports, symbol, lhs, flags, 0 /* None */);
            }
        }
        function bindModuleExportsAssignment(node) {
            // A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports'
            // is still pointing to 'module.exports'.
            // We do not want to consider this as 'export=' since a module can have only one of these.
            // Similarly we do not want to treat 'module.exports = exports' as an 'export='.
            if (!setCommonJsModuleIndicator(node)) {
                return;
            }
            var assignedExpression = ts.getRightMostAssignedExpression(node.right);
            if (ts.isEmptyObjectLiteral(assignedExpression) || container === file && isExportsOrModuleExportsOrAlias(file, assignedExpression)) {
                return;
            }
            // 'module.exports = expr' assignment
            var flags = ts.exportAssignmentIsAlias(node)
                ? 2097152 /* Alias */
                : 4 /* Property */ | 1048576 /* ExportValue */ | 512 /* ValueModule */;
            declareSymbol(file.symbol.exports, file.symbol, node, flags | 67108864 /* Assignment */, 0 /* None */);
        }
        function bindThisPropertyAssignment(node) {
            ts.Debug.assert(ts.isInJSFile(node));
            var thisContainer = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
            switch (thisContainer.kind) {
                case 240 /* FunctionDeclaration */:
                case 197 /* FunctionExpression */:
                    var constructorSymbol = thisContainer.symbol;
                    // For `f.prototype.m = function() { this.x = 0; }`, `this.x = 0` should modify `f`'s members, not the function expression.
                    if (ts.isBinaryExpression(thisContainer.parent) && thisContainer.parent.operatorToken.kind === 60 /* EqualsToken */) {
                        var l = thisContainer.parent.left;
                        if (ts.isPropertyAccessEntityNameExpression(l) && ts.isPrototypeAccess(l.expression)) {
                            constructorSymbol = lookupSymbolForPropertyAccess(l.expression.expression, thisParentContainer);
                        }
                    }
                    if (constructorSymbol) {
                        // Declare a 'member' if the container is an ES5 class or ES6 constructor
                        constructorSymbol.members = constructorSymbol.members || ts.createSymbolTable();
                        // It's acceptable for multiple 'this' assignments of the same identifier to occur
                        declareSymbol(constructorSymbol.members, constructorSymbol, node, 4 /* Property */, 0 /* PropertyExcludes */ & ~4 /* Property */);
                    }
                    break;
                case 158 /* Constructor */:
                case 155 /* PropertyDeclaration */:
                case 157 /* MethodDeclaration */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    // this.foo assignment in a JavaScript class
                    // Bind this property to the containing class
                    var containingClass = thisContainer.parent;
                    var symbolTable = ts.hasModifier(thisContainer, 32 /* Static */) ? containingClass.symbol.exports : containingClass.symbol.members;
                    declareSymbol(symbolTable, containingClass.symbol, node, 4 /* Property */, 0 /* None */, /*isReplaceableByMethod*/ true);
                    break;
                case 285 /* SourceFile */:
                    // this.property = assignment in a source file -- declare symbol in exports for a module, in locals for a script
                    if (thisContainer.commonJsModuleIndicator) {
                        declareSymbol(thisContainer.symbol.exports, thisContainer.symbol, node, 4 /* Property */ | 1048576 /* ExportValue */, 0 /* None */);
                    }
                    else {
                        declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 67220414 /* FunctionScopedVariableExcludes */);
                    }
                    break;
                default:
                    ts.Debug.failBadSyntaxKind(thisContainer);
            }
        }
        function bindSpecialPropertyDeclaration(node) {
            if (node.expression.kind === 101 /* ThisKeyword */) {
                bindThisPropertyAssignment(node);
            }
            else if (ts.isPropertyAccessEntityNameExpression(node) && node.parent.parent.kind === 285 /* SourceFile */) {
                if (ts.isPrototypeAccess(node.expression)) {
                    bindPrototypePropertyAssignment(node, node.parent);
                }
                else {
                    bindStaticPropertyAssignment(node);
                }
            }
        }
        /** For `x.prototype = { p, ... }`, declare members p,... if `x` is function/class/{}, or not declared. */
        function bindPrototypeAssignment(node) {
            node.left.parent = node;
            node.right.parent = node;
            var lhs = node.left;
            bindPropertyAssignment(lhs.expression, lhs, /*isPrototypeProperty*/ false);
        }
        function bindObjectDefinePrototypeProperty(node) {
            var namespaceSymbol = lookupSymbolForPropertyAccess(node.arguments[0].expression);
            bindPotentiallyNewExpandoMemberToNamespace(node, namespaceSymbol, /*isPrototypeProperty*/ true);
        }
        /**
         * For `x.prototype.y = z`, declare a member `y` on `x` if `x` is a function or class, or not declared.
         * Note that jsdoc preceding an ExpressionStatement like `x.prototype.y;` is also treated as a declaration.
         */
        function bindPrototypePropertyAssignment(lhs, parent) {
            // Look up the function in the local scope, since prototype assignments should
            // follow the function declaration
            var classPrototype = lhs.expression;
            var constructorFunction = classPrototype.expression;
            // Fix up parent pointers since we're going to use these nodes before we bind into them
            lhs.parent = parent;
            constructorFunction.parent = classPrototype;
            classPrototype.parent = lhs;
            bindPropertyAssignment(constructorFunction, lhs, /*isPrototypeProperty*/ true);
        }
        function bindObjectDefinePropertyAssignment(node) {
            var namespaceSymbol = lookupSymbolForPropertyAccess(node.arguments[0]);
            var isToplevel = node.parent.parent.kind === 285 /* SourceFile */;
            namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, node.arguments[0], isToplevel, /*isPrototypeProperty*/ false);
            bindPotentiallyNewExpandoMemberToNamespace(node, namespaceSymbol, /*isPrototypeProperty*/ false);
        }
        function bindSpecialPropertyAssignment(node) {
            var lhs = node.left;
            // Class declarations in Typescript do not allow property declarations
            var parentSymbol = lookupSymbolForPropertyAccess(lhs.expression);
            if (!ts.isInJSFile(node) && !ts.isFunctionSymbol(parentSymbol)) {
                return;
            }
            // Fix up parent pointers since we're going to use these nodes before we bind into them
            node.left.parent = node;
            node.right.parent = node;
            if (ts.isIdentifier(lhs.expression) && container === file && isExportsOrModuleExportsOrAlias(file, lhs.expression)) {
                // This can be an alias for the 'exports' or 'module.exports' names, e.g.
                //    var util = module.exports;
                //    util.property = function ...
                bindExportsPropertyAssignment(node);
            }
            else {
                bindStaticPropertyAssignment(lhs);
            }
        }
        /**
         * For nodes like `x.y = z`, declare a member 'y' on 'x' if x is a function (or IIFE) or class or {}, or not declared.
         * Also works for expression statements preceded by JSDoc, like / ** @type number * / x.y;
         */
        function bindStaticPropertyAssignment(node) {
            node.expression.parent = node;
            bindPropertyAssignment(node.expression, node, /*isPrototypeProperty*/ false);
        }
        function bindPotentiallyMissingNamespaces(namespaceSymbol, entityName, isToplevel, isPrototypeProperty) {
            if (isToplevel && !isPrototypeProperty && (!namespaceSymbol || !(namespaceSymbol.flags & 1920 /* Namespace */))) {
                // make symbols or add declarations for intermediate containers
                var flags_1 = 1536 /* Module */ | 67108864 /* Assignment */;
                var excludeFlags_1 = 110735 /* ValueModuleExcludes */ & ~67108864 /* Assignment */;
                namespaceSymbol = forEachIdentifierInEntityName(entityName, namespaceSymbol, function (id, symbol, parent) {
                    if (symbol) {
                        addDeclarationToSymbol(symbol, id, flags_1);
                        return symbol;
                    }
                    else {
                        var table = parent ? parent.exports :
                            file.jsGlobalAugmentations || (file.jsGlobalAugmentations = ts.createSymbolTable());
                        return declareSymbol(table, parent, id, flags_1, excludeFlags_1);
                    }
                });
            }
            return namespaceSymbol;
        }
        function bindPotentiallyNewExpandoMemberToNamespace(declaration, namespaceSymbol, isPrototypeProperty) {
            if (!namespaceSymbol || !isExpandoSymbol(namespaceSymbol)) {
                return;
            }
            // Set up the members collection if it doesn't exist already
            var symbolTable = isPrototypeProperty ?
                (namespaceSymbol.members || (namespaceSymbol.members = ts.createSymbolTable())) :
                (namespaceSymbol.exports || (namespaceSymbol.exports = ts.createSymbolTable()));
            var isMethod = ts.isFunctionLikeDeclaration(ts.getAssignedExpandoInitializer(declaration));
            var includes = isMethod ? 8192 /* Method */ : 4 /* Property */;
            var excludes = isMethod ? 67212223 /* MethodExcludes */ : 0 /* PropertyExcludes */;
            declareSymbol(symbolTable, namespaceSymbol, declaration, includes | 67108864 /* Assignment */, excludes & ~67108864 /* Assignment */);
        }
        function bindPropertyAssignment(name, propertyAccess, isPrototypeProperty) {
            var namespaceSymbol = lookupSymbolForPropertyAccess(name);
            var isToplevel = ts.isBinaryExpression(propertyAccess.parent)
                ? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === 285 /* SourceFile */
                : propertyAccess.parent.parent.kind === 285 /* SourceFile */;
            namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, propertyAccess.expression, isToplevel, isPrototypeProperty);
            bindPotentiallyNewExpandoMemberToNamespace(propertyAccess, namespaceSymbol, isPrototypeProperty);
        }
        /**
         * Javascript expando values are:
         * - Functions
         * - classes
         * - namespaces
         * - variables initialized with function expressions
         * -                       with class expressions
         * -                       with empty object literals
         * -                       with non-empty object literals if assigned to the prototype property
         */
        function isExpandoSymbol(symbol) {
            if (symbol.flags & (16 /* Function */ | 32 /* Class */ | 1024 /* NamespaceModule */)) {
                return true;
            }
            var node = symbol.valueDeclaration;
            if (node && ts.isCallExpression(node)) {
                return !!ts.getAssignedExpandoInitializer(node);
            }
            var init = !node ? undefined :
                ts.isVariableDeclaration(node) ? node.initializer :
                    ts.isBinaryExpression(node) ? node.right :
                        ts.isPropertyAccessExpression(node) && ts.isBinaryExpression(node.parent) ? node.parent.right :
                            undefined;
            init = init && ts.getRightMostAssignedExpression(init);
            if (init) {
                var isPrototypeAssignment = ts.isPrototypeAccess(ts.isVariableDeclaration(node) ? node.name : ts.isBinaryExpression(node) ? node.left : node);
                return !!ts.getExpandoInitializer(ts.isBinaryExpression(init) && init.operatorToken.kind === 55 /* BarBarToken */ ? init.right : init, isPrototypeAssignment);
            }
            return false;
        }
        function getParentOfBinaryExpression(expr) {
            while (ts.isBinaryExpression(expr.parent)) {
                expr = expr.parent;
            }
            return expr.parent;
        }
        function lookupSymbolForPropertyAccess(node, lookupContainer) {
            if (lookupContainer === void 0) { lookupContainer = container; }
            if (ts.isIdentifier(node)) {
                return lookupSymbolForNameWorker(lookupContainer, node.escapedText);
            }
            else {
                var symbol = lookupSymbolForPropertyAccess(node.expression);
                return symbol && symbol.exports && symbol.exports.get(node.name.escapedText);
            }
        }
        function forEachIdentifierInEntityName(e, parent, action) {
            if (isExportsOrModuleExportsOrAlias(file, e)) {
                return file.symbol;
            }
            else if (ts.isIdentifier(e)) {
                return action(e, lookupSymbolForPropertyAccess(e), parent);
            }
            else {
                var s = forEachIdentifierInEntityName(e.expression, parent, action);
                return action(e.name, s && s.exports && s.exports.get(e.name.escapedText), s);
            }
        }
        function bindCallExpression(node) {
            // We're only inspecting call expressions to detect CommonJS modules, so we can skip
            // this check if we've already seen the module indicator
            if (!file.commonJsModuleIndicator && ts.isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ false)) {
                setCommonJsModuleIndicator(node);
            }
        }
        function bindClassLikeDeclaration(node) {
            if (node.kind === 241 /* ClassDeclaration */) {
                bindBlockScopedDeclaration(node, 32 /* Class */, 68008383 /* ClassExcludes */);
            }
            else {
                var bindingName = node.name ? node.name.escapedText : "__class" /* Class */;
                bindAnonymousDeclaration(node, 32 /* Class */, bindingName);
                // Add name of class expression into the map for semantic classifier
                if (node.name) {
                    classifiableNames.set(node.name.escapedText, true);
                }
            }
            var symbol = node.symbol;
            // TypeScript 1.0 spec (April 2014): 8.4
            // Every class automatically contains a static property member named 'prototype', the
            // type of which is an instantiation of the class type with type Any supplied as a type
            // argument for each type parameter. It is an error to explicitly declare a static
            // property member with the name 'prototype'.
            //
            // Note: we check for this here because this class may be merging into a module.  The
            // module might have an exported variable called 'prototype'.  We can't allow that as
            // that would clash with the built-in 'prototype' for the class.
            var prototypeSymbol = createSymbol(4 /* Property */ | 4194304 /* Prototype */, "prototype");
            var symbolExport = symbol.exports.get(prototypeSymbol.escapedName);
            if (symbolExport) {
                if (node.name) {
                    node.name.parent = node;
                }
                file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], ts.Diagnostics.Duplicate_identifier_0, ts.symbolName(prototypeSymbol)));
            }
            symbol.exports.set(prototypeSymbol.escapedName, prototypeSymbol);
            prototypeSymbol.parent = symbol;
        }
        function bindEnumDeclaration(node) {
            return ts.isEnumConst(node)
                ? bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 68008831 /* ConstEnumExcludes */)
                : bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 68008191 /* RegularEnumExcludes */);
        }
        function bindVariableDeclarationOrBindingElement(node) {
            if (inStrictMode) {
                checkStrictModeEvalOrArguments(node, node.name);
            }
            if (!ts.isBindingPattern(node.name)) {
                var isEnum = ts.isInJSFile(node) && !!ts.getJSDocEnumTag(node);
                var enumFlags = (isEnum ? 256 /* RegularEnum */ : 0 /* None */);
                var enumExcludes = (isEnum ? 68008191 /* RegularEnumExcludes */ : 0 /* None */);
                if (ts.isBlockOrCatchScoped(node)) {
                    bindBlockScopedDeclaration(node, 2 /* BlockScopedVariable */ | enumFlags, 67220415 /* BlockScopedVariableExcludes */ | enumExcludes);
                }
                else if (ts.isParameterDeclaration(node)) {
                    // It is safe to walk up parent chain to find whether the node is a destructuring parameter declaration
                    // because its parent chain has already been set up, since parents are set before descending into children.
                    //
                    // If node is a binding element in parameter declaration, we need to use ParameterExcludes.
                    // Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration
                    // For example:
                    //      function foo([a,a]) {} // Duplicate Identifier error
                    //      function bar(a,a) {}   // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter
                    //                             // which correctly set excluded symbols
                    declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 67220415 /* ParameterExcludes */);
                }
                else {
                    declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */ | enumFlags, 67220414 /* FunctionScopedVariableExcludes */ | enumExcludes);
                }
            }
        }
        function bindParameter(node) {
            if (node.kind === 305 /* JSDocParameterTag */ && container.kind !== 299 /* JSDocSignature */) {
                return;
            }
            if (inStrictMode && !(node.flags & 4194304 /* Ambient */)) {
                // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
                // strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
                checkStrictModeEvalOrArguments(node, node.name);
            }
            if (ts.isBindingPattern(node.name)) {
                bindAnonymousDeclaration(node, 1 /* FunctionScopedVariable */, "__" + node.parent.parameters.indexOf(node));
            }
            else {
                declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 67220415 /* ParameterExcludes */);
            }
            // If this is a property-parameter, then also declare the property symbol into the
            // containing class.
            if (ts.isParameterPropertyDeclaration(node)) {
                var classDeclaration = node.parent.parent;
                declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */);
            }
        }
        function bindFunctionDeclaration(node) {
            if (!file.isDeclarationFile && !(node.flags & 4194304 /* Ambient */)) {
                if (ts.isAsyncFunction(node)) {
                    emitFlags |= 1024 /* HasAsyncFunctions */;
                }
            }
            checkStrictModeFunctionName(node);
            if (inStrictMode) {
                checkStrictModeFunctionDeclaration(node);
                bindBlockScopedDeclaration(node, 16 /* Function */, 67219887 /* FunctionExcludes */);
            }
            else {
                declareSymbolAndAddToSymbolTable(node, 16 /* Function */, 67219887 /* FunctionExcludes */);
            }
        }
        function bindFunctionExpression(node) {
            if (!file.isDeclarationFile && !(node.flags & 4194304 /* Ambient */)) {
                if (ts.isAsyncFunction(node)) {
                    emitFlags |= 1024 /* HasAsyncFunctions */;
                }
            }
            if (currentFlow) {
                node.flowNode = currentFlow;
            }
            checkStrictModeFunctionName(node);
            var bindingName = node.name ? node.name.escapedText : "__function" /* Function */;
            return bindAnonymousDeclaration(node, 16 /* Function */, bindingName);
        }
        function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) {
            if (!file.isDeclarationFile && !(node.flags & 4194304 /* Ambient */) && ts.isAsyncFunction(node)) {
                emitFlags |= 1024 /* HasAsyncFunctions */;
            }
            if (currentFlow && ts.isObjectLiteralOrClassExpressionMethod(node)) {
                node.flowNode = currentFlow;
            }
            return ts.hasDynamicName(node)
                ? bindAnonymousDeclaration(node, symbolFlags, "__computed" /* Computed */)
                : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
        }
        function getInferTypeContainer(node) {
            var extendsType = ts.findAncestor(node, function (n) { return n.parent && ts.isConditionalTypeNode(n.parent) && n.parent.extendsType === n; });
            return extendsType && extendsType.parent;
        }
        function bindTypeParameter(node) {
            if (ts.isJSDocTemplateTag(node.parent)) {
                var container_1 = ts.find(node.parent.parent.tags, ts.isJSDocTypeAlias) || ts.getHostSignatureFromJSDoc(node.parent); // TODO: GH#18217
                if (container_1) {
                    if (!container_1.locals) {
                        container_1.locals = ts.createSymbolTable();
                    }
                    declareSymbol(container_1.locals, /*parent*/ undefined, node, 262144 /* TypeParameter */, 67635688 /* TypeParameterExcludes */);
                }
                else {
                    declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 67635688 /* TypeParameterExcludes */);
                }
            }
            else if (node.parent.kind === 177 /* InferType */) {
                var container_2 = getInferTypeContainer(node.parent);
                if (container_2) {
                    if (!container_2.locals) {
                        container_2.locals = ts.createSymbolTable();
                    }
                    declareSymbol(container_2.locals, /*parent*/ undefined, node, 262144 /* TypeParameter */, 67635688 /* TypeParameterExcludes */);
                }
                else {
                    bindAnonymousDeclaration(node, 262144 /* TypeParameter */, getDeclarationName(node)); // TODO: GH#18217
                }
            }
            else {
                declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 67635688 /* TypeParameterExcludes */);
            }
        }
        // reachability checks
        function shouldReportErrorOnModuleDeclaration(node) {
            var instanceState = getModuleInstanceState(node);
            return instanceState === 1 /* Instantiated */ || (instanceState === 2 /* ConstEnumOnly */ && !!options.preserveConstEnums);
        }
        function checkUnreachable(node) {
            if (!(currentFlow.flags & 1 /* Unreachable */)) {
                return false;
            }
            if (currentFlow === unreachableFlow) {
                var reportError = 
                // report error on all statements except empty ones
                (ts.isStatementButNotDeclaration(node) && node.kind !== 221 /* EmptyStatement */) ||
                    // report error on class declarations
                    node.kind === 241 /* ClassDeclaration */ ||
                    // report error on instantiated modules or const-enums only modules if preserveConstEnums is set
                    (node.kind === 245 /* ModuleDeclaration */ && shouldReportErrorOnModuleDeclaration(node));
                if (reportError) {
                    currentFlow = reportedUnreachableFlow;
                    if (!options.allowUnreachableCode) {
                        // unreachable code is reported if
                        // - user has explicitly asked about it AND
                        // - statement is in not ambient context (statements in ambient context is already an error
                        //   so we should not report extras) AND
                        //   - node is not variable statement OR
                        //   - node is block scoped variable statement OR
                        //   - node is not block scoped variable statement and at least one variable declaration has initializer
                        //   Rationale: we don't want to report errors on non-initialized var's since they are hoisted
                        //   On the other side we do want to report errors on non-initialized 'lets' because of TDZ
                        var isError_1 = ts.unreachableCodeIsError(options) &&
                            !(node.flags & 4194304 /* Ambient */) &&
                            (!ts.isVariableStatement(node) ||
                                !!(ts.getCombinedNodeFlags(node.declarationList) & 3 /* BlockScoped */) ||
                                node.declarationList.declarations.some(function (d) { return !!d.initializer; }));
                        eachUnreachableRange(node, function (start, end) { return errorOrSuggestionOnRange(isError_1, start, end, ts.Diagnostics.Unreachable_code_detected); });
                    }
                }
            }
            return true;
        }
    }
    function eachUnreachableRange(node, cb) {
        if (ts.isStatement(node) && isExecutableStatement(node) && ts.isBlock(node.parent)) {
            var statements = node.parent.statements;
            var slice_1 = ts.sliceAfter(statements, node);
            ts.getRangesWhere(slice_1, isExecutableStatement, function (start, afterEnd) { return cb(slice_1[start], slice_1[afterEnd - 1]); });
        }
        else {
            cb(node, node);
        }
    }
    // As opposed to a pure declaration like an `interface`
    function isExecutableStatement(s) {
        // Don't remove statements that can validly be used before they appear.
        return !ts.isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) && !ts.isEnumDeclaration(s) &&
            // `var x;` may declare a variable used above
            !(ts.isVariableStatement(s) && !(ts.getCombinedNodeFlags(s) & (1 /* Let */ | 2 /* Const */)) && s.declarationList.declarations.some(function (d) { return !d.initializer; }));
    }
    function isPurelyTypeDeclaration(s) {
        switch (s.kind) {
            case 242 /* InterfaceDeclaration */:
            case 243 /* TypeAliasDeclaration */:
                return true;
            case 245 /* ModuleDeclaration */:
                return getModuleInstanceState(s) !== 1 /* Instantiated */;
            case 244 /* EnumDeclaration */:
                return ts.hasModifier(s, 2048 /* Const */);
            default:
                return false;
        }
    }
    function isExportsOrModuleExportsOrAlias(sourceFile, node) {
        var i = 0;
        var q = [node];
        while (q.length && i < 100) {
            i++;
            node = q.shift();
            if (ts.isExportsIdentifier(node) || ts.isModuleExportsPropertyAccessExpression(node)) {
                return true;
            }
            else if (ts.isIdentifier(node)) {
                var symbol = lookupSymbolForNameWorker(sourceFile, node.escapedText);
                if (!!symbol && !!symbol.valueDeclaration && ts.isVariableDeclaration(symbol.valueDeclaration) && !!symbol.valueDeclaration.initializer) {
                    var init = symbol.valueDeclaration.initializer;
                    q.push(init);
                    if (ts.isAssignmentExpression(init, /*excludeCompoundAssignment*/ true)) {
                        q.push(init.left);
                        q.push(init.right);
                    }
                }
            }
        }
        return false;
    }
    ts.isExportsOrModuleExportsOrAlias = isExportsOrModuleExportsOrAlias;
    function lookupSymbolForNameWorker(container, name) {
        var local = container.locals && container.locals.get(name);
        if (local) {
            return local.exportSymbol || local;
        }
        if (ts.isSourceFile(container) && container.jsGlobalAugmentations && container.jsGlobalAugmentations.has(name)) {
            return container.jsGlobalAugmentations.get(name);
        }
        return container.symbol && container.symbol.exports && container.symbol.exports.get(name);
    }
    /**
     * Computes the transform flags for a node, given the transform flags of its subtree
     *
     * @param node The node to analyze
     * @param subtreeFlags Transform flags computed for this node's subtree
     */
    function computeTransformFlagsForNode(node, subtreeFlags) {
        var kind = node.kind;
        switch (kind) {
            case 192 /* CallExpression */:
                return computeCallExpression(node, subtreeFlags);
            case 193 /* NewExpression */:
                return computeNewExpression(node, subtreeFlags);
            case 245 /* ModuleDeclaration */:
                return computeModuleDeclaration(node, subtreeFlags);
            case 196 /* ParenthesizedExpression */:
                return computeParenthesizedExpression(node, subtreeFlags);
            case 205 /* BinaryExpression */:
                return computeBinaryExpression(node, subtreeFlags);
            case 222 /* ExpressionStatement */:
                return computeExpressionStatement(node, subtreeFlags);
            case 152 /* Parameter */:
                return computeParameter(node, subtreeFlags);
            case 198 /* ArrowFunction */:
                return computeArrowFunction(node, subtreeFlags);
            case 197 /* FunctionExpression */:
                return computeFunctionExpression(node, subtreeFlags);
            case 240 /* FunctionDeclaration */:
                return computeFunctionDeclaration(node, subtreeFlags);
            case 238 /* VariableDeclaration */:
                return computeVariableDeclaration(node, subtreeFlags);
            case 239 /* VariableDeclarationList */:
                return computeVariableDeclarationList(node, subtreeFlags);
            case 220 /* VariableStatement */:
                return computeVariableStatement(node, subtreeFlags);
            case 234 /* LabeledStatement */:
                return computeLabeledStatement(node, subtreeFlags);
            case 241 /* ClassDeclaration */:
                return computeClassDeclaration(node, subtreeFlags);
            case 210 /* ClassExpression */:
                return computeClassExpression(node, subtreeFlags);
            case 274 /* HeritageClause */:
                return computeHeritageClause(node, subtreeFlags);
            case 275 /* CatchClause */:
                return computeCatchClause(node, subtreeFlags);
            case 212 /* ExpressionWithTypeArguments */:
                return computeExpressionWithTypeArguments(node, subtreeFlags);
            case 158 /* Constructor */:
                return computeConstructor(node, subtreeFlags);
            case 155 /* PropertyDeclaration */:
                return computePropertyDeclaration(node, subtreeFlags);
            case 157 /* MethodDeclaration */:
                return computeMethod(node, subtreeFlags);
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
                return computeAccessor(node, subtreeFlags);
            case 249 /* ImportEqualsDeclaration */:
                return computeImportEquals(node, subtreeFlags);
            case 190 /* PropertyAccessExpression */:
                return computePropertyAccess(node, subtreeFlags);
            case 191 /* ElementAccessExpression */:
                return computeElementAccess(node, subtreeFlags);
            default:
                return computeOther(node, kind, subtreeFlags);
        }
    }
    ts.computeTransformFlagsForNode = computeTransformFlagsForNode;
    function computeCallExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var callee = ts.skipOuterExpressions(node.expression);
        var expression = node.expression;
        if (node.typeArguments) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        if (subtreeFlags & 4096 /* ContainsRestOrSpread */ || ts.isSuperOrSuperProperty(callee)) {
            // If the this node contains a SpreadExpression, or is a super call, then it is an ES6
            // node.
            transformFlags |= 128 /* AssertES2015 */;
            if (ts.isSuperProperty(callee)) {
                transformFlags |= 2048 /* ContainsLexicalThis */;
            }
        }
        if (expression.kind === 93 /* ImportKeyword */) {
            transformFlags |= 524288 /* ContainsDynamicImport */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536875008 /* ArrayLiteralOrCallOrNewExcludes */;
    }
    function computeNewExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        if (node.typeArguments) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        if (subtreeFlags & 4096 /* ContainsRestOrSpread */) {
            // If the this node contains a SpreadElementExpression then it is an ES6
            // node.
            transformFlags |= 128 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536875008 /* ArrayLiteralOrCallOrNewExcludes */;
    }
    function computeBinaryExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var operatorTokenKind = node.operatorToken.kind;
        var leftKind = node.left.kind;
        if (operatorTokenKind === 60 /* EqualsToken */ && leftKind === 189 /* ObjectLiteralExpression */) {
            // Destructuring object assignments with are ES2015 syntax
            // and possibly ES2018 if they contain rest
            transformFlags |= 16 /* AssertES2018 */ | 128 /* AssertES2015 */ | 512 /* AssertDestructuringAssignment */;
        }
        else if (operatorTokenKind === 60 /* EqualsToken */ && leftKind === 188 /* ArrayLiteralExpression */) {
            // Destructuring assignments are ES2015 syntax.
            transformFlags |= 128 /* AssertES2015 */ | 512 /* AssertDestructuringAssignment */;
        }
        else if (operatorTokenKind === 41 /* AsteriskAsteriskToken */
            || operatorTokenKind === 64 /* AsteriskAsteriskEqualsToken */) {
            // Exponentiation is ES2016 syntax.
            transformFlags |= 64 /* AssertES2016 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeParameter(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var name = node.name;
        var initializer = node.initializer;
        var dotDotDotToken = node.dotDotDotToken;
        // The '?' token, type annotations, decorators, and 'this' parameters are TypeSCript
        // syntax.
        if (node.questionToken
            || node.type
            || (subtreeFlags & 1024 /* ContainsTypeScriptClassSyntax */ && ts.some(node.decorators))
            || ts.isThisIdentifier(name)) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // If a parameter has an accessibility modifier, then it is TypeScript syntax.
        if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) {
            transformFlags |= 1 /* AssertTypeScript */ | 1024 /* ContainsTypeScriptClassSyntax */;
        }
        // parameters with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 8192 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 16 /* AssertES2018 */;
        }
        // If a parameter has an initializer, a binding pattern or a dotDotDot token, then
        // it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel.
        if (subtreeFlags & 65536 /* ContainsBindingPattern */ || initializer || dotDotDotToken) {
            transformFlags |= 128 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* ParameterExcludes */;
    }
    function computeParenthesizedExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var expression = node.expression;
        var expressionKind = expression.kind;
        // If the node is synthesized, it means the emitter put the parentheses there,
        // not the user. If we didn't want them, the emitter would not have put them
        // there.
        if (expressionKind === 213 /* AsExpression */
            || expressionKind === 195 /* TypeAssertionExpression */) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* OuterExpressionExcludes */;
    }
    function computeClassDeclaration(node, subtreeFlags) {
        var transformFlags;
        if (ts.hasModifier(node, 2 /* Ambient */)) {
            // An ambient declaration is TypeScript syntax.
            transformFlags = 1 /* AssertTypeScript */;
        }
        else {
            // A ClassDeclaration is ES6 syntax.
            transformFlags = subtreeFlags | 128 /* AssertES2015 */;
            // A class with a parameter property assignment, property initializer, computed property name, or decorator is
            // TypeScript syntax.
            // An exported declaration may be TypeScript syntax, but is handled by the visitor
            // for a namespace declaration.
            if ((subtreeFlags & 1024 /* ContainsTypeScriptClassSyntax */)
                || node.typeParameters) {
                transformFlags |= 1 /* AssertTypeScript */;
            }
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536888320 /* ClassExcludes */;
    }
    function computeClassExpression(node, subtreeFlags) {
        // A ClassExpression is ES6 syntax.
        var transformFlags = subtreeFlags | 128 /* AssertES2015 */;
        // A class with a parameter property assignment, property initializer, or decorator is
        // TypeScript syntax.
        if (subtreeFlags & 1024 /* ContainsTypeScriptClassSyntax */
            || node.typeParameters) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536888320 /* ClassExcludes */;
    }
    function computeHeritageClause(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        switch (node.token) {
            case 87 /* ExtendsKeyword */:
                // An `extends` HeritageClause is ES6 syntax.
                transformFlags |= 128 /* AssertES2015 */;
                break;
            case 110 /* ImplementsKeyword */:
                // An `implements` HeritageClause is TypeScript syntax.
                transformFlags |= 1 /* AssertTypeScript */;
                break;
            default:
                ts.Debug.fail("Unexpected token for heritage clause");
                break;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeCatchClause(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        if (!node.variableDeclaration) {
            transformFlags |= 8 /* AssertES2019 */;
        }
        else if (ts.isBindingPattern(node.variableDeclaration.name)) {
            transformFlags |= 128 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536879104 /* CatchClauseExcludes */;
    }
    function computeExpressionWithTypeArguments(node, subtreeFlags) {
        // An ExpressionWithTypeArguments is ES6 syntax, as it is used in the
        // extends clause of a class.
        var transformFlags = subtreeFlags | 128 /* AssertES2015 */;
        // If an ExpressionWithTypeArguments contains type arguments, then it
        // is TypeScript syntax.
        if (node.typeArguments) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeConstructor(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // TypeScript-specific modifiers and overloads are TypeScript syntax
        if (ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || !node.body) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // function declarations with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 8192 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 16 /* AssertES2018 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~537372672 /* ConstructorExcludes */;
    }
    function computeMethod(node, subtreeFlags) {
        // A MethodDeclaration is ES6 syntax.
        var transformFlags = subtreeFlags | 128 /* AssertES2015 */;
        // Decorators, TypeScript-specific modifiers, type parameters, type annotations, and
        // overloads are TypeScript syntax.
        if (node.decorators
            || ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.typeParameters
            || node.type
            || (node.name && ts.isComputedPropertyName(node.name)) // While computed method names aren't typescript, the TS transform must visit them to emit property declarations correctly
            || !node.body) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // function declarations with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 8192 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 16 /* AssertES2018 */;
        }
        // An async method declaration is ES2017 syntax.
        if (ts.hasModifier(node, 256 /* Async */)) {
            transformFlags |= node.asteriskToken ? 16 /* AssertES2018 */ : 32 /* AssertES2017 */;
        }
        if (node.asteriskToken) {
            transformFlags |= 256 /* AssertGenerator */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return propagatePropertyNameFlags(node.name, transformFlags & ~537372672 /* MethodOrAccessorExcludes */);
    }
    function computeAccessor(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // Decorators, TypeScript-specific modifiers, type annotations, and overloads are
        // TypeScript syntax.
        if (node.decorators
            || ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.type
            || (node.name && ts.isComputedPropertyName(node.name)) // While computed accessor names aren't typescript, the TS transform must visit them to emit property declarations correctly
            || !node.body) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // function declarations with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 8192 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 16 /* AssertES2018 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return propagatePropertyNameFlags(node.name, transformFlags & ~537372672 /* MethodOrAccessorExcludes */);
    }
    function computePropertyDeclaration(node, subtreeFlags) {
        // A PropertyDeclaration is TypeScript syntax.
        var transformFlags = subtreeFlags | 1 /* AssertTypeScript */;
        // If the PropertyDeclaration has an initializer or a computed name, we need to inform its ancestor
        // so that it handle the transformation.
        if (node.initializer || ts.isComputedPropertyName(node.name)) {
            transformFlags |= 1024 /* ContainsTypeScriptClassSyntax */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return propagatePropertyNameFlags(node.name, transformFlags & ~536872960 /* PropertyExcludes */);
    }
    function computeFunctionDeclaration(node, subtreeFlags) {
        var transformFlags;
        var modifierFlags = ts.getModifierFlags(node);
        var body = node.body;
        if (!body || (modifierFlags & 2 /* Ambient */)) {
            // An ambient declaration is TypeScript syntax.
            // A FunctionDeclaration without a body is an overload and is TypeScript syntax.
            transformFlags = 1 /* AssertTypeScript */;
        }
        else {
            transformFlags = subtreeFlags | 262144 /* ContainsHoistedDeclarationOrCompletion */;
            // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
            // syntax.
            if (modifierFlags & 2270 /* TypeScriptModifier */
                || node.typeParameters
                || node.type) {
                transformFlags |= 1 /* AssertTypeScript */;
            }
            // An async function declaration is ES2017 syntax.
            if (modifierFlags & 256 /* Async */) {
                transformFlags |= node.asteriskToken ? 16 /* AssertES2018 */ : 32 /* AssertES2017 */;
            }
            // function declarations with object rest destructuring are ES2018 syntax
            if (subtreeFlags & 8192 /* ContainsObjectRestOrSpread */) {
                transformFlags |= 16 /* AssertES2018 */;
            }
            // If a FunctionDeclaration is generator function and is the body of a
            // transformed async function, then this node can be transformed to a
            // down-level generator.
            // Currently we do not support transforming any other generator functions
            // down level.
            if (node.asteriskToken) {
                transformFlags |= 256 /* AssertGenerator */;
            }
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~537373696 /* FunctionExcludes */;
    }
    function computeFunctionExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
        // syntax.
        if (ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.typeParameters
            || node.type) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // An async function expression is ES2017 syntax.
        if (ts.hasModifier(node, 256 /* Async */)) {
            transformFlags |= node.asteriskToken ? 16 /* AssertES2018 */ : 32 /* AssertES2017 */;
        }
        // function expressions with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 8192 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 16 /* AssertES2018 */;
        }
        // If a FunctionExpression is generator function and is the body of a
        // transformed async function, then this node can be transformed to a
        // down-level generator.
        if (node.asteriskToken) {
            transformFlags |= 256 /* AssertGenerator */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~537373696 /* FunctionExcludes */;
    }
    function computeArrowFunction(node, subtreeFlags) {
        // An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction.
        var transformFlags = subtreeFlags | 128 /* AssertES2015 */;
        // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
        // syntax.
        if (ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.typeParameters
            || node.type) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // An async arrow function is ES2017 syntax.
        if (ts.hasModifier(node, 256 /* Async */)) {
            transformFlags |= 32 /* AssertES2017 */;
        }
        // arrow functions with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 8192 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 16 /* AssertES2018 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~537371648 /* ArrowFunctionExcludes */;
    }
    function computePropertyAccess(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // If a PropertyAccessExpression starts with a super keyword, then it is
        // ES6 syntax, and requires a lexical `this` binding.
        if (node.expression.kind === 99 /* SuperKeyword */) {
            // super inside of an async function requires hoisting the super access (ES2017).
            // same for super inside of an async generator, which is ES2018.
            transformFlags |= 32 /* ContainsES2017 */ | 16 /* ContainsES2018 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* PropertyAccessExcludes */;
    }
    function computeElementAccess(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // If an ElementAccessExpression starts with a super keyword, then it is
        // ES6 syntax, and requires a lexical `this` binding.
        if (node.expression.kind === 99 /* SuperKeyword */) {
            // super inside of an async function requires hoisting the super access (ES2017).
            // same for super inside of an async generator, which is ES2018.
            transformFlags |= 32 /* ContainsES2017 */ | 16 /* ContainsES2018 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* PropertyAccessExcludes */;
    }
    function computeVariableDeclaration(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        transformFlags |= 128 /* AssertES2015 */ | 65536 /* ContainsBindingPattern */; // TODO(rbuckton): Why are these set unconditionally?
        // A VariableDeclaration containing ObjectRest is ES2018 syntax
        if (subtreeFlags & 8192 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 16 /* AssertES2018 */;
        }
        // Type annotations are TypeScript syntax.
        if (node.type) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeVariableStatement(node, subtreeFlags) {
        var transformFlags;
        var declarationListTransformFlags = node.declarationList.transformFlags;
        // An ambient declaration is TypeScript syntax.
        if (ts.hasModifier(node, 2 /* Ambient */)) {
            transformFlags = 1 /* AssertTypeScript */;
        }
        else {
            transformFlags = subtreeFlags;
            if (declarationListTransformFlags & 65536 /* ContainsBindingPattern */) {
                transformFlags |= 128 /* AssertES2015 */;
            }
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeLabeledStatement(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // A labeled statement containing a block scoped binding *may* need to be transformed from ES6.
        if (subtreeFlags & 32768 /* ContainsBlockScopedBinding */
            && ts.isIterationStatement(node, /*lookInLabeledStatements*/ true)) {
            transformFlags |= 128 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeImportEquals(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // An ImportEqualsDeclaration with a namespace reference is TypeScript.
        if (!ts.isExternalModuleImportEqualsDeclaration(node)) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeExpressionStatement(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeModuleDeclaration(node, subtreeFlags) {
        var transformFlags = 1 /* AssertTypeScript */;
        var modifierFlags = ts.getModifierFlags(node);
        if ((modifierFlags & 2 /* Ambient */) === 0) {
            transformFlags |= subtreeFlags;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~537168896 /* ModuleExcludes */;
    }
    function computeVariableDeclarationList(node, subtreeFlags) {
        var transformFlags = subtreeFlags | 262144 /* ContainsHoistedDeclarationOrCompletion */;
        if (subtreeFlags & 65536 /* ContainsBindingPattern */) {
            transformFlags |= 128 /* AssertES2015 */;
        }
        // If a VariableDeclarationList is `let` or `const`, then it is ES6 syntax.
        if (node.flags & 3 /* BlockScoped */) {
            transformFlags |= 128 /* AssertES2015 */ | 32768 /* ContainsBlockScopedBinding */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536944640 /* VariableDeclarationListExcludes */;
    }
    function computeOther(node, kind, subtreeFlags) {
        // Mark transformations needed for each node
        var transformFlags = subtreeFlags;
        var excludeFlags = 536870912 /* NodeExcludes */;
        switch (kind) {
            case 122 /* AsyncKeyword */:
            case 202 /* AwaitExpression */:
                // async/await is ES2017 syntax, but may be ES2018 syntax (for async generators)
                transformFlags |= 16 /* AssertES2018 */ | 32 /* AssertES2017 */;
                break;
            case 195 /* TypeAssertionExpression */:
            case 213 /* AsExpression */:
            case 314 /* PartiallyEmittedExpression */:
                // These nodes are TypeScript syntax.
                transformFlags |= 1 /* AssertTypeScript */;
                excludeFlags = 536870912 /* OuterExpressionExcludes */;
                break;
            case 116 /* PublicKeyword */:
            case 114 /* PrivateKeyword */:
            case 115 /* ProtectedKeyword */:
            case 119 /* AbstractKeyword */:
            case 126 /* DeclareKeyword */:
            case 78 /* ConstKeyword */:
            case 244 /* EnumDeclaration */:
            case 279 /* EnumMember */:
            case 214 /* NonNullExpression */:
            case 134 /* ReadonlyKeyword */:
                // These nodes are TypeScript syntax.
                transformFlags |= 1 /* AssertTypeScript */;
                break;
            case 261 /* JsxElement */:
            case 262 /* JsxSelfClosingElement */:
            case 263 /* JsxOpeningElement */:
            case 11 /* JsxText */:
            case 264 /* JsxClosingElement */:
            case 265 /* JsxFragment */:
            case 266 /* JsxOpeningFragment */:
            case 267 /* JsxClosingFragment */:
            case 268 /* JsxAttribute */:
            case 269 /* JsxAttributes */:
            case 270 /* JsxSpreadAttribute */:
            case 271 /* JsxExpression */:
                // These nodes are Jsx syntax.
                transformFlags |= 2 /* AssertJsx */;
                break;
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 15 /* TemplateHead */:
            case 16 /* TemplateMiddle */:
            case 17 /* TemplateTail */:
            case 207 /* TemplateExpression */:
            case 194 /* TaggedTemplateExpression */:
            case 277 /* ShorthandPropertyAssignment */:
            case 117 /* StaticKeyword */:
            case 215 /* MetaProperty */:
                // These nodes are ES6 syntax.
                transformFlags |= 128 /* AssertES2015 */;
                break;
            case 10 /* StringLiteral */:
                if (node.hasExtendedUnicodeEscape) {
                    transformFlags |= 128 /* AssertES2015 */;
                }
                break;
            case 8 /* NumericLiteral */:
                if (node.numericLiteralFlags & 384 /* BinaryOrOctalSpecifier */) {
                    transformFlags |= 128 /* AssertES2015 */;
                }
                break;
            case 9 /* BigIntLiteral */:
                transformFlags |= 4 /* AssertESNext */;
                break;
            case 228 /* ForOfStatement */:
                // This node is either ES2015 syntax or ES2017 syntax (if it is a for-await-of).
                if (node.awaitModifier) {
                    transformFlags |= 16 /* AssertES2018 */;
                }
                transformFlags |= 128 /* AssertES2015 */;
                break;
            case 208 /* YieldExpression */:
                // This node is either ES2015 syntax (in a generator) or ES2017 syntax (in an async
                // generator).
                transformFlags |= 16 /* AssertES2018 */ | 128 /* AssertES2015 */ | 131072 /* ContainsYield */;
                break;
            case 121 /* AnyKeyword */:
            case 136 /* NumberKeyword */:
            case 147 /* BigIntKeyword */:
            case 133 /* NeverKeyword */:
            case 137 /* ObjectKeyword */:
            case 139 /* StringKeyword */:
            case 124 /* BooleanKeyword */:
            case 140 /* SymbolKeyword */:
            case 107 /* VoidKeyword */:
            case 151 /* TypeParameter */:
            case 154 /* PropertySignature */:
            case 156 /* MethodSignature */:
            case 161 /* CallSignature */:
            case 162 /* ConstructSignature */:
            case 163 /* IndexSignature */:
            case 164 /* TypePredicate */:
            case 165 /* TypeReference */:
            case 166 /* FunctionType */:
            case 167 /* ConstructorType */:
            case 168 /* TypeQuery */:
            case 169 /* TypeLiteral */:
            case 170 /* ArrayType */:
            case 171 /* TupleType */:
            case 172 /* OptionalType */:
            case 173 /* RestType */:
            case 174 /* UnionType */:
            case 175 /* IntersectionType */:
            case 176 /* ConditionalType */:
            case 177 /* InferType */:
            case 178 /* ParenthesizedType */:
            case 242 /* InterfaceDeclaration */:
            case 243 /* TypeAliasDeclaration */:
            case 179 /* ThisType */:
            case 180 /* TypeOperator */:
            case 181 /* IndexedAccessType */:
            case 182 /* MappedType */:
            case 183 /* LiteralType */:
            case 248 /* NamespaceExportDeclaration */:
                // Types and signatures are TypeScript syntax, and exclude all other facts.
                transformFlags = 1 /* AssertTypeScript */;
                excludeFlags = -2 /* TypeExcludes */;
                break;
            case 150 /* ComputedPropertyName */:
                // Even though computed property names are ES6, we don't treat them as such.
                // This is so that they can flow through PropertyName transforms unaffected.
                // Instead, we mark the container as ES6, so that it can properly handle the transform.
                transformFlags |= 16384 /* ContainsComputedPropertyName */;
                break;
            case 209 /* SpreadElement */:
                transformFlags |= 128 /* AssertES2015 */ | 4096 /* ContainsRestOrSpread */;
                break;
            case 278 /* SpreadAssignment */:
                transformFlags |= 16 /* AssertES2018 */ | 8192 /* ContainsObjectRestOrSpread */;
                break;
            case 99 /* SuperKeyword */:
                // This node is ES6 syntax.
                transformFlags |= 128 /* AssertES2015 */;
                excludeFlags = 536870912 /* OuterExpressionExcludes */; // must be set to persist `Super`
                break;
            case 101 /* ThisKeyword */:
                // Mark this node and its ancestors as containing a lexical `this` keyword.
                transformFlags |= 2048 /* ContainsLexicalThis */;
                break;
            case 185 /* ObjectBindingPattern */:
                transformFlags |= 128 /* AssertES2015 */ | 65536 /* ContainsBindingPattern */;
                if (subtreeFlags & 4096 /* ContainsRestOrSpread */) {
                    transformFlags |= 16 /* AssertES2018 */ | 8192 /* ContainsObjectRestOrSpread */;
                }
                excludeFlags = 536875008 /* BindingPatternExcludes */;
                break;
            case 186 /* ArrayBindingPattern */:
                transformFlags |= 128 /* AssertES2015 */ | 65536 /* ContainsBindingPattern */;
                excludeFlags = 536875008 /* BindingPatternExcludes */;
                break;
            case 187 /* BindingElement */:
                transformFlags |= 128 /* AssertES2015 */;
                if (node.dotDotDotToken) {
                    transformFlags |= 4096 /* ContainsRestOrSpread */;
                }
                break;
            case 153 /* Decorator */:
                // This node is TypeScript syntax, and marks its container as also being TypeScript syntax.
                transformFlags |= 1 /* AssertTypeScript */ | 1024 /* ContainsTypeScriptClassSyntax */;
                break;
            case 189 /* ObjectLiteralExpression */:
                excludeFlags = 536896512 /* ObjectLiteralExcludes */;
                if (subtreeFlags & 16384 /* ContainsComputedPropertyName */) {
                    // If an ObjectLiteralExpression contains a ComputedPropertyName, then it
                    // is an ES6 node.
                    transformFlags |= 128 /* AssertES2015 */;
                }
                if (subtreeFlags & 8192 /* ContainsObjectRestOrSpread */) {
                    // If an ObjectLiteralExpression contains a spread element, then it
                    // is an ES2018 node.
                    transformFlags |= 16 /* AssertES2018 */;
                }
                break;
            case 188 /* ArrayLiteralExpression */:
                excludeFlags = 536875008 /* ArrayLiteralOrCallOrNewExcludes */;
                break;
            case 224 /* DoStatement */:
            case 225 /* WhileStatement */:
            case 226 /* ForStatement */:
            case 227 /* ForInStatement */:
                // A loop containing a block scoped binding *may* need to be transformed from ES6.
                if (subtreeFlags & 32768 /* ContainsBlockScopedBinding */) {
                    transformFlags |= 128 /* AssertES2015 */;
                }
                break;
            case 285 /* SourceFile */:
                break;
            case 231 /* ReturnStatement */:
                // Return statements may require an `await` in ES2018.
                transformFlags |= 262144 /* ContainsHoistedDeclarationOrCompletion */ | 16 /* AssertES2018 */;
                break;
            case 229 /* ContinueStatement */:
            case 230 /* BreakStatement */:
                transformFlags |= 262144 /* ContainsHoistedDeclarationOrCompletion */;
                break;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~excludeFlags;
    }
    function propagatePropertyNameFlags(node, transformFlags) {
        return transformFlags | (node.transformFlags & 2048 /* PropertyNamePropagatingFlags */);
    }
    /**
     * Gets the transform flags to exclude when unioning the transform flags of a subtree.
     *
     * NOTE: This needs to be kept up-to-date with the exclusions used in `computeTransformFlagsForNode`.
     *       For performance reasons, `computeTransformFlagsForNode` uses local constant values rather
     *       than calling this function.
     */
    function getTransformFlagsSubtreeExclusions(kind) {
        if (kind >= 164 /* FirstTypeNode */ && kind <= 184 /* LastTypeNode */) {
            return -2 /* TypeExcludes */;
        }
        switch (kind) {
            case 192 /* CallExpression */:
            case 193 /* NewExpression */:
            case 188 /* ArrayLiteralExpression */:
                return 536875008 /* ArrayLiteralOrCallOrNewExcludes */;
            case 245 /* ModuleDeclaration */:
                return 537168896 /* ModuleExcludes */;
            case 152 /* Parameter */:
                return 536870912 /* ParameterExcludes */;
            case 198 /* ArrowFunction */:
                return 537371648 /* ArrowFunctionExcludes */;
            case 197 /* FunctionExpression */:
            case 240 /* FunctionDeclaration */:
                return 537373696 /* FunctionExcludes */;
            case 239 /* VariableDeclarationList */:
                return 536944640 /* VariableDeclarationListExcludes */;
            case 241 /* ClassDeclaration */:
            case 210 /* ClassExpression */:
                return 536888320 /* ClassExcludes */;
            case 158 /* Constructor */:
                return 537372672 /* ConstructorExcludes */;
            case 157 /* MethodDeclaration */:
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
                return 537372672 /* MethodOrAccessorExcludes */;
            case 121 /* AnyKeyword */:
            case 136 /* NumberKeyword */:
            case 147 /* BigIntKeyword */:
            case 133 /* NeverKeyword */:
            case 139 /* StringKeyword */:
            case 137 /* ObjectKeyword */:
            case 124 /* BooleanKeyword */:
            case 140 /* SymbolKeyword */:
            case 107 /* VoidKeyword */:
            case 151 /* TypeParameter */:
            case 154 /* PropertySignature */:
            case 156 /* MethodSignature */:
            case 161 /* CallSignature */:
            case 162 /* ConstructSignature */:
            case 163 /* IndexSignature */:
            case 242 /* InterfaceDeclaration */:
            case 243 /* TypeAliasDeclaration */:
                return -2 /* TypeExcludes */;
            case 189 /* ObjectLiteralExpression */:
                return 536896512 /* ObjectLiteralExcludes */;
            case 275 /* CatchClause */:
                return 536879104 /* CatchClauseExcludes */;
            case 185 /* ObjectBindingPattern */:
            case 186 /* ArrayBindingPattern */:
                return 536875008 /* BindingPatternExcludes */;
            case 195 /* TypeAssertionExpression */:
            case 213 /* AsExpression */:
            case 314 /* PartiallyEmittedExpression */:
            case 196 /* ParenthesizedExpression */:
            case 99 /* SuperKeyword */:
                return 536870912 /* OuterExpressionExcludes */;
            case 190 /* PropertyAccessExpression */:
            case 191 /* ElementAccessExpression */:
                return 536870912 /* PropertyAccessExcludes */;
            default:
                return 536870912 /* NodeExcludes */;
        }
    }
    ts.getTransformFlagsSubtreeExclusions = getTransformFlagsSubtreeExclusions;
    /**
     * "Binds" JSDoc nodes in TypeScript code.
     * Since we will never create symbols for JSDoc, we just set parent pointers instead.
     */
    function setParentPointers(parent, child) {
        child.parent = parent;
        ts.forEachChild(child, function (grandchild) { return setParentPointers(child, grandchild); });
    }
})(ts || (ts = {}));
/** @internal */
var ts;
(function (ts) {
    function createGetSymbolWalker(getRestTypeOfSignature, getTypePredicateOfSignature, getReturnTypeOfSignature, getBaseTypes, resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, getConstraintOfTypeParameter, getFirstIdentifier) {
        return getSymbolWalker;
        function getSymbolWalker(accept) {
            if (accept === void 0) { accept = function () { return true; }; }
            var visitedTypes = []; // Sparse array from id to type
            var visitedSymbols = []; // Sparse array from id to symbol
            return {
                walkType: function (type) {
                    try {
                        visitType(type);
                        return { visitedTypes: ts.getOwnValues(visitedTypes), visitedSymbols: ts.getOwnValues(visitedSymbols) };
                    }
                    finally {
                        ts.clear(visitedTypes);
                        ts.clear(visitedSymbols);
                    }
                },
                walkSymbol: function (symbol) {
                    try {
                        visitSymbol(symbol);
                        return { visitedTypes: ts.getOwnValues(visitedTypes), visitedSymbols: ts.getOwnValues(visitedSymbols) };
                    }
                    finally {
                        ts.clear(visitedTypes);
                        ts.clear(visitedSymbols);
                    }
                },
            };
            function visitType(type) {
                if (!type) {
                    return;
                }
                if (visitedTypes[type.id]) {
                    return;
                }
                visitedTypes[type.id] = type;
                // Reuse visitSymbol to visit the type's symbol,
                //  but be sure to bail on recuring into the type if accept declines the symbol.
                var shouldBail = visitSymbol(type.symbol);
                if (shouldBail)
                    return;
                // Visit the type's related types, if any
                if (type.flags & 524288 /* Object */) {
                    var objectType = type;
                    var objectFlags = objectType.objectFlags;
                    if (objectFlags & 4 /* Reference */) {
                        visitTypeReference(type);
                    }
                    if (objectFlags & 32 /* Mapped */) {
                        visitMappedType(type);
                    }
                    if (objectFlags & (1 /* Class */ | 2 /* Interface */)) {
                        visitInterfaceType(type);
                    }
                    if (objectFlags & (8 /* Tuple */ | 16 /* Anonymous */)) {
                        visitObjectType(objectType);
                    }
                }
                if (type.flags & 262144 /* TypeParameter */) {
                    visitTypeParameter(type);
                }
                if (type.flags & 3145728 /* UnionOrIntersection */) {
                    visitUnionOrIntersectionType(type);
                }
                if (type.flags & 4194304 /* Index */) {
                    visitIndexType(type);
                }
                if (type.flags & 8388608 /* IndexedAccess */) {
                    visitIndexedAccessType(type);
                }
            }
            function visitTypeReference(type) {
                visitType(type.target);
                ts.forEach(type.typeArguments, visitType);
            }
            function visitTypeParameter(type) {
                visitType(getConstraintOfTypeParameter(type));
            }
            function visitUnionOrIntersectionType(type) {
                ts.forEach(type.types, visitType);
            }
            function visitIndexType(type) {
                visitType(type.type);
            }
            function visitIndexedAccessType(type) {
                visitType(type.objectType);
                visitType(type.indexType);
                visitType(type.constraint);
            }
            function visitMappedType(type) {
                visitType(type.typeParameter);
                visitType(type.constraintType);
                visitType(type.templateType);
                visitType(type.modifiersType);
            }
            function visitSignature(signature) {
                var typePredicate = getTypePredicateOfSignature(signature);
                if (typePredicate) {
                    visitType(typePredicate.type);
                }
                ts.forEach(signature.typeParameters, visitType);
                for (var _i = 0, _a = signature.parameters; _i < _a.length; _i++) {
                    var parameter = _a[_i];
                    visitSymbol(parameter);
                }
                visitType(getRestTypeOfSignature(signature));
                visitType(getReturnTypeOfSignature(signature));
            }
            function visitInterfaceType(interfaceT) {
                visitObjectType(interfaceT);
                ts.forEach(interfaceT.typeParameters, visitType);
                ts.forEach(getBaseTypes(interfaceT), visitType);
                visitType(interfaceT.thisType);
            }
            function visitObjectType(type) {
                var stringIndexType = getIndexTypeOfStructuredType(type, 0 /* String */);
                visitType(stringIndexType);
                var numberIndexType = getIndexTypeOfStructuredType(type, 1 /* Number */);
                visitType(numberIndexType);
                // The two checks above *should* have already resolved the type (if needed), so this should be cached
                var resolved = resolveStructuredTypeMembers(type);
                for (var _i = 0, _a = resolved.callSignatures; _i < _a.length; _i++) {
                    var signature = _a[_i];
                    visitSignature(signature);
                }
                for (var _b = 0, _c = resolved.constructSignatures; _b < _c.length; _b++) {
                    var signature = _c[_b];
                    visitSignature(signature);
                }
                for (var _d = 0, _e = resolved.properties; _d < _e.length; _d++) {
                    var p = _e[_d];
                    visitSymbol(p);
                }
            }
            function visitSymbol(symbol) {
                if (!symbol) {
                    return false;
                }
                var symbolId = ts.getSymbolId(symbol);
                if (visitedSymbols[symbolId]) {
                    return false;
                }
                visitedSymbols[symbolId] = symbol;
                if (!accept(symbol)) {
                    return true;
                }
                var t = getTypeOfSymbol(symbol);
                visitType(t); // Should handle members on classes and such
                if (symbol.exports) {
                    symbol.exports.forEach(visitSymbol);
                }
                ts.forEach(symbol.declarations, function (d) {
                    // Type queries are too far resolved when we just visit the symbol's type
                    //  (their type resolved directly to the member deeply referenced)
                    // So to get the intervening symbols, we need to check if there's a type
                    // query node on any of the symbol's declarations and get symbols there
                    if (d.type && d.type.kind === 168 /* TypeQuery */) {
                        var query = d.type;
                        var entity = getResolvedSymbol(getFirstIdentifier(query.exprName));
                        visitSymbol(entity);
                    }
                });
                return false;
            }
        }
    }
    ts.createGetSymbolWalker = createGetSymbolWalker;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var ambientModuleSymbolRegex = /^".+"$/;
    var nextSymbolId = 1;
    var nextNodeId = 1;
    var nextMergeId = 1;
    var nextFlowId = 1;
    function getNodeId(node) {
        if (!node.id) {
            node.id = nextNodeId;
            nextNodeId++;
        }
        return node.id;
    }
    ts.getNodeId = getNodeId;
    function getSymbolId(symbol) {
        if (!symbol.id) {
            symbol.id = nextSymbolId;
            nextSymbolId++;
        }
        return symbol.id;
    }
    ts.getSymbolId = getSymbolId;
    function isInstantiatedModule(node, preserveConstEnums) {
        var moduleState = ts.getModuleInstanceState(node);
        return moduleState === 1 /* Instantiated */ ||
            (preserveConstEnums && moduleState === 2 /* ConstEnumOnly */);
    }
    ts.isInstantiatedModule = isInstantiatedModule;
    function createTypeChecker(host, produceDiagnostics) {
        var getPackagesSet = ts.memoize(function () {
            var set = ts.createMap();
            host.getSourceFiles().forEach(function (sf) {
                if (!sf.resolvedModules)
                    return;
                ts.forEachEntry(sf.resolvedModules, function (r) {
                    if (r && r.packageId)
                        set.set(r.packageId.name, true);
                });
            });
            return set;
        });
        // Cancellation that controls whether or not we can cancel in the middle of type checking.
        // In general cancelling is *not* safe for the type checker.  We might be in the middle of
        // computing something, and we will leave our internals in an inconsistent state.  Callers
        // who set the cancellation token should catch if a cancellation exception occurs, and
        // should throw away and create a new TypeChecker.
        //
        // Currently we only support setting the cancellation token when getting diagnostics.  This
        // is because diagnostics can be quite expensive, and we want to allow hosts to bail out if
        // they no longer need the information (for example, if the user started editing again).
        var cancellationToken;
        var requestedExternalEmitHelpers;
        var externalHelpersModule;
        // tslint:disable variable-name
        var Symbol = ts.objectAllocator.getSymbolConstructor();
        var Type = ts.objectAllocator.getTypeConstructor();
        var Signature = ts.objectAllocator.getSignatureConstructor();
        // tslint:enable variable-name
        var typeCount = 0;
        var symbolCount = 0;
        var enumCount = 0;
        var instantiationDepth = 0;
        var constraintDepth = 0;
        var currentNode;
        var emptySymbols = ts.createSymbolTable();
        var identityMapper = ts.identity;
        var compilerOptions = host.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        var allowSyntheticDefaultImports = ts.getAllowSyntheticDefaultImports(compilerOptions);
        var strictNullChecks = ts.getStrictOptionValue(compilerOptions, "strictNullChecks");
        var strictFunctionTypes = ts.getStrictOptionValue(compilerOptions, "strictFunctionTypes");
        var strictBindCallApply = ts.getStrictOptionValue(compilerOptions, "strictBindCallApply");
        var strictPropertyInitialization = ts.getStrictOptionValue(compilerOptions, "strictPropertyInitialization");
        var noImplicitAny = ts.getStrictOptionValue(compilerOptions, "noImplicitAny");
        var noImplicitThis = ts.getStrictOptionValue(compilerOptions, "noImplicitThis");
        var keyofStringsOnly = !!compilerOptions.keyofStringsOnly;
        var freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : 32768 /* FreshLiteral */;
        var emitResolver = createResolver();
        var nodeBuilder = createNodeBuilder();
        var globals = ts.createSymbolTable();
        var undefinedSymbol = createSymbol(4 /* Property */, "undefined");
        undefinedSymbol.declarations = [];
        var globalThisSymbol = createSymbol(1536 /* Module */, "globalThis", 8 /* Readonly */);
        globalThisSymbol.exports = globals;
        globals.set(globalThisSymbol.escapedName, globalThisSymbol);
        var argumentsSymbol = createSymbol(4 /* Property */, "arguments");
        var requireSymbol = createSymbol(4 /* Property */, "require");
        /** This will be set during calls to `getResolvedSignature` where services determines an apparent number of arguments greater than what is actually provided. */
        var apparentArgumentCount;
        // for public members that accept a Node or one of its subtypes, we must guard against
        // synthetic nodes created during transformations by calling `getParseTreeNode`.
        // for most of these, we perform the guard only on `checker` to avoid any possible
        // extra cost of calling `getParseTreeNode` when calling these functions from inside the
        // checker.
        var checker = {
            getNodeCount: function () { return ts.sum(host.getSourceFiles(), "nodeCount"); },
            getIdentifierCount: function () { return ts.sum(host.getSourceFiles(), "identifierCount"); },
            getSymbolCount: function () { return ts.sum(host.getSourceFiles(), "symbolCount") + symbolCount; },
            getTypeCount: function () { return typeCount; },
            getRelationCacheSizes: function () { return ({
                assignable: assignableRelation.size,
                identity: identityRelation.size,
                subtype: subtypeRelation.size,
            }); },
            isUndefinedSymbol: function (symbol) { return symbol === undefinedSymbol; },
            isArgumentsSymbol: function (symbol) { return symbol === argumentsSymbol; },
            isUnknownSymbol: function (symbol) { return symbol === unknownSymbol; },
            getMergedSymbol: getMergedSymbol,
            getDiagnostics: getDiagnostics,
            getGlobalDiagnostics: getGlobalDiagnostics,
            getTypeOfSymbolAtLocation: function (symbol, location) {
                location = ts.getParseTreeNode(location);
                return location ? getTypeOfSymbolAtLocation(symbol, location) : errorType;
            },
            getSymbolsOfParameterPropertyDeclaration: function (parameterIn, parameterName) {
                var parameter = ts.getParseTreeNode(parameterIn, ts.isParameter);
                if (parameter === undefined)
                    return ts.Debug.fail("Cannot get symbols of a synthetic parameter that cannot be resolved to a parse-tree node.");
                return getSymbolsOfParameterPropertyDeclaration(parameter, ts.escapeLeadingUnderscores(parameterName));
            },
            getDeclaredTypeOfSymbol: getDeclaredTypeOfSymbol,
            getPropertiesOfType: getPropertiesOfType,
            getPropertyOfType: function (type, name) { return getPropertyOfType(type, ts.escapeLeadingUnderscores(name)); },
            getTypeOfPropertyOfType: function (type, name) { return getTypeOfPropertyOfType(type, ts.escapeLeadingUnderscores(name)); },
            getIndexInfoOfType: getIndexInfoOfType,
            getSignaturesOfType: getSignaturesOfType,
            getIndexTypeOfType: getIndexTypeOfType,
            getBaseTypes: getBaseTypes,
            getBaseTypeOfLiteralType: getBaseTypeOfLiteralType,
            getWidenedType: getWidenedType,
            getTypeFromTypeNode: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isTypeNode);
                return node ? getTypeFromTypeNode(node) : errorType;
            },
            getParameterType: getTypeAtPosition,
            getPromisedTypeOfPromise: getPromisedTypeOfPromise,
            getReturnTypeOfSignature: getReturnTypeOfSignature,
            getNullableType: getNullableType,
            getNonNullableType: getNonNullableType,
            typeToTypeNode: nodeBuilder.typeToTypeNode,
            indexInfoToIndexSignatureDeclaration: nodeBuilder.indexInfoToIndexSignatureDeclaration,
            signatureToSignatureDeclaration: nodeBuilder.signatureToSignatureDeclaration,
            symbolToEntityName: nodeBuilder.symbolToEntityName,
            symbolToExpression: nodeBuilder.symbolToExpression,
            symbolToTypeParameterDeclarations: nodeBuilder.symbolToTypeParameterDeclarations,
            symbolToParameterDeclaration: nodeBuilder.symbolToParameterDeclaration,
            typeParameterToDeclaration: nodeBuilder.typeParameterToDeclaration,
            getSymbolsInScope: function (location, meaning) {
                location = ts.getParseTreeNode(location);
                return location ? getSymbolsInScope(location, meaning) : [];
            },
            getSymbolAtLocation: function (node) {
                node = ts.getParseTreeNode(node);
                return node ? getSymbolAtLocation(node) : undefined;
            },
            getShorthandAssignmentValueSymbol: function (node) {
                node = ts.getParseTreeNode(node);
                return node ? getShorthandAssignmentValueSymbol(node) : undefined;
            },
            getExportSpecifierLocalTargetSymbol: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isExportSpecifier);
                return node ? getExportSpecifierLocalTargetSymbol(node) : undefined;
            },
            getExportSymbolOfSymbol: function (symbol) {
                return getMergedSymbol(symbol.exportSymbol || symbol);
            },
            getTypeAtLocation: function (node) {
                node = ts.getParseTreeNode(node);
                return node ? getTypeOfNode(node) : errorType;
            },
            getTypeOfAssignmentPattern: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isAssignmentPattern);
                return node && getTypeOfAssignmentPattern(node) || errorType;
            },
            getPropertySymbolOfDestructuringAssignment: function (locationIn) {
                var location = ts.getParseTreeNode(locationIn, ts.isIdentifier);
                return location ? getPropertySymbolOfDestructuringAssignment(location) : undefined;
            },
            signatureToString: function (signature, enclosingDeclaration, flags, kind) {
                return signatureToString(signature, ts.getParseTreeNode(enclosingDeclaration), flags, kind);
            },
            typeToString: function (type, enclosingDeclaration, flags) {
                return typeToString(type, ts.getParseTreeNode(enclosingDeclaration), flags);
            },
            symbolToString: function (symbol, enclosingDeclaration, meaning, flags) {
                return symbolToString(symbol, ts.getParseTreeNode(enclosingDeclaration), meaning, flags);
            },
            typePredicateToString: function (predicate, enclosingDeclaration, flags) {
                return typePredicateToString(predicate, ts.getParseTreeNode(enclosingDeclaration), flags);
            },
            writeSignature: function (signature, enclosingDeclaration, flags, kind, writer) {
                return signatureToString(signature, ts.getParseTreeNode(enclosingDeclaration), flags, kind, writer);
            },
            writeType: function (type, enclosingDeclaration, flags, writer) {
                return typeToString(type, ts.getParseTreeNode(enclosingDeclaration), flags, writer);
            },
            writeSymbol: function (symbol, enclosingDeclaration, meaning, flags, writer) {
                return symbolToString(symbol, ts.getParseTreeNode(enclosingDeclaration), meaning, flags, writer);
            },
            writeTypePredicate: function (predicate, enclosingDeclaration, flags, writer) {
                return typePredicateToString(predicate, ts.getParseTreeNode(enclosingDeclaration), flags, writer);
            },
            getAugmentedPropertiesOfType: getAugmentedPropertiesOfType,
            getRootSymbols: getRootSymbols,
            getContextualType: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isExpression);
                return node ? getContextualType(node) : undefined;
            },
            getContextualTypeForObjectLiteralElement: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isObjectLiteralElementLike);
                return node ? getContextualTypeForObjectLiteralElement(node) : undefined;
            },
            getContextualTypeForArgumentAtIndex: function (nodeIn, argIndex) {
                var node = ts.getParseTreeNode(nodeIn, ts.isCallLikeExpression);
                return node && getContextualTypeForArgumentAtIndex(node, argIndex);
            },
            getContextualTypeForJsxAttribute: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isJsxAttributeLike);
                return node && getContextualTypeForJsxAttribute(node);
            },
            isContextSensitive: isContextSensitive,
            getFullyQualifiedName: getFullyQualifiedName,
            getResolvedSignature: function (node, candidatesOutArray, argumentCount) {
                return getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, 0 /* Normal */);
            },
            getResolvedSignatureForSignatureHelp: function (node, candidatesOutArray, argumentCount) {
                return getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, 16 /* IsForSignatureHelp */);
            },
            getExpandedParameters: getExpandedParameters,
            hasEffectiveRestParameter: hasEffectiveRestParameter,
            getConstantValue: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, canHaveConstantValue);
                return node ? getConstantValue(node) : undefined;
            },
            isValidPropertyAccess: function (nodeIn, propertyName) {
                var node = ts.getParseTreeNode(nodeIn, ts.isPropertyAccessOrQualifiedNameOrImportTypeNode);
                return !!node && isValidPropertyAccess(node, ts.escapeLeadingUnderscores(propertyName));
            },
            isValidPropertyAccessForCompletions: function (nodeIn, type, property) {
                var node = ts.getParseTreeNode(nodeIn, ts.isPropertyAccessExpression);
                return !!node && isValidPropertyAccessForCompletions(node, type, property);
            },
            getSignatureFromDeclaration: function (declarationIn) {
                var declaration = ts.getParseTreeNode(declarationIn, ts.isFunctionLike);
                return declaration ? getSignatureFromDeclaration(declaration) : undefined;
            },
            isImplementationOfOverload: function (node) {
                var parsed = ts.getParseTreeNode(node, ts.isFunctionLike);
                return parsed ? isImplementationOfOverload(parsed) : undefined;
            },
            getImmediateAliasedSymbol: getImmediateAliasedSymbol,
            getAliasedSymbol: resolveAlias,
            getEmitResolver: getEmitResolver,
            getExportsOfModule: getExportsOfModuleAsArray,
            getExportsAndPropertiesOfModule: getExportsAndPropertiesOfModule,
            getSymbolWalker: ts.createGetSymbolWalker(getRestTypeOfSignature, getTypePredicateOfSignature, getReturnTypeOfSignature, getBaseTypes, resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, getConstraintOfTypeParameter, getFirstIdentifier),
            getAmbientModules: getAmbientModules,
            getJsxIntrinsicTagNamesAt: getJsxIntrinsicTagNamesAt,
            isOptionalParameter: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isParameter);
                return node ? isOptionalParameter(node) : false;
            },
            tryGetMemberInModuleExports: function (name, symbol) { return tryGetMemberInModuleExports(ts.escapeLeadingUnderscores(name), symbol); },
            tryGetMemberInModuleExportsAndProperties: function (name, symbol) { return tryGetMemberInModuleExportsAndProperties(ts.escapeLeadingUnderscores(name), symbol); },
            tryFindAmbientModuleWithoutAugmentations: function (moduleName) {
                // we deliberately exclude augmentations
                // since we are only interested in declarations of the module itself
                return tryFindAmbientModule(moduleName, /*withAugmentations*/ false);
            },
            getApparentType: getApparentType,
            getUnionType: getUnionType,
            createAnonymousType: createAnonymousType,
            createSignature: createSignature,
            createSymbol: createSymbol,
            createIndexInfo: createIndexInfo,
            getAnyType: function () { return anyType; },
            getStringType: function () { return stringType; },
            getNumberType: function () { return numberType; },
            createPromiseType: createPromiseType,
            createArrayType: createArrayType,
            getElementTypeOfArrayType: getElementTypeOfArrayType,
            getBooleanType: function () { return booleanType; },
            getFalseType: function (fresh) { return fresh ? falseType : regularFalseType; },
            getTrueType: function (fresh) { return fresh ? trueType : regularTrueType; },
            getVoidType: function () { return voidType; },
            getUndefinedType: function () { return undefinedType; },
            getNullType: function () { return nullType; },
            getESSymbolType: function () { return esSymbolType; },
            getNeverType: function () { return neverType; },
            isSymbolAccessible: isSymbolAccessible,
            getObjectFlags: ts.getObjectFlags,
            isArrayType: isArrayType,
            isTupleType: isTupleType,
            isArrayLikeType: isArrayLikeType,
            isTypeInvalidDueToUnionDiscriminant: isTypeInvalidDueToUnionDiscriminant,
            getAllPossiblePropertiesOfTypes: getAllPossiblePropertiesOfTypes,
            getSuggestionForNonexistentProperty: function (node, type) { return getSuggestionForNonexistentProperty(node, type); },
            getSuggestionForNonexistentSymbol: function (location, name, meaning) { return getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); },
            getSuggestionForNonexistentExport: function (node, target) { return getSuggestionForNonexistentExport(node, target); },
            getBaseConstraintOfType: getBaseConstraintOfType,
            getDefaultFromTypeParameter: function (type) { return type && type.flags & 262144 /* TypeParameter */ ? getDefaultFromTypeParameter(type) : undefined; },
            resolveName: function (name, location, meaning, excludeGlobals) {
                return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false, excludeGlobals);
            },
            getJsxNamespace: function (n) { return ts.unescapeLeadingUnderscores(getJsxNamespace(n)); },
            getAccessibleSymbolChain: getAccessibleSymbolChain,
            getTypePredicateOfSignature: getTypePredicateOfSignature,
            resolveExternalModuleSymbol: resolveExternalModuleSymbol,
            tryGetThisTypeAt: function (node, includeGlobalThis) {
                node = ts.getParseTreeNode(node);
                return node && tryGetThisTypeAt(node, includeGlobalThis);
            },
            getTypeArgumentConstraint: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isTypeNode);
                return node && getTypeArgumentConstraint(node);
            },
            getSuggestionDiagnostics: function (file, ct) {
                if (ts.skipTypeChecking(file, compilerOptions)) {
                    return ts.emptyArray;
                }
                var diagnostics;
                try {
                    // Record the cancellation token so it can be checked later on during checkSourceElement.
                    // Do this in a finally block so we can ensure that it gets reset back to nothing after
                    // this call is done.
                    cancellationToken = ct;
                    // Ensure file is type checked
                    checkSourceFile(file);
                    ts.Debug.assert(!!(getNodeLinks(file).flags & 1 /* TypeChecked */));
                    diagnostics = ts.addRange(diagnostics, suggestionDiagnostics.get(file.fileName));
                    if (!file.isDeclarationFile && (!unusedIsError(0 /* Local */) || !unusedIsError(1 /* Parameter */))) {
                        addUnusedDiagnostics();
                    }
                    return diagnostics || ts.emptyArray;
                }
                finally {
                    cancellationToken = undefined;
                }
                function addUnusedDiagnostics() {
                    checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(file), function (containingNode, kind, diag) {
                        if (!ts.containsParseError(containingNode) && !unusedIsError(kind)) {
                            (diagnostics || (diagnostics = [])).push(__assign({}, diag, { category: ts.DiagnosticCategory.Suggestion }));
                        }
                    });
                }
            },
            runWithCancellationToken: function (token, callback) {
                try {
                    cancellationToken = token;
                    return callback(checker);
                }
                finally {
                    cancellationToken = undefined;
                }
            },
            getLocalTypeParametersOfClassOrInterfaceOrTypeAlias: getLocalTypeParametersOfClassOrInterfaceOrTypeAlias,
        };
        function getResolvedSignatureWorker(nodeIn, candidatesOutArray, argumentCount, checkMode) {
            var node = ts.getParseTreeNode(nodeIn, ts.isCallLikeExpression);
            apparentArgumentCount = argumentCount;
            var res = node ? getResolvedSignature(node, candidatesOutArray, checkMode) : undefined;
            apparentArgumentCount = undefined;
            return res;
        }
        var tupleTypes = ts.createMap();
        var unionTypes = ts.createMap();
        var intersectionTypes = ts.createMap();
        var literalTypes = ts.createMap();
        var indexedAccessTypes = ts.createMap();
        var substitutionTypes = ts.createMap();
        var evolvingArrayTypes = [];
        var undefinedProperties = ts.createMap();
        var unknownSymbol = createSymbol(4 /* Property */, "unknown");
        var resolvingSymbol = createSymbol(0, "__resolving__" /* Resolving */);
        var anyType = createIntrinsicType(1 /* Any */, "any");
        var autoType = createIntrinsicType(1 /* Any */, "any");
        var wildcardType = createIntrinsicType(1 /* Any */, "any");
        var errorType = createIntrinsicType(1 /* Any */, "error");
        var unknownType = createIntrinsicType(2 /* Unknown */, "unknown");
        var undefinedType = createIntrinsicType(32768 /* Undefined */, "undefined");
        var undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(32768 /* Undefined */, "undefined", 131072 /* ContainsWideningType */);
        var nullType = createIntrinsicType(65536 /* Null */, "null");
        var nullWideningType = strictNullChecks ? nullType : createIntrinsicType(65536 /* Null */, "null", 131072 /* ContainsWideningType */);
        var stringType = createIntrinsicType(4 /* String */, "string");
        var numberType = createIntrinsicType(8 /* Number */, "number");
        var bigintType = createIntrinsicType(64 /* BigInt */, "bigint");
        var falseType = createIntrinsicType(512 /* BooleanLiteral */, "false");
        var regularFalseType = createIntrinsicType(512 /* BooleanLiteral */, "false");
        var trueType = createIntrinsicType(512 /* BooleanLiteral */, "true");
        var regularTrueType = createIntrinsicType(512 /* BooleanLiteral */, "true");
        trueType.regularType = regularTrueType;
        trueType.freshType = trueType;
        regularTrueType.regularType = regularTrueType;
        regularTrueType.freshType = trueType;
        falseType.regularType = regularFalseType;
        falseType.freshType = falseType;
        regularFalseType.regularType = regularFalseType;
        regularFalseType.freshType = falseType;
        var booleanType = createBooleanType([regularFalseType, regularTrueType]);
        // Also mark all combinations of fresh/regular booleans as "Boolean" so they print as `boolean` instead of `true | false`
        // (The union is cached, so simply doing the marking here is sufficient)
        createBooleanType([regularFalseType, trueType]);
        createBooleanType([falseType, regularTrueType]);
        createBooleanType([falseType, trueType]);
        var esSymbolType = createIntrinsicType(4096 /* ESSymbol */, "symbol");
        var voidType = createIntrinsicType(16384 /* Void */, "void");
        var neverType = createIntrinsicType(131072 /* Never */, "never");
        var silentNeverType = createIntrinsicType(131072 /* Never */, "never");
        var nonInferrableType = createIntrinsicType(131072 /* Never */, "never", 524288 /* NonInferrableType */);
        var implicitNeverType = createIntrinsicType(131072 /* Never */, "never");
        var nonPrimitiveType = createIntrinsicType(67108864 /* NonPrimitive */, "object");
        var stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]);
        var keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType;
        var numberOrBigIntType = getUnionType([numberType, bigintType]);
        var emptyObjectType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var emptyJsxObjectType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        emptyJsxObjectType.objectFlags |= 4096 /* JsxAttributes */;
        var emptyTypeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */);
        emptyTypeLiteralSymbol.members = ts.createSymbolTable();
        var emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var emptyGenericType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        emptyGenericType.instantiations = ts.createMap();
        var anyFunctionType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        // The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated
        // in getPropagatingFlagsOfTypes, and it is checked in inferFromTypes.
        anyFunctionType.objectFlags |= 524288 /* NonInferrableType */;
        var noConstraintType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var circularConstraintType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var resolvingDefaultType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var markerSuperType = createTypeParameter();
        var markerSubType = createTypeParameter();
        markerSubType.constraint = markerSuperType;
        var markerOtherType = createTypeParameter();
        var noTypePredicate = createIdentifierTypePredicate("<<unresolved>>", 0, anyType);
        var anySignature = createSignature(undefined, undefined, undefined, ts.emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
        var unknownSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, errorType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
        var resolvingSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
        var silentNeverSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, silentNeverType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
        var enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
        /** Key is "/path/to/a.ts|/path/to/b.ts". */
        var amalgamatedDuplicates;
        var reverseMappedCache = ts.createMap();
        var ambientModulesCache;
        /**
         * List of every ambient module with a "*" wildcard.
         * Unlike other ambient modules, these can't be stored in `globals` because symbol tables only deal with exact matches.
         * This is only used if there is no exact match.
         */
        var patternAmbientModules;
        var patternAmbientModuleAugmentations;
        var globalObjectType;
        var globalFunctionType;
        var globalCallableFunctionType;
        var globalNewableFunctionType;
        var globalArrayType;
        var globalReadonlyArrayType;
        var globalStringType;
        var globalNumberType;
        var globalBooleanType;
        var globalRegExpType;
        var globalThisType;
        var anyArrayType;
        var autoArrayType;
        var anyReadonlyArrayType;
        var deferredGlobalNonNullableTypeAlias;
        // The library files are only loaded when the feature is used.
        // This allows users to just specify library files they want to used through --lib
        // and they will not get an error from not having unrelated library files
        var deferredGlobalESSymbolConstructorSymbol;
        var deferredGlobalESSymbolType;
        var deferredGlobalTypedPropertyDescriptorType;
        var deferredGlobalPromiseType;
        var deferredGlobalPromiseLikeType;
        var deferredGlobalPromiseConstructorSymbol;
        var deferredGlobalPromiseConstructorLikeType;
        var deferredGlobalIterableType;
        var deferredGlobalIteratorType;
        var deferredGlobalIterableIteratorType;
        var deferredGlobalAsyncIterableType;
        var deferredGlobalAsyncIteratorType;
        var deferredGlobalAsyncIterableIteratorType;
        var deferredGlobalTemplateStringsArrayType;
        var deferredGlobalImportMetaType;
        var deferredGlobalExtractSymbol;
        var deferredGlobalOmitSymbol;
        var deferredGlobalBigIntType;
        var allPotentiallyUnusedIdentifiers = ts.createMap(); // key is file name
        var flowLoopStart = 0;
        var flowLoopCount = 0;
        var sharedFlowCount = 0;
        var flowAnalysisDisabled = false;
        var emptyStringType = getLiteralType("");
        var zeroType = getLiteralType(0);
        var zeroBigIntType = getLiteralType({ negative: false, base10Value: "0" });
        var resolutionTargets = [];
        var resolutionResults = [];
        var resolutionPropertyNames = [];
        var suggestionCount = 0;
        var maximumSuggestionCount = 10;
        var mergedSymbols = [];
        var symbolLinks = [];
        var nodeLinks = [];
        var flowLoopCaches = [];
        var flowAssignmentKeys = [];
        var flowAssignmentTypes = [];
        var flowLoopNodes = [];
        var flowLoopKeys = [];
        var flowLoopTypes = [];
        var sharedFlowNodes = [];
        var sharedFlowTypes = [];
        var potentialThisCollisions = [];
        var potentialNewTargetCollisions = [];
        var awaitedTypeStack = [];
        var diagnostics = ts.createDiagnosticCollection();
        // Suggestion diagnostics must have a file. Keyed by source file name.
        var suggestionDiagnostics = ts.createMultiMap();
        var TypeFacts;
        (function (TypeFacts) {
            TypeFacts[TypeFacts["None"] = 0] = "None";
            TypeFacts[TypeFacts["TypeofEQString"] = 1] = "TypeofEQString";
            TypeFacts[TypeFacts["TypeofEQNumber"] = 2] = "TypeofEQNumber";
            TypeFacts[TypeFacts["TypeofEQBigInt"] = 4] = "TypeofEQBigInt";
            TypeFacts[TypeFacts["TypeofEQBoolean"] = 8] = "TypeofEQBoolean";
            TypeFacts[TypeFacts["TypeofEQSymbol"] = 16] = "TypeofEQSymbol";
            TypeFacts[TypeFacts["TypeofEQObject"] = 32] = "TypeofEQObject";
            TypeFacts[TypeFacts["TypeofEQFunction"] = 64] = "TypeofEQFunction";
            TypeFacts[TypeFacts["TypeofEQHostObject"] = 128] = "TypeofEQHostObject";
            TypeFacts[TypeFacts["TypeofNEString"] = 256] = "TypeofNEString";
            TypeFacts[TypeFacts["TypeofNENumber"] = 512] = "TypeofNENumber";
            TypeFacts[TypeFacts["TypeofNEBigInt"] = 1024] = "TypeofNEBigInt";
            TypeFacts[TypeFacts["TypeofNEBoolean"] = 2048] = "TypeofNEBoolean";
            TypeFacts[TypeFacts["TypeofNESymbol"] = 4096] = "TypeofNESymbol";
            TypeFacts[TypeFacts["TypeofNEObject"] = 8192] = "TypeofNEObject";
            TypeFacts[TypeFacts["TypeofNEFunction"] = 16384] = "TypeofNEFunction";
            TypeFacts[TypeFacts["TypeofNEHostObject"] = 32768] = "TypeofNEHostObject";
            TypeFacts[TypeFacts["EQUndefined"] = 65536] = "EQUndefined";
            TypeFacts[TypeFacts["EQNull"] = 131072] = "EQNull";
            TypeFacts[TypeFacts["EQUndefinedOrNull"] = 262144] = "EQUndefinedOrNull";
            TypeFacts[TypeFacts["NEUndefined"] = 524288] = "NEUndefined";
            TypeFacts[TypeFacts["NENull"] = 1048576] = "NENull";
            TypeFacts[TypeFacts["NEUndefinedOrNull"] = 2097152] = "NEUndefinedOrNull";
            TypeFacts[TypeFacts["Truthy"] = 4194304] = "Truthy";
            TypeFacts[TypeFacts["Falsy"] = 8388608] = "Falsy";
            TypeFacts[TypeFacts["All"] = 16777215] = "All";
            // The following members encode facts about particular kinds of types for use in the getTypeFacts function.
            // The presence of a particular fact means that the given test is true for some (and possibly all) values
            // of that kind of type.
            TypeFacts[TypeFacts["BaseStringStrictFacts"] = 3735041] = "BaseStringStrictFacts";
            TypeFacts[TypeFacts["BaseStringFacts"] = 12582401] = "BaseStringFacts";
            TypeFacts[TypeFacts["StringStrictFacts"] = 16317953] = "StringStrictFacts";
            TypeFacts[TypeFacts["StringFacts"] = 16776705] = "StringFacts";
            TypeFacts[TypeFacts["EmptyStringStrictFacts"] = 12123649] = "EmptyStringStrictFacts";
            TypeFacts[TypeFacts["EmptyStringFacts"] = 12582401] = "EmptyStringFacts";
            TypeFacts[TypeFacts["NonEmptyStringStrictFacts"] = 7929345] = "NonEmptyStringStrictFacts";
            TypeFacts[TypeFacts["NonEmptyStringFacts"] = 16776705] = "NonEmptyStringFacts";
            TypeFacts[TypeFacts["BaseNumberStrictFacts"] = 3734786] = "BaseNumberStrictFacts";
            TypeFacts[TypeFacts["BaseNumberFacts"] = 12582146] = "BaseNumberFacts";
            TypeFacts[TypeFacts["NumberStrictFacts"] = 16317698] = "NumberStrictFacts";
            TypeFacts[TypeFacts["NumberFacts"] = 16776450] = "NumberFacts";
            TypeFacts[TypeFacts["ZeroNumberStrictFacts"] = 12123394] = "ZeroNumberStrictFacts";
            TypeFacts[TypeFacts["ZeroNumberFacts"] = 12582146] = "ZeroNumberFacts";
            TypeFacts[TypeFacts["NonZeroNumberStrictFacts"] = 7929090] = "NonZeroNumberStrictFacts";
            TypeFacts[TypeFacts["NonZeroNumberFacts"] = 16776450] = "NonZeroNumberFacts";
            TypeFacts[TypeFacts["BaseBigIntStrictFacts"] = 3734276] = "BaseBigIntStrictFacts";
            TypeFacts[TypeFacts["BaseBigIntFacts"] = 12581636] = "BaseBigIntFacts";
            TypeFacts[TypeFacts["BigIntStrictFacts"] = 16317188] = "BigIntStrictFacts";
            TypeFacts[TypeFacts["BigIntFacts"] = 16775940] = "BigIntFacts";
            TypeFacts[TypeFacts["ZeroBigIntStrictFacts"] = 12122884] = "ZeroBigIntStrictFacts";
            TypeFacts[TypeFacts["ZeroBigIntFacts"] = 12581636] = "ZeroBigIntFacts";
            TypeFacts[TypeFacts["NonZeroBigIntStrictFacts"] = 7928580] = "NonZeroBigIntStrictFacts";
            TypeFacts[TypeFacts["NonZeroBigIntFacts"] = 16775940] = "NonZeroBigIntFacts";
            TypeFacts[TypeFacts["BaseBooleanStrictFacts"] = 3733256] = "BaseBooleanStrictFacts";
            TypeFacts[TypeFacts["BaseBooleanFacts"] = 12580616] = "BaseBooleanFacts";
            TypeFacts[TypeFacts["BooleanStrictFacts"] = 16316168] = "BooleanStrictFacts";
            TypeFacts[TypeFacts["BooleanFacts"] = 16774920] = "BooleanFacts";
            TypeFacts[TypeFacts["FalseStrictFacts"] = 12121864] = "FalseStrictFacts";
            TypeFacts[TypeFacts["FalseFacts"] = 12580616] = "FalseFacts";
            TypeFacts[TypeFacts["TrueStrictFacts"] = 7927560] = "TrueStrictFacts";
            TypeFacts[TypeFacts["TrueFacts"] = 16774920] = "TrueFacts";
            TypeFacts[TypeFacts["SymbolStrictFacts"] = 7925520] = "SymbolStrictFacts";
            TypeFacts[TypeFacts["SymbolFacts"] = 16772880] = "SymbolFacts";
            TypeFacts[TypeFacts["ObjectStrictFacts"] = 7888800] = "ObjectStrictFacts";
            TypeFacts[TypeFacts["ObjectFacts"] = 16736160] = "ObjectFacts";
            TypeFacts[TypeFacts["FunctionStrictFacts"] = 7880640] = "FunctionStrictFacts";
            TypeFacts[TypeFacts["FunctionFacts"] = 16728000] = "FunctionFacts";
            TypeFacts[TypeFacts["UndefinedFacts"] = 9830144] = "UndefinedFacts";
            TypeFacts[TypeFacts["NullFacts"] = 9363232] = "NullFacts";
            TypeFacts[TypeFacts["EmptyObjectStrictFacts"] = 16318463] = "EmptyObjectStrictFacts";
            TypeFacts[TypeFacts["EmptyObjectFacts"] = 16777215] = "EmptyObjectFacts";
        })(TypeFacts || (TypeFacts = {}));
        var typeofEQFacts = ts.createMapFromTemplate({
            string: 1 /* TypeofEQString */,
            number: 2 /* TypeofEQNumber */,
            bigint: 4 /* TypeofEQBigInt */,
            boolean: 8 /* TypeofEQBoolean */,
            symbol: 16 /* TypeofEQSymbol */,
            undefined: 65536 /* EQUndefined */,
            object: 32 /* TypeofEQObject */,
            function: 64 /* TypeofEQFunction */
        });
        var typeofNEFacts = ts.createMapFromTemplate({
            string: 256 /* TypeofNEString */,
            number: 512 /* TypeofNENumber */,
            bigint: 1024 /* TypeofNEBigInt */,
            boolean: 2048 /* TypeofNEBoolean */,
            symbol: 4096 /* TypeofNESymbol */,
            undefined: 524288 /* NEUndefined */,
            object: 8192 /* TypeofNEObject */,
            function: 16384 /* TypeofNEFunction */
        });
        var typeofTypesByName = ts.createMapFromTemplate({
            string: stringType,
            number: numberType,
            bigint: bigintType,
            boolean: booleanType,
            symbol: esSymbolType,
            undefined: undefinedType
        });
        var typeofType = createTypeofType();
        var _jsxNamespace;
        var _jsxFactoryEntity;
        var outofbandVarianceMarkerHandler;
        var subtypeRelation = ts.createMap();
        var assignableRelation = ts.createMap();
        var comparableRelation = ts.createMap();
        var identityRelation = ts.createMap();
        var enumRelation = ts.createMap();
        var TypeSystemPropertyName;
        (function (TypeSystemPropertyName) {
            TypeSystemPropertyName[TypeSystemPropertyName["Type"] = 0] = "Type";
            TypeSystemPropertyName[TypeSystemPropertyName["ResolvedBaseConstructorType"] = 1] = "ResolvedBaseConstructorType";
            TypeSystemPropertyName[TypeSystemPropertyName["DeclaredType"] = 2] = "DeclaredType";
            TypeSystemPropertyName[TypeSystemPropertyName["ResolvedReturnType"] = 3] = "ResolvedReturnType";
            TypeSystemPropertyName[TypeSystemPropertyName["ImmediateBaseConstraint"] = 4] = "ImmediateBaseConstraint";
            TypeSystemPropertyName[TypeSystemPropertyName["EnumTagType"] = 5] = "EnumTagType";
            TypeSystemPropertyName[TypeSystemPropertyName["JSDocTypeReference"] = 6] = "JSDocTypeReference";
        })(TypeSystemPropertyName || (TypeSystemPropertyName = {}));
        var CheckMode;
        (function (CheckMode) {
            CheckMode[CheckMode["Normal"] = 0] = "Normal";
            CheckMode[CheckMode["Contextual"] = 1] = "Contextual";
            CheckMode[CheckMode["Inferential"] = 2] = "Inferential";
            CheckMode[CheckMode["SkipContextSensitive"] = 4] = "SkipContextSensitive";
            CheckMode[CheckMode["SkipGenericFunctions"] = 8] = "SkipGenericFunctions";
            CheckMode[CheckMode["IsForSignatureHelp"] = 16] = "IsForSignatureHelp";
        })(CheckMode || (CheckMode = {}));
        var ContextFlags;
        (function (ContextFlags) {
            ContextFlags[ContextFlags["None"] = 0] = "None";
            ContextFlags[ContextFlags["Signature"] = 1] = "Signature";
        })(ContextFlags || (ContextFlags = {}));
        var AccessFlags;
        (function (AccessFlags) {
            AccessFlags[AccessFlags["None"] = 0] = "None";
            AccessFlags[AccessFlags["NoIndexSignatures"] = 1] = "NoIndexSignatures";
            AccessFlags[AccessFlags["Writing"] = 2] = "Writing";
            AccessFlags[AccessFlags["CacheSymbol"] = 4] = "CacheSymbol";
        })(AccessFlags || (AccessFlags = {}));
        var CallbackCheck;
        (function (CallbackCheck) {
            CallbackCheck[CallbackCheck["None"] = 0] = "None";
            CallbackCheck[CallbackCheck["Bivariant"] = 1] = "Bivariant";
            CallbackCheck[CallbackCheck["Strict"] = 2] = "Strict";
        })(CallbackCheck || (CallbackCheck = {}));
        var MappedTypeModifiers;
        (function (MappedTypeModifiers) {
            MappedTypeModifiers[MappedTypeModifiers["IncludeReadonly"] = 1] = "IncludeReadonly";
            MappedTypeModifiers[MappedTypeModifiers["ExcludeReadonly"] = 2] = "ExcludeReadonly";
            MappedTypeModifiers[MappedTypeModifiers["IncludeOptional"] = 4] = "IncludeOptional";
            MappedTypeModifiers[MappedTypeModifiers["ExcludeOptional"] = 8] = "ExcludeOptional";
        })(MappedTypeModifiers || (MappedTypeModifiers = {}));
        var ExpandingFlags;
        (function (ExpandingFlags) {
            ExpandingFlags[ExpandingFlags["None"] = 0] = "None";
            ExpandingFlags[ExpandingFlags["Source"] = 1] = "Source";
            ExpandingFlags[ExpandingFlags["Target"] = 2] = "Target";
            ExpandingFlags[ExpandingFlags["Both"] = 3] = "Both";
        })(ExpandingFlags || (ExpandingFlags = {}));
        var MembersOrExportsResolutionKind;
        (function (MembersOrExportsResolutionKind) {
            MembersOrExportsResolutionKind["resolvedExports"] = "resolvedExports";
            MembersOrExportsResolutionKind["resolvedMembers"] = "resolvedMembers";
        })(MembersOrExportsResolutionKind || (MembersOrExportsResolutionKind = {}));
        var UnusedKind;
        (function (UnusedKind) {
            UnusedKind[UnusedKind["Local"] = 0] = "Local";
            UnusedKind[UnusedKind["Parameter"] = 1] = "Parameter";
        })(UnusedKind || (UnusedKind = {}));
        var builtinGlobals = ts.createSymbolTable();
        builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol);
        var isNotOverloadAndNotAccessor = ts.and(isNotOverload, isNotAccessor);
        initializeTypeChecker();
        return checker;
        function getJsxNamespace(location) {
            if (location) {
                var file = ts.getSourceFileOfNode(location);
                if (file) {
                    if (file.localJsxNamespace) {
                        return file.localJsxNamespace;
                    }
                    var jsxPragma = file.pragmas.get("jsx");
                    if (jsxPragma) {
                        var chosenpragma = ts.isArray(jsxPragma) ? jsxPragma[0] : jsxPragma; // TODO: GH#18217
                        file.localJsxFactory = ts.parseIsolatedEntityName(chosenpragma.arguments.factory, languageVersion);
                        if (file.localJsxFactory) {
                            return file.localJsxNamespace = getFirstIdentifier(file.localJsxFactory).escapedText;
                        }
                    }
                }
            }
            if (!_jsxNamespace) {
                _jsxNamespace = "React";
                if (compilerOptions.jsxFactory) {
                    _jsxFactoryEntity = ts.parseIsolatedEntityName(compilerOptions.jsxFactory, languageVersion);
                    if (_jsxFactoryEntity) {
                        _jsxNamespace = getFirstIdentifier(_jsxFactoryEntity).escapedText;
                    }
                }
                else if (compilerOptions.reactNamespace) {
                    _jsxNamespace = ts.escapeLeadingUnderscores(compilerOptions.reactNamespace);
                }
            }
            return _jsxNamespace;
        }
        function getEmitResolver(sourceFile, cancellationToken) {
            // Ensure we have all the type information in place for this file so that all the
            // emitter questions of this resolver will return the right information.
            getDiagnostics(sourceFile, cancellationToken);
            return emitResolver;
        }
        function lookupOrIssueError(location, message, arg0, arg1, arg2, arg3) {
            var diagnostic = location
                ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3)
                : ts.createCompilerDiagnostic(message, arg0, arg1, arg2, arg3);
            var existing = diagnostics.lookup(diagnostic);
            if (existing) {
                return existing;
            }
            else {
                diagnostics.add(diagnostic);
                return diagnostic;
            }
        }
        function error(location, message, arg0, arg1, arg2, arg3) {
            var diagnostic = location
                ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3)
                : ts.createCompilerDiagnostic(message, arg0, arg1, arg2, arg3);
            diagnostics.add(diagnostic);
            return diagnostic;
        }
        function addErrorOrSuggestion(isError, diagnostic) {
            if (isError) {
                diagnostics.add(diagnostic);
            }
            else {
                suggestionDiagnostics.add(diagnostic.file.fileName, __assign({}, diagnostic, { category: ts.DiagnosticCategory.Suggestion }));
            }
        }
        function errorOrSuggestion(isError, location, message, arg0, arg1, arg2, arg3) {
            addErrorOrSuggestion(isError, "message" in message ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) : ts.createDiagnosticForNodeFromMessageChain(location, message));
        }
        function createSymbol(flags, name, checkFlags) {
            symbolCount++;
            var symbol = (new Symbol(flags | 33554432 /* Transient */, name));
            symbol.checkFlags = checkFlags || 0;
            return symbol;
        }
        function isTransientSymbol(symbol) {
            return (symbol.flags & 33554432 /* Transient */) !== 0;
        }
        function getExcludedSymbolFlags(flags) {
            var result = 0;
            if (flags & 2 /* BlockScopedVariable */)
                result |= 67220415 /* BlockScopedVariableExcludes */;
            if (flags & 1 /* FunctionScopedVariable */)
                result |= 67220414 /* FunctionScopedVariableExcludes */;
            if (flags & 4 /* Property */)
                result |= 0 /* PropertyExcludes */;
            if (flags & 8 /* EnumMember */)
                result |= 68008959 /* EnumMemberExcludes */;
            if (flags & 16 /* Function */)
                result |= 67219887 /* FunctionExcludes */;
            if (flags & 32 /* Class */)
                result |= 68008383 /* ClassExcludes */;
            if (flags & 64 /* Interface */)
                result |= 67897736 /* InterfaceExcludes */;
            if (flags & 256 /* RegularEnum */)
                result |= 68008191 /* RegularEnumExcludes */;
            if (flags & 128 /* ConstEnum */)
                result |= 68008831 /* ConstEnumExcludes */;
            if (flags & 512 /* ValueModule */)
                result |= 110735 /* ValueModuleExcludes */;
            if (flags & 8192 /* Method */)
                result |= 67212223 /* MethodExcludes */;
            if (flags & 32768 /* GetAccessor */)
                result |= 67154879 /* GetAccessorExcludes */;
            if (flags & 65536 /* SetAccessor */)
                result |= 67187647 /* SetAccessorExcludes */;
            if (flags & 262144 /* TypeParameter */)
                result |= 67635688 /* TypeParameterExcludes */;
            if (flags & 524288 /* TypeAlias */)
                result |= 67897832 /* TypeAliasExcludes */;
            if (flags & 2097152 /* Alias */)
                result |= 2097152 /* AliasExcludes */;
            return result;
        }
        function recordMergedSymbol(target, source) {
            if (!source.mergeId) {
                source.mergeId = nextMergeId;
                nextMergeId++;
            }
            mergedSymbols[source.mergeId] = target;
        }
        function cloneSymbol(symbol) {
            var result = createSymbol(symbol.flags, symbol.escapedName);
            result.declarations = symbol.declarations ? symbol.declarations.slice() : [];
            result.parent = symbol.parent;
            if (symbol.valueDeclaration)
                result.valueDeclaration = symbol.valueDeclaration;
            if (symbol.constEnumOnlyModule)
                result.constEnumOnlyModule = true;
            if (symbol.members)
                result.members = ts.cloneMap(symbol.members);
            if (symbol.exports)
                result.exports = ts.cloneMap(symbol.exports);
            recordMergedSymbol(result, symbol);
            return result;
        }
        /**
         * Note: if target is transient, then it is mutable, and mergeSymbol with both mutate and return it.
         * If target is not transient, mergeSymbol will produce a transient clone, mutate that and return it.
         */
        function mergeSymbol(target, source, unidirectional) {
            if (unidirectional === void 0) { unidirectional = false; }
            if (!(target.flags & getExcludedSymbolFlags(source.flags)) ||
                (source.flags | target.flags) & 67108864 /* Assignment */) {
                ts.Debug.assert(source !== target);
                if (!(target.flags & 33554432 /* Transient */)) {
                    var resolvedTarget = resolveSymbol(target);
                    if (resolvedTarget === unknownSymbol) {
                        return source;
                    }
                    target = cloneSymbol(resolvedTarget);
                }
                // Javascript static-property-assignment declarations always merge, even though they are also values
                if (source.flags & 512 /* ValueModule */ && target.flags & 512 /* ValueModule */ && target.constEnumOnlyModule && !source.constEnumOnlyModule) {
                    // reset flag when merging instantiated module into value module that has only const enums
                    target.constEnumOnlyModule = false;
                }
                target.flags |= source.flags;
                if (source.valueDeclaration &&
                    (!target.valueDeclaration ||
                        ts.isAssignmentDeclaration(target.valueDeclaration) && !ts.isAssignmentDeclaration(source.valueDeclaration) ||
                        ts.isEffectiveModuleDeclaration(target.valueDeclaration) && !ts.isEffectiveModuleDeclaration(source.valueDeclaration))) {
                    // other kinds of value declarations take precedence over modules and assignment declarations
                    target.valueDeclaration = source.valueDeclaration;
                }
                ts.addRange(target.declarations, source.declarations);
                if (source.members) {
                    if (!target.members)
                        target.members = ts.createSymbolTable();
                    mergeSymbolTable(target.members, source.members, unidirectional);
                }
                if (source.exports) {
                    if (!target.exports)
                        target.exports = ts.createSymbolTable();
                    mergeSymbolTable(target.exports, source.exports, unidirectional);
                }
                if (!unidirectional) {
                    recordMergedSymbol(target, source);
                }
            }
            else if (target.flags & 1024 /* NamespaceModule */) {
                // Do not report an error when merging `var globalThis` with the built-in `globalThis`,
                // as we will already report a "Declaration name conflicts..." error, and this error
                // won't make much sense.
                if (target !== globalThisSymbol) {
                    error(ts.getNameOfDeclaration(source.declarations[0]), ts.Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target));
                }
            }
            else { // error
                var isEitherEnum = !!(target.flags & 384 /* Enum */ || source.flags & 384 /* Enum */);
                var isEitherBlockScoped_1 = !!(target.flags & 2 /* BlockScopedVariable */ || source.flags & 2 /* BlockScopedVariable */);
                var message = isEitherEnum
                    ? ts.Diagnostics.Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations
                    : isEitherBlockScoped_1
                        ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0
                        : ts.Diagnostics.Duplicate_identifier_0;
                var sourceSymbolFile = source.declarations && ts.getSourceFileOfNode(source.declarations[0]);
                var targetSymbolFile = target.declarations && ts.getSourceFileOfNode(target.declarations[0]);
                var symbolName_1 = symbolToString(source);
                // Collect top-level duplicate identifier errors into one mapping, so we can then merge their diagnostics if there are a bunch
                if (sourceSymbolFile && targetSymbolFile && amalgamatedDuplicates && !isEitherEnum && sourceSymbolFile !== targetSymbolFile) {
                    var firstFile_1 = ts.comparePaths(sourceSymbolFile.path, targetSymbolFile.path) === -1 /* LessThan */ ? sourceSymbolFile : targetSymbolFile;
                    var secondFile_1 = firstFile_1 === sourceSymbolFile ? targetSymbolFile : sourceSymbolFile;
                    var filesDuplicates = ts.getOrUpdate(amalgamatedDuplicates, firstFile_1.path + "|" + secondFile_1.path, function () {
                        return ({ firstFile: firstFile_1, secondFile: secondFile_1, conflictingSymbols: ts.createMap() });
                    });
                    var conflictingSymbolInfo = ts.getOrUpdate(filesDuplicates.conflictingSymbols, symbolName_1, function () {
                        return ({ isBlockScoped: isEitherBlockScoped_1, firstFileLocations: [], secondFileLocations: [] });
                    });
                    addDuplicateLocations(conflictingSymbolInfo.firstFileLocations, source);
                    addDuplicateLocations(conflictingSymbolInfo.secondFileLocations, target);
                }
                else {
                    addDuplicateDeclarationErrorsForSymbols(source, message, symbolName_1, target);
                    addDuplicateDeclarationErrorsForSymbols(target, message, symbolName_1, source);
                }
            }
            return target;
            function addDuplicateLocations(locs, symbol) {
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    ts.pushIfUnique(locs, (ts.getExpandoInitializer(decl, /*isPrototypeAssignment*/ false) ? ts.getNameOfExpando(decl) : ts.getNameOfDeclaration(decl)) || decl);
                }
            }
        }
        function addDuplicateDeclarationErrorsForSymbols(target, message, symbolName, source) {
            ts.forEach(target.declarations, function (node) {
                var errorNode = (ts.getExpandoInitializer(node, /*isPrototypeAssignment*/ false) ? ts.getNameOfExpando(node) : ts.getNameOfDeclaration(node)) || node;
                addDuplicateDeclarationError(errorNode, message, symbolName, source.declarations);
            });
        }
        function addDuplicateDeclarationError(errorNode, message, symbolName, relatedNodes) {
            var err = lookupOrIssueError(errorNode, message, symbolName);
            for (var _i = 0, _a = relatedNodes || ts.emptyArray; _i < _a.length; _i++) {
                var relatedNode = _a[_i];
                err.relatedInformation = err.relatedInformation || [];
                if (ts.length(err.relatedInformation) >= 5)
                    continue;
                ts.addRelatedInfo(err, !ts.length(err.relatedInformation) ? ts.createDiagnosticForNode(relatedNode, ts.Diagnostics._0_was_also_declared_here, symbolName) : ts.createDiagnosticForNode(relatedNode, ts.Diagnostics.and_here));
            }
        }
        function combineSymbolTables(first, second) {
            if (!ts.hasEntries(first))
                return second;
            if (!ts.hasEntries(second))
                return first;
            var combined = ts.createSymbolTable();
            mergeSymbolTable(combined, first);
            mergeSymbolTable(combined, second);
            return combined;
        }
        function mergeSymbolTable(target, source, unidirectional) {
            if (unidirectional === void 0) { unidirectional = false; }
            source.forEach(function (sourceSymbol, id) {
                var targetSymbol = target.get(id);
                target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol, unidirectional) : sourceSymbol);
            });
        }
        function mergeModuleAugmentation(moduleName) {
            var moduleAugmentation = moduleName.parent;
            if (moduleAugmentation.symbol.declarations[0] !== moduleAugmentation) {
                // this is a combined symbol for multiple augmentations within the same file.
                // its symbol already has accumulated information for all declarations
                // so we need to add it just once - do the work only for first declaration
                ts.Debug.assert(moduleAugmentation.symbol.declarations.length > 1);
                return;
            }
            if (ts.isGlobalScopeAugmentation(moduleAugmentation)) {
                mergeSymbolTable(globals, moduleAugmentation.symbol.exports);
            }
            else {
                // find a module that about to be augmented
                // do not validate names of augmentations that are defined in ambient context
                var moduleNotFoundError = !(moduleName.parent.parent.flags & 4194304 /* Ambient */)
                    ? ts.Diagnostics.Invalid_module_name_in_augmentation_module_0_cannot_be_found
                    : undefined;
                var mainModule_1 = resolveExternalModuleNameWorker(moduleName, moduleName, moduleNotFoundError, /*isForAugmentation*/ true);
                if (!mainModule_1) {
                    return;
                }
                // obtain item referenced by 'export='
                mainModule_1 = resolveExternalModuleSymbol(mainModule_1);
                if (mainModule_1.flags & 1920 /* Namespace */) {
                    // If we’re merging an augmentation to a pattern ambient module, we want to
                    // perform the merge unidirectionally from the augmentation ('a.foo') to
                    // the pattern ('*.foo'), so that 'getMergedSymbol()' on a.foo gives you
                    // all the exports both from the pattern and from the augmentation, but
                    // 'getMergedSymbol()' on *.foo only gives you exports from *.foo.
                    if (ts.some(patternAmbientModules, function (module) { return mainModule_1 === module.symbol; })) {
                        var merged = mergeSymbol(moduleAugmentation.symbol, mainModule_1, /*unidirectional*/ true);
                        if (!patternAmbientModuleAugmentations) {
                            patternAmbientModuleAugmentations = ts.createMap();
                        }
                        // moduleName will be a StringLiteral since this is not `declare global`.
                        patternAmbientModuleAugmentations.set(moduleName.text, merged);
                    }
                    else {
                        mergeSymbol(mainModule_1, moduleAugmentation.symbol);
                    }
                }
                else {
                    // moduleName will be a StringLiteral since this is not `declare global`.
                    error(moduleName, ts.Diagnostics.Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity, moduleName.text);
                }
            }
        }
        function addToSymbolTable(target, source, message) {
            source.forEach(function (sourceSymbol, id) {
                var targetSymbol = target.get(id);
                if (targetSymbol) {
                    // Error on redeclarations
                    ts.forEach(targetSymbol.declarations, addDeclarationDiagnostic(ts.unescapeLeadingUnderscores(id), message));
                }
                else {
                    target.set(id, sourceSymbol);
                }
            });
            function addDeclarationDiagnostic(id, message) {
                return function (declaration) { return diagnostics.add(ts.createDiagnosticForNode(declaration, message, id)); };
            }
        }
        function getSymbolLinks(symbol) {
            if (symbol.flags & 33554432 /* Transient */)
                return symbol;
            var id = getSymbolId(symbol);
            return symbolLinks[id] || (symbolLinks[id] = {});
        }
        function getNodeLinks(node) {
            var nodeId = getNodeId(node);
            return nodeLinks[nodeId] || (nodeLinks[nodeId] = { flags: 0 });
        }
        function isGlobalSourceFile(node) {
            return node.kind === 285 /* SourceFile */ && !ts.isExternalOrCommonJsModule(node);
        }
        function getSymbol(symbols, name, meaning) {
            if (meaning) {
                var symbol = symbols.get(name);
                if (symbol) {
                    ts.Debug.assert((ts.getCheckFlags(symbol) & 1 /* Instantiated */) === 0, "Should never get an instantiated symbol here.");
                    if (symbol.flags & meaning) {
                        return symbol;
                    }
                    if (symbol.flags & 2097152 /* Alias */) {
                        var target = resolveAlias(symbol);
                        // Unknown symbol means an error occurred in alias resolution, treat it as positive answer to avoid cascading errors
                        if (target === unknownSymbol || target.flags & meaning) {
                            return symbol;
                        }
                    }
                }
            }
            // return undefined if we can't find a symbol.
        }
        /**
         * Get symbols that represent parameter-property-declaration as parameter and as property declaration
         * @param parameter a parameterDeclaration node
         * @param parameterName a name of the parameter to get the symbols for.
         * @return a tuple of two symbols
         */
        function getSymbolsOfParameterPropertyDeclaration(parameter, parameterName) {
            var constructorDeclaration = parameter.parent;
            var classDeclaration = parameter.parent.parent;
            var parameterSymbol = getSymbol(constructorDeclaration.locals, parameterName, 67220415 /* Value */);
            var propertySymbol = getSymbol(getMembersOfSymbol(classDeclaration.symbol), parameterName, 67220415 /* Value */);
            if (parameterSymbol && propertySymbol) {
                return [parameterSymbol, propertySymbol];
            }
            return ts.Debug.fail("There should exist two symbols, one as property declaration and one as parameter declaration");
        }
        function isBlockScopedNameDeclaredBeforeUse(declaration, usage) {
            var declarationFile = ts.getSourceFileOfNode(declaration);
            var useFile = ts.getSourceFileOfNode(usage);
            if (declarationFile !== useFile) {
                if ((moduleKind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) ||
                    (!compilerOptions.outFile && !compilerOptions.out) ||
                    isInTypeQuery(usage) ||
                    declaration.flags & 4194304 /* Ambient */) {
                    // nodes are in different files and order cannot be determined
                    return true;
                }
                // declaration is after usage
                // can be legal if usage is deferred (i.e. inside function or in initializer of instance property)
                if (isUsedInFunctionOrInstanceProperty(usage, declaration)) {
                    return true;
                }
                var sourceFiles = host.getSourceFiles();
                return sourceFiles.indexOf(declarationFile) <= sourceFiles.indexOf(useFile);
            }
            if (declaration.pos <= usage.pos) {
                // declaration is before usage
                if (declaration.kind === 187 /* BindingElement */) {
                    // still might be illegal if declaration and usage are both binding elements (eg var [a = b, b = b] = [1, 2])
                    var errorBindingElement = ts.getAncestor(usage, 187 /* BindingElement */);
                    if (errorBindingElement) {
                        return ts.findAncestor(errorBindingElement, ts.isBindingElement) !== ts.findAncestor(declaration, ts.isBindingElement) ||
                            declaration.pos < errorBindingElement.pos;
                    }
                    // or it might be illegal if usage happens before parent variable is declared (eg var [a] = a)
                    return isBlockScopedNameDeclaredBeforeUse(ts.getAncestor(declaration, 238 /* VariableDeclaration */), usage);
                }
                else if (declaration.kind === 238 /* VariableDeclaration */) {
                    // still might be illegal if usage is in the initializer of the variable declaration (eg var a = a)
                    return !isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage);
                }
                else if (ts.isClassDeclaration(declaration)) {
                    // still might be illegal if the usage is within a computed property name in the class (eg class A { static p = "a"; [A.p]() {} })
                    return !ts.findAncestor(usage, function (n) { return ts.isComputedPropertyName(n) && n.parent.parent === declaration; });
                }
                else if (ts.isPropertyDeclaration(declaration)) {
                    // still might be illegal if a self-referencing property initializer (eg private x = this.x)
                    return !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage);
                }
                return true;
            }
            // declaration is after usage, but it can still be legal if usage is deferred:
            // 1. inside an export specifier
            // 2. inside a function
            // 3. inside an instance property initializer, a reference to a non-instance property
            // 4. inside a static property initializer, a reference to a static method in the same class
            // 5. inside a TS export= declaration (since we will move the export statement during emit to avoid TDZ)
            // or if usage is in a type context:
            // 1. inside a type query (typeof in type position)
            // 2. inside a jsdoc comment
            if (usage.parent.kind === 258 /* ExportSpecifier */ || (usage.parent.kind === 255 /* ExportAssignment */ && usage.parent.isExportEquals)) {
                // export specifiers do not use the variable, they only make it available for use
                return true;
            }
            // When resolving symbols for exports, the `usage` location passed in can be the export site directly
            if (usage.kind === 255 /* ExportAssignment */ && usage.isExportEquals) {
                return true;
            }
            var container = ts.getEnclosingBlockScopeContainer(declaration);
            return !!(usage.flags & 2097152 /* JSDoc */) || isInTypeQuery(usage) || isUsedInFunctionOrInstanceProperty(usage, declaration, container);
            function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage) {
                var container = ts.getEnclosingBlockScopeContainer(declaration);
                switch (declaration.parent.parent.kind) {
                    case 220 /* VariableStatement */:
                    case 226 /* ForStatement */:
                    case 228 /* ForOfStatement */:
                        // variable statement/for/for-of statement case,
                        // use site should not be inside variable declaration (initializer of declaration or binding element)
                        if (isSameScopeDescendentOf(usage, declaration, container)) {
                            return true;
                        }
                        break;
                }
                // ForIn/ForOf case - use site should not be used in expression part
                var grandparent = declaration.parent.parent;
                return ts.isForInOrOfStatement(grandparent) && isSameScopeDescendentOf(usage, grandparent.expression, container);
            }
            function isUsedInFunctionOrInstanceProperty(usage, declaration, container) {
                return !!ts.findAncestor(usage, function (current) {
                    if (current === container) {
                        return "quit";
                    }
                    if (ts.isFunctionLike(current)) {
                        return true;
                    }
                    var initializerOfProperty = current.parent &&
                        current.parent.kind === 155 /* PropertyDeclaration */ &&
                        current.parent.initializer === current;
                    if (initializerOfProperty) {
                        if (ts.hasModifier(current.parent, 32 /* Static */)) {
                            if (declaration.kind === 157 /* MethodDeclaration */) {
                                return true;
                            }
                        }
                        else {
                            var isDeclarationInstanceProperty = declaration.kind === 155 /* PropertyDeclaration */ && !ts.hasModifier(declaration, 32 /* Static */);
                            if (!isDeclarationInstanceProperty || ts.getContainingClass(usage) !== ts.getContainingClass(declaration)) {
                                return true;
                            }
                        }
                    }
                    return false;
                });
            }
            function isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage) {
                // always legal if usage is after declaration
                if (usage.end > declaration.end) {
                    return false;
                }
                // still might be legal if usage is deferred (e.g. x: any = () => this.x)
                // otherwise illegal if immediately referenced within the declaration (e.g. x: any = this.x)
                var ancestorChangingReferenceScope = ts.findAncestor(usage, function (node) {
                    if (node === declaration) {
                        return "quit";
                    }
                    switch (node.kind) {
                        case 198 /* ArrowFunction */:
                        case 155 /* PropertyDeclaration */:
                            return true;
                        case 219 /* Block */:
                            switch (node.parent.kind) {
                                case 159 /* GetAccessor */:
                                case 157 /* MethodDeclaration */:
                                case 160 /* SetAccessor */:
                                    return true;
                                default:
                                    return false;
                            }
                        default:
                            return false;
                    }
                });
                return ancestorChangingReferenceScope === undefined;
            }
        }
        /**
         * Resolve a given name for a given meaning at a given location. An error is reported if the name was not found and
         * the nameNotFoundMessage argument is not undefined. Returns the resolved symbol, or undefined if no symbol with
         * the given name can be found.
         *
         * @param isUse If true, this will count towards --noUnusedLocals / --noUnusedParameters.
         */
        function resolveName(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, suggestedNameNotFoundMessage) {
            if (excludeGlobals === void 0) { excludeGlobals = false; }
            return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSymbol, suggestedNameNotFoundMessage);
        }
        function resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, lookup, suggestedNameNotFoundMessage) {
            var originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location
            var result;
            var lastLocation;
            var lastSelfReferenceLocation;
            var propertyWithInvalidInitializer;
            var associatedDeclarationForContainingInitializer;
            var withinDeferredContext = false;
            var errorLocation = location;
            var grandparent;
            var isInExternalModule = false;
            loop: while (location) {
                // Locals of a source file are not in scope (because they get merged into the global symbol table)
                if (location.locals && !isGlobalSourceFile(location)) {
                    if (result = lookup(location.locals, name, meaning)) {
                        var useResult = true;
                        if (ts.isFunctionLike(location) && lastLocation && lastLocation !== location.body) {
                            // symbol lookup restrictions for function-like declarations
                            // - Type parameters of a function are in scope in the entire function declaration, including the parameter
                            //   list and return type. However, local types are only in scope in the function body.
                            // - parameters are only in the scope of function body
                            // This restriction does not apply to JSDoc comment types because they are parented
                            // at a higher level than type parameters would normally be
                            if (meaning & result.flags & 67897832 /* Type */ && lastLocation.kind !== 297 /* JSDocComment */) {
                                useResult = result.flags & 262144 /* TypeParameter */
                                    // type parameters are visible in parameter list, return type and type parameter list
                                    ? lastLocation === location.type ||
                                        lastLocation.kind === 152 /* Parameter */ ||
                                        lastLocation.kind === 151 /* TypeParameter */
                                    // local types not visible outside the function body
                                    : false;
                            }
                            if (meaning & result.flags & 3 /* Variable */) {
                                // expression inside parameter will lookup as normal variable scope when targeting es2015+
                                var functionLocation = location;
                                if (compilerOptions.target && compilerOptions.target >= 2 /* ES2015 */ && ts.isParameter(lastLocation) &&
                                    functionLocation.body && result.valueDeclaration.pos >= functionLocation.body.pos && result.valueDeclaration.end <= functionLocation.body.end) {
                                    useResult = false;
                                }
                                else if (result.flags & 1 /* FunctionScopedVariable */) {
                                    // parameters are visible only inside function body, parameter list and return type
                                    // technically for parameter list case here we might mix parameters and variables declared in function,
                                    // however it is detected separately when checking initializers of parameters
                                    // to make sure that they reference no variables declared after them.
                                    useResult =
                                        lastLocation.kind === 152 /* Parameter */ ||
                                            (lastLocation === location.type &&
                                                !!ts.findAncestor(result.valueDeclaration, ts.isParameter));
                                }
                            }
                        }
                        else if (location.kind === 176 /* ConditionalType */) {
                            // A type parameter declared using 'infer T' in a conditional type is visible only in
                            // the true branch of the conditional type.
                            useResult = lastLocation === location.trueType;
                        }
                        if (useResult) {
                            break loop;
                        }
                        else {
                            result = undefined;
                        }
                    }
                }
                withinDeferredContext = withinDeferredContext || getIsDeferredContext(location, lastLocation);
                switch (location.kind) {
                    case 285 /* SourceFile */:
                        if (!ts.isExternalOrCommonJsModule(location))
                            break;
                        isInExternalModule = true;
                    // falls through
                    case 245 /* ModuleDeclaration */:
                        var moduleExports = getSymbolOfNode(location).exports;
                        if (location.kind === 285 /* SourceFile */ || ts.isAmbientModule(location)) {
                            // It's an external module. First see if the module has an export default and if the local
                            // name of that export default matches.
                            if (result = moduleExports.get("default" /* Default */)) {
                                var localSymbol = ts.getLocalSymbolForExportDefault(result);
                                if (localSymbol && (result.flags & meaning) && localSymbol.escapedName === name) {
                                    break loop;
                                }
                                result = undefined;
                            }
                            // Because of module/namespace merging, a module's exports are in scope,
                            // yet we never want to treat an export specifier as putting a member in scope.
                            // Therefore, if the name we find is purely an export specifier, it is not actually considered in scope.
                            // Two things to note about this:
                            //     1. We have to check this without calling getSymbol. The problem with calling getSymbol
                            //        on an export specifier is that it might find the export specifier itself, and try to
                            //        resolve it as an alias. This will cause the checker to consider the export specifier
                            //        a circular alias reference when it might not be.
                            //     2. We check === SymbolFlags.Alias in order to check that the symbol is *purely*
                            //        an alias. If we used &, we'd be throwing out symbols that have non alias aspects,
                            //        which is not the desired behavior.
                            var moduleExport = moduleExports.get(name);
                            if (moduleExport &&
                                moduleExport.flags === 2097152 /* Alias */ &&
                                ts.getDeclarationOfKind(moduleExport, 258 /* ExportSpecifier */)) {
                                break;
                            }
                        }
                        // ES6 exports are also visible locally (except for 'default'), but commonjs exports are not (except typedefs)
                        if (name !== "default" /* Default */ && (result = lookup(moduleExports, name, meaning & 2623475 /* ModuleMember */))) {
                            if (ts.isSourceFile(location) && location.commonJsModuleIndicator && !result.declarations.some(ts.isJSDocTypeAlias)) {
                                result = undefined;
                            }
                            else {
                                break loop;
                            }
                        }
                        break;
                    case 244 /* EnumDeclaration */:
                        if (result = lookup(getSymbolOfNode(location).exports, name, meaning & 8 /* EnumMember */)) {
                            break loop;
                        }
                        break;
                    case 155 /* PropertyDeclaration */:
                        // TypeScript 1.0 spec (April 2014): 8.4.1
                        // Initializer expressions for instance member variables are evaluated in the scope
                        // of the class constructor body but are not permitted to reference parameters or
                        // local variables of the constructor. This effectively means that entities from outer scopes
                        // by the same name as a constructor parameter or local variable are inaccessible
                        // in initializer expressions for instance member variables.
                        if (!ts.hasModifier(location, 32 /* Static */)) {
                            var ctor = findConstructorDeclaration(location.parent);
                            if (ctor && ctor.locals) {
                                if (lookup(ctor.locals, name, meaning & 67220415 /* Value */)) {
                                    // Remember the property node, it will be used later to report appropriate error
                                    propertyWithInvalidInitializer = location;
                                }
                            }
                        }
                        break;
                    case 241 /* ClassDeclaration */:
                    case 210 /* ClassExpression */:
                    case 242 /* InterfaceDeclaration */:
                        // The below is used to lookup type parameters within a class or interface, as they are added to the class/interface locals
                        // These can never be latebound, so the symbol's raw members are sufficient. `getMembersOfNode` cannot be used, as it would
                        // trigger resolving late-bound names, which we may already be in the process of doing while we're here!
                        if (result = lookup(getSymbolOfNode(location).members || emptySymbols, name, meaning & 67897832 /* Type */)) {
                            if (!isTypeParameterSymbolDeclaredInContainer(result, location)) {
                                // ignore type parameters not declared in this container
                                result = undefined;
                                break;
                            }
                            if (lastLocation && ts.hasModifier(lastLocation, 32 /* Static */)) {
                                // TypeScript 1.0 spec (April 2014): 3.4.1
                                // The scope of a type parameter extends over the entire declaration with which the type
                                // parameter list is associated, with the exception of static member declarations in classes.
                                error(errorLocation, ts.Diagnostics.Static_members_cannot_reference_class_type_parameters);
                                return undefined;
                            }
                            break loop;
                        }
                        if (location.kind === 210 /* ClassExpression */ && meaning & 32 /* Class */) {
                            var className = location.name;
                            if (className && name === className.escapedText) {
                                result = location.symbol;
                                break loop;
                            }
                        }
                        break;
                    case 212 /* ExpressionWithTypeArguments */:
                        // The type parameters of a class are not in scope in the base class expression.
                        if (lastLocation === location.expression && location.parent.token === 87 /* ExtendsKeyword */) {
                            var container = location.parent.parent;
                            if (ts.isClassLike(container) && (result = lookup(getSymbolOfNode(container).members, name, meaning & 67897832 /* Type */))) {
                                if (nameNotFoundMessage) {
                                    error(errorLocation, ts.Diagnostics.Base_class_expressions_cannot_reference_class_type_parameters);
                                }
                                return undefined;
                            }
                        }
                        break;
                    // It is not legal to reference a class's own type parameters from a computed property name that
                    // belongs to the class. For example:
                    //
                    //   function foo<T>() { return '' }
                    //   class C<T> { // <-- Class's own type parameter T
                    //       [foo<T>()]() { } // <-- Reference to T from class's own computed property
                    //   }
                    //
                    case 150 /* ComputedPropertyName */:
                        grandparent = location.parent.parent;
                        if (ts.isClassLike(grandparent) || grandparent.kind === 242 /* InterfaceDeclaration */) {
                            // A reference to this grandparent's type parameters would be an error
                            if (result = lookup(getSymbolOfNode(grandparent).members, name, meaning & 67897832 /* Type */)) {
                                error(errorLocation, ts.Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type);
                                return undefined;
                            }
                        }
                        break;
                    case 198 /* ArrowFunction */:
                        // when targeting ES6 or higher there is no 'arguments' in an arrow function
                        // for lower compile targets the resolved symbol is used to emit an error
                        if (compilerOptions.target >= 2 /* ES2015 */) {
                            break;
                        }
                    // falls through
                    case 157 /* MethodDeclaration */:
                    case 158 /* Constructor */:
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                    case 240 /* FunctionDeclaration */:
                        if (meaning & 3 /* Variable */ && name === "arguments") {
                            result = argumentsSymbol;
                            break loop;
                        }
                        break;
                    case 197 /* FunctionExpression */:
                        if (meaning & 3 /* Variable */ && name === "arguments") {
                            result = argumentsSymbol;
                            break loop;
                        }
                        if (meaning & 16 /* Function */) {
                            var functionName = location.name;
                            if (functionName && name === functionName.escapedText) {
                                result = location.symbol;
                                break loop;
                            }
                        }
                        break;
                    case 153 /* Decorator */:
                        // Decorators are resolved at the class declaration. Resolving at the parameter
                        // or member would result in looking up locals in the method.
                        //
                        //   function y() {}
                        //   class C {
                        //       method(@y x, y) {} // <-- decorator y should be resolved at the class declaration, not the parameter.
                        //   }
                        //
                        if (location.parent && location.parent.kind === 152 /* Parameter */) {
                            location = location.parent;
                        }
                        //
                        //   function y() {}
                        //   class C {
                        //       @y method(x, y) {} // <-- decorator y should be resolved at the class declaration, not the method.
                        //   }
                        //
                        // class Decorators are resolved outside of the class to avoid referencing type parameters of that class.
                        //
                        //   type T = number;
                        //   declare function y(x: T): any;
                        //   @param(1 as T) // <-- T should resolve to the type alias outside of class C
                        //   class C<T> {}
                        if (location.parent && (ts.isClassElement(location.parent) || location.parent.kind === 241 /* ClassDeclaration */)) {
                            location = location.parent;
                        }
                        break;
                    case 310 /* JSDocTypedefTag */:
                    case 303 /* JSDocCallbackTag */:
                        // js type aliases do not resolve names from their host, so skip past it
                        location = ts.getJSDocHost(location);
                        break;
                    case 152 /* Parameter */:
                        if (lastLocation && lastLocation === location.initializer) {
                            associatedDeclarationForContainingInitializer = location;
                        }
                        break;
                    case 187 /* BindingElement */:
                        if (lastLocation && lastLocation === location.initializer) {
                            var root = ts.getRootDeclaration(location);
                            if (root.kind === 152 /* Parameter */) {
                                associatedDeclarationForContainingInitializer = location;
                            }
                        }
                        break;
                }
                if (isSelfReferenceLocation(location)) {
                    lastSelfReferenceLocation = location;
                }
                lastLocation = location;
                location = location.parent;
            }
            // We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`.
            // If `result === lastSelfReferenceLocation.symbol`, that means that we are somewhere inside `lastSelfReferenceLocation` looking up a name, and resolving to `lastLocation` itself.
            // That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used.
            if (isUse && result && (!lastSelfReferenceLocation || result !== lastSelfReferenceLocation.symbol)) {
                result.isReferenced |= meaning;
            }
            if (!result) {
                if (lastLocation) {
                    ts.Debug.assert(lastLocation.kind === 285 /* SourceFile */);
                    if (lastLocation.commonJsModuleIndicator && name === "exports" && meaning & lastLocation.symbol.flags) {
                        return lastLocation.symbol;
                    }
                }
                if (!excludeGlobals) {
                    result = lookup(globals, name, meaning);
                }
            }
            if (!result) {
                if (originalLocation && ts.isInJSFile(originalLocation) && originalLocation.parent) {
                    if (ts.isRequireCall(originalLocation.parent, /*checkArgumentIsStringLiteralLike*/ false)) {
                        return requireSymbol;
                    }
                }
            }
            if (!result) {
                if (nameNotFoundMessage) {
                    if (!errorLocation ||
                        !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) && // TODO: GH#18217
                            !checkAndReportErrorForExtendingInterface(errorLocation) &&
                            !checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) &&
                            !checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) &&
                            !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) &&
                            !checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning)) {
                        var suggestion = void 0;
                        if (suggestedNameNotFoundMessage && suggestionCount < maximumSuggestionCount) {
                            suggestion = getSuggestedSymbolForNonexistentSymbol(originalLocation, name, meaning);
                            if (suggestion) {
                                var suggestionName = symbolToString(suggestion);
                                var diagnostic = error(errorLocation, suggestedNameNotFoundMessage, diagnosticName(nameArg), suggestionName);
                                if (suggestion.valueDeclaration) {
                                    ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName));
                                }
                            }
                        }
                        if (!suggestion) {
                            error(errorLocation, nameNotFoundMessage, diagnosticName(nameArg));
                        }
                        suggestionCount++;
                    }
                }
                return undefined;
            }
            // Perform extra checks only if error reporting was requested
            if (nameNotFoundMessage) {
                if (propertyWithInvalidInitializer) {
                    // We have a match, but the reference occurred within a property initializer and the identifier also binds
                    // to a local variable in the constructor where the code will be emitted.
                    var propertyName = propertyWithInvalidInitializer.name;
                    error(errorLocation, ts.Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor, ts.declarationNameToString(propertyName), diagnosticName(nameArg));
                    return undefined;
                }
                // Only check for block-scoped variable if we have an error location and are looking for the
                // name with variable meaning
                //      For example,
                //          declare module foo {
                //              interface bar {}
                //          }
                //      const foo/*1*/: foo/*2*/.bar;
                // The foo at /*1*/ and /*2*/ will share same symbol with two meanings:
                // block-scoped variable and namespace module. However, only when we
                // try to resolve name in /*1*/ which is used in variable position,
                // we want to check for block-scoped
                if (errorLocation &&
                    (meaning & 2 /* BlockScopedVariable */ ||
                        ((meaning & 32 /* Class */ || meaning & 384 /* Enum */) && (meaning & 67220415 /* Value */) === 67220415 /* Value */))) {
                    var exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result);
                    if (exportOrLocalSymbol.flags & 2 /* BlockScopedVariable */ || exportOrLocalSymbol.flags & 32 /* Class */ || exportOrLocalSymbol.flags & 384 /* Enum */) {
                        checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation);
                    }
                }
                // If we're in an external module, we can't reference value symbols created from UMD export declarations
                if (result && isInExternalModule && (meaning & 67220415 /* Value */) === 67220415 /* Value */ && !(originalLocation.flags & 2097152 /* JSDoc */)) {
                    var merged = getMergedSymbol(result);
                    if (ts.length(merged.declarations) && ts.every(merged.declarations, function (d) { return ts.isNamespaceExportDeclaration(d) || ts.isSourceFile(d) && !!d.symbol.globalExports; })) {
                        errorOrSuggestion(!compilerOptions.allowUmdGlobalAccess, errorLocation, ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, ts.unescapeLeadingUnderscores(name));
                    }
                }
                // If we're in a parameter initializer, we can't reference the values of the parameter whose initializer we're within or parameters to the right
                if (result && associatedDeclarationForContainingInitializer && !withinDeferredContext && (meaning & 67220415 /* Value */) === 67220415 /* Value */) {
                    var candidate = getMergedSymbol(getLateBoundSymbol(result));
                    var root = ts.getRootDeclaration(associatedDeclarationForContainingInitializer);
                    // A parameter initializer or binding pattern initializer within a parameter cannot refer to itself
                    if (candidate === getSymbolOfNode(associatedDeclarationForContainingInitializer)) {
                        error(errorLocation, ts.Diagnostics.Parameter_0_cannot_be_referenced_in_its_initializer, ts.declarationNameToString(associatedDeclarationForContainingInitializer.name));
                    }
                    // And it cannot refer to any declarations which come after it
                    else if (candidate.valueDeclaration && candidate.valueDeclaration.pos > associatedDeclarationForContainingInitializer.pos && root.parent.locals && lookup(root.parent.locals, candidate.escapedName, meaning) === candidate) {
                        error(errorLocation, ts.Diagnostics.Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it, ts.declarationNameToString(associatedDeclarationForContainingInitializer.name), ts.declarationNameToString(errorLocation));
                    }
                }
            }
            return result;
        }
        function getIsDeferredContext(location, lastLocation) {
            if (location.kind !== 198 /* ArrowFunction */ && location.kind !== 197 /* FunctionExpression */) {
                // initializers in instance property declaration of class like entities are executed in constructor and thus deferred
                return ts.isTypeQueryNode(location) || ((ts.isFunctionLikeDeclaration(location) ||
                    (location.kind === 155 /* PropertyDeclaration */ && !ts.hasModifier(location, 32 /* Static */))) && (!lastLocation || lastLocation !== location.name)); // A name is evaluated within the enclosing scope - so it shouldn't count as deferred
            }
            if (lastLocation && lastLocation === location.name) {
                return false;
            }
            // generator functions and async functions are not inlined in control flow when immediately invoked
            if (location.asteriskToken || ts.hasModifier(location, 256 /* Async */)) {
                return true;
            }
            return !ts.getImmediatelyInvokedFunctionExpression(location);
        }
        function isSelfReferenceLocation(node) {
            switch (node.kind) {
                case 240 /* FunctionDeclaration */:
                case 241 /* ClassDeclaration */:
                case 242 /* InterfaceDeclaration */:
                case 244 /* EnumDeclaration */:
                case 243 /* TypeAliasDeclaration */:
                case 245 /* ModuleDeclaration */: // For `namespace N { N; }`
                    return true;
                default:
                    return false;
            }
        }
        function diagnosticName(nameArg) {
            return ts.isString(nameArg) ? ts.unescapeLeadingUnderscores(nameArg) : ts.declarationNameToString(nameArg);
        }
        function isTypeParameterSymbolDeclaredInContainer(symbol, container) {
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var decl = _a[_i];
                if (decl.kind === 151 /* TypeParameter */) {
                    var parent = ts.isJSDocTemplateTag(decl.parent) ? ts.getJSDocHost(decl.parent) : decl.parent;
                    if (parent === container) {
                        return !(ts.isJSDocTemplateTag(decl.parent) && ts.find(decl.parent.parent.tags, ts.isJSDocTypeAlias)); // TODO: GH#18217
                    }
                }
            }
            return false;
        }
        function checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) {
            if (!ts.isIdentifier(errorLocation) || errorLocation.escapedText !== name || isTypeReferenceIdentifier(errorLocation) || isInTypeQuery(errorLocation)) {
                return false;
            }
            var container = ts.getThisContainer(errorLocation, /*includeArrowFunctions*/ false);
            var location = container;
            while (location) {
                if (ts.isClassLike(location.parent)) {
                    var classSymbol = getSymbolOfNode(location.parent);
                    if (!classSymbol) {
                        break;
                    }
                    // Check to see if a static member exists.
                    var constructorType = getTypeOfSymbol(classSymbol);
                    if (getPropertyOfType(constructorType, name)) {
                        error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0, diagnosticName(nameArg), symbolToString(classSymbol));
                        return true;
                    }
                    // No static member is present.
                    // Check if we're in an instance method and look for a relevant instance member.
                    if (location === container && !ts.hasModifier(location, 32 /* Static */)) {
                        var instanceType = getDeclaredTypeOfSymbol(classSymbol).thisType; // TODO: GH#18217
                        if (getPropertyOfType(instanceType, name)) {
                            error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, diagnosticName(nameArg));
                            return true;
                        }
                    }
                }
                location = location.parent;
            }
            return false;
        }
        function checkAndReportErrorForExtendingInterface(errorLocation) {
            var expression = getEntityNameForExtendingInterface(errorLocation);
            if (expression && resolveEntityName(expression, 64 /* Interface */, /*ignoreErrors*/ true)) {
                error(errorLocation, ts.Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements, ts.getTextOfNode(expression));
                return true;
            }
            return false;
        }
        /**
         * Climbs up parents to an ExpressionWithTypeArguments, and returns its expression,
         * but returns undefined if that expression is not an EntityNameExpression.
         */
        function getEntityNameForExtendingInterface(node) {
            switch (node.kind) {
                case 73 /* Identifier */:
                case 190 /* PropertyAccessExpression */:
                    return node.parent ? getEntityNameForExtendingInterface(node.parent) : undefined;
                case 212 /* ExpressionWithTypeArguments */:
                    if (ts.isEntityNameExpression(node.expression)) {
                        return node.expression;
                    }
                // falls through
                default:
                    return undefined;
            }
        }
        function checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) {
            var namespaceMeaning = 1920 /* Namespace */ | (ts.isInJSFile(errorLocation) ? 67220415 /* Value */ : 0);
            if (meaning === namespaceMeaning) {
                var symbol = resolveSymbol(resolveName(errorLocation, name, 67897832 /* Type */ & ~namespaceMeaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                var parent = errorLocation.parent;
                if (symbol) {
                    if (ts.isQualifiedName(parent)) {
                        ts.Debug.assert(parent.left === errorLocation, "Should only be resolving left side of qualified name as a namespace");
                        var propName = parent.right.escapedText;
                        var propType = getPropertyOfType(getDeclaredTypeOfSymbol(symbol), propName);
                        if (propType) {
                            error(parent, ts.Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, ts.unescapeLeadingUnderscores(name), ts.unescapeLeadingUnderscores(propName));
                            return true;
                        }
                    }
                    error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            return false;
        }
        function checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning) {
            if (meaning & (67897832 /* Type */ & ~1920 /* Namespace */)) {
                var symbol = resolveSymbol(resolveName(errorLocation, name, ~67897832 /* Type */ & 67220415 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                if (symbol && !(symbol.flags & 1920 /* Namespace */)) {
                    error(errorLocation, ts.Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            return false;
        }
        function checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) {
            if (meaning & (67220415 /* Value */ & ~1024 /* NamespaceModule */)) {
                if (name === "any" || name === "string" || name === "number" || name === "boolean" || name === "never") {
                    error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
                var symbol = resolveSymbol(resolveName(errorLocation, name, 67897832 /* Type */ & ~67220415 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                if (symbol && !(symbol.flags & 1024 /* NamespaceModule */)) {
                    var message = isES2015OrLaterConstructorName(name)
                        ? ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later
                        : ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here;
                    error(errorLocation, message, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            return false;
        }
        function isES2015OrLaterConstructorName(n) {
            switch (n) {
                case "Promise":
                case "Symbol":
                case "Map":
                case "WeakMap":
                case "Set":
                case "WeakSet":
                    return true;
            }
            return false;
        }
        function checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) {
            if (meaning & (67220415 /* Value */ & ~1024 /* NamespaceModule */ & ~67897832 /* Type */)) {
                var symbol = resolveSymbol(resolveName(errorLocation, name, 1024 /* NamespaceModule */ & ~67220415 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                if (symbol) {
                    error(errorLocation, ts.Diagnostics.Cannot_use_namespace_0_as_a_value, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            else if (meaning & (67897832 /* Type */ & ~1024 /* NamespaceModule */ & ~67220415 /* Value */)) {
                var symbol = resolveSymbol(resolveName(errorLocation, name, (512 /* ValueModule */ | 1024 /* NamespaceModule */) & ~67897832 /* Type */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                if (symbol) {
                    error(errorLocation, ts.Diagnostics.Cannot_use_namespace_0_as_a_type, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            return false;
        }
        function checkResolvedBlockScopedVariable(result, errorLocation) {
            ts.Debug.assert(!!(result.flags & 2 /* BlockScopedVariable */ || result.flags & 32 /* Class */ || result.flags & 384 /* Enum */));
            // Block-scoped variables cannot be used before their definition
            var declaration = ts.find(result.declarations, function (d) { return ts.isBlockOrCatchScoped(d) || ts.isClassLike(d) || (d.kind === 244 /* EnumDeclaration */) || ts.isInJSFile(d) && !!ts.getJSDocEnumTag(d); });
            if (declaration === undefined)
                return ts.Debug.fail("Declaration to checkResolvedBlockScopedVariable is undefined");
            if (!(declaration.flags & 4194304 /* Ambient */) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) {
                var diagnosticMessage = void 0;
                var declarationName = ts.declarationNameToString(ts.getNameOfDeclaration(declaration));
                if (result.flags & 2 /* BlockScopedVariable */) {
                    diagnosticMessage = error(errorLocation, ts.Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationName);
                }
                else if (result.flags & 32 /* Class */) {
                    diagnosticMessage = error(errorLocation, ts.Diagnostics.Class_0_used_before_its_declaration, declarationName);
                }
                else if (result.flags & 256 /* RegularEnum */) {
                    diagnosticMessage = error(errorLocation, ts.Diagnostics.Enum_0_used_before_its_declaration, declarationName);
                }
                else {
                    ts.Debug.assert(!!(result.flags & 128 /* ConstEnum */));
                    if (compilerOptions.preserveConstEnums) {
                        diagnosticMessage = error(errorLocation, ts.Diagnostics.Class_0_used_before_its_declaration, declarationName);
                    }
                }
                if (diagnosticMessage) {
                    ts.addRelatedInfo(diagnosticMessage, ts.createDiagnosticForNode(declaration, ts.Diagnostics._0_is_declared_here, declarationName));
                }
            }
        }
        /* Starting from 'initial' node walk up the parent chain until 'stopAt' node is reached.
         * If at any point current node is equal to 'parent' node - return true.
         * Return false if 'stopAt' node is reached or isFunctionLike(current) === true.
         */
        function isSameScopeDescendentOf(initial, parent, stopAt) {
            return !!parent && !!ts.findAncestor(initial, function (n) { return n === stopAt || ts.isFunctionLike(n) ? "quit" : n === parent; });
        }
        function getAnyImportSyntax(node) {
            switch (node.kind) {
                case 249 /* ImportEqualsDeclaration */:
                    return node;
                case 251 /* ImportClause */:
                    return node.parent;
                case 252 /* NamespaceImport */:
                    return node.parent.parent;
                case 254 /* ImportSpecifier */:
                    return node.parent.parent.parent;
                default:
                    return undefined;
            }
        }
        function getDeclarationOfAliasSymbol(symbol) {
            return ts.find(symbol.declarations, ts.isAliasSymbolDeclaration);
        }
        function getTargetOfImportEqualsDeclaration(node, dontResolveAlias) {
            if (node.moduleReference.kind === 260 /* ExternalModuleReference */) {
                return resolveExternalModuleSymbol(resolveExternalModuleName(node, ts.getExternalModuleImportEqualsDeclarationExpression(node)));
            }
            return getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference, dontResolveAlias);
        }
        function resolveExportByName(moduleSymbol, name, dontResolveAlias) {
            var exportValue = moduleSymbol.exports.get("export=" /* ExportEquals */);
            return exportValue
                ? getPropertyOfType(getTypeOfSymbol(exportValue), name)
                : resolveSymbol(moduleSymbol.exports.get(name), dontResolveAlias);
        }
        function isSyntacticDefault(node) {
            return ((ts.isExportAssignment(node) && !node.isExportEquals) || ts.hasModifier(node, 512 /* Default */) || ts.isExportSpecifier(node));
        }
        function canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias) {
            if (!allowSyntheticDefaultImports) {
                return false;
            }
            // Declaration files (and ambient modules)
            if (!file || file.isDeclarationFile) {
                // Definitely cannot have a synthetic default if they have a syntactic default member specified
                var defaultExportSymbol = resolveExportByName(moduleSymbol, "default" /* Default */, /*dontResolveAlias*/ true); // Dont resolve alias because we want the immediately exported symbol's declaration
                if (defaultExportSymbol && ts.some(defaultExportSymbol.declarations, isSyntacticDefault)) {
                    return false;
                }
                // It _might_ still be incorrect to assume there is no __esModule marker on the import at runtime, even if there is no `default` member
                // So we check a bit more,
                if (resolveExportByName(moduleSymbol, ts.escapeLeadingUnderscores("__esModule"), dontResolveAlias)) {
                    // If there is an `__esModule` specified in the declaration (meaning someone explicitly added it or wrote it in their code),
                    // it definitely is a module and does not have a synthetic default
                    return false;
                }
                // There are _many_ declaration files not written with esmodules in mind that still get compiled into a format with __esModule set
                // Meaning there may be no default at runtime - however to be on the permissive side, we allow access to a synthetic default member
                // as there is no marker to indicate if the accompanying JS has `__esModule` or not, or is even native esm
                return true;
            }
            // TypeScript files never have a synthetic default (as they are always emitted with an __esModule marker) _unless_ they contain an export= statement
            if (!ts.isSourceFileJS(file)) {
                return hasExportAssignmentSymbol(moduleSymbol);
            }
            // JS files have a synthetic default if they do not contain ES2015+ module syntax (export = is not valid in js) _and_ do not have an __esModule marker
            return !file.externalModuleIndicator && !resolveExportByName(moduleSymbol, ts.escapeLeadingUnderscores("__esModule"), dontResolveAlias);
        }
        function getTargetOfImportClause(node, dontResolveAlias) {
            var moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier);
            if (moduleSymbol) {
                var exportDefaultSymbol = void 0;
                if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) {
                    exportDefaultSymbol = moduleSymbol;
                }
                else {
                    exportDefaultSymbol = resolveExportByName(moduleSymbol, "default" /* Default */, dontResolveAlias);
                }
                var file = ts.find(moduleSymbol.declarations, ts.isSourceFile);
                var hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias);
                if (!exportDefaultSymbol && !hasSyntheticDefault) {
                    if (hasExportAssignmentSymbol(moduleSymbol)) {
                        var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop";
                        var exportEqualsSymbol = moduleSymbol.exports.get("export=" /* ExportEquals */);
                        var exportAssignment = exportEqualsSymbol.valueDeclaration;
                        var err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName);
                        ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName));
                    }
                    else {
                        error(node.name, ts.Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
                    }
                }
                else if (hasSyntheticDefault) {
                    // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present
                    return resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
                }
                return exportDefaultSymbol;
            }
        }
        function getTargetOfNamespaceImport(node, dontResolveAlias) {
            var moduleSpecifier = node.parent.parent.moduleSpecifier;
            return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier, dontResolveAlias);
        }
        // This function creates a synthetic symbol that combines the value side of one symbol with the
        // type/namespace side of another symbol. Consider this example:
        //
        //   declare module graphics {
        //       interface Point {
        //           x: number;
        //           y: number;
        //       }
        //   }
        //   declare var graphics: {
        //       Point: new (x: number, y: number) => graphics.Point;
        //   }
        //   declare module "graphics" {
        //       export = graphics;
        //   }
        //
        // An 'import { Point } from "graphics"' needs to create a symbol that combines the value side 'Point'
        // property with the type/namespace side interface 'Point'.
        function combineValueAndTypeSymbols(valueSymbol, typeSymbol) {
            if (valueSymbol === unknownSymbol && typeSymbol === unknownSymbol) {
                return unknownSymbol;
            }
            if (valueSymbol.flags & (67897832 /* Type */ | 1920 /* Namespace */)) {
                return valueSymbol;
            }
            var result = createSymbol(valueSymbol.flags | typeSymbol.flags, valueSymbol.escapedName);
            result.declarations = ts.deduplicate(ts.concatenate(valueSymbol.declarations, typeSymbol.declarations), ts.equateValues);
            result.parent = valueSymbol.parent || typeSymbol.parent;
            if (valueSymbol.valueDeclaration)
                result.valueDeclaration = valueSymbol.valueDeclaration;
            if (typeSymbol.members)
                result.members = typeSymbol.members;
            if (valueSymbol.exports)
                result.exports = valueSymbol.exports;
            return result;
        }
        function getExportOfModule(symbol, name, dontResolveAlias) {
            if (symbol.flags & 1536 /* Module */) {
                return resolveSymbol(getExportsOfSymbol(symbol).get(name), dontResolveAlias);
            }
        }
        function getPropertyOfVariable(symbol, name) {
            if (symbol.flags & 3 /* Variable */) {
                var typeAnnotation = symbol.valueDeclaration.type;
                if (typeAnnotation) {
                    return resolveSymbol(getPropertyOfType(getTypeFromTypeNode(typeAnnotation), name));
                }
            }
        }
        function getExternalModuleMember(node, specifier, dontResolveAlias) {
            if (dontResolveAlias === void 0) { dontResolveAlias = false; }
            var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier); // TODO: GH#18217
            var targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier, dontResolveAlias);
            if (targetSymbol) {
                var name = specifier.propertyName || specifier.name;
                if (name.escapedText) {
                    if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) {
                        return moduleSymbol;
                    }
                    var symbolFromVariable = void 0;
                    // First check if module was specified with "export=". If so, get the member from the resolved type
                    if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get("export=" /* ExportEquals */)) {
                        symbolFromVariable = getPropertyOfType(getTypeOfSymbol(targetSymbol), name.escapedText);
                    }
                    else {
                        symbolFromVariable = getPropertyOfVariable(targetSymbol, name.escapedText);
                    }
                    // if symbolFromVariable is export - get its final target
                    symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias);
                    var symbolFromModule = getExportOfModule(targetSymbol, name.escapedText, dontResolveAlias);
                    // If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default
                    if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === "default" /* Default */) {
                        symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
                    }
                    var symbol = symbolFromModule && symbolFromVariable && symbolFromModule !== symbolFromVariable ?
                        combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) :
                        symbolFromModule || symbolFromVariable;
                    if (!symbol) {
                        var moduleName = getFullyQualifiedName(moduleSymbol, node);
                        var declarationName = ts.declarationNameToString(name);
                        var suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol);
                        if (suggestion !== undefined) {
                            var suggestionName = symbolToString(suggestion);
                            var diagnostic = error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_2, moduleName, declarationName, suggestionName);
                            if (suggestion.valueDeclaration) {
                                ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName));
                            }
                        }
                        else {
                            error(name, ts.Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName);
                        }
                    }
                    return symbol;
                }
            }
        }
        function getTargetOfImportSpecifier(node, dontResolveAlias) {
            return getExternalModuleMember(node.parent.parent.parent, node, dontResolveAlias);
        }
        function getTargetOfNamespaceExportDeclaration(node, dontResolveAlias) {
            return resolveExternalModuleSymbol(node.parent.symbol, dontResolveAlias);
        }
        function getTargetOfExportSpecifier(node, meaning, dontResolveAlias) {
            return node.parent.parent.moduleSpecifier ?
                getExternalModuleMember(node.parent.parent, node, dontResolveAlias) :
                resolveEntityName(node.propertyName || node.name, meaning, /*ignoreErrors*/ false, dontResolveAlias);
        }
        function getTargetOfExportAssignment(node, dontResolveAlias) {
            var expression = (ts.isExportAssignment(node) ? node.expression : node.right);
            if (ts.isClassExpression(expression)) {
                return checkExpression(expression).symbol;
            }
            var aliasLike = resolveEntityName(expression, 67220415 /* Value */ | 67897832 /* Type */ | 1920 /* Namespace */, /*ignoreErrors*/ true, dontResolveAlias);
            if (aliasLike) {
                return aliasLike;
            }
            checkExpression(expression);
            return getNodeLinks(expression).resolvedSymbol;
        }
        function getTargetOfAliasDeclaration(node, dontRecursivelyResolve) {
            if (dontRecursivelyResolve === void 0) { dontRecursivelyResolve = false; }
            switch (node.kind) {
                case 249 /* ImportEqualsDeclaration */:
                    return getTargetOfImportEqualsDeclaration(node, dontRecursivelyResolve);
                case 251 /* ImportClause */:
                    return getTargetOfImportClause(node, dontRecursivelyResolve);
                case 252 /* NamespaceImport */:
                    return getTargetOfNamespaceImport(node, dontRecursivelyResolve);
                case 254 /* ImportSpecifier */:
                    return getTargetOfImportSpecifier(node, dontRecursivelyResolve);
                case 258 /* ExportSpecifier */:
                    return getTargetOfExportSpecifier(node, 67220415 /* Value */ | 67897832 /* Type */ | 1920 /* Namespace */, dontRecursivelyResolve);
                case 255 /* ExportAssignment */:
                case 205 /* BinaryExpression */:
                    return getTargetOfExportAssignment(node, dontRecursivelyResolve);
                case 248 /* NamespaceExportDeclaration */:
                    return getTargetOfNamespaceExportDeclaration(node, dontRecursivelyResolve);
                default:
                    return ts.Debug.fail();
            }
        }
        /**
         * Indicates that a symbol is an alias that does not merge with a local declaration.
         * OR Is a JSContainer which may merge an alias with a local declaration
         */
        function isNonLocalAlias(symbol, excludes) {
            if (excludes === void 0) { excludes = 67220415 /* Value */ | 67897832 /* Type */ | 1920 /* Namespace */; }
            if (!symbol)
                return false;
            return (symbol.flags & (2097152 /* Alias */ | excludes)) === 2097152 /* Alias */ || !!(symbol.flags & 2097152 /* Alias */ && symbol.flags & 67108864 /* Assignment */);
        }
        function resolveSymbol(symbol, dontResolveAlias) {
            return !dontResolveAlias && isNonLocalAlias(symbol) ? resolveAlias(symbol) : symbol;
        }
        function resolveAlias(symbol) {
            ts.Debug.assert((symbol.flags & 2097152 /* Alias */) !== 0, "Should only get Alias here.");
            var links = getSymbolLinks(symbol);
            if (!links.target) {
                links.target = resolvingSymbol;
                var node = getDeclarationOfAliasSymbol(symbol);
                if (!node)
                    return ts.Debug.fail();
                var target = getTargetOfAliasDeclaration(node);
                if (links.target === resolvingSymbol) {
                    links.target = target || unknownSymbol;
                }
                else {
                    error(node, ts.Diagnostics.Circular_definition_of_import_alias_0, symbolToString(symbol));
                }
            }
            else if (links.target === resolvingSymbol) {
                links.target = unknownSymbol;
            }
            return links.target;
        }
        function markExportAsReferenced(node) {
            var symbol = getSymbolOfNode(node);
            var target = resolveAlias(symbol);
            if (target) {
                var markAlias = target === unknownSymbol ||
                    ((target.flags & 67220415 /* Value */) && !isConstEnumOrConstEnumOnlyModule(target));
                if (markAlias) {
                    markAliasSymbolAsReferenced(symbol);
                }
            }
        }
        // When an alias symbol is referenced, we need to mark the entity it references as referenced and in turn repeat that until
        // we reach a non-alias or an exported entity (which is always considered referenced). We do this by checking the target of
        // the alias as an expression (which recursively takes us back here if the target references another alias).
        function markAliasSymbolAsReferenced(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.referenced) {
                links.referenced = true;
                var node = getDeclarationOfAliasSymbol(symbol);
                if (!node)
                    return ts.Debug.fail();
                if (node.kind === 255 /* ExportAssignment */) {
                    // export default <symbol>
                    checkExpressionCached(node.expression);
                }
                else if (node.kind === 258 /* ExportSpecifier */) {
                    // export { <symbol> } or export { <symbol> as foo }
                    checkExpressionCached(node.propertyName || node.name);
                }
                else if (ts.isInternalModuleImportEqualsDeclaration(node)) {
                    // import foo = <symbol>
                    checkExpressionCached(node.moduleReference);
                }
            }
        }
        // This function is only for imports with entity names
        function getSymbolOfPartOfRightHandSideOfImportEquals(entityName, dontResolveAlias) {
            // There are three things we might try to look for. In the following examples,
            // the search term is enclosed in |...|:
            //
            //     import a = |b|; // Namespace
            //     import a = |b.c|; // Value, type, namespace
            //     import a = |b.c|.d; // Namespace
            if (entityName.kind === 73 /* Identifier */ && ts.isRightSideOfQualifiedNameOrPropertyAccess(entityName)) {
                entityName = entityName.parent;
            }
            // Check for case 1 and 3 in the above example
            if (entityName.kind === 73 /* Identifier */ || entityName.parent.kind === 149 /* QualifiedName */) {
                return resolveEntityName(entityName, 1920 /* Namespace */, /*ignoreErrors*/ false, dontResolveAlias);
            }
            else {
                // Case 2 in above example
                // entityName.kind could be a QualifiedName or a Missing identifier
                ts.Debug.assert(entityName.parent.kind === 249 /* ImportEqualsDeclaration */);
                return resolveEntityName(entityName, 67220415 /* Value */ | 67897832 /* Type */ | 1920 /* Namespace */, /*ignoreErrors*/ false, dontResolveAlias);
            }
        }
        function getFullyQualifiedName(symbol, containingLocation) {
            return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, /*meaning*/ undefined, 16 /* DoNotIncludeSymbolChain */ | 4 /* AllowAnyNodeKind */);
        }
        /**
         * Resolves a qualified name and any involved aliases.
         */
        function resolveEntityName(name, meaning, ignoreErrors, dontResolveAlias, location) {
            if (ts.nodeIsMissing(name)) {
                return undefined;
            }
            var namespaceMeaning = 1920 /* Namespace */ | (ts.isInJSFile(name) ? meaning & 67220415 /* Value */ : 0);
            var symbol;
            if (name.kind === 73 /* Identifier */) {
                var message = meaning === namespaceMeaning ? ts.Diagnostics.Cannot_find_namespace_0 : getCannotFindNameDiagnosticForName(getFirstIdentifier(name));
                var symbolFromJSPrototype = ts.isInJSFile(name) ? resolveEntityNameFromAssignmentDeclaration(name, meaning) : undefined;
                symbol = resolveName(location || name, name.escapedText, meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true);
                if (!symbol) {
                    return symbolFromJSPrototype;
                }
            }
            else if (name.kind === 149 /* QualifiedName */ || name.kind === 190 /* PropertyAccessExpression */) {
                var left = name.kind === 149 /* QualifiedName */ ? name.left : name.expression;
                var right = name.kind === 149 /* QualifiedName */ ? name.right : name.name;
                var namespace = resolveEntityName(left, namespaceMeaning, ignoreErrors, /*dontResolveAlias*/ false, location);
                if (!namespace || ts.nodeIsMissing(right)) {
                    return undefined;
                }
                else if (namespace === unknownSymbol) {
                    return namespace;
                }
                if (ts.isInJSFile(name)) {
                    if (namespace.valueDeclaration &&
                        ts.isVariableDeclaration(namespace.valueDeclaration) &&
                        namespace.valueDeclaration.initializer &&
                        isCommonJsRequire(namespace.valueDeclaration.initializer)) {
                        var moduleName = namespace.valueDeclaration.initializer.arguments[0];
                        var moduleSym = resolveExternalModuleName(moduleName, moduleName);
                        if (moduleSym) {
                            var resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym);
                            if (resolvedModuleSymbol) {
                                namespace = resolvedModuleSymbol;
                            }
                        }
                    }
                }
                symbol = getSymbol(getExportsOfSymbol(namespace), right.escapedText, meaning);
                if (!symbol) {
                    if (!ignoreErrors) {
                        error(right, ts.Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(namespace), ts.declarationNameToString(right));
                    }
                    return undefined;
                }
            }
            else {
                throw ts.Debug.assertNever(name, "Unknown entity name kind.");
            }
            ts.Debug.assert((ts.getCheckFlags(symbol) & 1 /* Instantiated */) === 0, "Should never get an instantiated symbol here.");
            return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol);
        }
        /**
         * 1. For prototype-property methods like `A.prototype.m = function () ...`, try to resolve names in the scope of `A` too.
         * Note that prototype-property assignment to locations outside the current file (eg globals) doesn't work, so
         * name resolution won't work either.
         * 2. For property assignments like `{ x: function f () { } }`, try to resolve names in the scope of `f` too.
         */
        function resolveEntityNameFromAssignmentDeclaration(name, meaning) {
            if (isJSDocTypeReference(name.parent)) {
                var secondaryLocation = getAssignmentDeclarationLocation(name.parent);
                if (secondaryLocation) {
                    return resolveName(secondaryLocation, name.escapedText, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ true);
                }
            }
        }
        function getAssignmentDeclarationLocation(node) {
            var typeAlias = ts.findAncestor(node, function (node) { return !(ts.isJSDocNode(node) || node.flags & 2097152 /* JSDoc */) ? "quit" : ts.isJSDocTypeAlias(node); });
            if (typeAlias) {
                return;
            }
            var host = ts.getJSDocHost(node);
            if (ts.isExpressionStatement(host) &&
                ts.isBinaryExpression(host.expression) &&
                ts.getAssignmentDeclarationKind(host.expression) === 3 /* PrototypeProperty */) {
                // X.prototype.m = /** @param {K} p */ function () { } <-- look for K on X's declaration
                var symbol = getSymbolOfNode(host.expression.left);
                if (symbol) {
                    return getDeclarationOfJSPrototypeContainer(symbol);
                }
            }
            if ((ts.isObjectLiteralMethod(host) || ts.isPropertyAssignment(host)) &&
                ts.isBinaryExpression(host.parent.parent) &&
                ts.getAssignmentDeclarationKind(host.parent.parent) === 6 /* Prototype */) {
                // X.prototype = { /** @param {K} p */m() { } } <-- look for K on X's declaration
                var symbol = getSymbolOfNode(host.parent.parent.left);
                if (symbol) {
                    return getDeclarationOfJSPrototypeContainer(symbol);
                }
            }
            var sig = ts.getHostSignatureFromJSDocHost(host);
            if (sig) {
                var symbol = getSymbolOfNode(sig);
                return symbol && symbol.valueDeclaration;
            }
        }
        function getDeclarationOfJSPrototypeContainer(symbol) {
            var decl = symbol.parent.valueDeclaration;
            if (!decl) {
                return undefined;
            }
            var initializer = ts.isAssignmentDeclaration(decl) ? ts.getAssignedExpandoInitializer(decl) :
                ts.hasOnlyExpressionInitializer(decl) ? ts.getDeclaredExpandoInitializer(decl) :
                    undefined;
            return initializer || decl;
        }
        function resolveExternalModuleName(location, moduleReferenceExpression, ignoreErrors) {
            return resolveExternalModuleNameWorker(location, moduleReferenceExpression, ignoreErrors ? undefined : ts.Diagnostics.Cannot_find_module_0);
        }
        function resolveExternalModuleNameWorker(location, moduleReferenceExpression, moduleNotFoundError, isForAugmentation) {
            if (isForAugmentation === void 0) { isForAugmentation = false; }
            return ts.isStringLiteralLike(moduleReferenceExpression)
                ? resolveExternalModule(location, moduleReferenceExpression.text, moduleNotFoundError, moduleReferenceExpression, isForAugmentation)
                : undefined;
        }
        function resolveExternalModule(location, moduleReference, moduleNotFoundError, errorNode, isForAugmentation) {
            if (isForAugmentation === void 0) { isForAugmentation = false; }
            if (moduleReference === undefined) {
                return;
            }
            if (ts.startsWith(moduleReference, "@types/")) {
                var diag = ts.Diagnostics.Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1;
                var withoutAtTypePrefix = ts.removePrefix(moduleReference, "@types/");
                error(errorNode, diag, withoutAtTypePrefix, moduleReference);
            }
            var ambientModule = tryFindAmbientModule(moduleReference, /*withAugmentations*/ true);
            if (ambientModule) {
                return ambientModule;
            }
            var currentSourceFile = ts.getSourceFileOfNode(location);
            var resolvedModule = ts.getResolvedModule(currentSourceFile, moduleReference); // TODO: GH#18217
            var resolutionDiagnostic = resolvedModule && ts.getResolutionDiagnostic(compilerOptions, resolvedModule);
            var sourceFile = resolvedModule && !resolutionDiagnostic && host.getSourceFile(resolvedModule.resolvedFileName);
            if (sourceFile) {
                if (sourceFile.symbol) {
                    if (resolvedModule.isExternalLibraryImport && !ts.resolutionExtensionIsTSOrJson(resolvedModule.extension)) {
                        errorOnImplicitAnyModule(/*isError*/ false, errorNode, resolvedModule, moduleReference);
                    }
                    // merged symbol is module declaration symbol combined with all augmentations
                    return getMergedSymbol(sourceFile.symbol);
                }
                if (moduleNotFoundError) {
                    // report errors only if it was requested
                    error(errorNode, ts.Diagnostics.File_0_is_not_a_module, sourceFile.fileName);
                }
                return undefined;
            }
            if (patternAmbientModules) {
                var pattern = ts.findBestPatternMatch(patternAmbientModules, function (_) { return _.pattern; }, moduleReference);
                if (pattern) {
                    // If the module reference matched a pattern ambient module ('*.foo') but there’s also a
                    // module augmentation by the specific name requested ('a.foo'), we store the merged symbol
                    // by the augmentation name ('a.foo'), because asking for *.foo should not give you exports
                    // from a.foo.
                    var augmentation = patternAmbientModuleAugmentations && patternAmbientModuleAugmentations.get(moduleReference);
                    if (augmentation) {
                        return getMergedSymbol(augmentation);
                    }
                    return getMergedSymbol(pattern.symbol);
                }
            }
            // May be an untyped module. If so, ignore resolutionDiagnostic.
            if (resolvedModule && !ts.resolutionExtensionIsTSOrJson(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) {
                if (isForAugmentation) {
                    var diag = ts.Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented;
                    error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName);
                }
                else {
                    errorOnImplicitAnyModule(/*isError*/ noImplicitAny && !!moduleNotFoundError, errorNode, resolvedModule, moduleReference);
                }
                // Failed imports and untyped modules are both treated in an untyped manner; only difference is whether we give a diagnostic first.
                return undefined;
            }
            if (moduleNotFoundError) {
                // See if this was possibly a projectReference redirect
                if (resolvedModule) {
                    var redirect = host.getProjectReferenceRedirect(resolvedModule.resolvedFileName);
                    if (redirect) {
                        error(errorNode, ts.Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, redirect, resolvedModule.resolvedFileName);
                        return undefined;
                    }
                }
                if (resolutionDiagnostic) {
                    error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.resolvedFileName);
                }
                else {
                    var tsExtension = ts.tryExtractTSExtension(moduleReference);
                    if (tsExtension) {
                        var diag = ts.Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead;
                        error(errorNode, diag, tsExtension, ts.removeExtension(moduleReference, tsExtension));
                    }
                    else if (!compilerOptions.resolveJsonModule &&
                        ts.fileExtensionIs(moduleReference, ".json" /* Json */) &&
                        ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeJs &&
                        ts.hasJsonModuleEmitEnabled(compilerOptions)) {
                        error(errorNode, ts.Diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference);
                    }
                    else {
                        error(errorNode, moduleNotFoundError, moduleReference);
                    }
                }
            }
            return undefined;
        }
        function errorOnImplicitAnyModule(isError, errorNode, _a, moduleReference) {
            var packageId = _a.packageId, resolvedFileName = _a.resolvedFileName;
            var errorInfo = !ts.isExternalModuleNameRelative(moduleReference) && packageId
                ? typesPackageExists(packageId.name)
                    ? ts.chainDiagnosticMessages(
                    /*details*/ undefined, ts.Diagnostics.If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1, packageId.name, ts.mangleScopedPackageName(packageId.name))
                    : ts.chainDiagnosticMessages(
                    /*details*/ undefined, ts.Diagnostics.Try_npm_install_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, moduleReference, ts.mangleScopedPackageName(packageId.name))
                : undefined;
            errorOrSuggestion(isError, errorNode, ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type, moduleReference, resolvedFileName));
        }
        function typesPackageExists(packageName) {
            return getPackagesSet().has(ts.getTypesPackageName(packageName));
        }
        function resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) {
            if (moduleSymbol) {
                var exportEquals = resolveSymbol(moduleSymbol.exports.get("export=" /* ExportEquals */), dontResolveAlias);
                var exported = getCommonJsExportEquals(exportEquals, moduleSymbol);
                return getMergedSymbol(exported) || moduleSymbol;
            }
            return undefined;
        }
        function getCommonJsExportEquals(exported, moduleSymbol) {
            if (!exported || exported === unknownSymbol || exported === moduleSymbol || moduleSymbol.exports.size === 1 || exported.flags & 2097152 /* Alias */) {
                return exported;
            }
            var merged = cloneSymbol(exported);
            if (merged.exports === undefined) {
                merged.flags = merged.flags | 512 /* ValueModule */;
                merged.exports = ts.createSymbolTable();
            }
            moduleSymbol.exports.forEach(function (s, name) {
                if (name === "export=" /* ExportEquals */)
                    return;
                merged.exports.set(name, merged.exports.has(name) ? mergeSymbol(merged.exports.get(name), s) : s);
            });
            return merged;
        }
        // An external module with an 'export =' declaration may be referenced as an ES6 module provided the 'export ='
        // references a symbol that is at least declared as a module or a variable. The target of the 'export =' may
        // combine other declarations with the module or variable (e.g. a class/module, function/module, interface/variable).
        function resolveESModuleSymbol(moduleSymbol, referencingLocation, dontResolveAlias) {
            var symbol = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias);
            if (!dontResolveAlias && symbol) {
                if (!(symbol.flags & (1536 /* Module */ | 3 /* Variable */)) && !ts.getDeclarationOfKind(symbol, 285 /* SourceFile */)) {
                    var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015
                        ? "allowSyntheticDefaultImports"
                        : "esModuleInterop";
                    error(referencingLocation, ts.Diagnostics.This_module_can_only_be_referenced_with_ECMAScript_imports_Slashexports_by_turning_on_the_0_flag_and_referencing_its_default_export, compilerOptionName);
                    return symbol;
                }
                if (compilerOptions.esModuleInterop) {
                    var referenceParent = referencingLocation.parent;
                    if ((ts.isImportDeclaration(referenceParent) && ts.getNamespaceDeclarationNode(referenceParent)) ||
                        ts.isImportCall(referenceParent)) {
                        var type = getTypeOfSymbol(symbol);
                        var sigs = getSignaturesOfStructuredType(type, 0 /* Call */);
                        if (!sigs || !sigs.length) {
                            sigs = getSignaturesOfStructuredType(type, 1 /* Construct */);
                        }
                        if (sigs && sigs.length) {
                            var moduleType = getTypeWithSyntheticDefaultImportType(type, symbol, moduleSymbol);
                            // Create a new symbol which has the module's type less the call and construct signatures
                            var result = createSymbol(symbol.flags, symbol.escapedName);
                            result.declarations = symbol.declarations ? symbol.declarations.slice() : [];
                            result.parent = symbol.parent;
                            result.target = symbol;
                            result.originatingImport = referenceParent;
                            if (symbol.valueDeclaration)
                                result.valueDeclaration = symbol.valueDeclaration;
                            if (symbol.constEnumOnlyModule)
                                result.constEnumOnlyModule = true;
                            if (symbol.members)
                                result.members = ts.cloneMap(symbol.members);
                            if (symbol.exports)
                                result.exports = ts.cloneMap(symbol.exports);
                            var resolvedModuleType = resolveStructuredTypeMembers(moduleType); // Should already be resolved from the signature checks above
                            result.type = createAnonymousType(result, resolvedModuleType.members, ts.emptyArray, ts.emptyArray, resolvedModuleType.stringIndexInfo, resolvedModuleType.numberIndexInfo);
                            return result;
                        }
                    }
                }
            }
            return symbol;
        }
        function hasExportAssignmentSymbol(moduleSymbol) {
            return moduleSymbol.exports.get("export=" /* ExportEquals */) !== undefined;
        }
        function getExportsOfModuleAsArray(moduleSymbol) {
            return symbolsToArray(getExportsOfModule(moduleSymbol));
        }
        function getExportsAndPropertiesOfModule(moduleSymbol) {
            var exports = getExportsOfModuleAsArray(moduleSymbol);
            var exportEquals = resolveExternalModuleSymbol(moduleSymbol);
            if (exportEquals !== moduleSymbol) {
                ts.addRange(exports, getPropertiesOfType(getTypeOfSymbol(exportEquals)));
            }
            return exports;
        }
        function tryGetMemberInModuleExports(memberName, moduleSymbol) {
            var symbolTable = getExportsOfModule(moduleSymbol);
            if (symbolTable) {
                return symbolTable.get(memberName);
            }
        }
        function tryGetMemberInModuleExportsAndProperties(memberName, moduleSymbol) {
            var symbol = tryGetMemberInModuleExports(memberName, moduleSymbol);
            if (symbol) {
                return symbol;
            }
            var exportEquals = resolveExternalModuleSymbol(moduleSymbol);
            if (exportEquals === moduleSymbol) {
                return undefined;
            }
            var type = getTypeOfSymbol(exportEquals);
            return type.flags & 131068 /* Primitive */ ? undefined : getPropertyOfType(type, memberName);
        }
        function getExportsOfSymbol(symbol) {
            return symbol.flags & 32 /* Class */ ? getResolvedMembersOrExportsOfSymbol(symbol, "resolvedExports" /* resolvedExports */) :
                symbol.flags & 1536 /* Module */ ? getExportsOfModule(symbol) :
                    symbol.exports || emptySymbols;
        }
        function getExportsOfModule(moduleSymbol) {
            var links = getSymbolLinks(moduleSymbol);
            return links.resolvedExports || (links.resolvedExports = getExportsOfModuleWorker(moduleSymbol));
        }
        /**
         * Extends one symbol table with another while collecting information on name collisions for error message generation into the `lookupTable` argument
         * Not passing `lookupTable` and `exportNode` disables this collection, and just extends the tables
         */
        function extendExportSymbols(target, source, lookupTable, exportNode) {
            if (!source)
                return;
            source.forEach(function (sourceSymbol, id) {
                if (id === "default" /* Default */)
                    return;
                var targetSymbol = target.get(id);
                if (!targetSymbol) {
                    target.set(id, sourceSymbol);
                    if (lookupTable && exportNode) {
                        lookupTable.set(id, {
                            specifierText: ts.getTextOfNode(exportNode.moduleSpecifier)
                        });
                    }
                }
                else if (lookupTable && exportNode && targetSymbol && resolveSymbol(targetSymbol) !== resolveSymbol(sourceSymbol)) {
                    var collisionTracker = lookupTable.get(id);
                    if (!collisionTracker.exportsWithDuplicate) {
                        collisionTracker.exportsWithDuplicate = [exportNode];
                    }
                    else {
                        collisionTracker.exportsWithDuplicate.push(exportNode);
                    }
                }
            });
        }
        function getExportsOfModuleWorker(moduleSymbol) {
            var visitedSymbols = [];
            // A module defined by an 'export=' consists of one export that needs to be resolved
            moduleSymbol = resolveExternalModuleSymbol(moduleSymbol);
            return visit(moduleSymbol) || emptySymbols;
            // The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example,
            // module 'a' can 'export * from "b"' and 'b' can 'export * from "a"' without error.
            function visit(symbol) {
                if (!(symbol && symbol.exports && ts.pushIfUnique(visitedSymbols, symbol))) {
                    return;
                }
                var symbols = ts.cloneMap(symbol.exports);
                // All export * declarations are collected in an __export symbol by the binder
                var exportStars = symbol.exports.get("__export" /* ExportStar */);
                if (exportStars) {
                    var nestedSymbols = ts.createSymbolTable();
                    var lookupTable_1 = ts.createMap();
                    for (var _i = 0, _a = exportStars.declarations; _i < _a.length; _i++) {
                        var node = _a[_i];
                        var resolvedModule = resolveExternalModuleName(node, node.moduleSpecifier);
                        var exportedSymbols = visit(resolvedModule);
                        extendExportSymbols(nestedSymbols, exportedSymbols, lookupTable_1, node);
                    }
                    lookupTable_1.forEach(function (_a, id) {
                        var exportsWithDuplicate = _a.exportsWithDuplicate;
                        // It's not an error if the file with multiple `export *`s with duplicate names exports a member with that name itself
                        if (id === "export=" || !(exportsWithDuplicate && exportsWithDuplicate.length) || symbols.has(id)) {
                            return;
                        }
                        for (var _i = 0, exportsWithDuplicate_1 = exportsWithDuplicate; _i < exportsWithDuplicate_1.length; _i++) {
                            var node = exportsWithDuplicate_1[_i];
                            diagnostics.add(ts.createDiagnosticForNode(node, ts.Diagnostics.Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, lookupTable_1.get(id).specifierText, ts.unescapeLeadingUnderscores(id)));
                        }
                    });
                    extendExportSymbols(symbols, nestedSymbols);
                }
                return symbols;
            }
        }
        function getMergedSymbol(symbol) {
            var merged;
            return symbol && symbol.mergeId && (merged = mergedSymbols[symbol.mergeId]) ? merged : symbol;
        }
        function getSymbolOfNode(node) {
            return getMergedSymbol(node.symbol && getLateBoundSymbol(node.symbol));
        }
        function getParentOfSymbol(symbol) {
            return getMergedSymbol(symbol.parent && getLateBoundSymbol(symbol.parent));
        }
        function getAlternativeContainingModules(symbol, enclosingDeclaration) {
            var containingFile = ts.getSourceFileOfNode(enclosingDeclaration);
            var id = "" + getNodeId(containingFile);
            var links = getSymbolLinks(symbol);
            var results;
            if (links.extendedContainersByFile && (results = links.extendedContainersByFile.get(id))) {
                return results;
            }
            if (containingFile && containingFile.imports) {
                // Try to make an import using an import already in the enclosing file, if possible
                for (var _i = 0, _a = containingFile.imports; _i < _a.length; _i++) {
                    var importRef = _a[_i];
                    if (ts.nodeIsSynthesized(importRef))
                        continue; // Synthetic names can't be resolved by `resolveExternalModuleName` - they'll cause a debug assert if they error
                    var resolvedModule = resolveExternalModuleName(enclosingDeclaration, importRef, /*ignoreErrors*/ true);
                    if (!resolvedModule)
                        continue;
                    var ref = getAliasForSymbolInContainer(resolvedModule, symbol);
                    if (!ref)
                        continue;
                    results = ts.append(results, resolvedModule);
                }
                if (ts.length(results)) {
                    (links.extendedContainersByFile || (links.extendedContainersByFile = ts.createMap())).set(id, results);
                    return results;
                }
            }
            if (links.extendedContainers) {
                return links.extendedContainers;
            }
            // No results from files already being imported by this file - expand search (expensive, but not location-specific, so cached)
            var otherFiles = host.getSourceFiles();
            for (var _b = 0, otherFiles_1 = otherFiles; _b < otherFiles_1.length; _b++) {
                var file = otherFiles_1[_b];
                if (!ts.isExternalModule(file))
                    continue;
                var sym = getSymbolOfNode(file);
                var ref = getAliasForSymbolInContainer(sym, symbol);
                if (!ref)
                    continue;
                results = ts.append(results, sym);
            }
            return links.extendedContainers = results || ts.emptyArray;
        }
        /**
         * Attempts to find the symbol corresponding to the container a symbol is in - usually this
         * is just its' `.parent`, but for locals, this value is `undefined`
         */
        function getContainersOfSymbol(symbol, enclosingDeclaration) {
            var container = getParentOfSymbol(symbol);
            if (container) {
                var additionalContainers = ts.mapDefined(container.declarations, fileSymbolIfFileSymbolExportEqualsContainer);
                var reexportContainers = enclosingDeclaration && getAlternativeContainingModules(symbol, enclosingDeclaration);
                if (enclosingDeclaration && getAccessibleSymbolChain(container, enclosingDeclaration, 1920 /* Namespace */, /*externalOnly*/ false)) {
                    return ts.concatenate(ts.concatenate([container], additionalContainers), reexportContainers); // This order expresses a preference for the real container if it is in scope
                }
                var res = ts.append(additionalContainers, container);
                return ts.concatenate(res, reexportContainers);
            }
            var candidates = ts.mapDefined(symbol.declarations, function (d) { return !ts.isAmbientModule(d) && d.parent && hasNonGlobalAugmentationExternalModuleSymbol(d.parent) ? getSymbolOfNode(d.parent) : undefined; });
            if (!ts.length(candidates)) {
                return undefined;
            }
            return ts.mapDefined(candidates, function (candidate) { return getAliasForSymbolInContainer(candidate, symbol) ? candidate : undefined; });
            function fileSymbolIfFileSymbolExportEqualsContainer(d) {
                var fileSymbol = getExternalModuleContainer(d);
                var exported = fileSymbol && fileSymbol.exports && fileSymbol.exports.get("export=" /* ExportEquals */);
                return resolveSymbol(exported) === resolveSymbol(container) ? fileSymbol : undefined;
            }
        }
        function getAliasForSymbolInContainer(container, symbol) {
            if (container === getParentOfSymbol(symbol)) {
                // fast path, `symbol` is either already the alias or isn't aliased
                return symbol;
            }
            var exports = getExportsOfSymbol(container);
            var quick = exports.get(symbol.escapedName);
            if (quick && symbolRefersToTarget(quick)) {
                return quick;
            }
            return ts.forEachEntry(exports, function (exported) {
                if (symbolRefersToTarget(exported)) {
                    return exported;
                }
            });
            function symbolRefersToTarget(s) {
                if (s === symbol || resolveSymbol(s) === symbol || resolveSymbol(s) === resolveSymbol(symbol)) {
                    return s;
                }
            }
        }
        function getExportSymbolOfValueSymbolIfExported(symbol) {
            return getMergedSymbol(symbol && (symbol.flags & 1048576 /* ExportValue */) !== 0 ? symbol.exportSymbol : symbol);
        }
        function symbolIsValue(symbol) {
            return !!(symbol.flags & 67220415 /* Value */ || symbol.flags & 2097152 /* Alias */ && resolveAlias(symbol).flags & 67220415 /* Value */);
        }
        function findConstructorDeclaration(node) {
            var members = node.members;
            for (var _i = 0, members_2 = members; _i < members_2.length; _i++) {
                var member = members_2[_i];
                if (member.kind === 158 /* Constructor */ && ts.nodeIsPresent(member.body)) {
                    return member;
                }
            }
        }
        function createType(flags) {
            var result = new Type(checker, flags);
            typeCount++;
            result.id = typeCount;
            return result;
        }
        function createIntrinsicType(kind, intrinsicName, objectFlags) {
            if (objectFlags === void 0) { objectFlags = 0; }
            var type = createType(kind);
            type.intrinsicName = intrinsicName;
            type.objectFlags = objectFlags;
            return type;
        }
        function createBooleanType(trueFalseTypes) {
            var type = getUnionType(trueFalseTypes);
            type.flags |= 16 /* Boolean */;
            type.intrinsicName = "boolean";
            return type;
        }
        function createObjectType(objectFlags, symbol) {
            var type = createType(524288 /* Object */);
            type.objectFlags = objectFlags;
            type.symbol = symbol;
            type.members = undefined;
            type.properties = undefined;
            type.callSignatures = undefined;
            type.constructSignatures = undefined;
            type.stringIndexInfo = undefined;
            type.numberIndexInfo = undefined;
            return type;
        }
        function createTypeofType() {
            return getUnionType(ts.arrayFrom(typeofEQFacts.keys(), getLiteralType));
        }
        function createTypeParameter(symbol) {
            var type = createType(262144 /* TypeParameter */);
            if (symbol)
                type.symbol = symbol;
            return type;
        }
        // A reserved member name starts with two underscores, but the third character cannot be an underscore
        // or the @ symbol. A third underscore indicates an escaped form of an identifier that started
        // with at least two underscores. The @ character indicates that the name is denoted by a well known ES
        // Symbol instance.
        function isReservedMemberName(name) {
            return name.charCodeAt(0) === 95 /* _ */ &&
                name.charCodeAt(1) === 95 /* _ */ &&
                name.charCodeAt(2) !== 95 /* _ */ &&
                name.charCodeAt(2) !== 64 /* at */;
        }
        function getNamedMembers(members) {
            var result;
            members.forEach(function (symbol, id) {
                if (!isReservedMemberName(id) && symbolIsValue(symbol)) {
                    (result || (result = [])).push(symbol);
                }
            });
            return result || ts.emptyArray;
        }
        function setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo) {
            type.members = members;
            type.properties = members === emptySymbols ? ts.emptyArray : getNamedMembers(members);
            type.callSignatures = callSignatures;
            type.constructSignatures = constructSignatures;
            type.stringIndexInfo = stringIndexInfo;
            type.numberIndexInfo = numberIndexInfo;
            return type;
        }
        function createAnonymousType(symbol, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo) {
            return setStructuredTypeMembers(createObjectType(16 /* Anonymous */, symbol), members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        function forEachSymbolTableInScope(enclosingDeclaration, callback) {
            var result;
            for (var location = enclosingDeclaration; location; location = location.parent) {
                // Locals of a source file are not in scope (because they get merged into the global symbol table)
                if (location.locals && !isGlobalSourceFile(location)) {
                    if (result = callback(location.locals)) {
                        return result;
                    }
                }
                switch (location.kind) {
                    case 285 /* SourceFile */:
                        if (!ts.isExternalOrCommonJsModule(location)) {
                            break;
                        }
                    // falls through
                    case 245 /* ModuleDeclaration */:
                        if (result = callback(getSymbolOfNode(location).exports)) {
                            return result;
                        }
                        break;
                }
            }
            return callback(globals);
        }
        function getQualifiedLeftMeaning(rightMeaning) {
            // If we are looking in value space, the parent meaning is value, other wise it is namespace
            return rightMeaning === 67220415 /* Value */ ? 67220415 /* Value */ : 1920 /* Namespace */;
        }
        function getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, useOnlyExternalAliasing, visitedSymbolTablesMap) {
            if (visitedSymbolTablesMap === void 0) { visitedSymbolTablesMap = ts.createMap(); }
            if (!(symbol && !isPropertyOrMethodDeclarationSymbol(symbol))) {
                return undefined;
            }
            var id = "" + getSymbolId(symbol);
            var visitedSymbolTables = visitedSymbolTablesMap.get(id);
            if (!visitedSymbolTables) {
                visitedSymbolTablesMap.set(id, visitedSymbolTables = []);
            }
            return forEachSymbolTableInScope(enclosingDeclaration, getAccessibleSymbolChainFromSymbolTable);
            /**
             * @param {ignoreQualification} boolean Set when a symbol is being looked for through the exports of another symbol (meaning we have a route to qualify it already)
             */
            function getAccessibleSymbolChainFromSymbolTable(symbols, ignoreQualification) {
                if (!ts.pushIfUnique(visitedSymbolTables, symbols)) {
                    return undefined;
                }
                var result = trySymbolTable(symbols, ignoreQualification);
                visitedSymbolTables.pop();
                return result;
            }
            function canQualifySymbol(symbolFromSymbolTable, meaning) {
                // If the symbol is equivalent and doesn't need further qualification, this symbol is accessible
                return !needsQualification(symbolFromSymbolTable, enclosingDeclaration, meaning) ||
                    // If symbol needs qualification, make sure that parent is accessible, if it is then this symbol is accessible too
                    !!getAccessibleSymbolChain(symbolFromSymbolTable.parent, enclosingDeclaration, getQualifiedLeftMeaning(meaning), useOnlyExternalAliasing, visitedSymbolTablesMap);
            }
            function isAccessible(symbolFromSymbolTable, resolvedAliasSymbol, ignoreQualification) {
                return symbol === (resolvedAliasSymbol || symbolFromSymbolTable) &&
                    // if the symbolFromSymbolTable is not external module (it could be if it was determined as ambient external module and would be in globals table)
                    // and if symbolFromSymbolTable or alias resolution matches the symbol,
                    // check the symbol can be qualified, it is only then this symbol is accessible
                    !ts.some(symbolFromSymbolTable.declarations, hasNonGlobalAugmentationExternalModuleSymbol) &&
                    (ignoreQualification || canQualifySymbol(symbolFromSymbolTable, meaning));
            }
            function trySymbolTable(symbols, ignoreQualification) {
                // If symbol is directly available by its name in the symbol table
                if (isAccessible(symbols.get(symbol.escapedName), /*resolvedAliasSymbol*/ undefined, ignoreQualification)) {
                    return [symbol];
                }
                // Check if symbol is any of the alias
                return ts.forEachEntry(symbols, function (symbolFromSymbolTable) {
                    if (symbolFromSymbolTable.flags & 2097152 /* Alias */
                        && symbolFromSymbolTable.escapedName !== "export=" /* ExportEquals */
                        && symbolFromSymbolTable.escapedName !== "default" /* Default */
                        && !(ts.isUMDExportSymbol(symbolFromSymbolTable) && enclosingDeclaration && ts.isExternalModule(ts.getSourceFileOfNode(enclosingDeclaration)))
                        // If `!useOnlyExternalAliasing`, we can use any type of alias to get the name
                        && (!useOnlyExternalAliasing || ts.some(symbolFromSymbolTable.declarations, ts.isExternalModuleImportEqualsDeclaration))
                        // While exports are generally considered to be in scope, export-specifier declared symbols are _not_
                        // See similar comment in `resolveName` for details
                        && (ignoreQualification || !ts.getDeclarationOfKind(symbolFromSymbolTable, 258 /* ExportSpecifier */))) {
                        var resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable);
                        if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol, ignoreQualification)) {
                            return [symbolFromSymbolTable];
                        }
                        // Look in the exported members, if we can find accessibleSymbolChain, symbol is accessible using this chain
                        // but only if the symbolFromSymbolTable can be qualified
                        var candidateTable = getExportsOfSymbol(resolvedImportedSymbol);
                        var accessibleSymbolsFromExports = candidateTable && getAccessibleSymbolChainFromSymbolTable(candidateTable, /*ignoreQualification*/ true);
                        if (accessibleSymbolsFromExports && canQualifySymbol(symbolFromSymbolTable, getQualifiedLeftMeaning(meaning))) {
                            return [symbolFromSymbolTable].concat(accessibleSymbolsFromExports);
                        }
                    }
                    if (symbolFromSymbolTable.escapedName === symbol.escapedName && symbolFromSymbolTable.exportSymbol) {
                        if (isAccessible(getMergedSymbol(symbolFromSymbolTable.exportSymbol), /*aliasSymbol*/ undefined, ignoreQualification)) {
                            return [symbol];
                        }
                    }
                });
            }
        }
        function needsQualification(symbol, enclosingDeclaration, meaning) {
            var qualify = false;
            forEachSymbolTableInScope(enclosingDeclaration, function (symbolTable) {
                // If symbol of this name is not available in the symbol table we are ok
                var symbolFromSymbolTable = getMergedSymbol(symbolTable.get(symbol.escapedName));
                if (!symbolFromSymbolTable) {
                    // Continue to the next symbol table
                    return false;
                }
                // If the symbol with this name is present it should refer to the symbol
                if (symbolFromSymbolTable === symbol) {
                    // No need to qualify
                    return true;
                }
                // Qualify if the symbol from symbol table has same meaning as expected
                symbolFromSymbolTable = (symbolFromSymbolTable.flags & 2097152 /* Alias */ && !ts.getDeclarationOfKind(symbolFromSymbolTable, 258 /* ExportSpecifier */)) ? resolveAlias(symbolFromSymbolTable) : symbolFromSymbolTable;
                if (symbolFromSymbolTable.flags & meaning) {
                    qualify = true;
                    return true;
                }
                // Continue to the next symbol table
                return false;
            });
            return qualify;
        }
        function isPropertyOrMethodDeclarationSymbol(symbol) {
            if (symbol.declarations && symbol.declarations.length) {
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    switch (declaration.kind) {
                        case 155 /* PropertyDeclaration */:
                        case 157 /* MethodDeclaration */:
                        case 159 /* GetAccessor */:
                        case 160 /* SetAccessor */:
                            continue;
                        default:
                            return false;
                    }
                }
                return true;
            }
            return false;
        }
        function isTypeSymbolAccessible(typeSymbol, enclosingDeclaration) {
            var access = isSymbolAccessible(typeSymbol, enclosingDeclaration, 67897832 /* Type */, /*shouldComputeAliasesToMakeVisible*/ false);
            return access.accessibility === 0 /* Accessible */;
        }
        function isValueSymbolAccessible(typeSymbol, enclosingDeclaration) {
            var access = isSymbolAccessible(typeSymbol, enclosingDeclaration, 67220415 /* Value */, /*shouldComputeAliasesToMakeVisible*/ false);
            return access.accessibility === 0 /* Accessible */;
        }
        function isAnySymbolAccessible(symbols, enclosingDeclaration, initialSymbol, meaning, shouldComputeAliasesToMakeVisible) {
            if (!ts.length(symbols))
                return;
            var hadAccessibleChain;
            for (var _i = 0, _a = symbols; _i < _a.length; _i++) {
                var symbol = _a[_i];
                // Symbol is accessible if it by itself is accessible
                var accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/ false);
                if (accessibleSymbolChain) {
                    hadAccessibleChain = symbol;
                    var hasAccessibleDeclarations = hasVisibleDeclarations(accessibleSymbolChain[0], shouldComputeAliasesToMakeVisible);
                    if (hasAccessibleDeclarations) {
                        return hasAccessibleDeclarations;
                    }
                }
                else {
                    if (ts.some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
                        // Any meaning of a module symbol is always accessible via an `import` type
                        return {
                            accessibility: 0 /* Accessible */
                        };
                    }
                }
                // If we haven't got the accessible symbol, it doesn't mean the symbol is actually inaccessible.
                // It could be a qualified symbol and hence verify the path
                // e.g.:
                // module m {
                //     export class c {
                //     }
                // }
                // const x: typeof m.c
                // In the above example when we start with checking if typeof m.c symbol is accessible,
                // we are going to see if c can be accessed in scope directly.
                // But it can't, hence the accessible is going to be undefined, but that doesn't mean m.c is inaccessible
                // It is accessible if the parent m is accessible because then m.c can be accessed through qualification
                var containers = getContainersOfSymbol(symbol, enclosingDeclaration);
                // If we're trying to reference some object literal in, eg `var a = { x: 1 }`, the symbol for the literal, `__object`, is distinct
                // from the symbol of the declaration it is being assigned to. Since we can use the declaration to refer to the literal, however,
                // we'd like to make that connection here - potentially causing us to paint the declaration's visibility, and therefore the literal.
                var firstDecl = ts.first(symbol.declarations);
                if (!ts.length(containers) && meaning & 67220415 /* Value */ && firstDecl && ts.isObjectLiteralExpression(firstDecl)) {
                    if (firstDecl.parent && ts.isVariableDeclaration(firstDecl.parent) && firstDecl === firstDecl.parent.initializer) {
                        containers = [getSymbolOfNode(firstDecl.parent)];
                    }
                }
                var parentResult = isAnySymbolAccessible(containers, enclosingDeclaration, initialSymbol, initialSymbol === symbol ? getQualifiedLeftMeaning(meaning) : meaning, shouldComputeAliasesToMakeVisible);
                if (parentResult) {
                    return parentResult;
                }
            }
            if (hadAccessibleChain) {
                return {
                    accessibility: 1 /* NotAccessible */,
                    errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
                    errorModuleName: hadAccessibleChain !== initialSymbol ? symbolToString(hadAccessibleChain, enclosingDeclaration, 1920 /* Namespace */) : undefined,
                };
            }
        }
        /**
         * Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested
         *
         * @param symbol a Symbol to check if accessible
         * @param enclosingDeclaration a Node containing reference to the symbol
         * @param meaning a SymbolFlags to check if such meaning of the symbol is accessible
         * @param shouldComputeAliasToMakeVisible a boolean value to indicate whether to return aliases to be mark visible in case the symbol is accessible
         */
        function isSymbolAccessible(symbol, enclosingDeclaration, meaning, shouldComputeAliasesToMakeVisible) {
            if (symbol && enclosingDeclaration) {
                var result = isAnySymbolAccessible([symbol], enclosingDeclaration, symbol, meaning, shouldComputeAliasesToMakeVisible);
                if (result) {
                    return result;
                }
                // This could be a symbol that is not exported in the external module
                // or it could be a symbol from different external module that is not aliased and hence cannot be named
                var symbolExternalModule = ts.forEach(symbol.declarations, getExternalModuleContainer);
                if (symbolExternalModule) {
                    var enclosingExternalModule = getExternalModuleContainer(enclosingDeclaration);
                    if (symbolExternalModule !== enclosingExternalModule) {
                        // name from different external module that is not visible
                        return {
                            accessibility: 2 /* CannotBeNamed */,
                            errorSymbolName: symbolToString(symbol, enclosingDeclaration, meaning),
                            errorModuleName: symbolToString(symbolExternalModule)
                        };
                    }
                }
                // Just a local name that is not accessible
                return {
                    accessibility: 1 /* NotAccessible */,
                    errorSymbolName: symbolToString(symbol, enclosingDeclaration, meaning),
                };
            }
            return { accessibility: 0 /* Accessible */ };
        }
        function getExternalModuleContainer(declaration) {
            var node = ts.findAncestor(declaration, hasExternalModuleSymbol);
            return node && getSymbolOfNode(node);
        }
        function hasExternalModuleSymbol(declaration) {
            return ts.isAmbientModule(declaration) || (declaration.kind === 285 /* SourceFile */ && ts.isExternalOrCommonJsModule(declaration));
        }
        function hasNonGlobalAugmentationExternalModuleSymbol(declaration) {
            return ts.isModuleWithStringLiteralName(declaration) || (declaration.kind === 285 /* SourceFile */ && ts.isExternalOrCommonJsModule(declaration));
        }
        function hasVisibleDeclarations(symbol, shouldComputeAliasToMakeVisible) {
            var aliasesToMakeVisible;
            if (!ts.every(symbol.declarations, getIsDeclarationVisible)) {
                return undefined;
            }
            return { accessibility: 0 /* Accessible */, aliasesToMakeVisible: aliasesToMakeVisible };
            function getIsDeclarationVisible(declaration) {
                if (!isDeclarationVisible(declaration)) {
                    // Mark the unexported alias as visible if its parent is visible
                    // because these kind of aliases can be used to name types in declaration file
                    var anyImportSyntax = getAnyImportSyntax(declaration);
                    if (anyImportSyntax &&
                        !ts.hasModifier(anyImportSyntax, 1 /* Export */) && // import clause without export
                        isDeclarationVisible(anyImportSyntax.parent)) {
                        return addVisibleAlias(declaration, anyImportSyntax);
                    }
                    else if (ts.isVariableDeclaration(declaration) && ts.isVariableStatement(declaration.parent.parent) &&
                        !ts.hasModifier(declaration.parent.parent, 1 /* Export */) && // unexported variable statement
                        isDeclarationVisible(declaration.parent.parent.parent)) {
                        return addVisibleAlias(declaration, declaration.parent.parent);
                    }
                    else if (ts.isLateVisibilityPaintedStatement(declaration) // unexported top-level statement
                        && !ts.hasModifier(declaration, 1 /* Export */)
                        && isDeclarationVisible(declaration.parent)) {
                        return addVisibleAlias(declaration, declaration);
                    }
                    // Declaration is not visible
                    return false;
                }
                return true;
            }
            function addVisibleAlias(declaration, aliasingStatement) {
                // In function "buildTypeDisplay" where we decide whether to write type-alias or serialize types,
                // we want to just check if type- alias is accessible or not but we don't care about emitting those alias at that time
                // since we will do the emitting later in trackSymbol.
                if (shouldComputeAliasToMakeVisible) {
                    getNodeLinks(declaration).isVisible = true;
                    aliasesToMakeVisible = ts.appendIfUnique(aliasesToMakeVisible, aliasingStatement);
                }
                return true;
            }
        }
        function isEntityNameVisible(entityName, enclosingDeclaration) {
            // get symbol of the first identifier of the entityName
            var meaning;
            if (entityName.parent.kind === 168 /* TypeQuery */ ||
                ts.isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent) ||
                entityName.parent.kind === 150 /* ComputedPropertyName */) {
                // Typeof value
                meaning = 67220415 /* Value */ | 1048576 /* ExportValue */;
            }
            else if (entityName.kind === 149 /* QualifiedName */ || entityName.kind === 190 /* PropertyAccessExpression */ ||
                entityName.parent.kind === 249 /* ImportEqualsDeclaration */) {
                // Left identifier from type reference or TypeAlias
                // Entity name of the import declaration
                meaning = 1920 /* Namespace */;
            }
            else {
                // Type Reference or TypeAlias entity = Identifier
                meaning = 67897832 /* Type */;
            }
            var firstIdentifier = getFirstIdentifier(entityName);
            var symbol = resolveName(enclosingDeclaration, firstIdentifier.escapedText, meaning, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
            // Verify if the symbol is accessible
            return (symbol && hasVisibleDeclarations(symbol, /*shouldComputeAliasToMakeVisible*/ true)) || {
                accessibility: 1 /* NotAccessible */,
                errorSymbolName: ts.getTextOfNode(firstIdentifier),
                errorNode: firstIdentifier
            };
        }
        function symbolToString(symbol, enclosingDeclaration, meaning, flags, writer) {
            if (flags === void 0) { flags = 4 /* AllowAnyNodeKind */; }
            var nodeFlags = 70221824 /* IgnoreErrors */;
            if (flags & 2 /* UseOnlyExternalAliasing */) {
                nodeFlags |= 128 /* UseOnlyExternalAliasing */;
            }
            if (flags & 1 /* WriteTypeParametersOrArguments */) {
                nodeFlags |= 512 /* WriteTypeParametersInQualifiedName */;
            }
            if (flags & 8 /* UseAliasDefinedOutsideCurrentScope */) {
                nodeFlags |= 16384 /* UseAliasDefinedOutsideCurrentScope */;
            }
            if (flags & 16 /* DoNotIncludeSymbolChain */) {
                nodeFlags |= 134217728 /* DoNotIncludeSymbolChain */;
            }
            var builder = flags & 4 /* AllowAnyNodeKind */ ? nodeBuilder.symbolToExpression : nodeBuilder.symbolToEntityName;
            return writer ? symbolToStringWorker(writer).getText() : ts.usingSingleLineStringWriter(symbolToStringWorker);
            function symbolToStringWorker(writer) {
                var entity = builder(symbol, meaning, enclosingDeclaration, nodeFlags); // TODO: GH#18217
                var printer = ts.createPrinter({ removeComments: true });
                var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration);
                printer.writeNode(4 /* Unspecified */, entity, /*sourceFile*/ sourceFile, writer);
                return writer;
            }
        }
        function signatureToString(signature, enclosingDeclaration, flags, kind, writer) {
            if (flags === void 0) { flags = 0 /* None */; }
            return writer ? signatureToStringWorker(writer).getText() : ts.usingSingleLineStringWriter(signatureToStringWorker);
            function signatureToStringWorker(writer) {
                var sigOutput;
                if (flags & 262144 /* WriteArrowStyleSignature */) {
                    sigOutput = kind === 1 /* Construct */ ? 167 /* ConstructorType */ : 166 /* FunctionType */;
                }
                else {
                    sigOutput = kind === 1 /* Construct */ ? 162 /* ConstructSignature */ : 161 /* CallSignature */;
                }
                var sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* IgnoreErrors */ | 512 /* WriteTypeParametersInQualifiedName */);
                var printer = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true });
                var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration);
                printer.writeNode(4 /* Unspecified */, sig, /*sourceFile*/ sourceFile, ts.getTrailingSemicolonOmittingWriter(writer)); // TODO: GH#18217
                return writer;
            }
        }
        function typeToString(type, enclosingDeclaration, flags, writer) {
            if (flags === void 0) { flags = 1048576 /* AllowUniqueESSymbolType */ | 16384 /* UseAliasDefinedOutsideCurrentScope */; }
            if (writer === void 0) { writer = ts.createTextWriter(""); }
            var noTruncation = compilerOptions.noErrorTruncation || flags & 1 /* NoTruncation */;
            var typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* IgnoreErrors */ | (noTruncation ? 1 /* NoTruncation */ : 0), writer);
            if (typeNode === undefined)
                return ts.Debug.fail("should always get typenode");
            var options = { removeComments: true };
            var printer = ts.createPrinter(options);
            var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration);
            printer.writeNode(4 /* Unspecified */, typeNode, /*sourceFile*/ sourceFile, writer);
            var result = writer.getText();
            var maxLength = noTruncation ? undefined : ts.defaultMaximumTruncationLength * 2;
            if (maxLength && result && result.length >= maxLength) {
                return result.substr(0, maxLength - "...".length) + "...";
            }
            return result;
        }
        function getTypeNamesForErrorDisplay(left, right) {
            var leftStr = typeToString(left);
            var rightStr = typeToString(right);
            if (leftStr === rightStr) {
                leftStr = typeToString(left, /*enclosingDeclaration*/ undefined, 64 /* UseFullyQualifiedType */);
                rightStr = typeToString(right, /*enclosingDeclaration*/ undefined, 64 /* UseFullyQualifiedType */);
            }
            return [leftStr, rightStr];
        }
        function toNodeBuilderFlags(flags) {
            if (flags === void 0) { flags = 0 /* None */; }
            return flags & 9469291 /* NodeBuilderFlagsMask */;
        }
        function createNodeBuilder() {
            return {
                typeToTypeNode: function (type, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return typeToTypeNodeHelper(type, context); });
                },
                indexInfoToIndexSignatureDeclaration: function (indexInfo, kind, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context); });
                },
                signatureToSignatureDeclaration: function (signature, kind, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return signatureToSignatureDeclarationHelper(signature, kind, context); });
                },
                symbolToEntityName: function (symbol, meaning, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return symbolToName(symbol, context, meaning, /*expectsIdentifier*/ false); });
                },
                symbolToExpression: function (symbol, meaning, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return symbolToExpression(symbol, context, meaning); });
                },
                symbolToTypeParameterDeclarations: function (symbol, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return typeParametersToTypeParameterDeclarations(symbol, context); });
                },
                symbolToParameterDeclaration: function (symbol, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return symbolToParameterDeclaration(symbol, context); });
                },
                typeParameterToDeclaration: function (parameter, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return typeParameterToDeclaration(parameter, context); });
                },
            };
            function withContext(enclosingDeclaration, flags, tracker, cb) {
                ts.Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & 8 /* Synthesized */) === 0);
                var context = {
                    enclosingDeclaration: enclosingDeclaration,
                    flags: flags || 0 /* None */,
                    // If no full tracker is provided, fake up a dummy one with a basic limited-functionality moduleResolverHost
                    tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: ts.noop, moduleResolverHost: flags & 134217728 /* DoNotIncludeSymbolChain */ ? {
                            getCommonSourceDirectory: host.getCommonSourceDirectory ? function () { return host.getCommonSourceDirectory(); } : function () { return ""; },
                            getSourceFiles: function () { return host.getSourceFiles(); },
                            getCurrentDirectory: host.getCurrentDirectory && (function () { return host.getCurrentDirectory(); })
                        } : undefined },
                    encounteredError: false,
                    visitedTypes: undefined,
                    symbolDepth: undefined,
                    inferTypeParameters: undefined,
                    approximateLength: 0
                };
                var resultingNode = cb(context);
                return context.encounteredError ? undefined : resultingNode;
            }
            function checkTruncationLength(context) {
                if (context.truncating)
                    return context.truncating;
                return context.truncating = !(context.flags & 1 /* NoTruncation */) && context.approximateLength > ts.defaultMaximumTruncationLength;
            }
            function typeToTypeNodeHelper(type, context) {
                if (cancellationToken && cancellationToken.throwIfCancellationRequested) {
                    cancellationToken.throwIfCancellationRequested();
                }
                var inTypeAlias = context.flags & 8388608 /* InTypeAlias */;
                context.flags &= ~8388608 /* InTypeAlias */;
                if (!type) {
                    context.encounteredError = true;
                    return undefined; // TODO: GH#18217
                }
                if (type.flags & 1 /* Any */) {
                    context.approximateLength += 3;
                    return ts.createKeywordTypeNode(121 /* AnyKeyword */);
                }
                if (type.flags & 2 /* Unknown */) {
                    return ts.createKeywordTypeNode(144 /* UnknownKeyword */);
                }
                if (type.flags & 4 /* String */) {
                    context.approximateLength += 6;
                    return ts.createKeywordTypeNode(139 /* StringKeyword */);
                }
                if (type.flags & 8 /* Number */) {
                    context.approximateLength += 6;
                    return ts.createKeywordTypeNode(136 /* NumberKeyword */);
                }
                if (type.flags & 64 /* BigInt */) {
                    context.approximateLength += 6;
                    return ts.createKeywordTypeNode(147 /* BigIntKeyword */);
                }
                if (type.flags & 16 /* Boolean */) {
                    context.approximateLength += 7;
                    return ts.createKeywordTypeNode(124 /* BooleanKeyword */);
                }
                if (type.flags & 1024 /* EnumLiteral */ && !(type.flags & 1048576 /* Union */)) {
                    var parentSymbol = getParentOfSymbol(type.symbol);
                    var parentName = symbolToTypeNode(parentSymbol, context, 67897832 /* Type */);
                    var enumLiteralName = getDeclaredTypeOfSymbol(parentSymbol) === type
                        ? parentName
                        : appendReferenceToType(parentName, ts.createTypeReferenceNode(ts.symbolName(type.symbol), /*typeArguments*/ undefined));
                    return enumLiteralName;
                }
                if (type.flags & 1056 /* EnumLike */) {
                    return symbolToTypeNode(type.symbol, context, 67897832 /* Type */);
                }
                if (type.flags & 128 /* StringLiteral */) {
                    context.approximateLength += (type.value.length + 2);
                    return ts.createLiteralTypeNode(ts.setEmitFlags(ts.createLiteral(type.value), 16777216 /* NoAsciiEscaping */));
                }
                if (type.flags & 256 /* NumberLiteral */) {
                    var value = type.value;
                    context.approximateLength += ("" + value).length;
                    return ts.createLiteralTypeNode(value < 0 ? ts.createPrefix(39 /* MinusToken */, ts.createLiteral(-value)) : ts.createLiteral(value));
                }
                if (type.flags & 2048 /* BigIntLiteral */) {
                    context.approximateLength += (ts.pseudoBigIntToString(type.value).length) + 1;
                    return ts.createLiteralTypeNode((ts.createLiteral(type.value)));
                }
                if (type.flags & 512 /* BooleanLiteral */) {
                    context.approximateLength += type.intrinsicName.length;
                    return type.intrinsicName === "true" ? ts.createTrue() : ts.createFalse();
                }
                if (type.flags & 8192 /* UniqueESSymbol */) {
                    if (!(context.flags & 1048576 /* AllowUniqueESSymbolType */)) {
                        if (isValueSymbolAccessible(type.symbol, context.enclosingDeclaration)) {
                            context.approximateLength += 6;
                            return symbolToTypeNode(type.symbol, context, 67220415 /* Value */);
                        }
                        if (context.tracker.reportInaccessibleUniqueSymbolError) {
                            context.tracker.reportInaccessibleUniqueSymbolError();
                        }
                    }
                    context.approximateLength += 13;
                    return ts.createTypeOperatorNode(143 /* UniqueKeyword */, ts.createKeywordTypeNode(140 /* SymbolKeyword */));
                }
                if (type.flags & 16384 /* Void */) {
                    context.approximateLength += 4;
                    return ts.createKeywordTypeNode(107 /* VoidKeyword */);
                }
                if (type.flags & 32768 /* Undefined */) {
                    context.approximateLength += 9;
                    return ts.createKeywordTypeNode(142 /* UndefinedKeyword */);
                }
                if (type.flags & 65536 /* Null */) {
                    context.approximateLength += 4;
                    return ts.createKeywordTypeNode(97 /* NullKeyword */);
                }
                if (type.flags & 131072 /* Never */) {
                    context.approximateLength += 5;
                    return ts.createKeywordTypeNode(133 /* NeverKeyword */);
                }
                if (type.flags & 4096 /* ESSymbol */) {
                    context.approximateLength += 6;
                    return ts.createKeywordTypeNode(140 /* SymbolKeyword */);
                }
                if (type.flags & 67108864 /* NonPrimitive */) {
                    context.approximateLength += 6;
                    return ts.createKeywordTypeNode(137 /* ObjectKeyword */);
                }
                if (isThisTypeParameter(type)) {
                    if (context.flags & 4194304 /* InObjectTypeLiteral */) {
                        if (!context.encounteredError && !(context.flags & 32768 /* AllowThisInObjectLiteral */)) {
                            context.encounteredError = true;
                        }
                        if (context.tracker.reportInaccessibleThisError) {
                            context.tracker.reportInaccessibleThisError();
                        }
                    }
                    context.approximateLength += 4;
                    return ts.createThis();
                }
                var objectFlags = ts.getObjectFlags(type);
                if (objectFlags & 4 /* Reference */) {
                    ts.Debug.assert(!!(type.flags & 524288 /* Object */));
                    return typeReferenceToTypeNode(type);
                }
                if (type.flags & 262144 /* TypeParameter */ || objectFlags & 3 /* ClassOrInterface */) {
                    if (type.flags & 262144 /* TypeParameter */ && ts.contains(context.inferTypeParameters, type)) {
                        context.approximateLength += (ts.symbolName(type.symbol).length + 6);
                        return ts.createInferTypeNode(typeParameterToDeclarationWithConstraint(type, context, /*constraintNode*/ undefined));
                    }
                    if (context.flags & 4 /* GenerateNamesForShadowedTypeParams */ &&
                        type.flags & 262144 /* TypeParameter */ &&
                        ts.length(type.symbol.declarations) &&
                        ts.isTypeParameterDeclaration(type.symbol.declarations[0]) &&
                        typeParameterShadowsNameInScope(type, context) &&
                        !isTypeSymbolAccessible(type.symbol, context.enclosingDeclaration)) {
                        var name = type.symbol.declarations[0].name;
                        context.approximateLength += ts.idText(name).length;
                        return ts.createTypeReferenceNode(ts.getGeneratedNameForNode(name, 16 /* Optimistic */ | 8 /* ReservedInNestedScopes */), /*typeArguments*/ undefined);
                    }
                    // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter.
                    return type.symbol
                        ? symbolToTypeNode(type.symbol, context, 67897832 /* Type */)
                        : ts.createTypeReferenceNode(ts.createIdentifier("?"), /*typeArguments*/ undefined);
                }
                if (!inTypeAlias && type.aliasSymbol && (context.flags & 16384 /* UseAliasDefinedOutsideCurrentScope */ || isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration))) {
                    var typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context);
                    if (isReservedMemberName(type.aliasSymbol.escapedName) && !(type.aliasSymbol.flags & 32 /* Class */))
                        return ts.createTypeReferenceNode(ts.createIdentifier(""), typeArgumentNodes);
                    return symbolToTypeNode(type.aliasSymbol, context, 67897832 /* Type */, typeArgumentNodes);
                }
                if (type.flags & (1048576 /* Union */ | 2097152 /* Intersection */)) {
                    var types = type.flags & 1048576 /* Union */ ? formatUnionTypes(type.types) : type.types;
                    if (ts.length(types) === 1) {
                        return typeToTypeNodeHelper(types[0], context);
                    }
                    var typeNodes = mapToTypeNodes(types, context, /*isBareList*/ true);
                    if (typeNodes && typeNodes.length > 0) {
                        var unionOrIntersectionTypeNode = ts.createUnionOrIntersectionTypeNode(type.flags & 1048576 /* Union */ ? 174 /* UnionType */ : 175 /* IntersectionType */, typeNodes);
                        return unionOrIntersectionTypeNode;
                    }
                    else {
                        if (!context.encounteredError && !(context.flags & 262144 /* AllowEmptyUnionOrIntersection */)) {
                            context.encounteredError = true;
                        }
                        return undefined; // TODO: GH#18217
                    }
                }
                if (objectFlags & (16 /* Anonymous */ | 32 /* Mapped */)) {
                    ts.Debug.assert(!!(type.flags & 524288 /* Object */));
                    // The type is an object literal type.
                    return createAnonymousTypeNode(type);
                }
                if (type.flags & 4194304 /* Index */) {
                    var indexedType = type.type;
                    context.approximateLength += 6;
                    var indexTypeNode = typeToTypeNodeHelper(indexedType, context);
                    return ts.createTypeOperatorNode(indexTypeNode);
                }
                if (type.flags & 8388608 /* IndexedAccess */) {
                    var objectTypeNode = typeToTypeNodeHelper(type.objectType, context);
                    var indexTypeNode = typeToTypeNodeHelper(type.indexType, context);
                    context.approximateLength += 2;
                    return ts.createIndexedAccessTypeNode(objectTypeNode, indexTypeNode);
                }
                if (type.flags & 16777216 /* Conditional */) {
                    var checkTypeNode = typeToTypeNodeHelper(type.checkType, context);
                    var saveInferTypeParameters = context.inferTypeParameters;
                    context.inferTypeParameters = type.root.inferTypeParameters;
                    var extendsTypeNode = typeToTypeNodeHelper(type.extendsType, context);
                    context.inferTypeParameters = saveInferTypeParameters;
                    var trueTypeNode = typeToTypeNodeHelper(getTrueTypeFromConditionalType(type), context);
                    var falseTypeNode = typeToTypeNodeHelper(getFalseTypeFromConditionalType(type), context);
                    context.approximateLength += 15;
                    return ts.createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode);
                }
                if (type.flags & 33554432 /* Substitution */) {
                    return typeToTypeNodeHelper(type.typeVariable, context);
                }
                return ts.Debug.fail("Should be unreachable.");
                function createMappedTypeNodeFromType(type) {
                    ts.Debug.assert(!!(type.flags & 524288 /* Object */));
                    var readonlyToken = type.declaration.readonlyToken ? ts.createToken(type.declaration.readonlyToken.kind) : undefined;
                    var questionToken = type.declaration.questionToken ? ts.createToken(type.declaration.questionToken.kind) : undefined;
                    var appropriateConstraintTypeNode;
                    if (isMappedTypeWithKeyofConstraintDeclaration(type)) {
                        // We have a { [P in keyof T]: X }
                        // We do this to ensure we retain the toplevel keyof-ness of the type which may be lost due to keyof distribution during `getConstraintTypeFromMappedType`
                        appropriateConstraintTypeNode = ts.createTypeOperatorNode(typeToTypeNodeHelper(getModifiersTypeFromMappedType(type), context));
                    }
                    else {
                        appropriateConstraintTypeNode = typeToTypeNodeHelper(getConstraintTypeFromMappedType(type), context);
                    }
                    var typeParameterNode = typeParameterToDeclarationWithConstraint(getTypeParameterFromMappedType(type), context, appropriateConstraintTypeNode);
                    var templateTypeNode = typeToTypeNodeHelper(getTemplateTypeFromMappedType(type), context);
                    var mappedTypeNode = ts.createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode);
                    context.approximateLength += 10;
                    return ts.setEmitFlags(mappedTypeNode, 1 /* SingleLine */);
                }
                function createAnonymousTypeNode(type) {
                    var typeId = "" + type.id;
                    var symbol = type.symbol;
                    var id;
                    if (symbol) {
                        var isConstructorObject = ts.getObjectFlags(type) & 16 /* Anonymous */ && type.symbol && type.symbol.flags & 32 /* Class */;
                        id = (isConstructorObject ? "+" : "") + getSymbolId(symbol);
                        if (isJSConstructor(symbol.valueDeclaration)) {
                            // Instance and static types share the same symbol; only add 'typeof' for the static side.
                            var isInstanceType = type === getInferredClassType(symbol) ? 67897832 /* Type */ : 67220415 /* Value */;
                            return symbolToTypeNode(symbol, context, isInstanceType);
                        }
                        // Always use 'typeof T' for type of class, enum, and module objects
                        else if (symbol.flags & 32 /* Class */ && !getBaseTypeVariableOfClass(symbol) && !(symbol.valueDeclaration.kind === 210 /* ClassExpression */ && context.flags & 2048 /* WriteClassExpressionAsTypeLiteral */) ||
                            symbol.flags & (384 /* Enum */ | 512 /* ValueModule */) ||
                            shouldWriteTypeOfFunctionSymbol()) {
                            return symbolToTypeNode(symbol, context, 67220415 /* Value */);
                        }
                        else if (context.visitedTypes && context.visitedTypes.has(typeId)) {
                            // If type is an anonymous type literal in a type alias declaration, use type alias name
                            var typeAlias = getTypeAliasForTypeLiteral(type);
                            if (typeAlias) {
                                // The specified symbol flags need to be reinterpreted as type flags
                                return symbolToTypeNode(typeAlias, context, 67897832 /* Type */);
                            }
                            else {
                                return createElidedInformationPlaceholder(context);
                            }
                        }
                        else {
                            // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead
                            // of types allows us to catch circular references to instantiations of the same anonymous type
                            if (!context.visitedTypes) {
                                context.visitedTypes = ts.createMap();
                            }
                            if (!context.symbolDepth) {
                                context.symbolDepth = ts.createMap();
                            }
                            var depth = context.symbolDepth.get(id) || 0;
                            if (depth > 10) {
                                return createElidedInformationPlaceholder(context);
                            }
                            context.symbolDepth.set(id, depth + 1);
                            context.visitedTypes.set(typeId, true);
                            var result = createTypeNodeFromObjectType(type);
                            context.visitedTypes.delete(typeId);
                            context.symbolDepth.set(id, depth);
                            return result;
                        }
                    }
                    else {
                        // Anonymous types without a symbol are never circular.
                        return createTypeNodeFromObjectType(type);
                    }
                    function shouldWriteTypeOfFunctionSymbol() {
                        var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */) && // typeof static method
                            ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32 /* Static */); });
                        var isNonLocalFunctionSymbol = !!(symbol.flags & 16 /* Function */) &&
                            (symbol.parent || // is exported function symbol
                                ts.forEach(symbol.declarations, function (declaration) {
                                    return declaration.parent.kind === 285 /* SourceFile */ || declaration.parent.kind === 246 /* ModuleBlock */;
                                }));
                        if (isStaticMethodSymbol || isNonLocalFunctionSymbol) {
                            // typeof is allowed only for static/non local functions
                            return (!!(context.flags & 4096 /* UseTypeOfFunction */) || (context.visitedTypes && context.visitedTypes.has(typeId))) && // it is type of the symbol uses itself recursively
                                (!(context.flags & 8 /* UseStructuralFallback */) || isValueSymbolAccessible(symbol, context.enclosingDeclaration)); // TODO: GH#18217 // And the build is going to succeed without visibility error or there is no structural fallback allowed
                        }
                    }
                }
                function createTypeNodeFromObjectType(type) {
                    if (isGenericMappedType(type)) {
                        return createMappedTypeNodeFromType(type);
                    }
                    var resolved = resolveStructuredTypeMembers(type);
                    if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
                        if (!resolved.callSignatures.length && !resolved.constructSignatures.length) {
                            context.approximateLength += 2;
                            return ts.setEmitFlags(ts.createTypeLiteralNode(/*members*/ undefined), 1 /* SingleLine */);
                        }
                        if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) {
                            var signature = resolved.callSignatures[0];
                            var signatureNode = signatureToSignatureDeclarationHelper(signature, 166 /* FunctionType */, context);
                            return signatureNode;
                        }
                        if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) {
                            var signature = resolved.constructSignatures[0];
                            var signatureNode = signatureToSignatureDeclarationHelper(signature, 167 /* ConstructorType */, context);
                            return signatureNode;
                        }
                    }
                    var savedFlags = context.flags;
                    context.flags |= 4194304 /* InObjectTypeLiteral */;
                    var members = createTypeNodesFromResolvedType(resolved);
                    context.flags = savedFlags;
                    var typeLiteralNode = ts.createTypeLiteralNode(members);
                    context.approximateLength += 2;
                    return ts.setEmitFlags(typeLiteralNode, (context.flags & 1024 /* MultilineObjectLiterals */) ? 0 : 1 /* SingleLine */);
                }
                function typeReferenceToTypeNode(type) {
                    var typeArguments = type.typeArguments || ts.emptyArray;
                    if (type.target === globalArrayType || type.target === globalReadonlyArrayType) {
                        if (context.flags & 2 /* WriteArrayAsGenericType */) {
                            var typeArgumentNode = typeToTypeNodeHelper(typeArguments[0], context);
                            return ts.createTypeReferenceNode(type.target === globalArrayType ? "Array" : "ReadonlyArray", [typeArgumentNode]);
                        }
                        var elementType = typeToTypeNodeHelper(typeArguments[0], context);
                        var arrayType = ts.createArrayTypeNode(elementType);
                        return type.target === globalArrayType ? arrayType : ts.createTypeOperatorNode(134 /* ReadonlyKeyword */, arrayType);
                    }
                    else if (type.target.objectFlags & 8 /* Tuple */) {
                        if (typeArguments.length > 0) {
                            var arity = getTypeReferenceArity(type);
                            var tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, arity), context);
                            var hasRestElement = type.target.hasRestElement;
                            if (tupleConstituentNodes) {
                                for (var i = type.target.minLength; i < Math.min(arity, tupleConstituentNodes.length); i++) {
                                    tupleConstituentNodes[i] = hasRestElement && i === arity - 1 ?
                                        ts.createRestTypeNode(ts.createArrayTypeNode(tupleConstituentNodes[i])) :
                                        ts.createOptionalTypeNode(tupleConstituentNodes[i]);
                                }
                                var tupleTypeNode = ts.createTupleTypeNode(tupleConstituentNodes);
                                return type.target.readonly ? ts.createTypeOperatorNode(134 /* ReadonlyKeyword */, tupleTypeNode) : tupleTypeNode;
                            }
                        }
                        if (context.encounteredError || (context.flags & 524288 /* AllowEmptyTuple */)) {
                            var tupleTypeNode = ts.createTupleTypeNode([]);
                            return type.target.readonly ? ts.createTypeOperatorNode(134 /* ReadonlyKeyword */, tupleTypeNode) : tupleTypeNode;
                        }
                        context.encounteredError = true;
                        return undefined; // TODO: GH#18217
                    }
                    else if (context.flags & 2048 /* WriteClassExpressionAsTypeLiteral */ &&
                        type.symbol.valueDeclaration &&
                        ts.isClassLike(type.symbol.valueDeclaration) &&
                        !isValueSymbolAccessible(type.symbol, context.enclosingDeclaration)) {
                        return createAnonymousTypeNode(type);
                    }
                    else {
                        var outerTypeParameters = type.target.outerTypeParameters;
                        var i = 0;
                        var resultType = void 0;
                        if (outerTypeParameters) {
                            var length_1 = outerTypeParameters.length;
                            while (i < length_1) {
                                // Find group of type arguments for type parameters with the same declaring container.
                                var start = i;
                                var parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]);
                                do {
                                    i++;
                                } while (i < length_1 && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent);
                                // When type parameters are their own type arguments for the whole group (i.e. we have
                                // the default outer type arguments), we don't show the group.
                                if (!ts.rangeEquals(outerTypeParameters, typeArguments, start, i)) {
                                    var typeArgumentSlice = mapToTypeNodes(typeArguments.slice(start, i), context);
                                    var flags_2 = context.flags;
                                    context.flags |= 16 /* ForbidIndexedAccessSymbolReferences */;
                                    var ref = symbolToTypeNode(parent, context, 67897832 /* Type */, typeArgumentSlice);
                                    context.flags = flags_2;
                                    resultType = !resultType ? ref : appendReferenceToType(resultType, ref);
                                }
                            }
                        }
                        var typeArgumentNodes = void 0;
                        if (typeArguments.length > 0) {
                            var typeParameterCount = (type.target.typeParameters || ts.emptyArray).length;
                            typeArgumentNodes = mapToTypeNodes(typeArguments.slice(i, typeParameterCount), context);
                        }
                        var flags = context.flags;
                        context.flags |= 16 /* ForbidIndexedAccessSymbolReferences */;
                        var finalRef = symbolToTypeNode(type.symbol, context, 67897832 /* Type */, typeArgumentNodes);
                        context.flags = flags;
                        return !resultType ? finalRef : appendReferenceToType(resultType, finalRef);
                    }
                }
                function appendReferenceToType(root, ref) {
                    if (ts.isImportTypeNode(root)) {
                        // first shift type arguments
                        var innerParams = root.typeArguments;
                        if (root.qualifier) {
                            (ts.isIdentifier(root.qualifier) ? root.qualifier : root.qualifier.right).typeArguments = innerParams;
                        }
                        root.typeArguments = ref.typeArguments;
                        // then move qualifiers
                        var ids = getAccessStack(ref);
                        for (var _i = 0, ids_1 = ids; _i < ids_1.length; _i++) {
                            var id = ids_1[_i];
                            root.qualifier = root.qualifier ? ts.createQualifiedName(root.qualifier, id) : id;
                        }
                        return root;
                    }
                    else {
                        // first shift type arguments
                        var innerParams = root.typeArguments;
                        (ts.isIdentifier(root.typeName) ? root.typeName : root.typeName.right).typeArguments = innerParams;
                        root.typeArguments = ref.typeArguments;
                        // then move qualifiers
                        var ids = getAccessStack(ref);
                        for (var _a = 0, ids_2 = ids; _a < ids_2.length; _a++) {
                            var id = ids_2[_a];
                            root.typeName = ts.createQualifiedName(root.typeName, id);
                        }
                        return root;
                    }
                }
                function getAccessStack(ref) {
                    var state = ref.typeName;
                    var ids = [];
                    while (!ts.isIdentifier(state)) {
                        ids.unshift(state.right);
                        state = state.left;
                    }
                    ids.unshift(state);
                    return ids;
                }
                function createTypeNodesFromResolvedType(resolvedType) {
                    if (checkTruncationLength(context)) {
                        return [ts.createPropertySignature(/*modifiers*/ undefined, "...", /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined)];
                    }
                    var typeElements = [];
                    for (var _i = 0, _a = resolvedType.callSignatures; _i < _a.length; _i++) {
                        var signature = _a[_i];
                        typeElements.push(signatureToSignatureDeclarationHelper(signature, 161 /* CallSignature */, context));
                    }
                    for (var _b = 0, _c = resolvedType.constructSignatures; _b < _c.length; _b++) {
                        var signature = _c[_b];
                        typeElements.push(signatureToSignatureDeclarationHelper(signature, 162 /* ConstructSignature */, context));
                    }
                    if (resolvedType.stringIndexInfo) {
                        var indexSignature = void 0;
                        if (resolvedType.objectFlags & 2048 /* ReverseMapped */) {
                            indexSignature = indexInfoToIndexSignatureDeclarationHelper(createIndexInfo(anyType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration), 0 /* String */, context);
                            indexSignature.type = createElidedInformationPlaceholder(context);
                        }
                        else {
                            indexSignature = indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, 0 /* String */, context);
                        }
                        typeElements.push(indexSignature);
                    }
                    if (resolvedType.numberIndexInfo) {
                        typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, 1 /* Number */, context));
                    }
                    var properties = resolvedType.properties;
                    if (!properties) {
                        return typeElements;
                    }
                    var i = 0;
                    for (var _d = 0, properties_1 = properties; _d < properties_1.length; _d++) {
                        var propertySymbol = properties_1[_d];
                        i++;
                        if (context.flags & 2048 /* WriteClassExpressionAsTypeLiteral */) {
                            if (propertySymbol.flags & 4194304 /* Prototype */) {
                                continue;
                            }
                            if (ts.getDeclarationModifierFlagsFromSymbol(propertySymbol) & (8 /* Private */ | 16 /* Protected */) && context.tracker.reportPrivateInBaseOfClassExpression) {
                                context.tracker.reportPrivateInBaseOfClassExpression(ts.unescapeLeadingUnderscores(propertySymbol.escapedName));
                            }
                        }
                        if (checkTruncationLength(context) && (i + 2 < properties.length - 1)) {
                            typeElements.push(ts.createPropertySignature(/*modifiers*/ undefined, "... " + (properties.length - i) + " more ...", /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined));
                            addPropertyToElementList(properties[properties.length - 1], context, typeElements);
                            break;
                        }
                        addPropertyToElementList(propertySymbol, context, typeElements);
                    }
                    return typeElements.length ? typeElements : undefined;
                }
            }
            function createElidedInformationPlaceholder(context) {
                context.approximateLength += 3;
                if (!(context.flags & 1 /* NoTruncation */)) {
                    return ts.createTypeReferenceNode(ts.createIdentifier("..."), /*typeArguments*/ undefined);
                }
                return ts.createKeywordTypeNode(121 /* AnyKeyword */);
            }
            function addPropertyToElementList(propertySymbol, context, typeElements) {
                var propertyIsReverseMapped = !!(ts.getCheckFlags(propertySymbol) & 8192 /* ReverseMapped */);
                var propertyType = propertyIsReverseMapped && context.flags & 33554432 /* InReverseMappedType */ ?
                    anyType : getTypeOfSymbol(propertySymbol);
                var saveEnclosingDeclaration = context.enclosingDeclaration;
                context.enclosingDeclaration = undefined;
                if (context.tracker.trackSymbol && ts.getCheckFlags(propertySymbol) & 4096 /* Late */) {
                    var decl = ts.first(propertySymbol.declarations);
                    if (hasLateBindableName(decl)) {
                        trackComputedName(decl.name, saveEnclosingDeclaration, context);
                    }
                }
                var propertyName = symbolToName(propertySymbol, context, 67220415 /* Value */, /*expectsIdentifier*/ true);
                context.approximateLength += (ts.symbolName(propertySymbol).length + 1);
                context.enclosingDeclaration = saveEnclosingDeclaration;
                var optionalToken = propertySymbol.flags & 16777216 /* Optional */ ? ts.createToken(56 /* QuestionToken */) : undefined;
                if (propertySymbol.flags & (16 /* Function */ | 8192 /* Method */) && !getPropertiesOfObjectType(propertyType).length && !isReadonlySymbol(propertySymbol)) {
                    var signatures = getSignaturesOfType(propertyType, 0 /* Call */);
                    for (var _i = 0, signatures_1 = signatures; _i < signatures_1.length; _i++) {
                        var signature = signatures_1[_i];
                        var methodDeclaration = signatureToSignatureDeclarationHelper(signature, 156 /* MethodSignature */, context);
                        methodDeclaration.name = propertyName;
                        methodDeclaration.questionToken = optionalToken;
                        if (propertySymbol.valueDeclaration) {
                            // Copy comments to node for declaration emit
                            ts.setCommentRange(methodDeclaration, propertySymbol.valueDeclaration);
                        }
                        typeElements.push(methodDeclaration);
                    }
                }
                else {
                    var savedFlags = context.flags;
                    context.flags |= propertyIsReverseMapped ? 33554432 /* InReverseMappedType */ : 0;
                    var propertyTypeNode = void 0;
                    if (propertyIsReverseMapped && !!(savedFlags & 33554432 /* InReverseMappedType */)) {
                        propertyTypeNode = createElidedInformationPlaceholder(context);
                    }
                    else {
                        propertyTypeNode = propertyType ? typeToTypeNodeHelper(propertyType, context) : ts.createKeywordTypeNode(121 /* AnyKeyword */);
                    }
                    context.flags = savedFlags;
                    var modifiers = isReadonlySymbol(propertySymbol) ? [ts.createToken(134 /* ReadonlyKeyword */)] : undefined;
                    if (modifiers) {
                        context.approximateLength += 9;
                    }
                    var propertySignature = ts.createPropertySignature(modifiers, propertyName, optionalToken, propertyTypeNode, 
                    /*initializer*/ undefined);
                    if (propertySymbol.valueDeclaration) {
                        // Copy comments to node for declaration emit
                        ts.setCommentRange(propertySignature, propertySymbol.valueDeclaration);
                    }
                    typeElements.push(propertySignature);
                }
            }
            function mapToTypeNodes(types, context, isBareList) {
                if (ts.some(types)) {
                    if (checkTruncationLength(context)) {
                        if (!isBareList) {
                            return [ts.createTypeReferenceNode("...", /*typeArguments*/ undefined)];
                        }
                        else if (types.length > 2) {
                            return [
                                typeToTypeNodeHelper(types[0], context),
                                ts.createTypeReferenceNode("... " + (types.length - 2) + " more ...", /*typeArguments*/ undefined),
                                typeToTypeNodeHelper(types[types.length - 1], context)
                            ];
                        }
                    }
                    var result = [];
                    var i = 0;
                    for (var _i = 0, types_1 = types; _i < types_1.length; _i++) {
                        var type = types_1[_i];
                        i++;
                        if (checkTruncationLength(context) && (i + 2 < types.length - 1)) {
                            result.push(ts.createTypeReferenceNode("... " + (types.length - i) + " more ...", /*typeArguments*/ undefined));
                            var typeNode_1 = typeToTypeNodeHelper(types[types.length - 1], context);
                            if (typeNode_1) {
                                result.push(typeNode_1);
                            }
                            break;
                        }
                        context.approximateLength += 2; // Account for whitespace + separator
                        var typeNode = typeToTypeNodeHelper(type, context);
                        if (typeNode) {
                            result.push(typeNode);
                        }
                    }
                    return result;
                }
            }
            function indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context) {
                var name = ts.getNameFromIndexInfo(indexInfo) || "x";
                var indexerTypeNode = ts.createKeywordTypeNode(kind === 0 /* String */ ? 139 /* StringKeyword */ : 136 /* NumberKeyword */);
                var indexingParameter = ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, name, 
                /*questionToken*/ undefined, indexerTypeNode, 
                /*initializer*/ undefined);
                var typeNode = typeToTypeNodeHelper(indexInfo.type || anyType, context);
                if (!indexInfo.type && !(context.flags & 2097152 /* AllowEmptyIndexInfoType */)) {
                    context.encounteredError = true;
                }
                context.approximateLength += (name.length + 4);
                return ts.createIndexSignature(
                /*decorators*/ undefined, indexInfo.isReadonly ? [ts.createToken(134 /* ReadonlyKeyword */)] : undefined, [indexingParameter], typeNode);
            }
            function signatureToSignatureDeclarationHelper(signature, kind, context) {
                var typeParameters;
                var typeArguments;
                if (context.flags & 32 /* WriteTypeArgumentsOfSignature */ && signature.target && signature.mapper && signature.target.typeParameters) {
                    typeArguments = signature.target.typeParameters.map(function (parameter) { return typeToTypeNodeHelper(instantiateType(parameter, signature.mapper), context); });
                }
                else {
                    typeParameters = signature.typeParameters && signature.typeParameters.map(function (parameter) { return typeParameterToDeclaration(parameter, context); });
                }
                var parameters = getExpandedParameters(signature).map(function (parameter) { return symbolToParameterDeclaration(parameter, context, kind === 158 /* Constructor */); });
                if (signature.thisParameter) {
                    var thisParameter = symbolToParameterDeclaration(signature.thisParameter, context);
                    parameters.unshift(thisParameter);
                }
                var returnTypeNode;
                var typePredicate = getTypePredicateOfSignature(signature);
                if (typePredicate) {
                    var parameterName = typePredicate.kind === 1 /* Identifier */ ?
                        ts.setEmitFlags(ts.createIdentifier(typePredicate.parameterName), 16777216 /* NoAsciiEscaping */) :
                        ts.createThisTypeNode();
                    var typeNode = typeToTypeNodeHelper(typePredicate.type, context);
                    returnTypeNode = ts.createTypePredicateNode(parameterName, typeNode);
                }
                else {
                    var returnType = getReturnTypeOfSignature(signature);
                    returnTypeNode = returnType && typeToTypeNodeHelper(returnType, context);
                }
                if (context.flags & 256 /* SuppressAnyReturnType */) {
                    if (returnTypeNode && returnTypeNode.kind === 121 /* AnyKeyword */) {
                        returnTypeNode = undefined;
                    }
                }
                else if (!returnTypeNode) {
                    returnTypeNode = ts.createKeywordTypeNode(121 /* AnyKeyword */);
                }
                context.approximateLength += 3; // Usually a signature contributes a few more characters than this, but 3 is the minimum
                return ts.createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode, typeArguments);
            }
            function typeParameterShadowsNameInScope(type, context) {
                return !!resolveName(context.enclosingDeclaration, type.symbol.escapedName, 67897832 /* Type */, /*nameNotFoundArg*/ undefined, type.symbol.escapedName, /*isUse*/ false);
            }
            function typeParameterToDeclarationWithConstraint(type, context, constraintNode) {
                var savedContextFlags = context.flags;
                context.flags &= ~512 /* WriteTypeParametersInQualifiedName */; // Avoids potential infinite loop when building for a claimspace with a generic
                var shouldUseGeneratedName = context.flags & 4 /* GenerateNamesForShadowedTypeParams */ &&
                    type.symbol.declarations && type.symbol.declarations[0] &&
                    ts.isTypeParameterDeclaration(type.symbol.declarations[0]) &&
                    typeParameterShadowsNameInScope(type, context);
                var name = shouldUseGeneratedName
                    ? ts.getGeneratedNameForNode(type.symbol.declarations[0].name, 16 /* Optimistic */ | 8 /* ReservedInNestedScopes */)
                    : symbolToName(type.symbol, context, 67897832 /* Type */, /*expectsIdentifier*/ true);
                var defaultParameter = getDefaultFromTypeParameter(type);
                var defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, context);
                context.flags = savedContextFlags;
                return ts.createTypeParameterDeclaration(name, constraintNode, defaultParameterNode);
            }
            function typeParameterToDeclaration(type, context, constraint) {
                if (constraint === void 0) { constraint = getConstraintOfTypeParameter(type); }
                var constraintNode = constraint && typeToTypeNodeHelper(constraint, context);
                return typeParameterToDeclarationWithConstraint(type, context, constraintNode);
            }
            function symbolToParameterDeclaration(parameterSymbol, context, preserveModifierFlags) {
                var parameterDeclaration = ts.getDeclarationOfKind(parameterSymbol, 152 /* Parameter */);
                if (!parameterDeclaration && !isTransientSymbol(parameterSymbol)) {
                    parameterDeclaration = ts.getDeclarationOfKind(parameterSymbol, 305 /* JSDocParameterTag */);
                }
                var parameterType = getTypeOfSymbol(parameterSymbol);
                if (parameterDeclaration && isRequiredInitializedParameter(parameterDeclaration)) {
                    parameterType = getOptionalType(parameterType);
                }
                var parameterTypeNode = typeToTypeNodeHelper(parameterType, context);
                var modifiers = !(context.flags & 8192 /* OmitParameterModifiers */) && preserveModifierFlags && parameterDeclaration && parameterDeclaration.modifiers ? parameterDeclaration.modifiers.map(ts.getSynthesizedClone) : undefined;
                var isRest = parameterDeclaration && ts.isRestParameter(parameterDeclaration) || ts.getCheckFlags(parameterSymbol) & 32768 /* RestParameter */;
                var dotDotDotToken = isRest ? ts.createToken(25 /* DotDotDotToken */) : undefined;
                var name = parameterDeclaration
                    ? parameterDeclaration.name ?
                        parameterDeclaration.name.kind === 73 /* Identifier */ ? ts.setEmitFlags(ts.getSynthesizedClone(parameterDeclaration.name), 16777216 /* NoAsciiEscaping */) :
                            parameterDeclaration.name.kind === 149 /* QualifiedName */ ? ts.setEmitFlags(ts.getSynthesizedClone(parameterDeclaration.name.right), 16777216 /* NoAsciiEscaping */) :
                                cloneBindingName(parameterDeclaration.name) :
                        ts.symbolName(parameterSymbol)
                    : ts.symbolName(parameterSymbol);
                var isOptional = parameterDeclaration && isOptionalParameter(parameterDeclaration) || ts.getCheckFlags(parameterSymbol) & 16384 /* OptionalParameter */;
                var questionToken = isOptional ? ts.createToken(56 /* QuestionToken */) : undefined;
                var parameterNode = ts.createParameter(
                /*decorators*/ undefined, modifiers, dotDotDotToken, name, questionToken, parameterTypeNode, 
                /*initializer*/ undefined);
                context.approximateLength += ts.symbolName(parameterSymbol).length + 3;
                return parameterNode;
                function cloneBindingName(node) {
                    return elideInitializerAndSetEmitFlags(node);
                    function elideInitializerAndSetEmitFlags(node) {
                        if (context.tracker.trackSymbol && ts.isComputedPropertyName(node) && isLateBindableName(node)) {
                            trackComputedName(node, context.enclosingDeclaration, context);
                        }
                        var visited = ts.visitEachChild(node, elideInitializerAndSetEmitFlags, ts.nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags);
                        var clone = ts.nodeIsSynthesized(visited) ? visited : ts.getSynthesizedClone(visited);
                        if (clone.kind === 187 /* BindingElement */) {
                            clone.initializer = undefined;
                        }
                        return ts.setEmitFlags(clone, 1 /* SingleLine */ | 16777216 /* NoAsciiEscaping */);
                    }
                }
            }
            function trackComputedName(node, enclosingDeclaration, context) {
                if (!context.tracker.trackSymbol)
                    return;
                // get symbol of the first identifier of the entityName
                var firstIdentifier = getFirstIdentifier(node.expression);
                var name = resolveName(firstIdentifier, firstIdentifier.escapedText, 67220415 /* Value */ | 1048576 /* ExportValue */, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
                if (name) {
                    context.tracker.trackSymbol(name, enclosingDeclaration, 67220415 /* Value */);
                }
            }
            function lookupSymbolChain(symbol, context, meaning, yieldModuleSymbol) {
                context.tracker.trackSymbol(symbol, context.enclosingDeclaration, meaning); // TODO: GH#18217
                // Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration.
                var chain;
                var isTypeParameter = symbol.flags & 262144 /* TypeParameter */;
                if (!isTypeParameter && (context.enclosingDeclaration || context.flags & 64 /* UseFullyQualifiedType */) && !(context.flags & 134217728 /* DoNotIncludeSymbolChain */)) {
                    chain = ts.Debug.assertDefined(getSymbolChain(symbol, meaning, /*endOfChain*/ true));
                    ts.Debug.assert(chain && chain.length > 0);
                }
                else {
                    chain = [symbol];
                }
                return chain;
                /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */
                function getSymbolChain(symbol, meaning, endOfChain) {
                    var accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & 128 /* UseOnlyExternalAliasing */));
                    var parentSpecifiers;
                    if (!accessibleSymbolChain ||
                        needsQualification(accessibleSymbolChain[0], context.enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) {
                        // Go up and add our parent.
                        var parents_1 = getContainersOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol, context.enclosingDeclaration);
                        if (ts.length(parents_1)) {
                            parentSpecifiers = parents_1.map(function (symbol) {
                                return ts.some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)
                                    ? getSpecifierForModuleSymbol(symbol, context)
                                    : undefined;
                            });
                            var indices = parents_1.map(function (_, i) { return i; });
                            indices.sort(sortByBestName);
                            var sortedParents = indices.map(function (i) { return parents_1[i]; });
                            for (var _i = 0, sortedParents_1 = sortedParents; _i < sortedParents_1.length; _i++) {
                                var parent = sortedParents_1[_i];
                                var parentChain = getSymbolChain(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false);
                                if (parentChain) {
                                    accessibleSymbolChain = parentChain.concat(accessibleSymbolChain || [getAliasForSymbolInContainer(parent, symbol) || symbol]);
                                    break;
                                }
                            }
                        }
                    }
                    if (accessibleSymbolChain) {
                        return accessibleSymbolChain;
                    }
                    if (
                    // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols.
                    endOfChain ||
                        // If a parent symbol is an anonymous type, don't write it.
                        !(symbol.flags & (2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */))) {
                        // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.)
                        if (!endOfChain && !yieldModuleSymbol && !!ts.forEach(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
                            return;
                        }
                        return [symbol];
                    }
                    function sortByBestName(a, b) {
                        var specifierA = parentSpecifiers[a];
                        var specifierB = parentSpecifiers[b];
                        if (specifierA && specifierB) {
                            var isBRelative = ts.pathIsRelative(specifierB);
                            if (ts.pathIsRelative(specifierA) === isBRelative) {
                                // Both relative or both non-relative, sort by number of parts
                                return ts.moduleSpecifiers.countPathComponents(specifierA) - ts.moduleSpecifiers.countPathComponents(specifierB);
                            }
                            if (isBRelative) {
                                // A is non-relative, B is relative: prefer A
                                return -1;
                            }
                            // A is relative, B is non-relative: prefer B
                            return 1;
                        }
                        return 0;
                    }
                }
            }
            function typeParametersToTypeParameterDeclarations(symbol, context) {
                var typeParameterNodes;
                var targetSymbol = getTargetSymbol(symbol);
                if (targetSymbol.flags & (32 /* Class */ | 64 /* Interface */ | 524288 /* TypeAlias */)) {
                    typeParameterNodes = ts.createNodeArray(ts.map(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), function (tp) { return typeParameterToDeclaration(tp, context); }));
                }
                return typeParameterNodes;
            }
            function lookupTypeParameterNodes(chain, index, context) {
                ts.Debug.assert(chain && 0 <= index && index < chain.length);
                var symbol = chain[index];
                var symbolId = "" + getSymbolId(symbol);
                if (context.typeParameterSymbolList && context.typeParameterSymbolList.get(symbolId)) {
                    return undefined;
                }
                (context.typeParameterSymbolList || (context.typeParameterSymbolList = ts.createMap())).set(symbolId, true);
                var typeParameterNodes;
                if (context.flags & 512 /* WriteTypeParametersInQualifiedName */ && index < (chain.length - 1)) {
                    var parentSymbol = symbol;
                    var nextSymbol = chain[index + 1];
                    if (ts.getCheckFlags(nextSymbol) & 1 /* Instantiated */) {
                        var params = getTypeParametersOfClassOrInterface(parentSymbol.flags & 2097152 /* Alias */ ? resolveAlias(parentSymbol) : parentSymbol);
                        typeParameterNodes = mapToTypeNodes(ts.map(params, nextSymbol.mapper), context);
                    }
                    else {
                        typeParameterNodes = typeParametersToTypeParameterDeclarations(symbol, context);
                    }
                }
                return typeParameterNodes;
            }
            /**
             * Given A[B][C][D], finds A[B]
             */
            function getTopmostIndexedAccessType(top) {
                if (ts.isIndexedAccessTypeNode(top.objectType)) {
                    return getTopmostIndexedAccessType(top.objectType);
                }
                return top;
            }
            function getSpecifierForModuleSymbol(symbol, context) {
                var file = ts.getDeclarationOfKind(symbol, 285 /* SourceFile */);
                if (file && file.moduleName !== undefined) {
                    // Use the amd name if it is available
                    return file.moduleName;
                }
                if (!file) {
                    if (context.tracker.trackReferencedAmbientModule) {
                        var ambientDecls = ts.filter(symbol.declarations, ts.isAmbientModule);
                        if (ts.length(ambientDecls)) {
                            for (var _i = 0, ambientDecls_1 = ambientDecls; _i < ambientDecls_1.length; _i++) {
                                var decl = ambientDecls_1[_i];
                                context.tracker.trackReferencedAmbientModule(decl, symbol);
                            }
                        }
                    }
                    if (ambientModuleSymbolRegex.test(symbol.escapedName)) {
                        return symbol.escapedName.substring(1, symbol.escapedName.length - 1);
                    }
                }
                if (!context.enclosingDeclaration || !context.tracker.moduleResolverHost) {
                    // If there's no context declaration, we can't lookup a non-ambient specifier, so we just use the symbol name
                    if (ambientModuleSymbolRegex.test(symbol.escapedName)) {
                        return symbol.escapedName.substring(1, symbol.escapedName.length - 1);
                    }
                    return ts.getSourceFileOfNode(ts.getNonAugmentationDeclaration(symbol)).fileName; // A resolver may not be provided for baselines and errors - in those cases we use the fileName in full
                }
                var contextFile = ts.getSourceFileOfNode(ts.getOriginalNode(context.enclosingDeclaration));
                var links = getSymbolLinks(symbol);
                var specifier = links.specifierCache && links.specifierCache.get(contextFile.path);
                if (!specifier) {
                    var isBundle_1 = (compilerOptions.out || compilerOptions.outFile);
                    // For declaration bundles, we need to generate absolute paths relative to the common source dir for imports,
                    // just like how the declaration emitter does for the ambient module declarations - we can easily accomplish this
                    // using the `baseUrl` compiler option (which we would otherwise never use in declaration emit) and a non-relative
                    // specifier preference
                    var moduleResolverHost = context.tracker.moduleResolverHost;
                    var specifierCompilerOptions = isBundle_1 ? __assign({}, compilerOptions, { baseUrl: moduleResolverHost.getCommonSourceDirectory() }) : compilerOptions;
                    specifier = ts.first(ts.moduleSpecifiers.getModuleSpecifiers(symbol, specifierCompilerOptions, contextFile, moduleResolverHost, host.getSourceFiles(), { importModuleSpecifierPreference: isBundle_1 ? "non-relative" : "relative" }, host.redirectTargetsMap));
                    links.specifierCache = links.specifierCache || ts.createMap();
                    links.specifierCache.set(contextFile.path, specifier);
                }
                return specifier;
            }
            function symbolToTypeNode(symbol, context, meaning, overrideTypeArguments) {
                var chain = lookupSymbolChain(symbol, context, meaning, !(context.flags & 16384 /* UseAliasDefinedOutsideCurrentScope */)); // If we're using aliases outside the current scope, dont bother with the module
                var isTypeOf = meaning === 67220415 /* Value */;
                if (ts.some(chain[0].declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
                    // module is root, must use `ImportTypeNode`
                    var nonRootParts = chain.length > 1 ? createAccessFromSymbolChain(chain, chain.length - 1, 1) : undefined;
                    var typeParameterNodes = overrideTypeArguments || lookupTypeParameterNodes(chain, 0, context);
                    var specifier = getSpecifierForModuleSymbol(chain[0], context);
                    if (!(context.flags & 67108864 /* AllowNodeModulesRelativePaths */) && ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeJs && specifier.indexOf("/node_modules/") >= 0) {
                        // If ultimately we can only name the symbol with a reference that dives into a `node_modules` folder, we should error
                        // since declaration files with these kinds of references are liable to fail when published :(
                        context.encounteredError = true;
                        if (context.tracker.reportLikelyUnsafeImportRequiredError) {
                            context.tracker.reportLikelyUnsafeImportRequiredError(specifier);
                        }
                    }
                    var lit = ts.createLiteralTypeNode(ts.createLiteral(specifier));
                    if (context.tracker.trackExternalModuleSymbolOfImportTypeNode)
                        context.tracker.trackExternalModuleSymbolOfImportTypeNode(chain[0]);
                    context.approximateLength += specifier.length + 10; // specifier + import("")
                    if (!nonRootParts || ts.isEntityName(nonRootParts)) {
                        if (nonRootParts) {
                            var lastId = ts.isIdentifier(nonRootParts) ? nonRootParts : nonRootParts.right;
                            lastId.typeArguments = undefined;
                        }
                        return ts.createImportTypeNode(lit, nonRootParts, typeParameterNodes, isTypeOf);
                    }
                    else {
                        var splitNode = getTopmostIndexedAccessType(nonRootParts);
                        var qualifier = splitNode.objectType.typeName;
                        return ts.createIndexedAccessTypeNode(ts.createImportTypeNode(lit, qualifier, typeParameterNodes, isTypeOf), splitNode.indexType);
                    }
                }
                var entityName = createAccessFromSymbolChain(chain, chain.length - 1, 0);
                if (ts.isIndexedAccessTypeNode(entityName)) {
                    return entityName; // Indexed accesses can never be `typeof`
                }
                if (isTypeOf) {
                    return ts.createTypeQueryNode(entityName);
                }
                else {
                    var lastId = ts.isIdentifier(entityName) ? entityName : entityName.right;
                    var lastTypeArgs = lastId.typeArguments;
                    lastId.typeArguments = undefined;
                    return ts.createTypeReferenceNode(entityName, lastTypeArgs);
                }
                function createAccessFromSymbolChain(chain, index, stopper) {
                    var typeParameterNodes = index === (chain.length - 1) ? overrideTypeArguments : lookupTypeParameterNodes(chain, index, context);
                    var symbol = chain[index];
                    if (index === 0) {
                        context.flags |= 16777216 /* InInitialEntityName */;
                    }
                    var symbolName = getNameOfSymbolAsWritten(symbol, context);
                    context.approximateLength += symbolName.length + 1;
                    if (index === 0) {
                        context.flags ^= 16777216 /* InInitialEntityName */;
                    }
                    var parent = chain[index - 1];
                    if (!(context.flags & 16 /* ForbidIndexedAccessSymbolReferences */) && parent && getMembersOfSymbol(parent) && getMembersOfSymbol(parent).get(symbol.escapedName) === symbol) {
                        // Should use an indexed access
                        var LHS = createAccessFromSymbolChain(chain, index - 1, stopper);
                        if (ts.isIndexedAccessTypeNode(LHS)) {
                            return ts.createIndexedAccessTypeNode(LHS, ts.createLiteralTypeNode(ts.createLiteral(symbolName)));
                        }
                        else {
                            return ts.createIndexedAccessTypeNode(ts.createTypeReferenceNode(LHS, typeParameterNodes), ts.createLiteralTypeNode(ts.createLiteral(symbolName)));
                        }
                    }
                    var identifier = ts.setEmitFlags(ts.createIdentifier(symbolName, typeParameterNodes), 16777216 /* NoAsciiEscaping */);
                    identifier.symbol = symbol;
                    if (index > stopper) {
                        var LHS = createAccessFromSymbolChain(chain, index - 1, stopper);
                        if (!ts.isEntityName(LHS)) {
                            return ts.Debug.fail("Impossible construct - an export of an indexed access cannot be reachable");
                        }
                        return ts.createQualifiedName(LHS, identifier);
                    }
                    return identifier;
                }
            }
            function symbolToName(symbol, context, meaning, expectsIdentifier) {
                var chain = lookupSymbolChain(symbol, context, meaning);
                if (expectsIdentifier && chain.length !== 1
                    && !context.encounteredError
                    && !(context.flags & 65536 /* AllowQualifedNameInPlaceOfIdentifier */)) {
                    context.encounteredError = true;
                }
                return createEntityNameFromSymbolChain(chain, chain.length - 1);
                function createEntityNameFromSymbolChain(chain, index) {
                    var typeParameterNodes = lookupTypeParameterNodes(chain, index, context);
                    var symbol = chain[index];
                    if (index === 0) {
                        context.flags |= 16777216 /* InInitialEntityName */;
                    }
                    var symbolName = getNameOfSymbolAsWritten(symbol, context);
                    if (index === 0) {
                        context.flags ^= 16777216 /* InInitialEntityName */;
                    }
                    var identifier = ts.setEmitFlags(ts.createIdentifier(symbolName, typeParameterNodes), 16777216 /* NoAsciiEscaping */);
                    identifier.symbol = symbol;
                    return index > 0 ? ts.createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier;
                }
            }
            function symbolToExpression(symbol, context, meaning) {
                var chain = lookupSymbolChain(symbol, context, meaning);
                return createExpressionFromSymbolChain(chain, chain.length - 1);
                function createExpressionFromSymbolChain(chain, index) {
                    var typeParameterNodes = lookupTypeParameterNodes(chain, index, context);
                    var symbol = chain[index];
                    if (ts.some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
                        return ts.createLiteral(getSpecifierForModuleSymbol(symbol, context));
                    }
                    if (index === 0) {
                        context.flags |= 16777216 /* InInitialEntityName */;
                    }
                    var symbolName = getNameOfSymbolAsWritten(symbol, context);
                    if (index === 0) {
                        context.flags ^= 16777216 /* InInitialEntityName */;
                    }
                    var firstChar = symbolName.charCodeAt(0);
                    var canUsePropertyAccess = ts.isIdentifierStart(firstChar, languageVersion);
                    if (index === 0 || canUsePropertyAccess) {
                        var identifier = ts.setEmitFlags(ts.createIdentifier(symbolName, typeParameterNodes), 16777216 /* NoAsciiEscaping */);
                        identifier.symbol = symbol;
                        return index > 0 ? ts.createPropertyAccess(createExpressionFromSymbolChain(chain, index - 1), identifier) : identifier;
                    }
                    else {
                        if (firstChar === 91 /* openBracket */) {
                            symbolName = symbolName.substring(1, symbolName.length - 1);
                            firstChar = symbolName.charCodeAt(0);
                        }
                        var expression = void 0;
                        if (ts.isSingleOrDoubleQuote(firstChar)) {
                            expression = ts.createLiteral(symbolName.substring(1, symbolName.length - 1).replace(/\\./g, function (s) { return s.substring(1); }));
                            expression.singleQuote = firstChar === 39 /* singleQuote */;
                        }
                        else if (("" + +symbolName) === symbolName) {
                            expression = ts.createLiteral(+symbolName);
                        }
                        if (!expression) {
                            expression = ts.setEmitFlags(ts.createIdentifier(symbolName, typeParameterNodes), 16777216 /* NoAsciiEscaping */);
                            expression.symbol = symbol;
                        }
                        return ts.createElementAccess(createExpressionFromSymbolChain(chain, index - 1), expression);
                    }
                }
            }
        }
        function typePredicateToString(typePredicate, enclosingDeclaration, flags, writer) {
            if (flags === void 0) { flags = 16384 /* UseAliasDefinedOutsideCurrentScope */; }
            return writer ? typePredicateToStringWorker(writer).getText() : ts.usingSingleLineStringWriter(typePredicateToStringWorker);
            function typePredicateToStringWorker(writer) {
                var predicate = ts.createTypePredicateNode(typePredicate.kind === 1 /* Identifier */ ? ts.createIdentifier(typePredicate.parameterName) : ts.createThisTypeNode(), nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* IgnoreErrors */ | 512 /* WriteTypeParametersInQualifiedName */));
                var printer = ts.createPrinter({ removeComments: true });
                var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration);
                printer.writeNode(4 /* Unspecified */, predicate, /*sourceFile*/ sourceFile, writer);
                return writer;
            }
        }
        function formatUnionTypes(types) {
            var result = [];
            var flags = 0;
            for (var i = 0; i < types.length; i++) {
                var t = types[i];
                flags |= t.flags;
                if (!(t.flags & 98304 /* Nullable */)) {
                    if (t.flags & (512 /* BooleanLiteral */ | 1024 /* EnumLiteral */)) {
                        var baseType = t.flags & 512 /* BooleanLiteral */ ? booleanType : getBaseTypeOfEnumLiteralType(t);
                        if (baseType.flags & 1048576 /* Union */) {
                            var count = baseType.types.length;
                            if (i + count <= types.length && getRegularTypeOfLiteralType(types[i + count - 1]) === getRegularTypeOfLiteralType(baseType.types[count - 1])) {
                                result.push(baseType);
                                i += count - 1;
                                continue;
                            }
                        }
                    }
                    result.push(t);
                }
            }
            if (flags & 65536 /* Null */)
                result.push(nullType);
            if (flags & 32768 /* Undefined */)
                result.push(undefinedType);
            return result || types;
        }
        function visibilityToString(flags) {
            if (flags === 8 /* Private */) {
                return "private";
            }
            if (flags === 16 /* Protected */) {
                return "protected";
            }
            return "public";
        }
        function getTypeAliasForTypeLiteral(type) {
            if (type.symbol && type.symbol.flags & 2048 /* TypeLiteral */) {
                var node = ts.findAncestor(type.symbol.declarations[0].parent, function (n) { return n.kind !== 178 /* ParenthesizedType */; });
                if (node.kind === 243 /* TypeAliasDeclaration */) {
                    return getSymbolOfNode(node);
                }
            }
            return undefined;
        }
        function isTopLevelInExternalModuleAugmentation(node) {
            return node && node.parent &&
                node.parent.kind === 246 /* ModuleBlock */ &&
                ts.isExternalModuleAugmentation(node.parent.parent);
        }
        function isDefaultBindingContext(location) {
            return location.kind === 285 /* SourceFile */ || ts.isAmbientModule(location);
        }
        function getNameOfSymbolFromNameType(symbol, context) {
            var nameType = symbol.nameType;
            if (nameType) {
                if (nameType.flags & 384 /* StringOrNumberLiteral */) {
                    var name = "" + nameType.value;
                    if (!ts.isIdentifierText(name, compilerOptions.target) && !isNumericLiteralName(name)) {
                        return "\"" + ts.escapeString(name, 34 /* doubleQuote */) + "\"";
                    }
                    return name;
                }
                if (nameType.flags & 8192 /* UniqueESSymbol */) {
                    return "[" + getNameOfSymbolAsWritten(nameType.symbol, context) + "]";
                }
            }
        }
        /**
         * Gets a human-readable name for a symbol.
         * Should *not* be used for the right-hand side of a `.` -- use `symbolName(symbol)` for that instead.
         *
         * Unlike `symbolName(symbol)`, this will include quotes if the name is from a string literal.
         * It will also use a representation of a number as written instead of a decimal form, e.g. `0o11` instead of `9`.
         */
        function getNameOfSymbolAsWritten(symbol, context) {
            if (context && symbol.escapedName === "default" /* Default */ && !(context.flags & 16384 /* UseAliasDefinedOutsideCurrentScope */) &&
                // If it's not the first part of an entity name, it must print as `default`
                (!(context.flags & 16777216 /* InInitialEntityName */) ||
                    // if the symbol is synthesized, it will only be referenced externally it must print as `default`
                    !symbol.declarations ||
                    // if not in the same binding context (source file, module declaration), it must print as `default`
                    (context.enclosingDeclaration && ts.findAncestor(symbol.declarations[0], isDefaultBindingContext) !== ts.findAncestor(context.enclosingDeclaration, isDefaultBindingContext)))) {
                return "default";
            }
            if (symbol.declarations && symbol.declarations.length) {
                var declaration = symbol.declarations[0];
                var name_2 = ts.getNameOfDeclaration(declaration);
                if (name_2) {
                    if (ts.isCallExpression(declaration) && ts.isBindableObjectDefinePropertyCall(declaration)) {
                        return ts.symbolName(symbol);
                    }
                    if (ts.isComputedPropertyName(name_2) && !(ts.getCheckFlags(symbol) & 4096 /* Late */) && symbol.nameType && symbol.nameType.flags & 384 /* StringOrNumberLiteral */) {
                        // Computed property name isn't late bound, but has a well-known name type - use name type to generate a symbol name
                        var result = getNameOfSymbolFromNameType(symbol, context);
                        if (result !== undefined) {
                            return result;
                        }
                    }
                    return ts.declarationNameToString(name_2);
                }
                if (declaration.parent && declaration.parent.kind === 238 /* VariableDeclaration */) {
                    return ts.declarationNameToString(declaration.parent.name);
                }
                switch (declaration.kind) {
                    case 210 /* ClassExpression */:
                    case 197 /* FunctionExpression */:
                    case 198 /* ArrowFunction */:
                        if (context && !context.encounteredError && !(context.flags & 131072 /* AllowAnonymousIdentifier */)) {
                            context.encounteredError = true;
                        }
                        return declaration.kind === 210 /* ClassExpression */ ? "(Anonymous class)" : "(Anonymous function)";
                }
            }
            var name = getNameOfSymbolFromNameType(symbol, context);
            return name !== undefined ? name : ts.symbolName(symbol);
        }
        function isDeclarationVisible(node) {
            if (node) {
                var links = getNodeLinks(node);
                if (links.isVisible === undefined) {
                    links.isVisible = !!determineIfDeclarationIsVisible();
                }
                return links.isVisible;
            }
            return false;
            function determineIfDeclarationIsVisible() {
                switch (node.kind) {
                    case 303 /* JSDocCallbackTag */:
                    case 310 /* JSDocTypedefTag */:
                        // Top-level jsdoc type aliases are considered exported
                        // First parent is comment node, second is hosting declaration or token; we only care about those tokens or declarations whose parent is a source file
                        return !!(node.parent && node.parent.parent && node.parent.parent.parent && ts.isSourceFile(node.parent.parent.parent));
                    case 187 /* BindingElement */:
                        return isDeclarationVisible(node.parent.parent);
                    case 238 /* VariableDeclaration */:
                        if (ts.isBindingPattern(node.name) &&
                            !node.name.elements.length) {
                            // If the binding pattern is empty, this variable declaration is not visible
                            return false;
                        }
                    // falls through
                    case 245 /* ModuleDeclaration */:
                    case 241 /* ClassDeclaration */:
                    case 242 /* InterfaceDeclaration */:
                    case 243 /* TypeAliasDeclaration */:
                    case 240 /* FunctionDeclaration */:
                    case 244 /* EnumDeclaration */:
                    case 249 /* ImportEqualsDeclaration */:
                        // external module augmentation is always visible
                        if (ts.isExternalModuleAugmentation(node)) {
                            return true;
                        }
                        var parent = getDeclarationContainer(node);
                        // If the node is not exported or it is not ambient module element (except import declaration)
                        if (!(ts.getCombinedModifierFlags(node) & 1 /* Export */) &&
                            !(node.kind !== 249 /* ImportEqualsDeclaration */ && parent.kind !== 285 /* SourceFile */ && parent.flags & 4194304 /* Ambient */)) {
                            return isGlobalSourceFile(parent);
                        }
                        // Exported members/ambient module elements (exception import declaration) are visible if parent is visible
                        return isDeclarationVisible(parent);
                    case 155 /* PropertyDeclaration */:
                    case 154 /* PropertySignature */:
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                    case 157 /* MethodDeclaration */:
                    case 156 /* MethodSignature */:
                        if (ts.hasModifier(node, 8 /* Private */ | 16 /* Protected */)) {
                            // Private/protected properties/methods are not visible
                            return false;
                        }
                    // Public properties/methods are visible if its parents are visible, so:
                    // falls through
                    case 158 /* Constructor */:
                    case 162 /* ConstructSignature */:
                    case 161 /* CallSignature */:
                    case 163 /* IndexSignature */:
                    case 152 /* Parameter */:
                    case 246 /* ModuleBlock */:
                    case 166 /* FunctionType */:
                    case 167 /* ConstructorType */:
                    case 169 /* TypeLiteral */:
                    case 165 /* TypeReference */:
                    case 170 /* ArrayType */:
                    case 171 /* TupleType */:
                    case 174 /* UnionType */:
                    case 175 /* IntersectionType */:
                    case 178 /* ParenthesizedType */:
                        return isDeclarationVisible(node.parent);
                    // Default binding, import specifier and namespace import is visible
                    // only on demand so by default it is not visible
                    case 251 /* ImportClause */:
                    case 252 /* NamespaceImport */:
                    case 254 /* ImportSpecifier */:
                        return false;
                    // Type parameters are always visible
                    case 151 /* TypeParameter */:
                    // Source file and namespace export are always visible
                    case 285 /* SourceFile */:
                    case 248 /* NamespaceExportDeclaration */:
                        return true;
                    // Export assignments do not create name bindings outside the module
                    case 255 /* ExportAssignment */:
                        return false;
                    default:
                        return false;
                }
            }
        }
        function collectLinkedAliases(node, setVisibility) {
            var exportSymbol;
            if (node.parent && node.parent.kind === 255 /* ExportAssignment */) {
                exportSymbol = resolveName(node, node.escapedText, 67220415 /* Value */ | 67897832 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */, /*nameNotFoundMessage*/ undefined, node, /*isUse*/ false);
            }
            else if (node.parent.kind === 258 /* ExportSpecifier */) {
                exportSymbol = getTargetOfExportSpecifier(node.parent, 67220415 /* Value */ | 67897832 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */);
            }
            var result;
            if (exportSymbol) {
                buildVisibleNodeList(exportSymbol.declarations);
            }
            return result;
            function buildVisibleNodeList(declarations) {
                ts.forEach(declarations, function (declaration) {
                    var resultNode = getAnyImportSyntax(declaration) || declaration;
                    if (setVisibility) {
                        getNodeLinks(declaration).isVisible = true;
                    }
                    else {
                        result = result || [];
                        ts.pushIfUnique(result, resultNode);
                    }
                    if (ts.isInternalModuleImportEqualsDeclaration(declaration)) {
                        // Add the referenced top container visible
                        var internalModuleReference = declaration.moduleReference;
                        var firstIdentifier = getFirstIdentifier(internalModuleReference);
                        var importSymbol = resolveName(declaration, firstIdentifier.escapedText, 67220415 /* Value */ | 67897832 /* Type */ | 1920 /* Namespace */, undefined, undefined, /*isUse*/ false);
                        if (importSymbol) {
                            buildVisibleNodeList(importSymbol.declarations);
                        }
                    }
                });
            }
        }
        /**
         * Push an entry on the type resolution stack. If an entry with the given target and the given property name
         * is already on the stack, and no entries in between already have a type, then a circularity has occurred.
         * In this case, the result values of the existing entry and all entries pushed after it are changed to false,
         * and the value false is returned. Otherwise, the new entry is just pushed onto the stack, and true is returned.
         * In order to see if the same query has already been done before, the target object and the propertyName both
         * must match the one passed in.
         *
         * @param target The symbol, type, or signature whose type is being queried
         * @param propertyName The property name that should be used to query the target for its type
         */
        function pushTypeResolution(target, propertyName) {
            var resolutionCycleStartIndex = findResolutionCycleStartIndex(target, propertyName);
            if (resolutionCycleStartIndex >= 0) {
                // A cycle was found
                var length_2 = resolutionTargets.length;
                for (var i = resolutionCycleStartIndex; i < length_2; i++) {
                    resolutionResults[i] = false;
                }
                return false;
            }
            resolutionTargets.push(target);
            resolutionResults.push(/*items*/ true);
            resolutionPropertyNames.push(propertyName);
            return true;
        }
        function findResolutionCycleStartIndex(target, propertyName) {
            for (var i = resolutionTargets.length - 1; i >= 0; i--) {
                if (hasType(resolutionTargets[i], resolutionPropertyNames[i])) {
                    return -1;
                }
                if (resolutionTargets[i] === target && resolutionPropertyNames[i] === propertyName) {
                    return i;
                }
            }
            return -1;
        }
        function hasType(target, propertyName) {
            switch (propertyName) {
                case 0 /* Type */:
                    return !!getSymbolLinks(target).type;
                case 5 /* EnumTagType */:
                    return !!(getNodeLinks(target).resolvedEnumType);
                case 2 /* DeclaredType */:
                    return !!getSymbolLinks(target).declaredType;
                case 1 /* ResolvedBaseConstructorType */:
                    return !!target.resolvedBaseConstructorType;
                case 3 /* ResolvedReturnType */:
                    return !!target.resolvedReturnType;
                case 4 /* ImmediateBaseConstraint */:
                    return !!target.immediateBaseConstraint;
                case 6 /* JSDocTypeReference */:
                    return !!getSymbolLinks(target).resolvedJSDocType;
            }
            return ts.Debug.assertNever(propertyName);
        }
        // Pop an entry from the type resolution stack and return its associated result value. The result value will
        // be true if no circularities were detected, or false if a circularity was found.
        function popTypeResolution() {
            resolutionTargets.pop();
            resolutionPropertyNames.pop();
            return resolutionResults.pop();
        }
        function getDeclarationContainer(node) {
            return ts.findAncestor(ts.getRootDeclaration(node), function (node) {
                switch (node.kind) {
                    case 238 /* VariableDeclaration */:
                    case 239 /* VariableDeclarationList */:
                    case 254 /* ImportSpecifier */:
                    case 253 /* NamedImports */:
                    case 252 /* NamespaceImport */:
                    case 251 /* ImportClause */:
                        return false;
                    default:
                        return true;
                }
            }).parent;
        }
        function getTypeOfPrototypeProperty(prototype) {
            // TypeScript 1.0 spec (April 2014): 8.4
            // Every class automatically contains a static property member named 'prototype',
            // the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter.
            // It is an error to explicitly declare a static property member with the name 'prototype'.
            var classType = getDeclaredTypeOfSymbol(getParentOfSymbol(prototype));
            return classType.typeParameters ? createTypeReference(classType, ts.map(classType.typeParameters, function (_) { return anyType; })) : classType;
        }
        // Return the type of the given property in the given type, or undefined if no such property exists
        function getTypeOfPropertyOfType(type, name) {
            var prop = getPropertyOfType(type, name);
            return prop ? getTypeOfSymbol(prop) : undefined;
        }
        function getTypeOfPropertyOrIndexSignature(type, name) {
            return getTypeOfPropertyOfType(type, name) || isNumericLiteralName(name) && getIndexTypeOfType(type, 1 /* Number */) || getIndexTypeOfType(type, 0 /* String */) || unknownType;
        }
        function isTypeAny(type) {
            return type && (type.flags & 1 /* Any */) !== 0;
        }
        // Return the type of a binding element parent. We check SymbolLinks first to see if a type has been
        // assigned by contextual typing.
        function getTypeForBindingElementParent(node) {
            var symbol = getSymbolOfNode(node);
            return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, /*includeOptionality*/ false);
        }
        function isComputedNonLiteralName(name) {
            return name.kind === 150 /* ComputedPropertyName */ && !ts.isStringOrNumericLiteralLike(name.expression);
        }
        function getRestType(source, properties, symbol) {
            source = filterType(source, function (t) { return !(t.flags & 98304 /* Nullable */); });
            if (source.flags & 131072 /* Never */) {
                return emptyObjectType;
            }
            if (source.flags & 1048576 /* Union */) {
                return mapType(source, function (t) { return getRestType(t, properties, symbol); });
            }
            var omitKeyType = getUnionType(ts.map(properties, getLiteralTypeFromPropertyName));
            if (isGenericObjectType(source) || isGenericIndexType(omitKeyType)) {
                if (omitKeyType.flags & 131072 /* Never */) {
                    return source;
                }
                var omitTypeAlias = getGlobalOmitSymbol();
                if (!omitTypeAlias) {
                    return errorType;
                }
                return getTypeAliasInstantiation(omitTypeAlias, [source, omitKeyType]);
            }
            var members = ts.createSymbolTable();
            for (var _i = 0, _a = getPropertiesOfType(source); _i < _a.length; _i++) {
                var prop = _a[_i];
                if (!isTypeAssignableTo(getLiteralTypeFromProperty(prop, 8576 /* StringOrNumberLiteralOrUnique */), omitKeyType)
                    && !(ts.getDeclarationModifierFlagsFromSymbol(prop) & (8 /* Private */ | 16 /* Protected */))
                    && isSpreadableProperty(prop)) {
                    members.set(prop.escapedName, getSpreadSymbol(prop, /*readonly*/ false));
                }
            }
            var stringIndexInfo = getIndexInfoOfType(source, 0 /* String */);
            var numberIndexInfo = getIndexInfoOfType(source, 1 /* Number */);
            return createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
        }
        // Determine the control flow type associated with a destructuring declaration or assignment. The following
        // forms of destructuring are possible:
        //   let { x } = obj;  // BindingElement
        //   let [ x ] = obj;  // BindingElement
        //   { x } = obj;      // ShorthandPropertyAssignment
        //   { x: v } = obj;   // PropertyAssignment
        //   [ x ] = obj;      // Expression
        // We construct a synthetic element access expression corresponding to 'obj.x' such that the control
        // flow analyzer doesn't have to handle all the different syntactic forms.
        function getFlowTypeOfDestructuring(node, declaredType) {
            var reference = getSyntheticElementAccess(node);
            return reference ? getFlowTypeOfReference(reference, declaredType) : declaredType;
        }
        function getSyntheticElementAccess(node) {
            var parentAccess = getParentElementAccess(node);
            if (parentAccess && parentAccess.flowNode) {
                var propName = getDestructuringPropertyName(node);
                if (propName) {
                    var result = ts.createNode(191 /* ElementAccessExpression */, node.pos, node.end);
                    result.parent = node;
                    result.expression = parentAccess;
                    var literal = ts.createNode(10 /* StringLiteral */, node.pos, node.end);
                    literal.parent = result;
                    literal.text = propName;
                    result.argumentExpression = literal;
                    result.flowNode = parentAccess.flowNode;
                    return result;
                }
            }
        }
        function getParentElementAccess(node) {
            var ancestor = node.parent.parent;
            switch (ancestor.kind) {
                case 187 /* BindingElement */:
                case 276 /* PropertyAssignment */:
                    return getSyntheticElementAccess(ancestor);
                case 188 /* ArrayLiteralExpression */:
                    return getSyntheticElementAccess(node.parent);
                case 238 /* VariableDeclaration */:
                    return ancestor.initializer;
                case 205 /* BinaryExpression */:
                    return ancestor.right;
            }
        }
        function getDestructuringPropertyName(node) {
            var parent = node.parent;
            if (node.kind === 187 /* BindingElement */ && parent.kind === 185 /* ObjectBindingPattern */) {
                return getLiteralPropertyNameText(node.propertyName || node.name);
            }
            if (node.kind === 276 /* PropertyAssignment */ || node.kind === 277 /* ShorthandPropertyAssignment */) {
                return getLiteralPropertyNameText(node.name);
            }
            return "" + parent.elements.indexOf(node);
        }
        function getLiteralPropertyNameText(name) {
            var type = getLiteralTypeFromPropertyName(name);
            return type.flags & (128 /* StringLiteral */ | 256 /* NumberLiteral */) ? "" + type.value : undefined;
        }
        /** Return the inferred type for a binding element */
        function getTypeForBindingElement(declaration) {
            var pattern = declaration.parent;
            var parentType = getTypeForBindingElementParent(pattern.parent);
            // If no type or an any type was inferred for parent, infer that for the binding element
            if (!parentType || isTypeAny(parentType)) {
                return parentType;
            }
            // Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation
            if (strictNullChecks && declaration.flags & 4194304 /* Ambient */ && ts.isParameterDeclaration(declaration)) {
                parentType = getNonNullableType(parentType);
            }
            var type;
            if (pattern.kind === 185 /* ObjectBindingPattern */) {
                if (declaration.dotDotDotToken) {
                    if (parentType.flags & 2 /* Unknown */ || !isValidSpreadType(parentType)) {
                        error(declaration, ts.Diagnostics.Rest_types_may_only_be_created_from_object_types);
                        return errorType;
                    }
                    var literalMembers = [];
                    for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                        var element = _a[_i];
                        if (!element.dotDotDotToken) {
                            literalMembers.push(element.propertyName || element.name);
                        }
                    }
                    type = getRestType(parentType, literalMembers, declaration.symbol);
                }
                else {
                    // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
                    var name = declaration.propertyName || declaration.name;
                    var indexType = getLiteralTypeFromPropertyName(name);
                    var declaredType = getConstraintForLocation(getIndexedAccessType(parentType, indexType, name), declaration.name);
                    type = getFlowTypeOfDestructuring(declaration, declaredType);
                }
            }
            else {
                // This elementType will be used if the specific property corresponding to this index is not
                // present (aka the tuple element property). This call also checks that the parentType is in
                // fact an iterable or array (depending on target language).
                var elementType = checkIteratedTypeOrElementType(parentType, pattern, /*allowStringInput*/ false, /*allowAsyncIterables*/ false);
                var index_1 = pattern.elements.indexOf(declaration);
                if (declaration.dotDotDotToken) {
                    // If the parent is a tuple type, the rest element has a tuple type of the
                    // remaining tuple element types. Otherwise, the rest element has an array type with same
                    // element type as the parent type.
                    type = everyType(parentType, isTupleType) ?
                        mapType(parentType, function (t) { return sliceTupleType(t, index_1); }) :
                        createArrayType(elementType);
                }
                else if (isArrayLikeType(parentType)) {
                    var indexType = getLiteralType(index_1);
                    var declaredType = getConstraintForLocation(getIndexedAccessType(parentType, indexType, declaration.name), declaration.name);
                    type = getFlowTypeOfDestructuring(declaration, declaredType);
                }
                else {
                    type = elementType;
                }
            }
            // In strict null checking mode, if a default value of a non-undefined type is specified, remove
            // undefined from the final type.
            if (strictNullChecks && declaration.initializer && !(getFalsyFlags(checkDeclarationInitializer(declaration)) & 32768 /* Undefined */)) {
                type = getTypeWithFacts(type, 524288 /* NEUndefined */);
            }
            return declaration.initializer && !ts.getEffectiveTypeAnnotationNode(ts.walkUpBindingElementsAndPatterns(declaration)) ?
                getUnionType([type, checkDeclarationInitializer(declaration)], 2 /* Subtype */) :
                type;
        }
        function getTypeForDeclarationFromJSDocComment(declaration) {
            var jsdocType = ts.getJSDocType(declaration);
            if (jsdocType) {
                return getTypeFromTypeNode(jsdocType);
            }
            return undefined;
        }
        function isNullOrUndefined(node) {
            var expr = ts.skipParentheses(node);
            return expr.kind === 97 /* NullKeyword */ || expr.kind === 73 /* Identifier */ && getResolvedSymbol(expr) === undefinedSymbol;
        }
        function isEmptyArrayLiteral(node) {
            var expr = ts.skipParentheses(node);
            return expr.kind === 188 /* ArrayLiteralExpression */ && expr.elements.length === 0;
        }
        function addOptionality(type, optional) {
            if (optional === void 0) { optional = true; }
            return strictNullChecks && optional ? getOptionalType(type) : type;
        }
        function isParameterOfContextuallyTypedFunction(node) {
            return node.kind === 152 /* Parameter */ &&
                (node.parent.kind === 197 /* FunctionExpression */ || node.parent.kind === 198 /* ArrowFunction */) &&
                !!getContextualType(node.parent);
        }
        // Return the inferred type for a variable, parameter, or property declaration
        function getTypeForVariableLikeDeclaration(declaration, includeOptionality) {
            // A variable declared in a for..in statement is of type string, or of type keyof T when the
            // right hand expression is of a type parameter type.
            if (ts.isVariableDeclaration(declaration) && declaration.parent.parent.kind === 227 /* ForInStatement */) {
                var indexType = getIndexType(getNonNullableTypeIfNeeded(checkExpression(declaration.parent.parent.expression)));
                return indexType.flags & (262144 /* TypeParameter */ | 4194304 /* Index */) ? getExtractStringType(indexType) : stringType;
            }
            if (ts.isVariableDeclaration(declaration) && declaration.parent.parent.kind === 228 /* ForOfStatement */) {
                // checkRightHandSideOfForOf will return undefined if the for-of expression type was
                // missing properties/signatures required to get its iteratedType (like
                // [Symbol.iterator] or next). This may be because we accessed properties from anyType,
                // or it may have led to an error inside getElementTypeOfIterable.
                var forOfStatement = declaration.parent.parent;
                return checkRightHandSideOfForOf(forOfStatement.expression, forOfStatement.awaitModifier) || anyType;
            }
            if (ts.isBindingPattern(declaration.parent)) {
                return getTypeForBindingElement(declaration);
            }
            var isOptional = includeOptionality && (ts.isParameter(declaration) && isJSDocOptionalParameter(declaration)
                || !ts.isBindingElement(declaration) && !ts.isVariableDeclaration(declaration) && !!declaration.questionToken);
            // Use type from type annotation if one is present
            var declaredType = tryGetTypeFromEffectiveTypeNode(declaration);
            if (declaredType) {
                return addOptionality(declaredType, isOptional);
            }
            if ((noImplicitAny || ts.isInJSFile(declaration)) &&
                declaration.kind === 238 /* VariableDeclaration */ && !ts.isBindingPattern(declaration.name) &&
                !(ts.getCombinedModifierFlags(declaration) & 1 /* Export */) && !(declaration.flags & 4194304 /* Ambient */)) {
                // If --noImplicitAny is on or the declaration is in a Javascript file,
                // use control flow tracked 'any' type for non-ambient, non-exported var or let variables with no
                // initializer or a 'null' or 'undefined' initializer.
                if (!(ts.getCombinedNodeFlags(declaration) & 2 /* Const */) && (!declaration.initializer || isNullOrUndefined(declaration.initializer))) {
                    return autoType;
                }
                // Use control flow tracked 'any[]' type for non-ambient, non-exported variables with an empty array
                // literal initializer.
                if (declaration.initializer && isEmptyArrayLiteral(declaration.initializer)) {
                    return autoArrayType;
                }
            }
            if (declaration.kind === 152 /* Parameter */) {
                var func = declaration.parent;
                // For a parameter of a set accessor, use the type of the get accessor if one is present
                if (func.kind === 160 /* SetAccessor */ && !hasNonBindableDynamicName(func)) {
                    var getter = ts.getDeclarationOfKind(getSymbolOfNode(declaration.parent), 159 /* GetAccessor */);
                    if (getter) {
                        var getterSignature = getSignatureFromDeclaration(getter);
                        var thisParameter = getAccessorThisParameter(func);
                        if (thisParameter && declaration === thisParameter) {
                            // Use the type from the *getter*
                            ts.Debug.assert(!thisParameter.type);
                            return getTypeOfSymbol(getterSignature.thisParameter);
                        }
                        return getReturnTypeOfSignature(getterSignature);
                    }
                }
                if (ts.isInJSFile(declaration)) {
                    var typeTag = ts.getJSDocType(func);
                    if (typeTag && ts.isFunctionTypeNode(typeTag)) {
                        return getTypeAtPosition(getSignatureFromDeclaration(typeTag), func.parameters.indexOf(declaration));
                    }
                }
                // Use contextual parameter type if one is available
                var type = declaration.symbol.escapedName === "this" /* This */ ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration);
                if (type) {
                    return addOptionality(type, isOptional);
                }
            }
            else if (ts.isInJSFile(declaration)) {
                var containerObjectType = getJSContainerObjectType(declaration, getSymbolOfNode(declaration), ts.getDeclaredExpandoInitializer(declaration));
                if (containerObjectType) {
                    return containerObjectType;
                }
            }
            // Use the type of the initializer expression if one is present and the declaration is
            // not a parameter of a contextually typed function
            if (declaration.initializer && !isParameterOfContextuallyTypedFunction(declaration)) {
                var type = checkDeclarationInitializer(declaration);
                return addOptionality(type, isOptional);
            }
            if (ts.isJsxAttribute(declaration)) {
                // if JSX attribute doesn't have initializer, by default the attribute will have boolean value of true.
                // I.e <Elem attr /> is sugar for <Elem attr={true} />
                return trueType;
            }
            // If the declaration specifies a binding pattern and is not a parameter of a contextually
            // typed function, use the type implied by the binding pattern
            if (ts.isBindingPattern(declaration.name) && !isParameterOfContextuallyTypedFunction(declaration)) {
                return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true);
            }
            // No type specified and nothing can be inferred
            return undefined;
        }
        function getWidenedTypeFromAssignmentDeclaration(symbol, resolvedSymbol) {
            // function/class/{} initializers are themselves containers, so they won't merge in the same way as other initializers
            var container = ts.getAssignedExpandoInitializer(symbol.valueDeclaration);
            if (container) {
                var tag = ts.getJSDocTypeTag(container);
                if (tag && tag.typeExpression) {
                    return getTypeFromTypeNode(tag.typeExpression);
                }
                var containerObjectType = getJSContainerObjectType(symbol.valueDeclaration, symbol, container);
                return containerObjectType || getWidenedLiteralType(checkExpressionCached(container));
            }
            var definedInConstructor = false;
            var definedInMethod = false;
            var jsdocType;
            var types;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                var expression = (ts.isBinaryExpression(declaration) || ts.isCallExpression(declaration)) ? declaration :
                    ts.isPropertyAccessExpression(declaration) ? ts.isBinaryExpression(declaration.parent) ? declaration.parent : declaration :
                        undefined;
                if (!expression) {
                    return errorType;
                }
                var kind = ts.isPropertyAccessExpression(expression) ? ts.getAssignmentDeclarationPropertyAccessKind(expression) : ts.getAssignmentDeclarationKind(expression);
                if (kind === 4 /* ThisProperty */) {
                    if (isDeclarationInConstructor(expression)) {
                        definedInConstructor = true;
                    }
                    else {
                        definedInMethod = true;
                    }
                }
                if (!ts.isCallExpression(expression)) {
                    jsdocType = getJSDocTypeFromAssignmentDeclaration(jsdocType, expression, symbol, declaration);
                }
                if (!jsdocType) {
                    (types || (types = [])).push((ts.isBinaryExpression(expression) || ts.isCallExpression(expression)) ? getInitializerTypeFromAssignmentDeclaration(symbol, resolvedSymbol, expression, kind) : neverType);
                }
            }
            var type = jsdocType;
            if (!type) {
                var constructorTypes = definedInConstructor ? getConstructorDefinedThisAssignmentTypes(types, symbol.declarations) : undefined;
                // use only the constructor types unless they were only assigned null | undefined (including widening variants)
                if (definedInMethod) {
                    var propType = getTypeOfAssignmentDeclarationPropertyOfBaseType(symbol);
                    if (propType) {
                        (constructorTypes || (constructorTypes = [])).push(propType);
                        definedInConstructor = true;
                    }
                }
                var sourceTypes = ts.some(constructorTypes, function (t) { return !!(t.flags & ~98304 /* Nullable */); }) ? constructorTypes : types; // TODO: GH#18217
                type = getUnionType(sourceTypes, 2 /* Subtype */);
            }
            var widened = getWidenedType(addOptionality(type, definedInMethod && !definedInConstructor));
            if (filterType(widened, function (t) { return !!(t.flags & ~98304 /* Nullable */); }) === neverType) {
                reportImplicitAny(symbol.valueDeclaration, anyType);
                return anyType;
            }
            return widened;
        }
        function getJSContainerObjectType(decl, symbol, init) {
            if (!ts.isInJSFile(decl) || !init || !ts.isObjectLiteralExpression(init) || init.properties.length) {
                return undefined;
            }
            var exports = ts.createSymbolTable();
            while (ts.isBinaryExpression(decl) || ts.isPropertyAccessExpression(decl)) {
                var s_1 = getSymbolOfNode(decl);
                if (s_1 && ts.hasEntries(s_1.exports)) {
                    mergeSymbolTable(exports, s_1.exports);
                }
                decl = ts.isBinaryExpression(decl) ? decl.parent : decl.parent.parent;
            }
            var s = getSymbolOfNode(decl);
            if (s && ts.hasEntries(s.exports)) {
                mergeSymbolTable(exports, s.exports);
            }
            var type = createAnonymousType(symbol, exports, ts.emptyArray, ts.emptyArray, undefined, undefined);
            type.objectFlags |= 16384 /* JSLiteral */;
            return type;
        }
        function getJSDocTypeFromAssignmentDeclaration(declaredType, expression, _symbol, declaration) {
            var typeNode = ts.getJSDocType(expression.parent);
            if (typeNode) {
                var type = getWidenedType(getTypeFromTypeNode(typeNode));
                if (!declaredType) {
                    return type;
                }
                else if (declaredType !== errorType && type !== errorType && !isTypeIdenticalTo(declaredType, type)) {
                    errorNextVariableOrPropertyDeclarationMustHaveSameType(/*firstDeclaration*/ undefined, declaredType, declaration, type);
                }
            }
            return declaredType;
        }
        /** If we don't have an explicit JSDoc type, get the type from the initializer. */
        function getInitializerTypeFromAssignmentDeclaration(symbol, resolvedSymbol, expression, kind) {
            if (ts.isCallExpression(expression)) {
                if (resolvedSymbol) {
                    return getTypeOfSymbol(resolvedSymbol); // This shouldn't happen except under some hopefully forbidden merges of export assignments and object define assignments
                }
                var objectLitType = checkExpressionCached(expression.arguments[2]);
                var valueType = getTypeOfPropertyOfType(objectLitType, "value");
                if (valueType) {
                    return valueType;
                }
                var getFunc = getTypeOfPropertyOfType(objectLitType, "get");
                if (getFunc) {
                    var getSig = getSingleCallSignature(getFunc);
                    if (getSig) {
                        return getReturnTypeOfSignature(getSig);
                    }
                }
                var setFunc = getTypeOfPropertyOfType(objectLitType, "set");
                if (setFunc) {
                    var setSig = getSingleCallSignature(setFunc);
                    if (setSig) {
                        return getTypeOfFirstParameterOfSignature(setSig);
                    }
                }
                return anyType;
            }
            var type = resolvedSymbol ? getTypeOfSymbol(resolvedSymbol) : getWidenedLiteralType(checkExpressionCached(expression.right));
            if (type.flags & 524288 /* Object */ &&
                kind === 2 /* ModuleExports */ &&
                symbol.escapedName === "export=" /* ExportEquals */) {
                var exportedType_1 = resolveStructuredTypeMembers(type);
                var members_3 = ts.createSymbolTable();
                ts.copyEntries(exportedType_1.members, members_3);
                if (resolvedSymbol && !resolvedSymbol.exports) {
                    resolvedSymbol.exports = ts.createSymbolTable();
                }
                (resolvedSymbol || symbol).exports.forEach(function (s, name) {
                    if (members_3.has(name)) {
                        var exportedMember = exportedType_1.members.get(name);
                        var union = createSymbol(s.flags | exportedMember.flags, name);
                        union.type = getUnionType([getTypeOfSymbol(s), getTypeOfSymbol(exportedMember)]);
                        members_3.set(name, union);
                    }
                    else {
                        members_3.set(name, s);
                    }
                });
                var result = createAnonymousType(exportedType_1.symbol, members_3, exportedType_1.callSignatures, exportedType_1.constructSignatures, exportedType_1.stringIndexInfo, exportedType_1.numberIndexInfo);
                result.objectFlags |= (ts.getObjectFlags(type) & 16384 /* JSLiteral */); // Propagate JSLiteral flag
                return result;
            }
            if (isEmptyArrayLiteralType(type)) {
                reportImplicitAny(expression, anyArrayType);
                return anyArrayType;
            }
            return type;
        }
        function isDeclarationInConstructor(expression) {
            var thisContainer = ts.getThisContainer(expression, /*includeArrowFunctions*/ false);
            // Properties defined in a constructor (or base constructor, or javascript constructor function) don't get undefined added.
            // Function expressions that are assigned to the prototype count as methods.
            return thisContainer.kind === 158 /* Constructor */ ||
                thisContainer.kind === 240 /* FunctionDeclaration */ ||
                (thisContainer.kind === 197 /* FunctionExpression */ && !ts.isPrototypePropertyAssignment(thisContainer.parent));
        }
        function getConstructorDefinedThisAssignmentTypes(types, declarations) {
            ts.Debug.assert(types.length === declarations.length);
            return types.filter(function (_, i) {
                var declaration = declarations[i];
                var expression = ts.isBinaryExpression(declaration) ? declaration :
                    ts.isBinaryExpression(declaration.parent) ? declaration.parent : undefined;
                return expression && isDeclarationInConstructor(expression);
            });
        }
        /** check for definition in base class if any declaration is in a class */
        function getTypeOfAssignmentDeclarationPropertyOfBaseType(property) {
            var parentDeclaration = ts.forEach(property.declarations, function (d) {
                var parent = ts.getThisContainer(d, /*includeArrowFunctions*/ false).parent;
                return ts.isClassLike(parent) && parent;
            });
            if (parentDeclaration) {
                var classType = getDeclaredTypeOfSymbol(getSymbolOfNode(parentDeclaration));
                var baseClassType = classType && getBaseTypes(classType)[0];
                if (baseClassType) {
                    return getTypeOfPropertyOfType(baseClassType, property.escapedName);
                }
            }
        }
        // Return the type implied by a binding pattern element. This is the type of the initializer of the element if
        // one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding
        // pattern. Otherwise, it is the type any.
        function getTypeFromBindingElement(element, includePatternInType, reportErrors) {
            if (element.initializer) {
                return addOptionality(checkDeclarationInitializer(element));
            }
            if (ts.isBindingPattern(element.name)) {
                return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors);
            }
            if (reportErrors && !declarationBelongsToPrivateAmbientMember(element)) {
                reportImplicitAny(element, anyType);
            }
            return anyType;
        }
        // Return the type implied by an object binding pattern
        function getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) {
            var members = ts.createSymbolTable();
            var stringIndexInfo;
            var objectFlags = 128 /* ObjectLiteral */ | 262144 /* ContainsObjectLiteral */;
            ts.forEach(pattern.elements, function (e) {
                var name = e.propertyName || e.name;
                if (e.dotDotDotToken) {
                    stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
                    return;
                }
                var exprType = getLiteralTypeFromPropertyName(name);
                if (!isTypeUsableAsPropertyName(exprType)) {
                    // do not include computed properties in the implied type
                    objectFlags |= 512 /* ObjectLiteralPatternWithComputedProperties */;
                    return;
                }
                var text = getPropertyNameFromType(exprType);
                var flags = 4 /* Property */ | (e.initializer ? 16777216 /* Optional */ : 0);
                var symbol = createSymbol(flags, text);
                symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors);
                symbol.bindingElement = e;
                members.set(symbol.escapedName, symbol);
            });
            var result = createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, undefined);
            result.objectFlags |= objectFlags;
            if (includePatternInType) {
                result.pattern = pattern;
            }
            return result;
        }
        // Return the type implied by an array binding pattern
        function getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors) {
            var elements = pattern.elements;
            var lastElement = ts.lastOrUndefined(elements);
            var hasRestElement = !!(lastElement && lastElement.kind === 187 /* BindingElement */ && lastElement.dotDotDotToken);
            if (elements.length === 0 || elements.length === 1 && hasRestElement) {
                return languageVersion >= 2 /* ES2015 */ ? createIterableType(anyType) : anyArrayType;
            }
            var elementTypes = ts.map(elements, function (e) { return ts.isOmittedExpression(e) ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors); });
            var minLength = ts.findLastIndex(elements, function (e) { return !ts.isOmittedExpression(e) && !hasDefaultValue(e); }, elements.length - (hasRestElement ? 2 : 1)) + 1;
            var result = createTupleType(elementTypes, minLength, hasRestElement);
            if (includePatternInType) {
                result = cloneTypeReference(result);
                result.pattern = pattern;
            }
            return result;
        }
        // Return the type implied by a binding pattern. This is the type implied purely by the binding pattern itself
        // and without regard to its context (i.e. without regard any type annotation or initializer associated with the
        // declaration in which the binding pattern is contained). For example, the implied type of [x, y] is [any, any]
        // and the implied type of { x, y: z = 1 } is { x: any; y: number; }. The type implied by a binding pattern is
        // used as the contextual type of an initializer associated with the binding pattern. Also, for a destructuring
        // parameter with no type annotation or initializer, the type implied by the binding pattern becomes the type of
        // the parameter.
        function getTypeFromBindingPattern(pattern, includePatternInType, reportErrors) {
            if (includePatternInType === void 0) { includePatternInType = false; }
            if (reportErrors === void 0) { reportErrors = false; }
            return pattern.kind === 185 /* ObjectBindingPattern */
                ? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors)
                : getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors);
        }
        // Return the type associated with a variable, parameter, or property declaration. In the simple case this is the type
        // specified in a type annotation or inferred from an initializer. However, in the case of a destructuring declaration it
        // is a bit more involved. For example:
        //
        //   var [x, s = ""] = [1, "one"];
        //
        // Here, the array literal [1, "one"] is contextually typed by the type [any, string], which is the implied type of the
        // binding pattern [x, s = ""]. Because the contextual type is a tuple type, the resulting type of [1, "one"] is the
        // tuple type [number, string]. Thus, the type inferred for 'x' is number and the type inferred for 's' is string.
        function getWidenedTypeForVariableLikeDeclaration(declaration, reportErrors) {
            return widenTypeForVariableLikeDeclaration(getTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true), declaration, reportErrors);
        }
        function widenTypeForVariableLikeDeclaration(type, declaration, reportErrors) {
            if (type) {
                if (reportErrors) {
                    reportErrorsFromWidening(declaration, type);
                }
                // always widen a 'unique symbol' type if the type was created for a different declaration.
                if (type.flags & 8192 /* UniqueESSymbol */ && (ts.isBindingElement(declaration) || !declaration.type) && type.symbol !== getSymbolOfNode(declaration)) {
                    type = esSymbolType;
                }
                return getWidenedType(type);
            }
            // Rest parameters default to type any[], other parameters default to type any
            type = ts.isParameter(declaration) && declaration.dotDotDotToken ? anyArrayType : anyType;
            // Report implicit any errors unless this is a private property within an ambient declaration
            if (reportErrors) {
                if (!declarationBelongsToPrivateAmbientMember(declaration)) {
                    reportImplicitAny(declaration, type);
                }
            }
            return type;
        }
        function declarationBelongsToPrivateAmbientMember(declaration) {
            var root = ts.getRootDeclaration(declaration);
            var memberDeclaration = root.kind === 152 /* Parameter */ ? root.parent : root;
            return isPrivateWithinAmbient(memberDeclaration);
        }
        function tryGetTypeFromEffectiveTypeNode(declaration) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(declaration);
            if (typeNode) {
                return getTypeFromTypeNode(typeNode);
            }
        }
        function getTypeOfVariableOrParameterOrProperty(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                var type = getTypeOfVariableOrParameterOrPropertyWorker(symbol);
                // For a contextually typed parameter it is possible that a type has already
                // been assigned (in assignTypeToParameterAndFixTypeParameters), and we want
                // to preserve this type.
                if (!links.type) {
                    links.type = type;
                }
            }
            return links.type;
        }
        function getTypeOfVariableOrParameterOrPropertyWorker(symbol) {
            // Handle prototype property
            if (symbol.flags & 4194304 /* Prototype */) {
                return getTypeOfPrototypeProperty(symbol);
            }
            // CommonsJS require and module both have type any.
            if (symbol === requireSymbol) {
                return anyType;
            }
            if (symbol.flags & 134217728 /* ModuleExports */) {
                var fileSymbol = getSymbolOfNode(ts.getSourceFileOfNode(symbol.valueDeclaration));
                var members = ts.createSymbolTable();
                members.set("exports", fileSymbol);
                return createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, undefined, undefined);
            }
            // Handle catch clause variables
            var declaration = symbol.valueDeclaration;
            if (ts.isCatchClauseVariableDeclarationOrBindingElement(declaration)) {
                return anyType;
            }
            // Handle export default expressions
            if (ts.isSourceFile(declaration) && ts.isJsonSourceFile(declaration)) {
                if (!declaration.statements.length) {
                    return emptyObjectType;
                }
                var type_1 = getWidenedLiteralType(checkExpression(declaration.statements[0].expression));
                if (type_1.flags & 524288 /* Object */) {
                    return getRegularTypeOfObjectLiteral(type_1);
                }
                return type_1;
            }
            // Handle variable, parameter or property
            if (!pushTypeResolution(symbol, 0 /* Type */)) {
                // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty`
                if (symbol.flags & 512 /* ValueModule */) {
                    return getTypeOfFuncClassEnumModule(symbol);
                }
                return reportCircularityError(symbol);
            }
            var type;
            if (declaration.kind === 255 /* ExportAssignment */) {
                type = widenTypeForVariableLikeDeclaration(checkExpressionCached(declaration.expression), declaration);
            }
            else if (ts.isInJSFile(declaration) &&
                (ts.isCallExpression(declaration) || ts.isBinaryExpression(declaration) || ts.isPropertyAccessExpression(declaration) && ts.isBinaryExpression(declaration.parent))) {
                type = getWidenedTypeFromAssignmentDeclaration(symbol);
            }
            else if (ts.isJSDocPropertyLikeTag(declaration)
                || ts.isPropertyAccessExpression(declaration)
                || ts.isIdentifier(declaration)
                || ts.isClassDeclaration(declaration)
                || ts.isFunctionDeclaration(declaration)
                || (ts.isMethodDeclaration(declaration) && !ts.isObjectLiteralMethod(declaration))
                || ts.isMethodSignature(declaration)
                || ts.isSourceFile(declaration)) {
                // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty`
                if (symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 384 /* Enum */ | 512 /* ValueModule */)) {
                    return getTypeOfFuncClassEnumModule(symbol);
                }
                type = ts.isBinaryExpression(declaration.parent) ?
                    getWidenedTypeFromAssignmentDeclaration(symbol) :
                    tryGetTypeFromEffectiveTypeNode(declaration) || anyType;
            }
            else if (ts.isPropertyAssignment(declaration)) {
                type = tryGetTypeFromEffectiveTypeNode(declaration) || checkPropertyAssignment(declaration);
            }
            else if (ts.isJsxAttribute(declaration)) {
                type = tryGetTypeFromEffectiveTypeNode(declaration) || checkJsxAttribute(declaration);
            }
            else if (ts.isShorthandPropertyAssignment(declaration)) {
                type = tryGetTypeFromEffectiveTypeNode(declaration) || checkExpressionForMutableLocation(declaration.name, 0 /* Normal */);
            }
            else if (ts.isObjectLiteralMethod(declaration)) {
                type = tryGetTypeFromEffectiveTypeNode(declaration) || checkObjectLiteralMethod(declaration, 0 /* Normal */);
            }
            else if (ts.isParameter(declaration)
                || ts.isPropertyDeclaration(declaration)
                || ts.isPropertySignature(declaration)
                || ts.isVariableDeclaration(declaration)
                || ts.isBindingElement(declaration)) {
                type = getWidenedTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true);
            }
            // getTypeOfSymbol dispatches some JS merges incorrectly because their symbol flags are not mutually exclusive.
            // Re-dispatch based on valueDeclaration.kind instead.
            else if (ts.isEnumDeclaration(declaration)) {
                type = getTypeOfFuncClassEnumModule(symbol);
            }
            else if (ts.isEnumMember(declaration)) {
                type = getTypeOfEnumMember(symbol);
            }
            else {
                return ts.Debug.fail("Unhandled declaration kind! " + ts.Debug.formatSyntaxKind(declaration.kind) + " for " + ts.Debug.formatSymbol(symbol));
            }
            if (!popTypeResolution()) {
                // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty`
                if (symbol.flags & 512 /* ValueModule */) {
                    return getTypeOfFuncClassEnumModule(symbol);
                }
                return reportCircularityError(symbol);
            }
            return type;
        }
        function getAnnotatedAccessorTypeNode(accessor) {
            if (accessor) {
                if (accessor.kind === 159 /* GetAccessor */) {
                    var getterTypeAnnotation = ts.getEffectiveReturnTypeNode(accessor);
                    return getterTypeAnnotation;
                }
                else {
                    var setterTypeAnnotation = ts.getEffectiveSetAccessorTypeAnnotationNode(accessor);
                    return setterTypeAnnotation;
                }
            }
            return undefined;
        }
        function getAnnotatedAccessorType(accessor) {
            var node = getAnnotatedAccessorTypeNode(accessor);
            return node && getTypeFromTypeNode(node);
        }
        function getAnnotatedAccessorThisParameter(accessor) {
            var parameter = getAccessorThisParameter(accessor);
            return parameter && parameter.symbol;
        }
        function getThisTypeOfDeclaration(declaration) {
            return getThisTypeOfSignature(getSignatureFromDeclaration(declaration));
        }
        function getTypeOfAccessors(symbol) {
            var links = getSymbolLinks(symbol);
            return links.type || (links.type = getTypeOfAccessorsWorker(symbol));
        }
        function getTypeOfAccessorsWorker(symbol) {
            var getter = ts.getDeclarationOfKind(symbol, 159 /* GetAccessor */);
            var setter = ts.getDeclarationOfKind(symbol, 160 /* SetAccessor */);
            if (getter && ts.isInJSFile(getter)) {
                var jsDocType = getTypeForDeclarationFromJSDocComment(getter);
                if (jsDocType) {
                    return jsDocType;
                }
            }
            if (!pushTypeResolution(symbol, 0 /* Type */)) {
                return errorType;
            }
            var type;
            // First try to see if the user specified a return type on the get-accessor.
            var getterReturnType = getAnnotatedAccessorType(getter);
            if (getterReturnType) {
                type = getterReturnType;
            }
            else {
                // If the user didn't specify a return type, try to use the set-accessor's parameter type.
                var setterParameterType = getAnnotatedAccessorType(setter);
                if (setterParameterType) {
                    type = setterParameterType;
                }
                else {
                    // If there are no specified types, try to infer it from the body of the get accessor if it exists.
                    if (getter && getter.body) {
                        type = getReturnTypeFromBody(getter);
                    }
                    // Otherwise, fall back to 'any'.
                    else {
                        if (setter) {
                            errorOrSuggestion(noImplicitAny, setter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol));
                        }
                        else {
                            ts.Debug.assert(!!getter, "there must existed getter as we are current checking either setter or getter in this function");
                            errorOrSuggestion(noImplicitAny, getter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation, symbolToString(symbol));
                        }
                        type = anyType;
                    }
                }
            }
            if (!popTypeResolution()) {
                type = anyType;
                if (noImplicitAny) {
                    var getter_1 = ts.getDeclarationOfKind(symbol, 159 /* GetAccessor */);
                    error(getter_1, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, symbolToString(symbol));
                }
            }
            return type;
        }
        function getBaseTypeVariableOfClass(symbol) {
            var baseConstructorType = getBaseConstructorTypeOfClass(getDeclaredTypeOfClassOrInterface(symbol));
            return baseConstructorType.flags & 8650752 /* TypeVariable */ ? baseConstructorType : undefined;
        }
        function getTypeOfFuncClassEnumModule(symbol) {
            var links = getSymbolLinks(symbol);
            var originalLinks = links;
            if (!links.type) {
                var jsDeclaration = ts.getDeclarationOfExpando(symbol.valueDeclaration);
                if (jsDeclaration) {
                    var jsSymbol = getSymbolOfNode(jsDeclaration);
                    if (jsSymbol && (ts.hasEntries(jsSymbol.exports) || ts.hasEntries(jsSymbol.members))) {
                        symbol = cloneSymbol(symbol);
                        // note:we overwrite links because we just cloned the symbol
                        links = symbol;
                        if (ts.hasEntries(jsSymbol.exports)) {
                            symbol.exports = symbol.exports || ts.createSymbolTable();
                            mergeSymbolTable(symbol.exports, jsSymbol.exports);
                        }
                        if (ts.hasEntries(jsSymbol.members)) {
                            symbol.members = symbol.members || ts.createSymbolTable();
                            mergeSymbolTable(symbol.members, jsSymbol.members);
                        }
                    }
                }
                originalLinks.type = links.type = getTypeOfFuncClassEnumModuleWorker(symbol);
            }
            return links.type;
        }
        function getTypeOfFuncClassEnumModuleWorker(symbol) {
            var declaration = symbol.valueDeclaration;
            if (symbol.flags & 1536 /* Module */ && ts.isShorthandAmbientModuleSymbol(symbol)) {
                return anyType;
            }
            else if (declaration.kind === 205 /* BinaryExpression */ ||
                declaration.kind === 190 /* PropertyAccessExpression */ && declaration.parent.kind === 205 /* BinaryExpression */) {
                return getWidenedTypeFromAssignmentDeclaration(symbol);
            }
            else if (symbol.flags & 512 /* ValueModule */ && declaration && ts.isSourceFile(declaration) && declaration.commonJsModuleIndicator) {
                var resolvedModule = resolveExternalModuleSymbol(symbol);
                if (resolvedModule !== symbol) {
                    if (!pushTypeResolution(symbol, 0 /* Type */)) {
                        return errorType;
                    }
                    var exportEquals = getMergedSymbol(symbol.exports.get("export=" /* ExportEquals */));
                    var type_2 = getWidenedTypeFromAssignmentDeclaration(exportEquals, exportEquals === resolvedModule ? undefined : resolvedModule);
                    if (!popTypeResolution()) {
                        return reportCircularityError(symbol);
                    }
                    return type_2;
                }
            }
            var type = createObjectType(16 /* Anonymous */, symbol);
            if (symbol.flags & 32 /* Class */) {
                var baseTypeVariable = getBaseTypeVariableOfClass(symbol);
                return baseTypeVariable ? getIntersectionType([type, baseTypeVariable]) : type;
            }
            else {
                return strictNullChecks && symbol.flags & 16777216 /* Optional */ ? getOptionalType(type) : type;
            }
        }
        function getTypeOfEnumMember(symbol) {
            var links = getSymbolLinks(symbol);
            return links.type || (links.type = getDeclaredTypeOfEnumMember(symbol));
        }
        function getTypeOfAlias(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                var targetSymbol = resolveAlias(symbol);
                // It only makes sense to get the type of a value symbol. If the result of resolving
                // the alias is not a value, then it has no type. To get the type associated with a
                // type symbol, call getDeclaredTypeOfSymbol.
                // This check is important because without it, a call to getTypeOfSymbol could end
                // up recursively calling getTypeOfAlias, causing a stack overflow.
                links.type = targetSymbol.flags & 67220415 /* Value */
                    ? getTypeOfSymbol(targetSymbol)
                    : errorType;
            }
            return links.type;
        }
        function getTypeOfInstantiatedSymbol(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                if (!pushTypeResolution(symbol, 0 /* Type */)) {
                    return links.type = errorType;
                }
                var type = instantiateType(getTypeOfSymbol(links.target), links.mapper);
                if (!popTypeResolution()) {
                    type = reportCircularityError(symbol);
                }
                links.type = type;
            }
            return links.type;
        }
        function reportCircularityError(symbol) {
            var declaration = symbol.valueDeclaration;
            // Check if variable has type annotation that circularly references the variable itself
            if (ts.getEffectiveTypeAnnotationNode(declaration)) {
                error(symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol));
                return errorType;
            }
            // Check if variable has initializer that circularly references the variable itself
            if (noImplicitAny && (declaration.kind !== 152 /* Parameter */ || declaration.initializer)) {
                error(symbol.valueDeclaration, ts.Diagnostics._0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, symbolToString(symbol));
            }
            // Circularities could also result from parameters in function expressions that end up
            // having themselves as contextual types following type argument inference. In those cases
            // we have already reported an implicit any error so we don't report anything here.
            return anyType;
        }
        function getTypeOfSymbolWithDeferredType(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                ts.Debug.assertDefined(links.deferralParent);
                ts.Debug.assertDefined(links.deferralConstituents);
                links.type = links.deferralParent.flags & 1048576 /* Union */ ? getUnionType(links.deferralConstituents) : getIntersectionType(links.deferralConstituents);
            }
            return links.type;
        }
        function getTypeOfSymbol(symbol) {
            if (ts.getCheckFlags(symbol) & 65536 /* DeferredType */) {
                return getTypeOfSymbolWithDeferredType(symbol);
            }
            if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) {
                return getTypeOfInstantiatedSymbol(symbol);
            }
            if (ts.getCheckFlags(symbol) & 8192 /* ReverseMapped */) {
                return getTypeOfReverseMappedSymbol(symbol);
            }
            if (symbol.flags & (3 /* Variable */ | 4 /* Property */)) {
                return getTypeOfVariableOrParameterOrProperty(symbol);
            }
            if (symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 384 /* Enum */ | 512 /* ValueModule */)) {
                return getTypeOfFuncClassEnumModule(symbol);
            }
            if (symbol.flags & 8 /* EnumMember */) {
                return getTypeOfEnumMember(symbol);
            }
            if (symbol.flags & 98304 /* Accessor */) {
                return getTypeOfAccessors(symbol);
            }
            if (symbol.flags & 2097152 /* Alias */) {
                return getTypeOfAlias(symbol);
            }
            return errorType;
        }
        function isReferenceToType(type, target) {
            return type !== undefined
                && target !== undefined
                && (ts.getObjectFlags(type) & 4 /* Reference */) !== 0
                && type.target === target;
        }
        function getTargetType(type) {
            return ts.getObjectFlags(type) & 4 /* Reference */ ? type.target : type;
        }
        // TODO: GH#18217 If `checkBase` is undefined, we should not call this because this will always return false.
        function hasBaseType(type, checkBase) {
            return check(type);
            function check(type) {
                if (ts.getObjectFlags(type) & (3 /* ClassOrInterface */ | 4 /* Reference */)) {
                    var target = getTargetType(type);
                    return target === checkBase || ts.some(getBaseTypes(target), check);
                }
                else if (type.flags & 2097152 /* Intersection */) {
                    return ts.some(type.types, check);
                }
                return false;
            }
        }
        // Appends the type parameters given by a list of declarations to a set of type parameters and returns the resulting set.
        // The function allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set
        // in-place and returns the same array.
        function appendTypeParameters(typeParameters, declarations) {
            for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) {
                var declaration = declarations_2[_i];
                typeParameters = ts.appendIfUnique(typeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration)));
            }
            return typeParameters;
        }
        // Return the outer type parameters of a node or undefined if the node has no outer type parameters.
        function getOuterTypeParameters(node, includeThisTypes) {
            while (true) {
                node = node.parent; // TODO: GH#18217 Use SourceFile kind check instead
                if (!node) {
                    return undefined;
                }
                switch (node.kind) {
                    case 241 /* ClassDeclaration */:
                    case 210 /* ClassExpression */:
                    case 242 /* InterfaceDeclaration */:
                    case 161 /* CallSignature */:
                    case 162 /* ConstructSignature */:
                    case 156 /* MethodSignature */:
                    case 166 /* FunctionType */:
                    case 167 /* ConstructorType */:
                    case 295 /* JSDocFunctionType */:
                    case 240 /* FunctionDeclaration */:
                    case 157 /* MethodDeclaration */:
                    case 197 /* FunctionExpression */:
                    case 198 /* ArrowFunction */:
                    case 243 /* TypeAliasDeclaration */:
                    case 309 /* JSDocTemplateTag */:
                    case 310 /* JSDocTypedefTag */:
                    case 303 /* JSDocCallbackTag */:
                    case 182 /* MappedType */:
                    case 176 /* ConditionalType */:
                        var outerTypeParameters = getOuterTypeParameters(node, includeThisTypes);
                        if (node.kind === 182 /* MappedType */) {
                            return ts.append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter)));
                        }
                        else if (node.kind === 176 /* ConditionalType */) {
                            return ts.concatenate(outerTypeParameters, getInferTypeParameters(node));
                        }
                        var outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, ts.getEffectiveTypeParameterDeclarations(node));
                        var thisType = includeThisTypes &&
                            (node.kind === 241 /* ClassDeclaration */ || node.kind === 210 /* ClassExpression */ || node.kind === 242 /* InterfaceDeclaration */) &&
                            getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType;
                        return thisType ? ts.append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters;
                }
            }
        }
        // The outer type parameters are those defined by enclosing generic classes, methods, or functions.
        function getOuterTypeParametersOfClassOrInterface(symbol) {
            var declaration = symbol.flags & 32 /* Class */ ? symbol.valueDeclaration : ts.getDeclarationOfKind(symbol, 242 /* InterfaceDeclaration */);
            return getOuterTypeParameters(declaration);
        }
        // The local type parameters are the combined set of type parameters from all declarations of the class,
        // interface, or type alias.
        function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) {
            var result;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var node = _a[_i];
                if (node.kind === 242 /* InterfaceDeclaration */ ||
                    node.kind === 241 /* ClassDeclaration */ ||
                    node.kind === 210 /* ClassExpression */ ||
                    ts.isTypeAlias(node)) {
                    var declaration = node;
                    result = appendTypeParameters(result, ts.getEffectiveTypeParameterDeclarations(declaration));
                }
            }
            return result;
        }
        // The full set of type parameters for a generic class or interface type consists of its outer type parameters plus
        // its locally declared type parameters.
        function getTypeParametersOfClassOrInterface(symbol) {
            return ts.concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol));
        }
        // A type is a mixin constructor if it has a single construct signature taking no type parameters and a single
        // rest parameter of type any[].
        function isMixinConstructorType(type) {
            var signatures = getSignaturesOfType(type, 1 /* Construct */);
            if (signatures.length === 1) {
                var s = signatures[0];
                return !s.typeParameters && s.parameters.length === 1 && s.hasRestParameter && getTypeOfParameter(s.parameters[0]) === anyArrayType;
            }
            return false;
        }
        function isConstructorType(type) {
            if (isValidBaseType(type) && getSignaturesOfType(type, 1 /* Construct */).length > 0) {
                return true;
            }
            if (type.flags & 8650752 /* TypeVariable */) {
                var constraint = getBaseConstraintOfType(type);
                return !!constraint && isValidBaseType(constraint) && isMixinConstructorType(constraint);
            }
            return isJSConstructorType(type);
        }
        function getBaseTypeNodeOfClass(type) {
            return ts.getEffectiveBaseTypeNode(type.symbol.valueDeclaration);
        }
        function getConstructorsForTypeArguments(type, typeArgumentNodes, location) {
            var typeArgCount = ts.length(typeArgumentNodes);
            var isJavascript = ts.isInJSFile(location);
            return ts.filter(getSignaturesOfType(type, 1 /* Construct */), function (sig) { return (isJavascript || typeArgCount >= getMinTypeArgumentCount(sig.typeParameters)) && typeArgCount <= ts.length(sig.typeParameters); });
        }
        function getInstantiatedConstructorsForTypeArguments(type, typeArgumentNodes, location) {
            var signatures = getConstructorsForTypeArguments(type, typeArgumentNodes, location);
            var typeArguments = ts.map(typeArgumentNodes, getTypeFromTypeNode);
            return ts.sameMap(signatures, function (sig) { return ts.some(sig.typeParameters) ? getSignatureInstantiation(sig, typeArguments, ts.isInJSFile(location)) : sig; });
        }
        /**
         * The base constructor of a class can resolve to
         * * undefinedType if the class has no extends clause,
         * * unknownType if an error occurred during resolution of the extends expression,
         * * nullType if the extends expression is the null value,
         * * anyType if the extends expression has type any, or
         * * an object type with at least one construct signature.
         */
        function getBaseConstructorTypeOfClass(type) {
            if (!type.resolvedBaseConstructorType) {
                var decl = type.symbol.valueDeclaration;
                var extended = ts.getEffectiveBaseTypeNode(decl);
                var baseTypeNode = getBaseTypeNodeOfClass(type);
                if (!baseTypeNode) {
                    return type.resolvedBaseConstructorType = undefinedType;
                }
                if (!pushTypeResolution(type, 1 /* ResolvedBaseConstructorType */)) {
                    return errorType;
                }
                var baseConstructorType = checkExpression(baseTypeNode.expression);
                if (extended && baseTypeNode !== extended) {
                    ts.Debug.assert(!extended.typeArguments); // Because this is in a JS file, and baseTypeNode is in an @extends tag
                    checkExpression(extended.expression);
                }
                if (baseConstructorType.flags & (524288 /* Object */ | 2097152 /* Intersection */)) {
                    // Resolving the members of a class requires us to resolve the base class of that class.
                    // We force resolution here such that we catch circularities now.
                    resolveStructuredTypeMembers(baseConstructorType);
                }
                if (!popTypeResolution()) {
                    error(type.symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, symbolToString(type.symbol));
                    return type.resolvedBaseConstructorType = errorType;
                }
                if (!(baseConstructorType.flags & 1 /* Any */) && baseConstructorType !== nullWideningType && !isConstructorType(baseConstructorType)) {
                    var err = error(baseTypeNode.expression, ts.Diagnostics.Type_0_is_not_a_constructor_function_type, typeToString(baseConstructorType));
                    if (baseConstructorType.flags & 262144 /* TypeParameter */) {
                        var constraint = getConstraintFromTypeParameter(baseConstructorType);
                        var ctorReturn = unknownType;
                        if (constraint) {
                            var ctorSig = getSignaturesOfType(constraint, 1 /* Construct */);
                            if (ctorSig[0]) {
                                ctorReturn = getReturnTypeOfSignature(ctorSig[0]);
                            }
                        }
                        ts.addRelatedInfo(err, ts.createDiagnosticForNode(baseConstructorType.symbol.declarations[0], ts.Diagnostics.Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1, symbolToString(baseConstructorType.symbol), typeToString(ctorReturn)));
                    }
                    return type.resolvedBaseConstructorType = errorType;
                }
                type.resolvedBaseConstructorType = baseConstructorType;
            }
            return type.resolvedBaseConstructorType;
        }
        function getBaseTypes(type) {
            if (!type.resolvedBaseTypes) {
                if (type.objectFlags & 8 /* Tuple */) {
                    type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters || ts.emptyArray), type.readonly)];
                }
                else if (type.symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                    if (type.symbol.flags & 32 /* Class */) {
                        resolveBaseTypesOfClass(type);
                    }
                    if (type.symbol.flags & 64 /* Interface */) {
                        resolveBaseTypesOfInterface(type);
                    }
                }
                else {
                    ts.Debug.fail("type must be class or interface");
                }
            }
            return type.resolvedBaseTypes;
        }
        function resolveBaseTypesOfClass(type) {
            type.resolvedBaseTypes = ts.resolvingEmptyArray;
            var baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type));
            if (!(baseConstructorType.flags & (524288 /* Object */ | 2097152 /* Intersection */ | 1 /* Any */))) {
                return type.resolvedBaseTypes = ts.emptyArray;
            }
            var baseTypeNode = getBaseTypeNodeOfClass(type);
            var typeArgs = typeArgumentsFromTypeReferenceNode(baseTypeNode);
            var baseType;
            var originalBaseType = isJSConstructorType(baseConstructorType) ? baseConstructorType :
                baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) :
                    undefined;
            if (baseConstructorType.symbol && baseConstructorType.symbol.flags & 32 /* Class */ &&
                areAllOuterTypeParametersApplied(originalBaseType)) {
                // When base constructor type is a class with no captured type arguments we know that the constructors all have the same type parameters as the
                // class and all return the instance type of the class. There is no need for further checks and we can apply the
                // type arguments in the same manner as a type reference to get the same error reporting experience.
                baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol, typeArgs);
            }
            else if (baseConstructorType.flags & 1 /* Any */) {
                baseType = baseConstructorType;
            }
            else if (isJSConstructorType(baseConstructorType)) {
                baseType = !baseTypeNode.typeArguments && getJSClassType(baseConstructorType.symbol) || anyType;
            }
            else {
                // The class derives from a "class-like" constructor function, check that we have at least one construct signature
                // with a matching number of type parameters and use the return type of the first instantiated signature. Elsewhere
                // we check that all instantiated signatures return the same type.
                var constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments, baseTypeNode);
                if (!constructors.length) {
                    error(baseTypeNode.expression, ts.Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments);
                    return type.resolvedBaseTypes = ts.emptyArray;
                }
                baseType = getReturnTypeOfSignature(constructors[0]);
            }
            if (baseType === errorType) {
                return type.resolvedBaseTypes = ts.emptyArray;
            }
            if (!isValidBaseType(baseType)) {
                error(baseTypeNode.expression, ts.Diagnostics.Base_constructor_return_type_0_is_not_an_object_type_or_intersection_of_object_types_with_statically_known_members, typeToString(baseType));
                return type.resolvedBaseTypes = ts.emptyArray;
            }
            if (type === baseType || hasBaseType(baseType, type)) {
                error(type.symbol.valueDeclaration, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, 2 /* WriteArrayAsGenericType */));
                return type.resolvedBaseTypes = ts.emptyArray;
            }
            if (type.resolvedBaseTypes === ts.resolvingEmptyArray) {
                // Circular reference, likely through instantiation of default parameters
                // (otherwise there'd be an error from hasBaseType) - this is fine, but `.members` should be reset
                // as `getIndexedAccessType` via `instantiateType` via `getTypeFromClassOrInterfaceReference` forces a
                // partial instantiation of the members without the base types fully resolved
                type.members = undefined;
            }
            return type.resolvedBaseTypes = [baseType];
        }
        function areAllOuterTypeParametersApplied(type) {
            // An unapplied type parameter has its symbol still the same as the matching argument symbol.
            // Since parameters are applied outer-to-inner, only the last outer parameter needs to be checked.
            var outerTypeParameters = type.outerTypeParameters;
            if (outerTypeParameters) {
                var last_1 = outerTypeParameters.length - 1;
                var typeArguments = type.typeArguments;
                return outerTypeParameters[last_1].symbol !== typeArguments[last_1].symbol;
            }
            return true;
        }
        // A valid base type is `any`, any non-generic object type or intersection of non-generic
        // object types.
        function isValidBaseType(type) {
            return !!(type.flags & (524288 /* Object */ | 67108864 /* NonPrimitive */ | 1 /* Any */)) && !isGenericMappedType(type) ||
                !!(type.flags & 2097152 /* Intersection */) && ts.every(type.types, isValidBaseType);
        }
        function resolveBaseTypesOfInterface(type) {
            type.resolvedBaseTypes = type.resolvedBaseTypes || ts.emptyArray;
            for (var _i = 0, _a = type.symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                if (declaration.kind === 242 /* InterfaceDeclaration */ && ts.getInterfaceBaseTypeNodes(declaration)) {
                    for (var _b = 0, _c = ts.getInterfaceBaseTypeNodes(declaration); _b < _c.length; _b++) {
                        var node = _c[_b];
                        var baseType = getTypeFromTypeNode(node);
                        if (baseType !== errorType) {
                            if (isValidBaseType(baseType)) {
                                if (type !== baseType && !hasBaseType(baseType, type)) {
                                    if (type.resolvedBaseTypes === ts.emptyArray) {
                                        type.resolvedBaseTypes = [baseType];
                                    }
                                    else {
                                        type.resolvedBaseTypes.push(baseType);
                                    }
                                }
                                else {
                                    error(declaration, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, 2 /* WriteArrayAsGenericType */));
                                }
                            }
                            else {
                                error(node, ts.Diagnostics.An_interface_can_only_extend_an_object_type_or_intersection_of_object_types_with_statically_known_members);
                            }
                        }
                    }
                }
            }
        }
        /**
         * Returns true if the interface given by the symbol is free of "this" references.
         *
         * Specifically, the result is true if the interface itself contains no references
         * to "this" in its body, if all base types are interfaces,
         * and if none of the base interfaces have a "this" type.
         */
        function isThislessInterface(symbol) {
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                if (declaration.kind === 242 /* InterfaceDeclaration */) {
                    if (declaration.flags & 64 /* ContainsThis */) {
                        return false;
                    }
                    var baseTypeNodes = ts.getInterfaceBaseTypeNodes(declaration);
                    if (baseTypeNodes) {
                        for (var _b = 0, baseTypeNodes_1 = baseTypeNodes; _b < baseTypeNodes_1.length; _b++) {
                            var node = baseTypeNodes_1[_b];
                            if (ts.isEntityNameExpression(node.expression)) {
                                var baseSymbol = resolveEntityName(node.expression, 67897832 /* Type */, /*ignoreErrors*/ true);
                                if (!baseSymbol || !(baseSymbol.flags & 64 /* Interface */) || getDeclaredTypeOfClassOrInterface(baseSymbol).thisType) {
                                    return false;
                                }
                            }
                        }
                    }
                }
            }
            return true;
        }
        function getDeclaredTypeOfClassOrInterface(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.declaredType) {
                var kind = symbol.flags & 32 /* Class */ ? 1 /* Class */ : 2 /* Interface */;
                var type = links.declaredType = createObjectType(kind, symbol);
                var outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol);
                var localTypeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
                // A class or interface is generic if it has type parameters or a "this" type. We always give classes a "this" type
                // because it is not feasible to analyze all members to determine if the "this" type escapes the class (in particular,
                // property types inferred from initializers and method return types inferred from return statements are very hard
                // to exhaustively analyze). We give interfaces a "this" type if we can't definitely determine that they are free of
                // "this" references.
                if (outerTypeParameters || localTypeParameters || kind === 1 /* Class */ || !isThislessInterface(symbol)) {
                    type.objectFlags |= 4 /* Reference */;
                    type.typeParameters = ts.concatenate(outerTypeParameters, localTypeParameters);
                    type.outerTypeParameters = outerTypeParameters;
                    type.localTypeParameters = localTypeParameters;
                    type.instantiations = ts.createMap();
                    type.instantiations.set(getTypeListId(type.typeParameters), type);
                    type.target = type;
                    type.typeArguments = type.typeParameters;
                    type.thisType = createTypeParameter(symbol);
                    type.thisType.isThisType = true;
                    type.thisType.constraint = type;
                }
            }
            return links.declaredType;
        }
        function getDeclaredTypeOfTypeAlias(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.declaredType) {
                // Note that we use the links object as the target here because the symbol object is used as the unique
                // identity for resolution of the 'type' property in SymbolLinks.
                if (!pushTypeResolution(symbol, 2 /* DeclaredType */)) {
                    return errorType;
                }
                var declaration = ts.find(symbol.declarations, function (d) {
                    return ts.isJSDocTypeAlias(d) || d.kind === 243 /* TypeAliasDeclaration */;
                });
                var typeNode = ts.isJSDocTypeAlias(declaration) ? declaration.typeExpression : declaration.type;
                // If typeNode is missing, we will error in checkJSDocTypedefTag.
                var type = typeNode ? getTypeFromTypeNode(typeNode) : errorType;
                if (popTypeResolution()) {
                    var typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
                    if (typeParameters) {
                        // Initialize the instantiation cache for generic type aliases. The declared type corresponds to
                        // an instantiation of the type alias with the type parameters supplied as type arguments.
                        links.typeParameters = typeParameters;
                        links.instantiations = ts.createMap();
                        links.instantiations.set(getTypeListId(typeParameters), type);
                    }
                }
                else {
                    type = errorType;
                    error(declaration.name, ts.Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol));
                }
                links.declaredType = type;
            }
            return links.declaredType;
        }
        function isStringConcatExpression(expr) {
            if (expr.kind === 10 /* StringLiteral */) {
                return true;
            }
            else if (expr.kind === 205 /* BinaryExpression */) {
                return isStringConcatExpression(expr.left) && isStringConcatExpression(expr.right);
            }
            return false;
        }
        function isLiteralEnumMember(member) {
            var expr = member.initializer;
            if (!expr) {
                return !(member.flags & 4194304 /* Ambient */);
            }
            switch (expr.kind) {
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                    return true;
                case 203 /* PrefixUnaryExpression */:
                    return expr.operator === 39 /* MinusToken */ &&
                        expr.operand.kind === 8 /* NumericLiteral */;
                case 73 /* Identifier */:
                    return ts.nodeIsMissing(expr) || !!getSymbolOfNode(member.parent).exports.get(expr.escapedText);
                case 205 /* BinaryExpression */:
                    return isStringConcatExpression(expr);
                default:
                    return false;
            }
        }
        function getEnumKind(symbol) {
            var links = getSymbolLinks(symbol);
            if (links.enumKind !== undefined) {
                return links.enumKind;
            }
            var hasNonLiteralMember = false;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                if (declaration.kind === 244 /* EnumDeclaration */) {
                    for (var _b = 0, _c = declaration.members; _b < _c.length; _b++) {
                        var member = _c[_b];
                        if (member.initializer && member.initializer.kind === 10 /* StringLiteral */) {
                            return links.enumKind = 1 /* Literal */;
                        }
                        if (!isLiteralEnumMember(member)) {
                            hasNonLiteralMember = true;
                        }
                    }
                }
            }
            return links.enumKind = hasNonLiteralMember ? 0 /* Numeric */ : 1 /* Literal */;
        }
        function getBaseTypeOfEnumLiteralType(type) {
            return type.flags & 1024 /* EnumLiteral */ && !(type.flags & 1048576 /* Union */) ? getDeclaredTypeOfSymbol(getParentOfSymbol(type.symbol)) : type;
        }
        function getDeclaredTypeOfEnum(symbol) {
            var links = getSymbolLinks(symbol);
            if (links.declaredType) {
                return links.declaredType;
            }
            if (getEnumKind(symbol) === 1 /* Literal */) {
                enumCount++;
                var memberTypeList = [];
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    if (declaration.kind === 244 /* EnumDeclaration */) {
                        for (var _b = 0, _c = declaration.members; _b < _c.length; _b++) {
                            var member = _c[_b];
                            var memberType = getFreshTypeOfLiteralType(getLiteralType(getEnumMemberValue(member), enumCount, getSymbolOfNode(member))); // TODO: GH#18217
                            getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType;
                            memberTypeList.push(getRegularTypeOfLiteralType(memberType));
                        }
                    }
                }
                if (memberTypeList.length) {
                    var enumType_1 = getUnionType(memberTypeList, 1 /* Literal */, symbol, /*aliasTypeArguments*/ undefined);
                    if (enumType_1.flags & 1048576 /* Union */) {
                        enumType_1.flags |= 1024 /* EnumLiteral */;
                        enumType_1.symbol = symbol;
                    }
                    return links.declaredType = enumType_1;
                }
            }
            var enumType = createType(32 /* Enum */);
            enumType.symbol = symbol;
            return links.declaredType = enumType;
        }
        function getDeclaredTypeOfEnumMember(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.declaredType) {
                var enumType = getDeclaredTypeOfEnum(getParentOfSymbol(symbol));
                if (!links.declaredType) {
                    links.declaredType = enumType;
                }
            }
            return links.declaredType;
        }
        function getDeclaredTypeOfTypeParameter(symbol) {
            var links = getSymbolLinks(symbol);
            return links.declaredType || (links.declaredType = createTypeParameter(symbol));
        }
        function getDeclaredTypeOfAlias(symbol) {
            var links = getSymbolLinks(symbol);
            return links.declaredType || (links.declaredType = getDeclaredTypeOfSymbol(resolveAlias(symbol)));
        }
        function getDeclaredTypeOfSymbol(symbol) {
            return tryGetDeclaredTypeOfSymbol(symbol) || errorType;
        }
        function tryGetDeclaredTypeOfSymbol(symbol) {
            if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                return getDeclaredTypeOfClassOrInterface(symbol);
            }
            if (symbol.flags & 524288 /* TypeAlias */) {
                return getDeclaredTypeOfTypeAlias(symbol);
            }
            if (symbol.flags & 262144 /* TypeParameter */) {
                return getDeclaredTypeOfTypeParameter(symbol);
            }
            if (symbol.flags & 384 /* Enum */) {
                return getDeclaredTypeOfEnum(symbol);
            }
            if (symbol.flags & 8 /* EnumMember */) {
                return getDeclaredTypeOfEnumMember(symbol);
            }
            if (symbol.flags & 2097152 /* Alias */) {
                return getDeclaredTypeOfAlias(symbol);
            }
            return undefined;
        }
        /**
         * A type is free of this references if it's the any, string, number, boolean, symbol, or void keyword, a string
         * literal type, an array with an element type that is free of this references, or a type reference that is
         * free of this references.
         */
        function isThislessType(node) {
            switch (node.kind) {
                case 121 /* AnyKeyword */:
                case 144 /* UnknownKeyword */:
                case 139 /* StringKeyword */:
                case 136 /* NumberKeyword */:
                case 147 /* BigIntKeyword */:
                case 124 /* BooleanKeyword */:
                case 140 /* SymbolKeyword */:
                case 137 /* ObjectKeyword */:
                case 107 /* VoidKeyword */:
                case 142 /* UndefinedKeyword */:
                case 97 /* NullKeyword */:
                case 133 /* NeverKeyword */:
                case 183 /* LiteralType */:
                    return true;
                case 170 /* ArrayType */:
                    return isThislessType(node.elementType);
                case 165 /* TypeReference */:
                    return !node.typeArguments || node.typeArguments.every(isThislessType);
            }
            return false;
        }
        /** A type parameter is thisless if its constraint is thisless, or if it has no constraint. */
        function isThislessTypeParameter(node) {
            var constraint = ts.getEffectiveConstraintOfTypeParameter(node);
            return !constraint || isThislessType(constraint);
        }
        /**
         * A variable-like declaration is free of this references if it has a type annotation
         * that is thisless, or if it has no type annotation and no initializer (and is thus of type any).
         */
        function isThislessVariableLikeDeclaration(node) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(node);
            return typeNode ? isThislessType(typeNode) : !ts.hasInitializer(node);
        }
        /**
         * A function-like declaration is considered free of `this` references if it has a return type
         * annotation that is free of this references and if each parameter is thisless and if
         * each type parameter (if present) is thisless.
         */
        function isThislessFunctionLikeDeclaration(node) {
            var returnType = ts.getEffectiveReturnTypeNode(node);
            var typeParameters = ts.getEffectiveTypeParameterDeclarations(node);
            return (node.kind === 158 /* Constructor */ || (!!returnType && isThislessType(returnType))) &&
                node.parameters.every(isThislessVariableLikeDeclaration) &&
                typeParameters.every(isThislessTypeParameter);
        }
        /**
         * Returns true if the class or interface member given by the symbol is free of "this" references. The
         * function may return false for symbols that are actually free of "this" references because it is not
         * feasible to perform a complete analysis in all cases. In particular, property members with types
         * inferred from their initializers and function members with inferred return types are conservatively
         * assumed not to be free of "this" references.
         */
        function isThisless(symbol) {
            if (symbol.declarations && symbol.declarations.length === 1) {
                var declaration = symbol.declarations[0];
                if (declaration) {
                    switch (declaration.kind) {
                        case 155 /* PropertyDeclaration */:
                        case 154 /* PropertySignature */:
                            return isThislessVariableLikeDeclaration(declaration);
                        case 157 /* MethodDeclaration */:
                        case 156 /* MethodSignature */:
                        case 158 /* Constructor */:
                        case 159 /* GetAccessor */:
                        case 160 /* SetAccessor */:
                            return isThislessFunctionLikeDeclaration(declaration);
                    }
                }
            }
            return false;
        }
        // The mappingThisOnly flag indicates that the only type parameter being mapped is "this". When the flag is true,
        // we check symbols to see if we can quickly conclude they are free of "this" references, thus needing no instantiation.
        function createInstantiatedSymbolTable(symbols, mapper, mappingThisOnly) {
            var result = ts.createSymbolTable();
            for (var _i = 0, symbols_2 = symbols; _i < symbols_2.length; _i++) {
                var symbol = symbols_2[_i];
                result.set(symbol.escapedName, mappingThisOnly && isThisless(symbol) ? symbol : instantiateSymbol(symbol, mapper));
            }
            return result;
        }
        function addInheritedMembers(symbols, baseSymbols) {
            for (var _i = 0, baseSymbols_1 = baseSymbols; _i < baseSymbols_1.length; _i++) {
                var s = baseSymbols_1[_i];
                if (!symbols.has(s.escapedName)) {
                    symbols.set(s.escapedName, s);
                }
            }
        }
        function resolveDeclaredMembers(type) {
            if (!type.declaredProperties) {
                var symbol = type.symbol;
                var members = getMembersOfSymbol(symbol);
                type.declaredProperties = getNamedMembers(members);
                // Start with signatures at empty array in case of recursive types
                type.declaredCallSignatures = ts.emptyArray;
                type.declaredConstructSignatures = ts.emptyArray;
                type.declaredCallSignatures = getSignaturesOfSymbol(members.get("__call" /* Call */));
                type.declaredConstructSignatures = getSignaturesOfSymbol(members.get("__new" /* New */));
                type.declaredStringIndexInfo = getIndexInfoOfSymbol(symbol, 0 /* String */);
                type.declaredNumberIndexInfo = getIndexInfoOfSymbol(symbol, 1 /* Number */);
            }
            return type;
        }
        /**
         * Indicates whether a type can be used as a property name.
         */
        function isTypeUsableAsPropertyName(type) {
            return !!(type.flags & 8576 /* StringOrNumberLiteralOrUnique */);
        }
        /**
         * Indicates whether a declaration name is definitely late-bindable.
         * A declaration name is only late-bindable if:
         * - It is a `ComputedPropertyName`.
         * - Its expression is an `Identifier` or either a `PropertyAccessExpression` an
         * `ElementAccessExpression` consisting only of these same three types of nodes.
         * - The type of its expression is a string or numeric literal type, or is a `unique symbol` type.
         */
        function isLateBindableName(node) {
            return ts.isComputedPropertyName(node)
                && ts.isEntityNameExpression(node.expression)
                && isTypeUsableAsPropertyName(checkComputedPropertyName(node));
        }
        function isLateBoundName(name) {
            return name.charCodeAt(0) === 95 /* _ */ &&
                name.charCodeAt(1) === 95 /* _ */ &&
                name.charCodeAt(2) === 64 /* at */;
        }
        /**
         * Indicates whether a declaration has a late-bindable dynamic name.
         */
        function hasLateBindableName(node) {
            var name = ts.getNameOfDeclaration(node);
            return !!name && isLateBindableName(name);
        }
        /**
         * Indicates whether a declaration has a dynamic name that cannot be late-bound.
         */
        function hasNonBindableDynamicName(node) {
            return ts.hasDynamicName(node) && !hasLateBindableName(node);
        }
        /**
         * Indicates whether a declaration name is a dynamic name that cannot be late-bound.
         */
        function isNonBindableDynamicName(node) {
            return ts.isDynamicName(node) && !isLateBindableName(node);
        }
        /**
         * Gets the symbolic name for a member from its type.
         */
        function getPropertyNameFromType(type) {
            if (type.flags & 8192 /* UniqueESSymbol */) {
                return type.escapedName;
            }
            if (type.flags & (128 /* StringLiteral */ | 256 /* NumberLiteral */)) {
                return ts.escapeLeadingUnderscores("" + type.value);
            }
            return ts.Debug.fail();
        }
        /**
         * Adds a declaration to a late-bound dynamic member. This performs the same function for
         * late-bound members that `addDeclarationToSymbol` in binder.ts performs for early-bound
         * members.
         */
        function addDeclarationToLateBoundSymbol(symbol, member, symbolFlags) {
            ts.Debug.assert(!!(ts.getCheckFlags(symbol) & 4096 /* Late */), "Expected a late-bound symbol.");
            symbol.flags |= symbolFlags;
            getSymbolLinks(member.symbol).lateSymbol = symbol;
            if (!symbol.declarations) {
                symbol.declarations = [member];
            }
            else {
                symbol.declarations.push(member);
            }
            if (symbolFlags & 67220415 /* Value */) {
                if (!symbol.valueDeclaration || symbol.valueDeclaration.kind !== member.kind) {
                    symbol.valueDeclaration = member;
                }
            }
        }
        /**
         * Performs late-binding of a dynamic member. This performs the same function for
         * late-bound members that `declareSymbol` in binder.ts performs for early-bound
         * members.
         *
         * If a symbol is a dynamic name from a computed property, we perform an additional "late"
         * binding phase to attempt to resolve the name for the symbol from the type of the computed
         * property's expression. If the type of the expression is a string-literal, numeric-literal,
         * or unique symbol type, we can use that type as the name of the symbol.
         *
         * For example, given:
         *
         *   const x = Symbol();
         *
         *   interface I {
         *     [x]: number;
         *   }
         *
         * The binder gives the property `[x]: number` a special symbol with the name "__computed".
         * In the late-binding phase we can type-check the expression `x` and see that it has a
         * unique symbol type which we can then use as the name of the member. This allows users
         * to define custom symbols that can be used in the members of an object type.
         *
         * @param parent The containing symbol for the member.
         * @param earlySymbols The early-bound symbols of the parent.
         * @param lateSymbols The late-bound symbols of the parent.
         * @param decl The member to bind.
         */
        function lateBindMember(parent, earlySymbols, lateSymbols, decl) {
            ts.Debug.assert(!!decl.symbol, "The member is expected to have a symbol.");
            var links = getNodeLinks(decl);
            if (!links.resolvedSymbol) {
                // In the event we attempt to resolve the late-bound name of this member recursively,
                // fall back to the early-bound name of this member.
                links.resolvedSymbol = decl.symbol;
                var type = checkComputedPropertyName(decl.name);
                if (isTypeUsableAsPropertyName(type)) {
                    var memberName = getPropertyNameFromType(type);
                    var symbolFlags = decl.symbol.flags;
                    // Get or add a late-bound symbol for the member. This allows us to merge late-bound accessor declarations.
                    var lateSymbol = lateSymbols.get(memberName);
                    if (!lateSymbol)
                        lateSymbols.set(memberName, lateSymbol = createSymbol(0 /* None */, memberName, 4096 /* Late */));
                    // Report an error if a late-bound member has the same name as an early-bound member,
                    // or if we have another early-bound symbol declaration with the same name and
                    // conflicting flags.
                    var earlySymbol = earlySymbols && earlySymbols.get(memberName);
                    if (lateSymbol.flags & getExcludedSymbolFlags(symbolFlags) || earlySymbol) {
                        // If we have an existing early-bound member, combine its declarations so that we can
                        // report an error at each declaration.
                        var declarations = earlySymbol ? ts.concatenate(earlySymbol.declarations, lateSymbol.declarations) : lateSymbol.declarations;
                        var name_3 = !(type.flags & 8192 /* UniqueESSymbol */) && ts.unescapeLeadingUnderscores(memberName) || ts.declarationNameToString(decl.name);
                        ts.forEach(declarations, function (declaration) { return error(ts.getNameOfDeclaration(declaration) || declaration, ts.Diagnostics.Property_0_was_also_declared_here, name_3); });
                        error(decl.name || decl, ts.Diagnostics.Duplicate_property_0, name_3);
                        lateSymbol = createSymbol(0 /* None */, memberName, 4096 /* Late */);
                    }
                    lateSymbol.nameType = type;
                    addDeclarationToLateBoundSymbol(lateSymbol, decl, symbolFlags);
                    if (lateSymbol.parent) {
                        ts.Debug.assert(lateSymbol.parent === parent, "Existing symbol parent should match new one");
                    }
                    else {
                        lateSymbol.parent = parent;
                    }
                    return links.resolvedSymbol = lateSymbol;
                }
            }
            return links.resolvedSymbol;
        }
        function getResolvedMembersOrExportsOfSymbol(symbol, resolutionKind) {
            var links = getSymbolLinks(symbol);
            if (!links[resolutionKind]) {
                var isStatic = resolutionKind === "resolvedExports" /* resolvedExports */;
                var earlySymbols = !isStatic ? symbol.members :
                    symbol.flags & 1536 /* Module */ ? getExportsOfModuleWorker(symbol) :
                        symbol.exports;
                // In the event we recursively resolve the members/exports of the symbol, we
                // set the initial value of resolvedMembers/resolvedExports to the early-bound
                // members/exports of the symbol.
                links[resolutionKind] = earlySymbols || emptySymbols;
                // fill in any as-yet-unresolved late-bound members.
                var lateSymbols = ts.createSymbolTable();
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var members = ts.getMembersOfDeclaration(decl);
                    if (members) {
                        for (var _b = 0, members_4 = members; _b < members_4.length; _b++) {
                            var member = members_4[_b];
                            if (isStatic === ts.hasStaticModifier(member) && hasLateBindableName(member)) {
                                lateBindMember(symbol, earlySymbols, lateSymbols, member);
                            }
                        }
                    }
                }
                links[resolutionKind] = combineSymbolTables(earlySymbols, lateSymbols) || emptySymbols;
            }
            return links[resolutionKind];
        }
        /**
         * Gets a SymbolTable containing both the early- and late-bound members of a symbol.
         *
         * For a description of late-binding, see `lateBindMember`.
         */
        function getMembersOfSymbol(symbol) {
            return symbol.flags & 6240 /* LateBindingContainer */
                ? getResolvedMembersOrExportsOfSymbol(symbol, "resolvedMembers" /* resolvedMembers */)
                : symbol.members || emptySymbols;
        }
        /**
         * If a symbol is the dynamic name of the member of an object type, get the late-bound
         * symbol of the member.
         *
         * For a description of late-binding, see `lateBindMember`.
         */
        function getLateBoundSymbol(symbol) {
            if (symbol.flags & 106500 /* ClassMember */ && symbol.escapedName === "__computed" /* Computed */) {
                var links = getSymbolLinks(symbol);
                if (!links.lateSymbol && ts.some(symbol.declarations, hasLateBindableName)) {
                    // force late binding of members/exports. This will set the late-bound symbol
                    var parent = getMergedSymbol(symbol.parent);
                    if (ts.some(symbol.declarations, ts.hasStaticModifier)) {
                        getExportsOfSymbol(parent);
                    }
                    else {
                        getMembersOfSymbol(parent);
                    }
                }
                return links.lateSymbol || (links.lateSymbol = symbol);
            }
            return symbol;
        }
        function getTypeWithThisArgument(type, thisArgument, needApparentType) {
            if (ts.getObjectFlags(type) & 4 /* Reference */) {
                var target = type.target;
                var typeArguments = type.typeArguments;
                if (ts.length(target.typeParameters) === ts.length(typeArguments)) {
                    var ref = createTypeReference(target, ts.concatenate(typeArguments, [thisArgument || target.thisType]));
                    return needApparentType ? getApparentType(ref) : ref;
                }
            }
            else if (type.flags & 2097152 /* Intersection */) {
                return getIntersectionType(ts.map(type.types, function (t) { return getTypeWithThisArgument(t, thisArgument, needApparentType); }));
            }
            return needApparentType ? getApparentType(type) : type;
        }
        function resolveObjectTypeMembers(type, source, typeParameters, typeArguments) {
            var mapper;
            var members;
            var callSignatures;
            var constructSignatures;
            var stringIndexInfo;
            var numberIndexInfo;
            if (ts.rangeEquals(typeParameters, typeArguments, 0, typeParameters.length)) {
                mapper = identityMapper;
                members = source.symbol ? getMembersOfSymbol(source.symbol) : ts.createSymbolTable(source.declaredProperties);
                callSignatures = source.declaredCallSignatures;
                constructSignatures = source.declaredConstructSignatures;
                stringIndexInfo = source.declaredStringIndexInfo;
                numberIndexInfo = source.declaredNumberIndexInfo;
            }
            else {
                mapper = createTypeMapper(typeParameters, typeArguments);
                members = createInstantiatedSymbolTable(source.declaredProperties, mapper, /*mappingThisOnly*/ typeParameters.length === 1);
                callSignatures = instantiateSignatures(source.declaredCallSignatures, mapper);
                constructSignatures = instantiateSignatures(source.declaredConstructSignatures, mapper);
                stringIndexInfo = instantiateIndexInfo(source.declaredStringIndexInfo, mapper);
                numberIndexInfo = instantiateIndexInfo(source.declaredNumberIndexInfo, mapper);
            }
            var baseTypes = getBaseTypes(source);
            if (baseTypes.length) {
                if (source.symbol && members === getMembersOfSymbol(source.symbol)) {
                    members = ts.createSymbolTable(source.declaredProperties);
                }
                setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
                var thisArgument = ts.lastOrUndefined(typeArguments);
                for (var _i = 0, baseTypes_1 = baseTypes; _i < baseTypes_1.length; _i++) {
                    var baseType = baseTypes_1[_i];
                    var instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType;
                    addInheritedMembers(members, getPropertiesOfType(instantiatedBaseType));
                    callSignatures = ts.concatenate(callSignatures, getSignaturesOfType(instantiatedBaseType, 0 /* Call */));
                    constructSignatures = ts.concatenate(constructSignatures, getSignaturesOfType(instantiatedBaseType, 1 /* Construct */));
                    if (!stringIndexInfo) {
                        stringIndexInfo = instantiatedBaseType === anyType ?
                            createIndexInfo(anyType, /*isReadonly*/ false) :
                            getIndexInfoOfType(instantiatedBaseType, 0 /* String */);
                    }
                    numberIndexInfo = numberIndexInfo || getIndexInfoOfType(instantiatedBaseType, 1 /* Number */);
                }
            }
            setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        function resolveClassOrInterfaceMembers(type) {
            resolveObjectTypeMembers(type, resolveDeclaredMembers(type), ts.emptyArray, ts.emptyArray);
        }
        function resolveTypeReferenceMembers(type) {
            var source = resolveDeclaredMembers(type.target);
            var typeParameters = ts.concatenate(source.typeParameters, [source.thisType]);
            var typeArguments = type.typeArguments && type.typeArguments.length === typeParameters.length ?
                type.typeArguments : ts.concatenate(type.typeArguments, [type]);
            resolveObjectTypeMembers(type, source, typeParameters, typeArguments);
        }
        function createSignature(declaration, typeParameters, thisParameter, parameters, resolvedReturnType, resolvedTypePredicate, minArgumentCount, hasRestParameter, hasLiteralTypes) {
            var sig = new Signature(checker);
            sig.declaration = declaration;
            sig.typeParameters = typeParameters;
            sig.parameters = parameters;
            sig.thisParameter = thisParameter;
            sig.resolvedReturnType = resolvedReturnType;
            sig.resolvedTypePredicate = resolvedTypePredicate;
            sig.minArgumentCount = minArgumentCount;
            sig.hasRestParameter = hasRestParameter;
            sig.hasLiteralTypes = hasLiteralTypes;
            sig.target = undefined;
            sig.mapper = undefined;
            return sig;
        }
        function cloneSignature(sig) {
            var result = createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, /*resolvedReturnType*/ undefined, 
            /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.hasRestParameter, sig.hasLiteralTypes);
            result.target = sig.target;
            result.mapper = sig.mapper;
            return result;
        }
        function createUnionSignature(signature, unionSignatures) {
            var result = cloneSignature(signature);
            result.unionSignatures = unionSignatures;
            result.target = undefined;
            result.mapper = undefined;
            return result;
        }
        function getExpandedParameters(sig) {
            if (sig.hasRestParameter) {
                var restIndex_1 = sig.parameters.length - 1;
                var restParameter = sig.parameters[restIndex_1];
                var restType = getTypeOfSymbol(restParameter);
                if (isTupleType(restType)) {
                    var elementTypes = restType.typeArguments || ts.emptyArray;
                    var minLength_1 = restType.target.minLength;
                    var tupleRestIndex_1 = restType.target.hasRestElement ? elementTypes.length - 1 : -1;
                    var restParams = ts.map(elementTypes, function (t, i) {
                        var name = getParameterNameAtPosition(sig, restIndex_1 + i);
                        var checkFlags = i === tupleRestIndex_1 ? 32768 /* RestParameter */ :
                            i >= minLength_1 ? 16384 /* OptionalParameter */ : 0;
                        var symbol = createSymbol(1 /* FunctionScopedVariable */, name, checkFlags);
                        symbol.type = i === tupleRestIndex_1 ? createArrayType(t) : t;
                        return symbol;
                    });
                    return ts.concatenate(sig.parameters.slice(0, restIndex_1), restParams);
                }
            }
            return sig.parameters;
        }
        function getDefaultConstructSignatures(classType) {
            var baseConstructorType = getBaseConstructorTypeOfClass(classType);
            var baseSignatures = getSignaturesOfType(baseConstructorType, 1 /* Construct */);
            if (baseSignatures.length === 0) {
                return [createSignature(undefined, classType.localTypeParameters, undefined, ts.emptyArray, classType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)]; // TODO: GH#18217
            }
            var baseTypeNode = getBaseTypeNodeOfClass(classType);
            var isJavaScript = ts.isInJSFile(baseTypeNode);
            var typeArguments = typeArgumentsFromTypeReferenceNode(baseTypeNode);
            var typeArgCount = ts.length(typeArguments);
            var result = [];
            for (var _i = 0, baseSignatures_1 = baseSignatures; _i < baseSignatures_1.length; _i++) {
                var baseSig = baseSignatures_1[_i];
                var minTypeArgumentCount = getMinTypeArgumentCount(baseSig.typeParameters);
                var typeParamCount = ts.length(baseSig.typeParameters);
                if (isJavaScript || typeArgCount >= minTypeArgumentCount && typeArgCount <= typeParamCount) {
                    var sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, isJavaScript)) : cloneSignature(baseSig);
                    sig.typeParameters = classType.localTypeParameters;
                    sig.resolvedReturnType = classType;
                    result.push(sig);
                }
            }
            return result;
        }
        function findMatchingSignature(signatureList, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes) {
            for (var _i = 0, signatureList_1 = signatureList; _i < signatureList_1.length; _i++) {
                var s = signatureList_1[_i];
                if (compareSignaturesIdentical(s, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes, partialMatch ? compareTypesSubtypeOf : compareTypesIdentical)) {
                    return s;
                }
            }
        }
        function findMatchingSignatures(signatureLists, signature, listIndex) {
            if (signature.typeParameters) {
                // We require an exact match for generic signatures, so we only return signatures from the first
                // signature list and only if they have exact matches in the other signature lists.
                if (listIndex > 0) {
                    return undefined;
                }
                for (var i = 1; i < signatureLists.length; i++) {
                    if (!findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false)) {
                        return undefined;
                    }
                }
                return [signature];
            }
            var result;
            for (var i = 0; i < signatureLists.length; i++) {
                // Allow matching non-generic signatures to have excess parameters and different return types
                var match = i === listIndex ? signature : findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ true, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true);
                if (!match) {
                    return undefined;
                }
                result = ts.appendIfUnique(result, match);
            }
            return result;
        }
        // The signatures of a union type are those signatures that are present in each of the constituent types.
        // Generic signatures must match exactly, but non-generic signatures are allowed to have extra optional
        // parameters and may differ in return types. When signatures differ in return types, the resulting return
        // type is the union of the constituent return types.
        function getUnionSignatures(signatureLists) {
            var result;
            var indexWithLengthOverOne;
            for (var i = 0; i < signatureLists.length; i++) {
                if (signatureLists[i].length === 0)
                    return ts.emptyArray;
                if (signatureLists[i].length > 1) {
                    indexWithLengthOverOne = indexWithLengthOverOne === undefined ? i : -1; // -1 is a signal there are multiple overload sets
                }
                for (var _i = 0, _a = signatureLists[i]; _i < _a.length; _i++) {
                    var signature = _a[_i];
                    // Only process signatures with parameter lists that aren't already in the result list
                    if (!result || !findMatchingSignature(result, signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true)) {
                        var unionSignatures = findMatchingSignatures(signatureLists, signature, i);
                        if (unionSignatures) {
                            var s = signature;
                            // Union the result types when more than one signature matches
                            if (unionSignatures.length > 1) {
                                var thisParameter = signature.thisParameter;
                                var firstThisParameterOfUnionSignatures = ts.forEach(unionSignatures, function (sig) { return sig.thisParameter; });
                                if (firstThisParameterOfUnionSignatures) {
                                    var thisType = getUnionType(ts.map(unionSignatures, function (sig) { return sig.thisParameter ? getTypeOfSymbol(sig.thisParameter) : anyType; }), 2 /* Subtype */);
                                    thisParameter = createSymbolWithType(firstThisParameterOfUnionSignatures, thisType);
                                }
                                s = createUnionSignature(signature, unionSignatures);
                                s.thisParameter = thisParameter;
                            }
                            (result || (result = [])).push(s);
                        }
                    }
                }
            }
            if (!ts.length(result) && indexWithLengthOverOne !== -1) {
                // No sufficiently similar signature existed to subsume all the other signatures in the union - time to see if we can make a single
                // signature that handles all over them. We only do this when there are overloads in only one constituent.
                // (Overloads are conditional in nature and having overloads in multiple constituents would necessitate making a power set of
                // signatures from the type, whose ordering would be non-obvious)
                var masterList = signatureLists[indexWithLengthOverOne !== undefined ? indexWithLengthOverOne : 0];
                var results = masterList.slice();
                var _loop_5 = function (signatures) {
                    if (signatures !== masterList) {
                        var signature_1 = signatures[0];
                        ts.Debug.assert(!!signature_1, "getUnionSignatures bails early on empty signature lists and should not have empty lists on second pass");
                        results = signature_1.typeParameters && ts.some(results, function (s) { return !!s.typeParameters; }) ? undefined : ts.map(results, function (sig) { return combineSignaturesOfUnionMembers(sig, signature_1); });
                        if (!results) {
                            return "break";
                        }
                    }
                };
                for (var _b = 0, signatureLists_1 = signatureLists; _b < signatureLists_1.length; _b++) {
                    var signatures = signatureLists_1[_b];
                    var state_2 = _loop_5(signatures);
                    if (state_2 === "break")
                        break;
                }
                result = results;
            }
            return result || ts.emptyArray;
        }
        function combineUnionThisParam(left, right) {
            if (!left || !right) {
                return left || right;
            }
            // A signature `this` type might be a read or a write position... It's very possible that it should be invariant
            // and we should refuse to merge signatures if there are `this` types and they do not match. However, so as to be
            // permissive when calling, for now, we'll union the `this` types just like the overlapping-union-signature check does
            var thisType = getUnionType([getTypeOfSymbol(left), getTypeOfSymbol(right)], 2 /* Subtype */);
            return createSymbolWithType(left, thisType);
        }
        function combineUnionParameters(left, right) {
            var longest = getParameterCount(left) >= getParameterCount(right) ? left : right;
            var shorter = longest === left ? right : left;
            var longestCount = getParameterCount(longest);
            var eitherHasEffectiveRest = (hasEffectiveRestParameter(left) || hasEffectiveRestParameter(right));
            var needsExtraRestElement = eitherHasEffectiveRest && !hasEffectiveRestParameter(longest);
            var params = new Array(longestCount + (needsExtraRestElement ? 1 : 0));
            for (var i = 0; i < longestCount; i++) {
                var longestParamType = tryGetTypeAtPosition(longest, i);
                var shorterParamType = tryGetTypeAtPosition(shorter, i) || unknownType;
                var unionParamType = getIntersectionType([longestParamType, shorterParamType]);
                var isRestParam = eitherHasEffectiveRest && !needsExtraRestElement && i === (longestCount - 1);
                var isOptional = i >= getMinArgumentCount(longest) && i >= getMinArgumentCount(shorter);
                var leftName = getParameterNameAtPosition(left, i);
                var rightName = getParameterNameAtPosition(right, i);
                var paramSymbol = createSymbol(1 /* FunctionScopedVariable */ | (isOptional && !isRestParam ? 16777216 /* Optional */ : 0), leftName === rightName ? leftName : "arg" + i);
                paramSymbol.type = isRestParam ? createArrayType(unionParamType) : unionParamType;
                params[i] = paramSymbol;
            }
            if (needsExtraRestElement) {
                var restParamSymbol = createSymbol(1 /* FunctionScopedVariable */, "args");
                restParamSymbol.type = createArrayType(getTypeAtPosition(shorter, longestCount));
                params[longestCount] = restParamSymbol;
            }
            return params;
        }
        function combineSignaturesOfUnionMembers(left, right) {
            var declaration = left.declaration;
            var params = combineUnionParameters(left, right);
            var thisParam = combineUnionThisParam(left.thisParameter, right.thisParameter);
            var minArgCount = Math.max(left.minArgumentCount, right.minArgumentCount);
            var hasRestParam = left.hasRestParameter || right.hasRestParameter;
            var hasLiteralTypes = left.hasLiteralTypes || right.hasLiteralTypes;
            var result = createSignature(declaration, left.typeParameters || right.typeParameters, thisParam, params, 
            /*resolvedReturnType*/ undefined, 
            /*resolvedTypePredicate*/ undefined, minArgCount, hasRestParam, hasLiteralTypes);
            result.unionSignatures = ts.concatenate(left.unionSignatures || [left], [right]);
            return result;
        }
        function getUnionIndexInfo(types, kind) {
            var indexTypes = [];
            var isAnyReadonly = false;
            for (var _i = 0, types_2 = types; _i < types_2.length; _i++) {
                var type = types_2[_i];
                var indexInfo = getIndexInfoOfType(type, kind);
                if (!indexInfo) {
                    return undefined;
                }
                indexTypes.push(indexInfo.type);
                isAnyReadonly = isAnyReadonly || indexInfo.isReadonly;
            }
            return createIndexInfo(getUnionType(indexTypes, 2 /* Subtype */), isAnyReadonly);
        }
        function resolveUnionTypeMembers(type) {
            // The members and properties collections are empty for union types. To get all properties of a union
            // type use getPropertiesOfType (only the language service uses this).
            var callSignatures = getUnionSignatures(ts.map(type.types, function (t) { return t === globalFunctionType ? [unknownSignature] : getSignaturesOfType(t, 0 /* Call */); }));
            var constructSignatures = getUnionSignatures(ts.map(type.types, function (t) { return getSignaturesOfType(t, 1 /* Construct */); }));
            var stringIndexInfo = getUnionIndexInfo(type.types, 0 /* String */);
            var numberIndexInfo = getUnionIndexInfo(type.types, 1 /* Number */);
            setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        function intersectTypes(type1, type2) {
            return !type1 ? type2 : !type2 ? type1 : getIntersectionType([type1, type2]);
        }
        function intersectIndexInfos(info1, info2) {
            return !info1 ? info2 : !info2 ? info1 : createIndexInfo(getIntersectionType([info1.type, info2.type]), info1.isReadonly && info2.isReadonly);
        }
        function unionSpreadIndexInfos(info1, info2) {
            return info1 && info2 && createIndexInfo(getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly);
        }
        function findMixins(types) {
            var constructorTypeCount = ts.countWhere(types, function (t) { return getSignaturesOfType(t, 1 /* Construct */).length > 0; });
            var mixinFlags = ts.map(types, isMixinConstructorType);
            if (constructorTypeCount > 0 && constructorTypeCount === ts.countWhere(mixinFlags, function (b) { return b; })) {
                var firstMixinIndex = mixinFlags.indexOf(/*searchElement*/ true);
                mixinFlags[firstMixinIndex] = false;
            }
            return mixinFlags;
        }
        function includeMixinType(type, types, mixinFlags, index) {
            var mixedTypes = [];
            for (var i = 0; i < types.length; i++) {
                if (i === index) {
                    mixedTypes.push(type);
                }
                else if (mixinFlags[i]) {
                    mixedTypes.push(getReturnTypeOfSignature(getSignaturesOfType(types[i], 1 /* Construct */)[0]));
                }
            }
            return getIntersectionType(mixedTypes);
        }
        function resolveIntersectionTypeMembers(type) {
            // The members and properties collections are empty for intersection types. To get all properties of an
            // intersection type use getPropertiesOfType (only the language service uses this).
            var callSignatures = ts.emptyArray;
            var constructSignatures = ts.emptyArray;
            var stringIndexInfo;
            var numberIndexInfo;
            var types = type.types;
            var mixinFlags = findMixins(types);
            var mixinCount = ts.countWhere(mixinFlags, function (b) { return b; });
            var _loop_6 = function (i) {
                var t = type.types[i];
                // When an intersection type contains mixin constructor types, the construct signatures from
                // those types are discarded and their return types are mixed into the return types of all
                // other construct signatures in the intersection type. For example, the intersection type
                // '{ new(...args: any[]) => A } & { new(s: string) => B }' has a single construct signature
                // 'new(s: string) => A & B'.
                if (!mixinFlags[i]) {
                    var signatures = getSignaturesOfType(t, 1 /* Construct */);
                    if (signatures.length && mixinCount > 0) {
                        signatures = ts.map(signatures, function (s) {
                            var clone = cloneSignature(s);
                            clone.resolvedReturnType = includeMixinType(getReturnTypeOfSignature(s), types, mixinFlags, i);
                            return clone;
                        });
                    }
                    constructSignatures = ts.concatenate(constructSignatures, signatures);
                }
                callSignatures = ts.concatenate(callSignatures, getSignaturesOfType(t, 0 /* Call */));
                stringIndexInfo = intersectIndexInfos(stringIndexInfo, getIndexInfoOfType(t, 0 /* String */));
                numberIndexInfo = intersectIndexInfos(numberIndexInfo, getIndexInfoOfType(t, 1 /* Number */));
            };
            for (var i = 0; i < types.length; i++) {
                _loop_6(i);
            }
            setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        /**
         * Converts an AnonymousType to a ResolvedType.
         */
        function resolveAnonymousTypeMembers(type) {
            var symbol = type.symbol;
            if (type.target) {
                setStructuredTypeMembers(type, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
                var members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper, /*mappingThisOnly*/ false);
                var callSignatures = instantiateSignatures(getSignaturesOfType(type.target, 0 /* Call */), type.mapper);
                var constructSignatures = instantiateSignatures(getSignaturesOfType(type.target, 1 /* Construct */), type.mapper);
                var stringIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, 0 /* String */), type.mapper);
                var numberIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, 1 /* Number */), type.mapper);
                setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
            }
            else if (symbol.flags & 2048 /* TypeLiteral */) {
                setStructuredTypeMembers(type, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
                var members = getMembersOfSymbol(symbol);
                var callSignatures = getSignaturesOfSymbol(members.get("__call" /* Call */));
                var constructSignatures = getSignaturesOfSymbol(members.get("__new" /* New */));
                var stringIndexInfo = getIndexInfoOfSymbol(symbol, 0 /* String */);
                var numberIndexInfo = getIndexInfoOfSymbol(symbol, 1 /* Number */);
                setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
            }
            else {
                // Combinations of function, class, enum and module
                var members = emptySymbols;
                var stringIndexInfo = void 0;
                if (symbol.exports) {
                    members = getExportsOfSymbol(symbol);
                    if (symbol === globalThisSymbol) {
                        var varsOnly_1 = ts.createMap();
                        members.forEach(function (p) {
                            if (!(p.flags & 418 /* BlockScoped */)) {
                                varsOnly_1.set(p.escapedName, p);
                            }
                        });
                        members = varsOnly_1;
                    }
                }
                setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, undefined, undefined);
                if (symbol.flags & 32 /* Class */) {
                    var classType = getDeclaredTypeOfClassOrInterface(symbol);
                    var baseConstructorType = getBaseConstructorTypeOfClass(classType);
                    if (baseConstructorType.flags & (524288 /* Object */ | 2097152 /* Intersection */ | 8650752 /* TypeVariable */)) {
                        members = ts.createSymbolTable(getNamedMembers(members));
                        addInheritedMembers(members, getPropertiesOfType(baseConstructorType));
                    }
                    else if (baseConstructorType === anyType) {
                        stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
                    }
                }
                var numberIndexInfo = symbol.flags & 384 /* Enum */ ? enumNumberIndexInfo : undefined;
                setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
                // We resolve the members before computing the signatures because a signature may use
                // typeof with a qualified name expression that circularly references the type we are
                // in the process of resolving (see issue #6072). The temporarily empty signature list
                // will never be observed because a qualified name can't reference signatures.
                if (symbol.flags & (16 /* Function */ | 8192 /* Method */)) {
                    type.callSignatures = getSignaturesOfSymbol(symbol);
                    type.constructSignatures = ts.filter(type.callSignatures, function (sig) { return isJSConstructor(sig.declaration); });
                }
                // And likewise for construct signatures for classes
                if (symbol.flags & 32 /* Class */) {
                    var classType = getDeclaredTypeOfClassOrInterface(symbol);
                    var constructSignatures = getSignaturesOfSymbol(symbol.members.get("__constructor" /* Constructor */));
                    if (!constructSignatures.length) {
                        constructSignatures = getDefaultConstructSignatures(classType);
                    }
                    type.constructSignatures = constructSignatures;
                }
            }
        }
        function resolveReverseMappedTypeMembers(type) {
            var indexInfo = getIndexInfoOfType(type.source, 0 /* String */);
            var modifiers = getMappedTypeModifiers(type.mappedType);
            var readonlyMask = modifiers & 1 /* IncludeReadonly */ ? false : true;
            var optionalMask = modifiers & 4 /* IncludeOptional */ ? 0 : 16777216 /* Optional */;
            var stringIndexInfo = indexInfo && createIndexInfo(inferReverseMappedType(indexInfo.type, type.mappedType, type.constraintType), readonlyMask && indexInfo.isReadonly);
            var members = ts.createSymbolTable();
            for (var _i = 0, _a = getPropertiesOfType(type.source); _i < _a.length; _i++) {
                var prop = _a[_i];
                var checkFlags = 8192 /* ReverseMapped */ | (readonlyMask && isReadonlySymbol(prop) ? 8 /* Readonly */ : 0);
                var inferredProp = createSymbol(4 /* Property */ | prop.flags & optionalMask, prop.escapedName, checkFlags);
                inferredProp.declarations = prop.declarations;
                inferredProp.nameType = prop.nameType;
                inferredProp.propertyType = getTypeOfSymbol(prop);
                inferredProp.mappedType = type.mappedType;
                inferredProp.constraintType = type.constraintType;
                members.set(prop.escapedName, inferredProp);
            }
            setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, undefined);
        }
        // Return the lower bound of the key type in a mapped type. Intuitively, the lower
        // bound includes those keys that are known to always be present, for example because
        // because of constraints on type parameters (e.g. 'keyof T' for a constrained T).
        function getLowerBoundOfKeyType(type) {
            if (type.flags & (1 /* Any */ | 131068 /* Primitive */)) {
                return type;
            }
            if (type.flags & 4194304 /* Index */) {
                return getIndexType(getApparentType(type.type));
            }
            if (type.flags & 16777216 /* Conditional */) {
                if (type.root.isDistributive) {
                    var checkType = type.checkType;
                    var constraint = getLowerBoundOfKeyType(checkType);
                    if (constraint !== checkType) {
                        var mapper = makeUnaryTypeMapper(type.root.checkType, constraint);
                        return getConditionalTypeInstantiation(type, combineTypeMappers(mapper, type.mapper));
                    }
                }
                return type;
            }
            if (type.flags & 1048576 /* Union */) {
                return getUnionType(ts.sameMap(type.types, getLowerBoundOfKeyType));
            }
            if (type.flags & 2097152 /* Intersection */) {
                return getIntersectionType(ts.sameMap(type.types, getLowerBoundOfKeyType));
            }
            return neverType;
        }
        /** Resolve the members of a mapped type { [P in K]: T } */
        function resolveMappedTypeMembers(type) {
            var members = ts.createSymbolTable();
            var stringIndexInfo;
            var numberIndexInfo;
            // Resolve upfront such that recursive references see an empty object type.
            setStructuredTypeMembers(type, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
            // In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type,
            // and T as the template type.
            var typeParameter = getTypeParameterFromMappedType(type);
            var constraintType = getConstraintTypeFromMappedType(type);
            var templateType = getTemplateTypeFromMappedType(type.target || type);
            var modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T'
            var templateModifiers = getMappedTypeModifiers(type);
            var include = keyofStringsOnly ? 128 /* StringLiteral */ : 8576 /* StringOrNumberLiteralOrUnique */;
            if (isMappedTypeWithKeyofConstraintDeclaration(type)) {
                // We have a { [P in keyof T]: X }
                for (var _i = 0, _a = getPropertiesOfType(modifiersType); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    addMemberForKeyType(getLiteralTypeFromProperty(prop, include));
                }
                if (modifiersType.flags & 1 /* Any */ || getIndexInfoOfType(modifiersType, 0 /* String */)) {
                    addMemberForKeyType(stringType);
                }
                if (!keyofStringsOnly && getIndexInfoOfType(modifiersType, 1 /* Number */)) {
                    addMemberForKeyType(numberType);
                }
            }
            else {
                forEachType(getLowerBoundOfKeyType(constraintType), addMemberForKeyType);
            }
            setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
            function addMemberForKeyType(t) {
                // Create a mapper from T to the current iteration type constituent. Then, if the
                // mapped type is itself an instantiated type, combine the iteration mapper with the
                // instantiation mapper.
                var templateMapper = combineTypeMappers(type.mapper, createTypeMapper([typeParameter], [t]));
                var propType = instantiateType(templateType, templateMapper);
                // If the current iteration type constituent is a string literal type, create a property.
                // Otherwise, for type string create a string index signature.
                if (isTypeUsableAsPropertyName(t)) {
                    var propName = getPropertyNameFromType(t);
                    var modifiersProp = getPropertyOfType(modifiersType, propName);
                    var isOptional = !!(templateModifiers & 4 /* IncludeOptional */ ||
                        !(templateModifiers & 8 /* ExcludeOptional */) && modifiersProp && modifiersProp.flags & 16777216 /* Optional */);
                    var isReadonly = !!(templateModifiers & 1 /* IncludeReadonly */ ||
                        !(templateModifiers & 2 /* ExcludeReadonly */) && modifiersProp && isReadonlySymbol(modifiersProp));
                    var prop = createSymbol(4 /* Property */ | (isOptional ? 16777216 /* Optional */ : 0), propName, isReadonly ? 8 /* Readonly */ : 0);
                    // When creating an optional property in strictNullChecks mode, if 'undefined' isn't assignable to the
                    // type, we include 'undefined' in the type. Similarly, when creating a non-optional property in strictNullChecks
                    // mode, if the underlying property is optional we remove 'undefined' from the type.
                    prop.type = strictNullChecks && isOptional && !isTypeAssignableTo(undefinedType, propType) ? getOptionalType(propType) :
                        strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & 16777216 /* Optional */ ? getTypeWithFacts(propType, 524288 /* NEUndefined */) :
                            propType;
                    if (modifiersProp) {
                        prop.syntheticOrigin = modifiersProp;
                        prop.declarations = modifiersProp.declarations;
                    }
                    prop.nameType = t;
                    members.set(propName, prop);
                }
                else if (t.flags & (1 /* Any */ | 4 /* String */)) {
                    stringIndexInfo = createIndexInfo(propType, !!(templateModifiers & 1 /* IncludeReadonly */));
                }
                else if (t.flags & 8 /* Number */) {
                    numberIndexInfo = createIndexInfo(propType, !!(templateModifiers & 1 /* IncludeReadonly */));
                }
            }
        }
        function getTypeParameterFromMappedType(type) {
            return type.typeParameter ||
                (type.typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(type.declaration.typeParameter)));
        }
        function getConstraintTypeFromMappedType(type) {
            return type.constraintType ||
                (type.constraintType = getConstraintOfTypeParameter(getTypeParameterFromMappedType(type)) || errorType);
        }
        function getTemplateTypeFromMappedType(type) {
            return type.templateType ||
                (type.templateType = type.declaration.type ?
                    instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), !!(getMappedTypeModifiers(type) & 4 /* IncludeOptional */)), type.mapper || identityMapper) :
                    errorType);
        }
        function getConstraintDeclarationForMappedType(type) {
            return ts.getEffectiveConstraintOfTypeParameter(type.declaration.typeParameter);
        }
        function isMappedTypeWithKeyofConstraintDeclaration(type) {
            var constraintDeclaration = getConstraintDeclarationForMappedType(type); // TODO: GH#18217
            return constraintDeclaration.kind === 180 /* TypeOperator */ &&
                constraintDeclaration.operator === 130 /* KeyOfKeyword */;
        }
        function getModifiersTypeFromMappedType(type) {
            if (!type.modifiersType) {
                if (isMappedTypeWithKeyofConstraintDeclaration(type)) {
                    // If the constraint declaration is a 'keyof T' node, the modifiers type is T. We check
                    // AST nodes here because, when T is a non-generic type, the logic below eagerly resolves
                    // 'keyof T' to a literal union type and we can't recover T from that type.
                    type.modifiersType = instantiateType(getTypeFromTypeNode(getConstraintDeclarationForMappedType(type).type), type.mapper || identityMapper);
                }
                else {
                    // Otherwise, get the declared constraint type, and if the constraint type is a type parameter,
                    // get the constraint of that type parameter. If the resulting type is an indexed type 'keyof T',
                    // the modifiers type is T. Otherwise, the modifiers type is {}.
                    var declaredType = getTypeFromMappedTypeNode(type.declaration);
                    var constraint = getConstraintTypeFromMappedType(declaredType);
                    var extendedConstraint = constraint && constraint.flags & 262144 /* TypeParameter */ ? getConstraintOfTypeParameter(constraint) : constraint;
                    type.modifiersType = extendedConstraint && extendedConstraint.flags & 4194304 /* Index */ ? instantiateType(extendedConstraint.type, type.mapper || identityMapper) : unknownType;
                }
            }
            return type.modifiersType;
        }
        function getMappedTypeModifiers(type) {
            var declaration = type.declaration;
            return (declaration.readonlyToken ? declaration.readonlyToken.kind === 39 /* MinusToken */ ? 2 /* ExcludeReadonly */ : 1 /* IncludeReadonly */ : 0) |
                (declaration.questionToken ? declaration.questionToken.kind === 39 /* MinusToken */ ? 8 /* ExcludeOptional */ : 4 /* IncludeOptional */ : 0);
        }
        function getMappedTypeOptionality(type) {
            var modifiers = getMappedTypeModifiers(type);
            return modifiers & 8 /* ExcludeOptional */ ? -1 : modifiers & 4 /* IncludeOptional */ ? 1 : 0;
        }
        function getCombinedMappedTypeOptionality(type) {
            var optionality = getMappedTypeOptionality(type);
            var modifiersType = getModifiersTypeFromMappedType(type);
            return optionality || (isGenericMappedType(modifiersType) ? getMappedTypeOptionality(modifiersType) : 0);
        }
        function isPartialMappedType(type) {
            return !!(ts.getObjectFlags(type) & 32 /* Mapped */ && getMappedTypeModifiers(type) & 4 /* IncludeOptional */);
        }
        function isGenericMappedType(type) {
            return !!(ts.getObjectFlags(type) & 32 /* Mapped */) && isGenericIndexType(getConstraintTypeFromMappedType(type));
        }
        function resolveStructuredTypeMembers(type) {
            if (!type.members) {
                if (type.flags & 524288 /* Object */) {
                    if (type.objectFlags & 4 /* Reference */) {
                        resolveTypeReferenceMembers(type);
                    }
                    else if (type.objectFlags & 3 /* ClassOrInterface */) {
                        resolveClassOrInterfaceMembers(type);
                    }
                    else if (type.objectFlags & 2048 /* ReverseMapped */) {
                        resolveReverseMappedTypeMembers(type);
                    }
                    else if (type.objectFlags & 16 /* Anonymous */) {
                        resolveAnonymousTypeMembers(type);
                    }
                    else if (type.objectFlags & 32 /* Mapped */) {
                        resolveMappedTypeMembers(type);
                    }
                }
                else if (type.flags & 1048576 /* Union */) {
                    resolveUnionTypeMembers(type);
                }
                else if (type.flags & 2097152 /* Intersection */) {
                    resolveIntersectionTypeMembers(type);
                }
            }
            return type;
        }
        /** Return properties of an object type or an empty array for other types */
        function getPropertiesOfObjectType(type) {
            if (type.flags & 524288 /* Object */) {
                return resolveStructuredTypeMembers(type).properties;
            }
            return ts.emptyArray;
        }
        /** If the given type is an object type and that type has a property by the given name,
         * return the symbol for that property. Otherwise return undefined.
         */
        function getPropertyOfObjectType(type, name) {
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                var symbol = resolved.members.get(name);
                if (symbol && symbolIsValue(symbol)) {
                    return symbol;
                }
            }
        }
        function getPropertiesOfUnionOrIntersectionType(type) {
            if (!type.resolvedProperties) {
                var members = ts.createSymbolTable();
                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                    var current = _a[_i];
                    for (var _b = 0, _c = getPropertiesOfType(current); _b < _c.length; _b++) {
                        var prop = _c[_b];
                        if (!members.has(prop.escapedName)) {
                            var combinedProp = getPropertyOfUnionOrIntersectionType(type, prop.escapedName);
                            if (combinedProp) {
                                members.set(prop.escapedName, combinedProp);
                            }
                        }
                    }
                    // The properties of a union type are those that are present in all constituent types, so
                    // we only need to check the properties of the first type
                    if (type.flags & 1048576 /* Union */) {
                        break;
                    }
                }
                type.resolvedProperties = getNamedMembers(members);
            }
            return type.resolvedProperties;
        }
        function getPossiblePropertiesOfUnionType(type) {
            if (type.possiblePropertyCache) {
                return type.possiblePropertyCache.size ? ts.arrayFrom(type.possiblePropertyCache.values()) : ts.emptyArray;
            }
            type.possiblePropertyCache = ts.createSymbolTable();
            for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                var t = _a[_i];
                for (var _b = 0, _c = getPropertiesOfType(t); _b < _c.length; _b++) {
                    var p = _c[_b];
                    if (!type.possiblePropertyCache.has(p.escapedName)) {
                        var prop = getUnionOrIntersectionProperty(type, p.escapedName);
                        if (prop) {
                            type.possiblePropertyCache.set(p.escapedName, prop);
                        }
                    }
                }
            }
            // We can't simply use the normal property cache here, since that will contain cached apparent type members :(
            return type.possiblePropertyCache.size ? ts.arrayFrom(type.possiblePropertyCache.values()) : ts.emptyArray;
        }
        function getPropertiesOfType(type) {
            type = getApparentType(type);
            return type.flags & 3145728 /* UnionOrIntersection */ ?
                getPropertiesOfUnionOrIntersectionType(type) :
                getPropertiesOfObjectType(type);
        }
        function isTypeInvalidDueToUnionDiscriminant(contextualType, obj) {
            var list = obj.properties;
            return list.some(function (property) {
                var nameType = property.name && getLiteralTypeFromPropertyName(property.name);
                var name = nameType && isTypeUsableAsPropertyName(nameType) ? getPropertyNameFromType(nameType) : undefined;
                var expected = name === undefined ? undefined : getTypeOfPropertyOfType(contextualType, name);
                return !!expected && isLiteralType(expected) && !isTypeAssignableTo(getTypeOfNode(property), expected);
            });
        }
        function getAllPossiblePropertiesOfTypes(types) {
            var unionType = getUnionType(types);
            if (!(unionType.flags & 1048576 /* Union */)) {
                return getAugmentedPropertiesOfType(unionType);
            }
            var props = ts.createSymbolTable();
            for (var _i = 0, types_3 = types; _i < types_3.length; _i++) {
                var memberType = types_3[_i];
                for (var _a = 0, _b = getAugmentedPropertiesOfType(memberType); _a < _b.length; _a++) {
                    var escapedName = _b[_a].escapedName;
                    if (!props.has(escapedName)) {
                        var prop = createUnionOrIntersectionProperty(unionType, escapedName);
                        // May be undefined if the property is private
                        if (prop)
                            props.set(escapedName, prop);
                    }
                }
            }
            return ts.arrayFrom(props.values());
        }
        function getConstraintOfType(type) {
            return type.flags & 262144 /* TypeParameter */ ? getConstraintOfTypeParameter(type) :
                type.flags & 8388608 /* IndexedAccess */ ? getConstraintOfIndexedAccess(type) :
                    type.flags & 16777216 /* Conditional */ ? getConstraintOfConditionalType(type) :
                        getBaseConstraintOfType(type);
        }
        function getConstraintOfTypeParameter(typeParameter) {
            return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined;
        }
        function getConstraintOfIndexedAccess(type) {
            return hasNonCircularBaseConstraint(type) ? getConstraintFromIndexedAccess(type) : undefined;
        }
        function getSimplifiedTypeOrConstraint(type) {
            var simplified = getSimplifiedType(type, /*writing*/ false);
            return simplified !== type ? simplified : getConstraintOfType(type);
        }
        function getConstraintFromIndexedAccess(type) {
            var indexConstraint = getSimplifiedTypeOrConstraint(type.indexType);
            if (indexConstraint && indexConstraint !== type.indexType) {
                var indexedAccess = getIndexedAccessTypeOrUndefined(type.objectType, indexConstraint);
                if (indexedAccess) {
                    return indexedAccess;
                }
            }
            var objectConstraint = getSimplifiedTypeOrConstraint(type.objectType);
            if (objectConstraint && objectConstraint !== type.objectType) {
                return getIndexedAccessTypeOrUndefined(objectConstraint, type.indexType);
            }
            return undefined;
        }
        function getDefaultConstraintOfConditionalType(type) {
            if (!type.resolvedDefaultConstraint) {
                // An `any` branch of a conditional type would normally be viral - specifically, without special handling here,
                // a conditional type with a single branch of type `any` would be assignable to anything, since it's constraint would simplify to
                // just `any`. This result is _usually_ unwanted - so instead here we elide an `any` branch from the constraint type,
                // in effect treating `any` like `never` rather than `unknown` in this location.
                var trueConstraint = getInferredTrueTypeFromConditionalType(type);
                var falseConstraint = getFalseTypeFromConditionalType(type);
                type.resolvedDefaultConstraint = isTypeAny(trueConstraint) ? falseConstraint : isTypeAny(falseConstraint) ? trueConstraint : getUnionType([trueConstraint, falseConstraint]);
            }
            return type.resolvedDefaultConstraint;
        }
        function getConstraintOfDistributiveConditionalType(type) {
            // Check if we have a conditional type of the form 'T extends U ? X : Y', where T is a constrained
            // type parameter. If so, create an instantiation of the conditional type where T is replaced
            // with its constraint. We do this because if the constraint is a union type it will be distributed
            // over the conditional type and possibly reduced. For example, 'T extends undefined ? never : T'
            // removes 'undefined' from T.
            // We skip returning a distributive constraint for a restrictive instantiation of a conditional type
            // as the constraint for all type params (check type included) have been replace with `unknown`, which
            // is going to produce even more false positive/negative results than the distribute constraint already does.
            // Please note: the distributive constraint is a kludge for emulating what a negated type could to do filter
            // a union - once negated types exist and are applied to the conditional false branch, this "constraint"
            // likely doesn't need to exist.
            if (type.root.isDistributive && type.restrictiveInstantiation !== type) {
                var simplified = getSimplifiedType(type.checkType, /*writing*/ false);
                var constraint = simplified === type.checkType ? getConstraintOfType(simplified) : simplified;
                if (constraint && constraint !== type.checkType) {
                    var mapper = makeUnaryTypeMapper(type.root.checkType, constraint);
                    var instantiated = getConditionalTypeInstantiation(type, combineTypeMappers(mapper, type.mapper));
                    if (!(instantiated.flags & 131072 /* Never */)) {
                        return instantiated;
                    }
                }
            }
            return undefined;
        }
        function getConstraintFromConditionalType(type) {
            return getConstraintOfDistributiveConditionalType(type) || getDefaultConstraintOfConditionalType(type);
        }
        function getConstraintOfConditionalType(type) {
            return hasNonCircularBaseConstraint(type) ? getConstraintFromConditionalType(type) : undefined;
        }
        function getUnionConstraintOfIntersection(type, targetIsUnion) {
            var constraints;
            var hasDisjointDomainType = false;
            for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                var t = _a[_i];
                if (t.flags & 63176704 /* Instantiable */) {
                    // We keep following constraints as long as we have an instantiable type that is known
                    // not to be circular or infinite (hence we stop on index access types).
                    var constraint = getConstraintOfType(t);
                    while (constraint && constraint.flags & (262144 /* TypeParameter */ | 4194304 /* Index */ | 16777216 /* Conditional */)) {
                        constraint = getConstraintOfType(constraint);
                    }
                    if (constraint) {
                        constraints = ts.append(constraints, constraint);
                    }
                }
                else if (t.flags & 67238908 /* DisjointDomains */) {
                    hasDisjointDomainType = true;
                }
            }
            // If the target is a union type or if we are intersecting with types belonging to one of the
            // disjoint domains, we may end up producing a constraint that hasn't been examined before.
            if (constraints && (targetIsUnion || hasDisjointDomainType)) {
                if (hasDisjointDomainType) {
                    // We add any types belong to one of the disjoint domains because they might cause the final
                    // intersection operation to reduce the union constraints.
                    for (var _b = 0, _c = type.types; _b < _c.length; _b++) {
                        var t = _c[_b];
                        if (t.flags & 67238908 /* DisjointDomains */) {
                            constraints = ts.append(constraints, t);
                        }
                    }
                }
                return getIntersectionType(constraints);
            }
            return undefined;
        }
        function getBaseConstraintOfType(type) {
            if (type.flags & (58982400 /* InstantiableNonPrimitive */ | 3145728 /* UnionOrIntersection */)) {
                var constraint = getResolvedBaseConstraint(type);
                return constraint !== noConstraintType && constraint !== circularConstraintType ? constraint : undefined;
            }
            return type.flags & 4194304 /* Index */ ? keyofConstraintType : undefined;
        }
        /**
         * This is similar to `getBaseConstraintOfType` except it returns the input type if there's no base constraint, instead of `undefined`
         * It also doesn't map indexes to `string`, as where this is used this would be unneeded (and likely undesirable)
         */
        function getBaseConstraintOrType(type) {
            return getBaseConstraintOfType(type) || type;
        }
        function hasNonCircularBaseConstraint(type) {
            return getResolvedBaseConstraint(type) !== circularConstraintType;
        }
        /**
         * Return the resolved base constraint of a type variable. The noConstraintType singleton is returned if the
         * type variable has no constraint, and the circularConstraintType singleton is returned if the constraint
         * circularly references the type variable.
         */
        function getResolvedBaseConstraint(type) {
            var nonTerminating = false;
            return type.resolvedBaseConstraint ||
                (type.resolvedBaseConstraint = getTypeWithThisArgument(getImmediateBaseConstraint(type), type));
            function getImmediateBaseConstraint(t) {
                if (!t.immediateBaseConstraint) {
                    if (!pushTypeResolution(t, 4 /* ImmediateBaseConstraint */)) {
                        return circularConstraintType;
                    }
                    if (constraintDepth >= 50) {
                        // We have reached 50 recursive invocations of getImmediateBaseConstraint and there is a
                        // very high likelihood we're dealing with an infinite generic type that perpetually generates
                        // new type identities as we descend into it. We stop the recursion here and mark this type
                        // and the outer types as having circular constraints.
                        error(currentNode, ts.Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
                        nonTerminating = true;
                        return t.immediateBaseConstraint = noConstraintType;
                    }
                    constraintDepth++;
                    var result = computeBaseConstraint(getSimplifiedType(t, /*writing*/ false));
                    constraintDepth--;
                    if (!popTypeResolution()) {
                        if (t.flags & 262144 /* TypeParameter */) {
                            var errorNode = getConstraintDeclaration(t);
                            if (errorNode) {
                                var diagnostic = error(errorNode, ts.Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(t));
                                if (currentNode && !ts.isNodeDescendantOf(errorNode, currentNode) && !ts.isNodeDescendantOf(currentNode, errorNode)) {
                                    ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(currentNode, ts.Diagnostics.Circularity_originates_in_type_at_this_location));
                                }
                            }
                        }
                        result = circularConstraintType;
                    }
                    if (nonTerminating) {
                        result = circularConstraintType;
                    }
                    t.immediateBaseConstraint = result || noConstraintType;
                }
                return t.immediateBaseConstraint;
            }
            function getBaseConstraint(t) {
                var c = getImmediateBaseConstraint(t);
                return c !== noConstraintType && c !== circularConstraintType ? c : undefined;
            }
            function computeBaseConstraint(t) {
                if (t.flags & 262144 /* TypeParameter */) {
                    var constraint = getConstraintFromTypeParameter(t);
                    return t.isThisType || !constraint ?
                        constraint :
                        getBaseConstraint(constraint);
                }
                if (t.flags & 3145728 /* UnionOrIntersection */) {
                    var types = t.types;
                    var baseTypes = [];
                    for (var _i = 0, types_4 = types; _i < types_4.length; _i++) {
                        var type_3 = types_4[_i];
                        var baseType = getBaseConstraint(type_3);
                        if (baseType) {
                            baseTypes.push(baseType);
                        }
                    }
                    return t.flags & 1048576 /* Union */ && baseTypes.length === types.length ? getUnionType(baseTypes) :
                        t.flags & 2097152 /* Intersection */ && baseTypes.length ? getIntersectionType(baseTypes) :
                            undefined;
                }
                if (t.flags & 4194304 /* Index */) {
                    return keyofConstraintType;
                }
                if (t.flags & 8388608 /* IndexedAccess */) {
                    var baseObjectType = getBaseConstraint(t.objectType);
                    var baseIndexType = getBaseConstraint(t.indexType);
                    var baseIndexedAccess = baseObjectType && baseIndexType && getIndexedAccessTypeOrUndefined(baseObjectType, baseIndexType);
                    return baseIndexedAccess && getBaseConstraint(baseIndexedAccess);
                }
                if (t.flags & 16777216 /* Conditional */) {
                    var constraint = getConstraintFromConditionalType(t);
                    constraintDepth++; // Penalize repeating conditional types (this captures the recursion within getConstraintFromConditionalType and carries it forward)
                    var result = constraint && getBaseConstraint(constraint);
                    constraintDepth--;
                    return result;
                }
                if (t.flags & 33554432 /* Substitution */) {
                    return getBaseConstraint(t.substitute);
                }
                return t;
            }
        }
        function getApparentTypeOfIntersectionType(type) {
            return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type, /*apparentType*/ true));
        }
        function getResolvedTypeParameterDefault(typeParameter) {
            if (!typeParameter.default) {
                if (typeParameter.target) {
                    var targetDefault = getResolvedTypeParameterDefault(typeParameter.target);
                    typeParameter.default = targetDefault ? instantiateType(targetDefault, typeParameter.mapper) : noConstraintType;
                }
                else {
                    // To block recursion, set the initial value to the resolvingDefaultType.
                    typeParameter.default = resolvingDefaultType;
                    var defaultDeclaration = typeParameter.symbol && ts.forEach(typeParameter.symbol.declarations, function (decl) { return ts.isTypeParameterDeclaration(decl) && decl.default; });
                    var defaultType = defaultDeclaration ? getTypeFromTypeNode(defaultDeclaration) : noConstraintType;
                    if (typeParameter.default === resolvingDefaultType) {
                        // If we have not been called recursively, set the correct default type.
                        typeParameter.default = defaultType;
                    }
                }
            }
            else if (typeParameter.default === resolvingDefaultType) {
                // If we are called recursively for this type parameter, mark the default as circular.
                typeParameter.default = circularConstraintType;
            }
            return typeParameter.default;
        }
        /**
         * Gets the default type for a type parameter.
         *
         * If the type parameter is the result of an instantiation, this gets the instantiated
         * default type of its target. If the type parameter has no default type or the default is
         * circular, `undefined` is returned.
         */
        function getDefaultFromTypeParameter(typeParameter) {
            var defaultType = getResolvedTypeParameterDefault(typeParameter);
            return defaultType !== noConstraintType && defaultType !== circularConstraintType ? defaultType : undefined;
        }
        function hasNonCircularTypeParameterDefault(typeParameter) {
            return getResolvedTypeParameterDefault(typeParameter) !== circularConstraintType;
        }
        /**
         * Indicates whether the declaration of a typeParameter has a default type.
         */
        function hasTypeParameterDefault(typeParameter) {
            return !!(typeParameter.symbol && ts.forEach(typeParameter.symbol.declarations, function (decl) { return ts.isTypeParameterDeclaration(decl) && decl.default; }));
        }
        function getApparentTypeOfMappedType(type) {
            return type.resolvedApparentType || (type.resolvedApparentType = getResolvedApparentTypeOfMappedType(type));
        }
        function getResolvedApparentTypeOfMappedType(type) {
            var typeVariable = getHomomorphicTypeVariable(type);
            if (typeVariable) {
                var constraint = getConstraintOfTypeParameter(typeVariable);
                if (constraint && (isArrayType(constraint) || isTupleType(constraint))) {
                    var mapper = makeUnaryTypeMapper(typeVariable, constraint);
                    return instantiateType(type, combineTypeMappers(mapper, type.mapper));
                }
            }
            return type;
        }
        /**
         * For a type parameter, return the base constraint of the type parameter. For the string, number,
         * boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
         * type itself. Note that the apparent type of a union type is the union type itself.
         */
        function getApparentType(type) {
            var t = type.flags & 63176704 /* Instantiable */ ? getBaseConstraintOfType(type) || unknownType : type;
            return ts.getObjectFlags(t) & 32 /* Mapped */ ? getApparentTypeOfMappedType(t) :
                t.flags & 2097152 /* Intersection */ ? getApparentTypeOfIntersectionType(t) :
                    t.flags & 132 /* StringLike */ ? globalStringType :
                        t.flags & 296 /* NumberLike */ ? globalNumberType :
                            t.flags & 2112 /* BigIntLike */ ? getGlobalBigIntType(/*reportErrors*/ languageVersion >= 8 /* ESNext */) :
                                t.flags & 528 /* BooleanLike */ ? globalBooleanType :
                                    t.flags & 12288 /* ESSymbolLike */ ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= 2 /* ES2015 */) :
                                        t.flags & 67108864 /* NonPrimitive */ ? emptyObjectType :
                                            t.flags & 4194304 /* Index */ ? keyofConstraintType :
                                                t.flags & 2 /* Unknown */ && !strictNullChecks ? emptyObjectType :
                                                    t;
        }
        function createUnionOrIntersectionProperty(containingType, name) {
            var propSet = ts.createMap();
            var indexTypes;
            var isUnion = containingType.flags & 1048576 /* Union */;
            var excludeModifiers = isUnion ? 24 /* NonPublicAccessibilityModifier */ : 0;
            // Flags we want to propagate to the result if they exist in all source symbols
            var optionalFlag = isUnion ? 0 /* None */ : 16777216 /* Optional */;
            var syntheticFlag = 4 /* SyntheticMethod */;
            var checkFlags = 0;
            for (var _i = 0, _a = containingType.types; _i < _a.length; _i++) {
                var current = _a[_i];
                var type = getApparentType(current);
                if (type !== errorType) {
                    var prop = getPropertyOfType(type, name);
                    var modifiers = prop ? ts.getDeclarationModifierFlagsFromSymbol(prop) : 0;
                    if (prop && !(modifiers & excludeModifiers)) {
                        if (isUnion) {
                            optionalFlag |= (prop.flags & 16777216 /* Optional */);
                        }
                        else {
                            optionalFlag &= prop.flags;
                        }
                        var id = "" + getSymbolId(prop);
                        if (!propSet.has(id)) {
                            propSet.set(id, prop);
                        }
                        checkFlags |= (isReadonlySymbol(prop) ? 8 /* Readonly */ : 0) |
                            (!(modifiers & 24 /* NonPublicAccessibilityModifier */) ? 256 /* ContainsPublic */ : 0) |
                            (modifiers & 16 /* Protected */ ? 512 /* ContainsProtected */ : 0) |
                            (modifiers & 8 /* Private */ ? 1024 /* ContainsPrivate */ : 0) |
                            (modifiers & 32 /* Static */ ? 2048 /* ContainsStatic */ : 0);
                        if (!isPrototypeProperty(prop)) {
                            syntheticFlag = 2 /* SyntheticProperty */;
                        }
                    }
                    else if (isUnion) {
                        var indexInfo = !isLateBoundName(name) && (isNumericLiteralName(name) && getIndexInfoOfType(type, 1 /* Number */) || getIndexInfoOfType(type, 0 /* String */));
                        if (indexInfo) {
                            checkFlags |= indexInfo.isReadonly ? 8 /* Readonly */ : 0;
                            checkFlags |= 32 /* WritePartial */;
                            indexTypes = ts.append(indexTypes, isTupleType(type) ? getRestTypeOfTupleType(type) || undefinedType : indexInfo.type);
                        }
                        else {
                            checkFlags |= 16 /* ReadPartial */;
                        }
                    }
                }
            }
            if (!propSet.size) {
                return undefined;
            }
            var props = ts.arrayFrom(propSet.values());
            if (props.length === 1 && !(checkFlags & 16 /* ReadPartial */) && !indexTypes) {
                return props[0];
            }
            var declarations;
            var firstType;
            var nameType;
            var propTypes = [];
            var firstValueDeclaration;
            var hasNonUniformValueDeclaration = false;
            for (var _b = 0, props_1 = props; _b < props_1.length; _b++) {
                var prop = props_1[_b];
                if (!firstValueDeclaration) {
                    firstValueDeclaration = prop.valueDeclaration;
                }
                else if (prop.valueDeclaration !== firstValueDeclaration) {
                    hasNonUniformValueDeclaration = true;
                }
                declarations = ts.addRange(declarations, prop.declarations);
                var type = getTypeOfSymbol(prop);
                if (!firstType) {
                    firstType = type;
                    nameType = prop.nameType;
                }
                else if (type !== firstType) {
                    checkFlags |= 64 /* HasNonUniformType */;
                }
                if (isLiteralType(type)) {
                    checkFlags |= 128 /* HasLiteralType */;
                }
                propTypes.push(type);
            }
            ts.addRange(propTypes, indexTypes);
            var result = createSymbol(4 /* Property */ | optionalFlag, name, syntheticFlag | checkFlags);
            result.containingType = containingType;
            if (!hasNonUniformValueDeclaration && firstValueDeclaration) {
                result.valueDeclaration = firstValueDeclaration;
                // Inherit information about parent type.
                if (firstValueDeclaration.symbol.parent) {
                    result.parent = firstValueDeclaration.symbol.parent;
                }
            }
            result.declarations = declarations;
            result.nameType = nameType;
            if (propTypes.length > 2) {
                // When `propTypes` has the potential to explode in size when normalized, defer normalization until absolutely needed
                result.checkFlags |= 65536 /* DeferredType */;
                result.deferralParent = containingType;
                result.deferralConstituents = propTypes;
            }
            else {
                result.type = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes);
            }
            return result;
        }
        // Return the symbol for a given property in a union or intersection type, or undefined if the property
        // does not exist in any constituent type. Note that the returned property may only be present in some
        // constituents, in which case the isPartial flag is set when the containing type is union type. We need
        // these partial properties when identifying discriminant properties, but otherwise they are filtered out
        // and do not appear to be present in the union type.
        function getUnionOrIntersectionProperty(type, name) {
            var properties = type.propertyCache || (type.propertyCache = ts.createSymbolTable());
            var property = properties.get(name);
            if (!property) {
                property = createUnionOrIntersectionProperty(type, name);
                if (property) {
                    properties.set(name, property);
                }
            }
            return property;
        }
        function getPropertyOfUnionOrIntersectionType(type, name) {
            var property = getUnionOrIntersectionProperty(type, name);
            // We need to filter out partial properties in union types
            return property && !(ts.getCheckFlags(property) & 16 /* ReadPartial */) ? property : undefined;
        }
        /**
         * Return the symbol for the property with the given name in the given type. Creates synthetic union properties when
         * necessary, maps primitive types and type parameters are to their apparent types, and augments with properties from
         * Object and Function as appropriate.
         *
         * @param type a type to look up property from
         * @param name a name of property to look up in a given type
         */
        function getPropertyOfType(type, name) {
            type = getApparentType(type);
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                var symbol = resolved.members.get(name);
                if (symbol && symbolIsValue(symbol)) {
                    return symbol;
                }
                var functionType = resolved === anyFunctionType ? globalFunctionType :
                    resolved.callSignatures.length ? globalCallableFunctionType :
                        resolved.constructSignatures.length ? globalNewableFunctionType :
                            undefined;
                if (functionType) {
                    var symbol_1 = getPropertyOfObjectType(functionType, name);
                    if (symbol_1) {
                        return symbol_1;
                    }
                }
                return getPropertyOfObjectType(globalObjectType, name);
            }
            if (type.flags & 3145728 /* UnionOrIntersection */) {
                return getPropertyOfUnionOrIntersectionType(type, name);
            }
            return undefined;
        }
        function getSignaturesOfStructuredType(type, kind) {
            if (type.flags & 3670016 /* StructuredType */) {
                var resolved = resolveStructuredTypeMembers(type);
                return kind === 0 /* Call */ ? resolved.callSignatures : resolved.constructSignatures;
            }
            return ts.emptyArray;
        }
        /**
         * Return the signatures of the given kind in the given type. Creates synthetic union signatures when necessary and
         * maps primitive types and type parameters are to their apparent types.
         */
        function getSignaturesOfType(type, kind) {
            return getSignaturesOfStructuredType(getApparentType(type), kind);
        }
        function getIndexInfoOfStructuredType(type, kind) {
            if (type.flags & 3670016 /* StructuredType */) {
                var resolved = resolveStructuredTypeMembers(type);
                return kind === 0 /* String */ ? resolved.stringIndexInfo : resolved.numberIndexInfo;
            }
        }
        function getIndexTypeOfStructuredType(type, kind) {
            var info = getIndexInfoOfStructuredType(type, kind);
            return info && info.type;
        }
        // Return the indexing info of the given kind in the given type. Creates synthetic union index types when necessary and
        // maps primitive types and type parameters are to their apparent types.
        function getIndexInfoOfType(type, kind) {
            return getIndexInfoOfStructuredType(getApparentType(type), kind);
        }
        // Return the index type of the given kind in the given type. Creates synthetic union index types when necessary and
        // maps primitive types and type parameters are to their apparent types.
        function getIndexTypeOfType(type, kind) {
            return getIndexTypeOfStructuredType(getApparentType(type), kind);
        }
        function getImplicitIndexTypeOfType(type, kind) {
            if (isObjectTypeWithInferableIndex(type)) {
                var propTypes = [];
                for (var _i = 0, _a = getPropertiesOfType(type); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (kind === 0 /* String */ || isNumericLiteralName(prop.escapedName)) {
                        propTypes.push(getTypeOfSymbol(prop));
                    }
                }
                if (propTypes.length) {
                    return getUnionType(propTypes, 2 /* Subtype */);
                }
            }
            return undefined;
        }
        // Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual
        // type checking functions).
        function getTypeParametersFromDeclaration(declaration) {
            var result;
            for (var _i = 0, _a = ts.getEffectiveTypeParameterDeclarations(declaration); _i < _a.length; _i++) {
                var node = _a[_i];
                result = ts.appendIfUnique(result, getDeclaredTypeOfTypeParameter(node.symbol));
            }
            return result;
        }
        function symbolsToArray(symbols) {
            var result = [];
            symbols.forEach(function (symbol, id) {
                if (!isReservedMemberName(id)) {
                    result.push(symbol);
                }
            });
            return result;
        }
        function isJSDocOptionalParameter(node) {
            return ts.isInJSFile(node) && (
            // node.type should only be a JSDocOptionalType when node is a parameter of a JSDocFunctionType
            node.type && node.type.kind === 294 /* JSDocOptionalType */
                || ts.getJSDocParameterTags(node).some(function (_a) {
                    var isBracketed = _a.isBracketed, typeExpression = _a.typeExpression;
                    return isBracketed || !!typeExpression && typeExpression.type.kind === 294 /* JSDocOptionalType */;
                }));
        }
        function tryFindAmbientModule(moduleName, withAugmentations) {
            if (ts.isExternalModuleNameRelative(moduleName)) {
                return undefined;
            }
            var symbol = getSymbol(globals, '"' + moduleName + '"', 512 /* ValueModule */);
            // merged symbol is module declaration symbol combined with all augmentations
            return symbol && withAugmentations ? getMergedSymbol(symbol) : symbol;
        }
        function isOptionalParameter(node) {
            if (ts.hasQuestionToken(node) || isOptionalJSDocParameterTag(node) || isJSDocOptionalParameter(node)) {
                return true;
            }
            if (node.initializer) {
                var signature = getSignatureFromDeclaration(node.parent);
                var parameterIndex = node.parent.parameters.indexOf(node);
                ts.Debug.assert(parameterIndex >= 0);
                return parameterIndex >= getMinArgumentCount(signature);
            }
            var iife = ts.getImmediatelyInvokedFunctionExpression(node.parent);
            if (iife) {
                return !node.type &&
                    !node.dotDotDotToken &&
                    node.parent.parameters.indexOf(node) >= iife.arguments.length;
            }
            return false;
        }
        function isOptionalJSDocParameterTag(node) {
            if (!ts.isJSDocParameterTag(node)) {
                return false;
            }
            var isBracketed = node.isBracketed, typeExpression = node.typeExpression;
            return isBracketed || !!typeExpression && typeExpression.type.kind === 294 /* JSDocOptionalType */;
        }
        function createIdentifierTypePredicate(parameterName, parameterIndex, type) {
            return { kind: 1 /* Identifier */, parameterName: parameterName, parameterIndex: parameterIndex, type: type };
        }
        function createThisTypePredicate(type) {
            return { kind: 0 /* This */, type: type };
        }
        /**
         * Gets the minimum number of type arguments needed to satisfy all non-optional type
         * parameters.
         */
        function getMinTypeArgumentCount(typeParameters) {
            var minTypeArgumentCount = 0;
            if (typeParameters) {
                for (var i = 0; i < typeParameters.length; i++) {
                    if (!hasTypeParameterDefault(typeParameters[i])) {
                        minTypeArgumentCount = i + 1;
                    }
                }
            }
            return minTypeArgumentCount;
        }
        function fillMissingTypeArguments(typeArguments, typeParameters, minTypeArgumentCount, isJavaScriptImplicitAny) {
            var numTypeParameters = ts.length(typeParameters);
            if (!numTypeParameters) {
                return [];
            }
            var numTypeArguments = ts.length(typeArguments);
            if (isJavaScriptImplicitAny || (numTypeArguments >= minTypeArgumentCount && numTypeArguments <= numTypeParameters)) {
                var result = typeArguments ? typeArguments.slice() : [];
                // Map invalid forward references in default types to the error type
                for (var i = numTypeArguments; i < numTypeParameters; i++) {
                    result[i] = errorType;
                }
                var baseDefaultType = getDefaultTypeArgumentType(isJavaScriptImplicitAny);
                for (var i = numTypeArguments; i < numTypeParameters; i++) {
                    var defaultType = getDefaultFromTypeParameter(typeParameters[i]);
                    if (isJavaScriptImplicitAny && defaultType && (isTypeIdenticalTo(defaultType, unknownType) || isTypeIdenticalTo(defaultType, emptyObjectType))) {
                        defaultType = anyType;
                    }
                    result[i] = defaultType ? instantiateType(defaultType, createTypeMapper(typeParameters, result)) : baseDefaultType;
                }
                result.length = typeParameters.length;
                return result;
            }
            return typeArguments && typeArguments.slice();
        }
        function getSignatureFromDeclaration(declaration) {
            var links = getNodeLinks(declaration);
            if (!links.resolvedSignature) {
                var parameters = [];
                var hasLiteralTypes = false;
                var minArgumentCount = 0;
                var thisParameter = void 0;
                var hasThisParameter = false;
                var iife = ts.getImmediatelyInvokedFunctionExpression(declaration);
                var isJSConstructSignature = ts.isJSDocConstructSignature(declaration);
                var isUntypedSignatureInJSFile = !iife &&
                    ts.isInJSFile(declaration) &&
                    ts.isValueSignatureDeclaration(declaration) &&
                    !ts.hasJSDocParameterTags(declaration) &&
                    !ts.getJSDocType(declaration);
                // If this is a JSDoc construct signature, then skip the first parameter in the
                // parameter list.  The first parameter represents the return type of the construct
                // signature.
                for (var i = isJSConstructSignature ? 1 : 0; i < declaration.parameters.length; i++) {
                    var param = declaration.parameters[i];
                    var paramSymbol = param.symbol;
                    var type = ts.isJSDocParameterTag(param) ? (param.typeExpression && param.typeExpression.type) : param.type;
                    // Include parameter symbol instead of property symbol in the signature
                    if (paramSymbol && !!(paramSymbol.flags & 4 /* Property */) && !ts.isBindingPattern(param.name)) {
                        var resolvedSymbol = resolveName(param, paramSymbol.escapedName, 67220415 /* Value */, undefined, undefined, /*isUse*/ false);
                        paramSymbol = resolvedSymbol;
                    }
                    if (i === 0 && paramSymbol.escapedName === "this" /* This */) {
                        hasThisParameter = true;
                        thisParameter = param.symbol;
                    }
                    else {
                        parameters.push(paramSymbol);
                    }
                    if (type && type.kind === 183 /* LiteralType */) {
                        hasLiteralTypes = true;
                    }
                    // Record a new minimum argument count if this is not an optional parameter
                    var isOptionalParameter_1 = isOptionalJSDocParameterTag(param) ||
                        param.initializer || param.questionToken || param.dotDotDotToken ||
                        iife && parameters.length > iife.arguments.length && !type ||
                        isUntypedSignatureInJSFile ||
                        isJSDocOptionalParameter(param);
                    if (!isOptionalParameter_1) {
                        minArgumentCount = parameters.length;
                    }
                }
                // If only one accessor includes a this-type annotation, the other behaves as if it had the same type annotation
                if ((declaration.kind === 159 /* GetAccessor */ || declaration.kind === 160 /* SetAccessor */) &&
                    !hasNonBindableDynamicName(declaration) &&
                    (!hasThisParameter || !thisParameter)) {
                    var otherKind = declaration.kind === 159 /* GetAccessor */ ? 160 /* SetAccessor */ : 159 /* GetAccessor */;
                    var other = ts.getDeclarationOfKind(getSymbolOfNode(declaration), otherKind);
                    if (other) {
                        thisParameter = getAnnotatedAccessorThisParameter(other);
                    }
                }
                var classType = declaration.kind === 158 /* Constructor */ ?
                    getDeclaredTypeOfClassOrInterface(getMergedSymbol(declaration.parent.symbol))
                    : undefined;
                var typeParameters = classType ? classType.localTypeParameters : getTypeParametersFromDeclaration(declaration);
                var hasRestLikeParameter = ts.hasRestParameter(declaration) || ts.isInJSFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters);
                links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, 
                /*resolvedReturnType*/ undefined, /*resolvedTypePredicate*/ undefined, minArgumentCount, hasRestLikeParameter, hasLiteralTypes);
            }
            return links.resolvedSignature;
        }
        /**
         * A JS function gets a synthetic rest parameter if it references `arguments` AND:
         * 1. It has no parameters but at least one `@param` with a type that starts with `...`
         * OR
         * 2. It has at least one parameter, and the last parameter has a matching `@param` with a type that starts with `...`
         */
        function maybeAddJsSyntheticRestParameter(declaration, parameters) {
            if (ts.isJSDocSignature(declaration) || !containsArgumentsReference(declaration)) {
                return false;
            }
            var lastParam = ts.lastOrUndefined(declaration.parameters);
            var lastParamTags = lastParam ? ts.getJSDocParameterTags(lastParam) : ts.getJSDocTags(declaration).filter(ts.isJSDocParameterTag);
            var lastParamVariadicType = ts.firstDefined(lastParamTags, function (p) {
                return p.typeExpression && ts.isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined;
            });
            var syntheticArgsSymbol = createSymbol(3 /* Variable */, "args", 32768 /* RestParameter */);
            syntheticArgsSymbol.type = lastParamVariadicType ? createArrayType(getTypeFromTypeNode(lastParamVariadicType.type)) : anyArrayType;
            if (lastParamVariadicType) {
                // Replace the last parameter with a rest parameter.
                parameters.pop();
            }
            parameters.push(syntheticArgsSymbol);
            return true;
        }
        function getSignatureOfTypeTag(node) {
            var typeTag = ts.isInJSFile(node) ? ts.getJSDocTypeTag(node) : undefined;
            var signature = typeTag && typeTag.typeExpression && getSingleCallSignature(getTypeFromTypeNode(typeTag.typeExpression));
            return signature && getErasedSignature(signature);
        }
        function getReturnTypeOfTypeTag(node) {
            var signature = getSignatureOfTypeTag(node);
            return signature && getReturnTypeOfSignature(signature);
        }
        function containsArgumentsReference(declaration) {
            var links = getNodeLinks(declaration);
            if (links.containsArgumentsReference === undefined) {
                if (links.flags & 8192 /* CaptureArguments */) {
                    links.containsArgumentsReference = true;
                }
                else {
                    links.containsArgumentsReference = traverse(declaration.body);
                }
            }
            return links.containsArgumentsReference;
            function traverse(node) {
                if (!node)
                    return false;
                switch (node.kind) {
                    case 73 /* Identifier */:
                        return node.escapedText === "arguments" && ts.isExpressionNode(node);
                    case 155 /* PropertyDeclaration */:
                    case 157 /* MethodDeclaration */:
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                        return node.name.kind === 150 /* ComputedPropertyName */
                            && traverse(node.name);
                    default:
                        return !ts.nodeStartsNewLexicalEnvironment(node) && !ts.isPartOfTypeNode(node) && !!ts.forEachChild(node, traverse);
                }
            }
        }
        function getSignaturesOfSymbol(symbol) {
            if (!symbol)
                return ts.emptyArray;
            var result = [];
            for (var i = 0; i < symbol.declarations.length; i++) {
                var decl = symbol.declarations[i];
                if (!ts.isFunctionLike(decl))
                    continue;
                // Don't include signature if node is the implementation of an overloaded function. A node is considered
                // an implementation node if it has a body and the previous node is of the same kind and immediately
                // precedes the implementation node (i.e. has the same parent and ends where the implementation starts).
                if (i > 0 && decl.body) {
                    var previous = symbol.declarations[i - 1];
                    if (decl.parent === previous.parent && decl.kind === previous.kind && decl.pos === previous.end) {
                        continue;
                    }
                }
                result.push(getSignatureFromDeclaration(decl));
            }
            return result;
        }
        function resolveExternalModuleTypeByLiteral(name) {
            var moduleSym = resolveExternalModuleName(name, name);
            if (moduleSym) {
                var resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym);
                if (resolvedModuleSymbol) {
                    return getTypeOfSymbol(resolvedModuleSymbol);
                }
            }
            return anyType;
        }
        function getThisTypeOfSignature(signature) {
            if (signature.thisParameter) {
                return getTypeOfSymbol(signature.thisParameter);
            }
        }
        function signatureHasTypePredicate(signature) {
            return getTypePredicateOfSignature(signature) !== undefined;
        }
        function getTypePredicateOfSignature(signature) {
            if (!signature.resolvedTypePredicate) {
                if (signature.target) {
                    var targetTypePredicate = getTypePredicateOfSignature(signature.target);
                    signature.resolvedTypePredicate = targetTypePredicate ? instantiateTypePredicate(targetTypePredicate, signature.mapper) : noTypePredicate;
                }
                else if (signature.unionSignatures) {
                    signature.resolvedTypePredicate = getUnionTypePredicate(signature.unionSignatures) || noTypePredicate;
                }
                else {
                    var type = signature.declaration && ts.getEffectiveReturnTypeNode(signature.declaration);
                    var jsdocPredicate = void 0;
                    if (!type && ts.isInJSFile(signature.declaration)) {
                        var jsdocSignature = getSignatureOfTypeTag(signature.declaration);
                        if (jsdocSignature && signature !== jsdocSignature) {
                            jsdocPredicate = getTypePredicateOfSignature(jsdocSignature);
                        }
                    }
                    signature.resolvedTypePredicate = type && ts.isTypePredicateNode(type) ?
                        createTypePredicateFromTypePredicateNode(type, signature) :
                        jsdocPredicate || noTypePredicate;
                }
                ts.Debug.assert(!!signature.resolvedTypePredicate);
            }
            return signature.resolvedTypePredicate === noTypePredicate ? undefined : signature.resolvedTypePredicate;
        }
        function createTypePredicateFromTypePredicateNode(node, signature) {
            var parameterName = node.parameterName;
            var type = getTypeFromTypeNode(node.type);
            if (parameterName.kind === 73 /* Identifier */) {
                return createIdentifierTypePredicate(parameterName.escapedText, ts.findIndex(signature.parameters, function (p) { return p.escapedName === parameterName.escapedText; }), type);
            }
            else {
                return createThisTypePredicate(type);
            }
        }
        function getReturnTypeOfSignature(signature) {
            if (!signature.resolvedReturnType) {
                if (!pushTypeResolution(signature, 3 /* ResolvedReturnType */)) {
                    return errorType;
                }
                var type = signature.target ? instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper) :
                    signature.unionSignatures ? getUnionType(ts.map(signature.unionSignatures, getReturnTypeOfSignature), 2 /* Subtype */) :
                        getReturnTypeFromAnnotation(signature.declaration) ||
                            isJSConstructor(signature.declaration) && getJSClassType(getSymbolOfNode(signature.declaration)) ||
                            (ts.nodeIsMissing(signature.declaration.body) ? anyType : getReturnTypeFromBody(signature.declaration));
                if (!popTypeResolution()) {
                    if (signature.declaration) {
                        var typeNode = ts.getEffectiveReturnTypeNode(signature.declaration);
                        if (typeNode) {
                            error(typeNode, ts.Diagnostics.Return_type_annotation_circularly_references_itself);
                        }
                        else if (noImplicitAny) {
                            var declaration = signature.declaration;
                            var name = ts.getNameOfDeclaration(declaration);
                            if (name) {
                                error(name, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, ts.declarationNameToString(name));
                            }
                            else {
                                error(declaration, ts.Diagnostics.Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions);
                            }
                        }
                    }
                    type = anyType;
                }
                signature.resolvedReturnType = type;
            }
            return signature.resolvedReturnType;
        }
        function getReturnTypeFromAnnotation(declaration) {
            if (declaration.kind === 158 /* Constructor */) {
                return getDeclaredTypeOfClassOrInterface(getMergedSymbol(declaration.parent.symbol));
            }
            if (ts.isJSDocConstructSignature(declaration)) {
                return getTypeFromTypeNode(declaration.parameters[0].type); // TODO: GH#18217
            }
            var typeNode = ts.getEffectiveReturnTypeNode(declaration);
            if (typeNode) {
                return getTypeFromTypeNode(typeNode);
            }
            if (declaration.kind === 159 /* GetAccessor */ && !hasNonBindableDynamicName(declaration)) {
                var jsDocType = ts.isInJSFile(declaration) && getTypeForDeclarationFromJSDocComment(declaration);
                if (jsDocType) {
                    return jsDocType;
                }
                var setter = ts.getDeclarationOfKind(getSymbolOfNode(declaration), 160 /* SetAccessor */);
                var setterType = getAnnotatedAccessorType(setter);
                if (setterType) {
                    return setterType;
                }
            }
            return getReturnTypeOfTypeTag(declaration);
        }
        function isResolvingReturnTypeOfSignature(signature) {
            return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3 /* ResolvedReturnType */) >= 0;
        }
        function getRestTypeOfSignature(signature) {
            return tryGetRestTypeOfSignature(signature) || anyType;
        }
        function tryGetRestTypeOfSignature(signature) {
            if (signature.hasRestParameter) {
                var sigRestType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
                var restType = isTupleType(sigRestType) ? getRestTypeOfTupleType(sigRestType) : sigRestType;
                return restType && getIndexTypeOfType(restType, 1 /* Number */);
            }
            return undefined;
        }
        function getSignatureInstantiation(signature, typeArguments, isJavascript, inferredTypeParameters) {
            var instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript));
            if (inferredTypeParameters) {
                var returnSignature = getSingleCallOrConstructSignature(getReturnTypeOfSignature(instantiatedSignature));
                if (returnSignature) {
                    var newReturnSignature = cloneSignature(returnSignature);
                    newReturnSignature.typeParameters = inferredTypeParameters;
                    var newInstantiatedSignature = cloneSignature(instantiatedSignature);
                    newInstantiatedSignature.resolvedReturnType = getOrCreateTypeFromSignature(newReturnSignature);
                    return newInstantiatedSignature;
                }
            }
            return instantiatedSignature;
        }
        function getSignatureInstantiationWithoutFillingInTypeArguments(signature, typeArguments) {
            var instantiations = signature.instantiations || (signature.instantiations = ts.createMap());
            var id = getTypeListId(typeArguments);
            var instantiation = instantiations.get(id);
            if (!instantiation) {
                instantiations.set(id, instantiation = createSignatureInstantiation(signature, typeArguments));
            }
            return instantiation;
        }
        function createSignatureInstantiation(signature, typeArguments) {
            return instantiateSignature(signature, createSignatureTypeMapper(signature, typeArguments), /*eraseTypeParameters*/ true);
        }
        function createSignatureTypeMapper(signature, typeArguments) {
            return createTypeMapper(signature.typeParameters, typeArguments);
        }
        function getErasedSignature(signature) {
            return signature.typeParameters ?
                signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) :
                signature;
        }
        function createErasedSignature(signature) {
            // Create an instantiation of the signature where all type arguments are the any type.
            return instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true);
        }
        function getCanonicalSignature(signature) {
            return signature.typeParameters ?
                signature.canonicalSignatureCache || (signature.canonicalSignatureCache = createCanonicalSignature(signature)) :
                signature;
        }
        function createCanonicalSignature(signature) {
            // Create an instantiation of the signature where each unconstrained type parameter is replaced with
            // its original. When a generic class or interface is instantiated, each generic method in the class or
            // interface is instantiated with a fresh set of cloned type parameters (which we need to handle scenarios
            // where different generations of the same type parameter are in scope). This leads to a lot of new type
            // identities, and potentially a lot of work comparing those identities, so here we create an instantiation
            // that uses the original type identities for all unconstrained type parameters.
            return getSignatureInstantiation(signature, ts.map(signature.typeParameters, function (tp) { return tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp; }), ts.isInJSFile(signature.declaration));
        }
        function getBaseSignature(signature) {
            var typeParameters = signature.typeParameters;
            if (typeParameters) {
                var typeEraser_1 = createTypeEraser(typeParameters);
                var baseConstraints = ts.map(typeParameters, function (tp) { return instantiateType(getBaseConstraintOfType(tp), typeEraser_1) || unknownType; });
                return instantiateSignature(signature, createTypeMapper(typeParameters, baseConstraints), /*eraseTypeParameters*/ true);
            }
            return signature;
        }
        function getOrCreateTypeFromSignature(signature) {
            // There are two ways to declare a construct signature, one is by declaring a class constructor
            // using the constructor keyword, and the other is declaring a bare construct signature in an
            // object type literal or interface (using the new keyword). Each way of declaring a constructor
            // will result in a different declaration kind.
            if (!signature.isolatedSignatureType) {
                var kind = signature.declaration ? signature.declaration.kind : 0 /* Unknown */;
                var isConstructor = kind === 158 /* Constructor */ || kind === 162 /* ConstructSignature */ || kind === 167 /* ConstructorType */;
                var type = createObjectType(16 /* Anonymous */);
                type.members = emptySymbols;
                type.properties = ts.emptyArray;
                type.callSignatures = !isConstructor ? [signature] : ts.emptyArray;
                type.constructSignatures = isConstructor ? [signature] : ts.emptyArray;
                signature.isolatedSignatureType = type;
            }
            return signature.isolatedSignatureType;
        }
        function getIndexSymbol(symbol) {
            return symbol.members.get("__index" /* Index */);
        }
        function getIndexDeclarationOfSymbol(symbol, kind) {
            var syntaxKind = kind === 1 /* Number */ ? 136 /* NumberKeyword */ : 139 /* StringKeyword */;
            var indexSymbol = getIndexSymbol(symbol);
            if (indexSymbol) {
                for (var _i = 0, _a = indexSymbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var node = ts.cast(decl, ts.isIndexSignatureDeclaration);
                    if (node.parameters.length === 1) {
                        var parameter = node.parameters[0];
                        if (parameter.type && parameter.type.kind === syntaxKind) {
                            return node;
                        }
                    }
                }
            }
            return undefined;
        }
        function createIndexInfo(type, isReadonly, declaration) {
            return { type: type, isReadonly: isReadonly, declaration: declaration };
        }
        function getIndexInfoOfSymbol(symbol, kind) {
            var declaration = getIndexDeclarationOfSymbol(symbol, kind);
            if (declaration) {
                return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, ts.hasModifier(declaration, 64 /* Readonly */), declaration);
            }
            return undefined;
        }
        function getConstraintDeclaration(type) {
            var decl = type.symbol && ts.getDeclarationOfKind(type.symbol, 151 /* TypeParameter */);
            return decl && ts.getEffectiveConstraintOfTypeParameter(decl);
        }
        function getInferredTypeParameterConstraint(typeParameter) {
            var inferences;
            if (typeParameter.symbol) {
                for (var _i = 0, _a = typeParameter.symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    if (declaration.parent.kind === 177 /* InferType */) {
                        // When an 'infer T' declaration is immediately contained in a type reference node
                        // (such as 'Foo<infer T>'), T's constraint is inferred from the constraint of the
                        // corresponding type parameter in 'Foo'. When multiple 'infer T' declarations are
                        // present, we form an intersection of the inferred constraint types.
                        var grandParent = declaration.parent.parent;
                        if (grandParent.kind === 165 /* TypeReference */) {
                            var typeReference = grandParent;
                            var typeParameters = getTypeParametersForTypeReference(typeReference);
                            if (typeParameters) {
                                var index = typeReference.typeArguments.indexOf(declaration.parent);
                                if (index < typeParameters.length) {
                                    var declaredConstraint = getConstraintOfTypeParameter(typeParameters[index]);
                                    if (declaredConstraint) {
                                        // Type parameter constraints can reference other type parameters so
                                        // constraints need to be instantiated. If instantiation produces the
                                        // type parameter itself, we discard that inference. For example, in
                                        //   type Foo<T extends string, U extends T> = [T, U];
                                        //   type Bar<T> = T extends Foo<infer X, infer X> ? Foo<X, X> : T;
                                        // the instantiated constraint for U is X, so we discard that inference.
                                        var mapper = createTypeMapper(typeParameters, getEffectiveTypeArguments(typeReference, typeParameters));
                                        var constraint = instantiateType(declaredConstraint, mapper);
                                        if (constraint !== typeParameter) {
                                            inferences = ts.append(inferences, constraint);
                                        }
                                    }
                                }
                            }
                        }
                        // When an 'infer T' declaration is immediately contained in a rest parameter
                        // declaration, we infer an 'unknown[]' constraint.
                        else if (grandParent.kind === 152 /* Parameter */ && grandParent.dotDotDotToken) {
                            inferences = ts.append(inferences, createArrayType(unknownType));
                        }
                    }
                }
            }
            return inferences && getIntersectionType(inferences);
        }
        /** This is a worker function. Use getConstraintOfTypeParameter which guards against circular constraints. */
        function getConstraintFromTypeParameter(typeParameter) {
            if (!typeParameter.constraint) {
                if (typeParameter.target) {
                    var targetConstraint = getConstraintOfTypeParameter(typeParameter.target);
                    typeParameter.constraint = targetConstraint ? instantiateType(targetConstraint, typeParameter.mapper) : noConstraintType;
                }
                else {
                    var constraintDeclaration = getConstraintDeclaration(typeParameter);
                    typeParameter.constraint = constraintDeclaration ? getTypeFromTypeNode(constraintDeclaration) :
                        getInferredTypeParameterConstraint(typeParameter) || noConstraintType;
                }
            }
            return typeParameter.constraint === noConstraintType ? undefined : typeParameter.constraint;
        }
        function getParentSymbolOfTypeParameter(typeParameter) {
            var tp = ts.getDeclarationOfKind(typeParameter.symbol, 151 /* TypeParameter */);
            var host = ts.isJSDocTemplateTag(tp.parent) ? ts.getHostSignatureFromJSDoc(tp.parent) : tp.parent;
            return host && getSymbolOfNode(host);
        }
        function getTypeListId(types) {
            var result = "";
            if (types) {
                var length_3 = types.length;
                var i = 0;
                while (i < length_3) {
                    var startId = types[i].id;
                    var count = 1;
                    while (i + count < length_3 && types[i + count].id === startId + count) {
                        count++;
                    }
                    if (result.length) {
                        result += ",";
                    }
                    result += startId;
                    if (count > 1) {
                        result += ":" + count;
                    }
                    i += count;
                }
            }
            return result;
        }
        // This function is used to propagate certain flags when creating new object type references and union types.
        // It is only necessary to do so if a constituent type might be the undefined type, the null type, the type
        // of an object literal or the anyFunctionType. This is because there are operations in the type checker
        // that care about the presence of such types at arbitrary depth in a containing type.
        function getPropagatingFlagsOfTypes(types, excludeKinds) {
            var result = 0;
            for (var _i = 0, types_5 = types; _i < types_5.length; _i++) {
                var type = types_5[_i];
                if (!(type.flags & excludeKinds)) {
                    result |= ts.getObjectFlags(type);
                }
            }
            return result & 917504 /* PropagatingFlags */;
        }
        function createTypeReference(target, typeArguments) {
            var id = getTypeListId(typeArguments);
            var type = target.instantiations.get(id);
            if (!type) {
                type = createObjectType(4 /* Reference */, target.symbol);
                target.instantiations.set(id, type);
                type.objectFlags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0;
                type.target = target;
                type.typeArguments = typeArguments;
            }
            return type;
        }
        function cloneTypeReference(source) {
            var type = createType(source.flags);
            type.symbol = source.symbol;
            type.objectFlags = source.objectFlags;
            type.target = source.target;
            type.typeArguments = source.typeArguments;
            return type;
        }
        function getTypeReferenceArity(type) {
            return ts.length(type.target.typeParameters);
        }
        /**
         * Get type from type-reference that reference to class or interface
         */
        function getTypeFromClassOrInterfaceReference(node, symbol, typeArgs) {
            var type = getDeclaredTypeOfSymbol(getMergedSymbol(symbol));
            var typeParameters = type.localTypeParameters;
            if (typeParameters) {
                var numTypeArguments = ts.length(node.typeArguments);
                var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
                var isJs = ts.isInJSFile(node);
                var isJsImplicitAny = !noImplicitAny && isJs;
                if (!isJsImplicitAny && (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length)) {
                    var missingAugmentsTag = isJs && ts.isExpressionWithTypeArguments(node) && !ts.isJSDocAugmentsTag(node.parent);
                    var diag = minTypeArgumentCount === typeParameters.length
                        ? missingAugmentsTag
                            ? ts.Diagnostics.Expected_0_type_arguments_provide_these_with_an_extends_tag
                            : ts.Diagnostics.Generic_type_0_requires_1_type_argument_s
                        : missingAugmentsTag
                            ? ts.Diagnostics.Expected_0_1_type_arguments_provide_these_with_an_extends_tag
                            : ts.Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments;
                    var typeStr = typeToString(type, /*enclosingDeclaration*/ undefined, 2 /* WriteArrayAsGenericType */);
                    error(node, diag, typeStr, minTypeArgumentCount, typeParameters.length);
                    if (!isJs) {
                        // TODO: Adopt same permissive behavior in TS as in JS to reduce follow-on editing experience failures (requires editing fillMissingTypeArguments)
                        return errorType;
                    }
                }
                // In a type reference, the outer type parameters of the referenced class or interface are automatically
                // supplied as type arguments and the type reference only specifies arguments for the local type parameters
                // of the class or interface.
                var typeArguments = ts.concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgs, typeParameters, minTypeArgumentCount, isJs));
                return createTypeReference(type, typeArguments);
            }
            return checkNoTypeArguments(node, symbol) ? type : errorType;
        }
        function getTypeAliasInstantiation(symbol, typeArguments) {
            var type = getDeclaredTypeOfSymbol(symbol);
            var links = getSymbolLinks(symbol);
            var typeParameters = links.typeParameters;
            var id = getTypeListId(typeArguments);
            var instantiation = links.instantiations.get(id);
            if (!instantiation) {
                links.instantiations.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), ts.isInJSFile(symbol.valueDeclaration)))));
            }
            return instantiation;
        }
        /**
         * Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include
         * references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the
         * declared type. Instantiations are cached using the type identities of the type arguments as the key.
         */
        function getTypeFromTypeAliasReference(node, symbol, typeArguments) {
            var type = getDeclaredTypeOfSymbol(symbol);
            var typeParameters = getSymbolLinks(symbol).typeParameters;
            if (typeParameters) {
                var numTypeArguments = ts.length(node.typeArguments);
                var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
                if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) {
                    error(node, minTypeArgumentCount === typeParameters.length
                        ? ts.Diagnostics.Generic_type_0_requires_1_type_argument_s
                        : ts.Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, symbolToString(symbol), minTypeArgumentCount, typeParameters.length);
                    return errorType;
                }
                return getTypeAliasInstantiation(symbol, typeArguments);
            }
            return checkNoTypeArguments(node, symbol) ? type : errorType;
        }
        function getTypeReferenceName(node) {
            switch (node.kind) {
                case 165 /* TypeReference */:
                    return node.typeName;
                case 212 /* ExpressionWithTypeArguments */:
                    // We only support expressions that are simple qualified names. For other
                    // expressions this produces undefined.
                    var expr = node.expression;
                    if (ts.isEntityNameExpression(expr)) {
                        return expr;
                    }
                // fall through;
            }
            return undefined;
        }
        function resolveTypeReferenceName(typeReferenceName, meaning) {
            if (!typeReferenceName) {
                return unknownSymbol;
            }
            return resolveEntityName(typeReferenceName, meaning) || unknownSymbol;
        }
        function getTypeReferenceType(node, symbol) {
            var typeArguments = typeArgumentsFromTypeReferenceNode(node); // Do unconditionally so we mark type arguments as referenced.
            if (symbol === unknownSymbol) {
                return errorType;
            }
            var type = getTypeReferenceTypeWorker(node, symbol, typeArguments);
            if (type) {
                return type;
            }
            // JS enums are 'string' or 'number', not an enum type.
            var enumTag = ts.isInJSFile(node) && symbol.valueDeclaration && ts.getJSDocEnumTag(symbol.valueDeclaration);
            if (enumTag) {
                var links = getNodeLinks(enumTag);
                if (!pushTypeResolution(enumTag, 5 /* EnumTagType */)) {
                    return errorType;
                }
                var type_4 = enumTag.typeExpression ? getTypeFromTypeNode(enumTag.typeExpression) : errorType;
                if (!popTypeResolution()) {
                    type_4 = errorType;
                    error(node, ts.Diagnostics.Enum_type_0_circularly_references_itself, symbolToString(symbol));
                }
                return (links.resolvedEnumType = type_4);
            }
            // Get type from reference to named type that cannot be generic (enum or type parameter)
            var res = tryGetDeclaredTypeOfSymbol(symbol);
            if (res) {
                return checkNoTypeArguments(node, symbol) ?
                    res.flags & 262144 /* TypeParameter */ ? getConstrainedTypeVariable(res, node) : getRegularTypeOfLiteralType(res) :
                    errorType;
            }
            if (!(symbol.flags & 67220415 /* Value */ && isJSDocTypeReference(node))) {
                return errorType;
            }
            var jsdocType = getJSDocTypeReference(node, symbol, typeArguments);
            if (jsdocType) {
                return jsdocType;
            }
            // Resolve the type reference as a Type for the purpose of reporting errors.
            resolveTypeReferenceName(getTypeReferenceName(node), 67897832 /* Type */);
            return getTypeOfSymbol(symbol);
        }
        /**
         * A jsdoc TypeReference may have resolved to a value (as opposed to a type). If
         * the symbol is a constructor function, return the inferred class type; otherwise,
         * the type of this reference is just the type of the value we resolved to.
         */
        function getJSDocTypeReference(node, symbol, typeArguments) {
            // In the case of an assignment of a function expression (binary expressions, variable declarations, etc.), we will get the
            // correct instance type for the symbol on the LHS by finding the type for RHS. For example if we want to get the type of the symbol `foo`:
            //   var foo = function() {}
            // We will find the static type of the assigned anonymous function.
            var staticType = getTypeOfSymbol(symbol);
            var instanceType = staticType.symbol &&
                staticType.symbol !== symbol && // Make sure this is an assignment like expression by checking that symbol -> type -> symbol doesn't roundtrips.
                getTypeReferenceTypeWorker(node, staticType.symbol, typeArguments); // Get the instance type of the RHS symbol.
            if (instanceType) {
                return getSymbolLinks(symbol).resolvedJSDocType = instanceType;
            }
        }
        function getTypeReferenceTypeWorker(node, symbol, typeArguments) {
            if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                if (symbol.valueDeclaration && symbol.valueDeclaration.parent && ts.isBinaryExpression(symbol.valueDeclaration.parent)) {
                    var jsdocType = getJSDocTypeReference(node, symbol, typeArguments);
                    if (jsdocType) {
                        return jsdocType;
                    }
                }
                return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments);
            }
            if (symbol.flags & 524288 /* TypeAlias */) {
                return getTypeFromTypeAliasReference(node, symbol, typeArguments);
            }
            if (symbol.flags & 16 /* Function */ &&
                isJSDocTypeReference(node) &&
                isJSConstructor(symbol.valueDeclaration)) {
                var resolved = resolveStructuredTypeMembers(getTypeOfSymbol(symbol));
                if (resolved.callSignatures.length === 1) {
                    return getReturnTypeOfSignature(resolved.callSignatures[0]);
                }
            }
        }
        function getSubstitutionType(typeVariable, substitute) {
            if (substitute.flags & 3 /* AnyOrUnknown */ || substitute === typeVariable) {
                return typeVariable;
            }
            var id = getTypeId(typeVariable) + ">" + getTypeId(substitute);
            var cached = substitutionTypes.get(id);
            if (cached) {
                return cached;
            }
            var result = createType(33554432 /* Substitution */);
            result.typeVariable = typeVariable;
            result.substitute = substitute;
            substitutionTypes.set(id, result);
            return result;
        }
        function isUnaryTupleTypeNode(node) {
            return node.kind === 171 /* TupleType */ && node.elementTypes.length === 1;
        }
        function getImpliedConstraint(typeVariable, checkNode, extendsNode) {
            return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(typeVariable, checkNode.elementTypes[0], extendsNode.elementTypes[0]) :
                getActualTypeVariable(getTypeFromTypeNode(checkNode)) === typeVariable ? getTypeFromTypeNode(extendsNode) :
                    undefined;
        }
        function getConstrainedTypeVariable(typeVariable, node) {
            var constraints;
            while (node && !ts.isStatement(node) && node.kind !== 297 /* JSDocComment */) {
                var parent = node.parent;
                if (parent.kind === 176 /* ConditionalType */ && node === parent.trueType) {
                    var constraint = getImpliedConstraint(typeVariable, parent.checkType, parent.extendsType);
                    if (constraint) {
                        constraints = ts.append(constraints, constraint);
                    }
                }
                node = parent;
            }
            return constraints ? getSubstitutionType(typeVariable, getIntersectionType(ts.append(constraints, typeVariable))) : typeVariable;
        }
        function isJSDocTypeReference(node) {
            return !!(node.flags & 2097152 /* JSDoc */) && (node.kind === 165 /* TypeReference */ || node.kind === 184 /* ImportType */);
        }
        function checkNoTypeArguments(node, symbol) {
            if (node.typeArguments) {
                error(node, ts.Diagnostics.Type_0_is_not_generic, symbol ? symbolToString(symbol) : node.typeName ? ts.declarationNameToString(node.typeName) : "(anonymous)");
                return false;
            }
            return true;
        }
        function getIntendedTypeFromJSDocTypeReference(node) {
            if (ts.isIdentifier(node.typeName)) {
                var typeArgs = node.typeArguments;
                switch (node.typeName.escapedText) {
                    case "String":
                        checkNoTypeArguments(node);
                        return stringType;
                    case "Number":
                        checkNoTypeArguments(node);
                        return numberType;
                    case "Boolean":
                        checkNoTypeArguments(node);
                        return booleanType;
                    case "Void":
                        checkNoTypeArguments(node);
                        return voidType;
                    case "Undefined":
                        checkNoTypeArguments(node);
                        return undefinedType;
                    case "Null":
                        checkNoTypeArguments(node);
                        return nullType;
                    case "Function":
                    case "function":
                        checkNoTypeArguments(node);
                        return globalFunctionType;
                    case "Array":
                    case "array":
                        return !typeArgs || !typeArgs.length ? anyArrayType : undefined;
                    case "Promise":
                    case "promise":
                        return !typeArgs || !typeArgs.length ? createPromiseType(anyType) : undefined;
                    case "Object":
                        if (typeArgs && typeArgs.length === 2) {
                            if (ts.isJSDocIndexSignature(node)) {
                                var indexed = getTypeFromTypeNode(typeArgs[0]);
                                var target = getTypeFromTypeNode(typeArgs[1]);
                                var index = createIndexInfo(target, /*isReadonly*/ false);
                                return createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, indexed === stringType ? index : undefined, indexed === numberType ? index : undefined);
                            }
                            return anyType;
                        }
                        checkNoTypeArguments(node);
                        return anyType;
                }
            }
        }
        function getTypeFromJSDocNullableTypeNode(node) {
            var type = getTypeFromTypeNode(node.type);
            return strictNullChecks ? getNullableType(type, 65536 /* Null */) : type;
        }
        function getTypeFromTypeReference(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var symbol = void 0;
                var type = void 0;
                var meaning = 67897832 /* Type */;
                if (isJSDocTypeReference(node)) {
                    type = getIntendedTypeFromJSDocTypeReference(node);
                    meaning |= 67220415 /* Value */;
                }
                if (!type) {
                    symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning);
                    type = getTypeReferenceType(node, symbol);
                }
                // Cache both the resolved symbol and the resolved type. The resolved symbol is needed when we check the
                // type reference in checkTypeReferenceNode.
                links.resolvedSymbol = symbol;
                links.resolvedType = type;
            }
            return links.resolvedType;
        }
        function typeArgumentsFromTypeReferenceNode(node) {
            return ts.map(node.typeArguments, getTypeFromTypeNode);
        }
        function getTypeFromTypeQueryNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                // TypeScript 1.0 spec (April 2014): 3.6.3
                // The expression is processed as an identifier expression (section 4.3)
                // or property access expression(section 4.10),
                // the widened type(section 3.9) of which becomes the result.
                links.resolvedType = getRegularTypeOfLiteralType(getWidenedType(checkExpression(node.exprName)));
            }
            return links.resolvedType;
        }
        function getTypeOfGlobalSymbol(symbol, arity) {
            function getTypeDeclaration(symbol) {
                var declarations = symbol.declarations;
                for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) {
                    var declaration = declarations_3[_i];
                    switch (declaration.kind) {
                        case 241 /* ClassDeclaration */:
                        case 242 /* InterfaceDeclaration */:
                        case 244 /* EnumDeclaration */:
                            return declaration;
                    }
                }
            }
            if (!symbol) {
                return arity ? emptyGenericType : emptyObjectType;
            }
            var type = getDeclaredTypeOfSymbol(symbol);
            if (!(type.flags & 524288 /* Object */)) {
                error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_be_a_class_or_interface_type, ts.symbolName(symbol));
                return arity ? emptyGenericType : emptyObjectType;
            }
            if (ts.length(type.typeParameters) !== arity) {
                error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_have_1_type_parameter_s, ts.symbolName(symbol), arity);
                return arity ? emptyGenericType : emptyObjectType;
            }
            return type;
        }
        function getGlobalValueSymbol(name, reportErrors) {
            return getGlobalSymbol(name, 67220415 /* Value */, reportErrors ? ts.Diagnostics.Cannot_find_global_value_0 : undefined);
        }
        function getGlobalTypeSymbol(name, reportErrors) {
            return getGlobalSymbol(name, 67897832 /* Type */, reportErrors ? ts.Diagnostics.Cannot_find_global_type_0 : undefined);
        }
        function getGlobalSymbol(name, meaning, diagnostic) {
            // Don't track references for global symbols anyway, so value if `isReference` is arbitrary
            return resolveName(undefined, name, meaning, diagnostic, name, /*isUse*/ false);
        }
        function getGlobalType(name, arity, reportErrors) {
            var symbol = getGlobalTypeSymbol(name, reportErrors);
            return symbol || reportErrors ? getTypeOfGlobalSymbol(symbol, arity) : undefined;
        }
        function getGlobalTypedPropertyDescriptorType() {
            return deferredGlobalTypedPropertyDescriptorType || (deferredGlobalTypedPropertyDescriptorType = getGlobalType("TypedPropertyDescriptor", /*arity*/ 1, /*reportErrors*/ true)) || emptyGenericType;
        }
        function getGlobalTemplateStringsArrayType() {
            return deferredGlobalTemplateStringsArrayType || (deferredGlobalTemplateStringsArrayType = getGlobalType("TemplateStringsArray", /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType;
        }
        function getGlobalImportMetaType() {
            return deferredGlobalImportMetaType || (deferredGlobalImportMetaType = getGlobalType("ImportMeta", /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType;
        }
        function getGlobalESSymbolConstructorSymbol(reportErrors) {
            return deferredGlobalESSymbolConstructorSymbol || (deferredGlobalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol", reportErrors));
        }
        function getGlobalESSymbolType(reportErrors) {
            return deferredGlobalESSymbolType || (deferredGlobalESSymbolType = getGlobalType("Symbol", /*arity*/ 0, reportErrors)) || emptyObjectType;
        }
        function getGlobalPromiseType(reportErrors) {
            return deferredGlobalPromiseType || (deferredGlobalPromiseType = getGlobalType("Promise", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalPromiseLikeType(reportErrors) {
            return deferredGlobalPromiseLikeType || (deferredGlobalPromiseLikeType = getGlobalType("PromiseLike", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalPromiseConstructorSymbol(reportErrors) {
            return deferredGlobalPromiseConstructorSymbol || (deferredGlobalPromiseConstructorSymbol = getGlobalValueSymbol("Promise", reportErrors));
        }
        function getGlobalPromiseConstructorLikeType(reportErrors) {
            return deferredGlobalPromiseConstructorLikeType || (deferredGlobalPromiseConstructorLikeType = getGlobalType("PromiseConstructorLike", /*arity*/ 0, reportErrors)) || emptyObjectType;
        }
        function getGlobalAsyncIterableType(reportErrors) {
            return deferredGlobalAsyncIterableType || (deferredGlobalAsyncIterableType = getGlobalType("AsyncIterable", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalAsyncIteratorType(reportErrors) {
            return deferredGlobalAsyncIteratorType || (deferredGlobalAsyncIteratorType = getGlobalType("AsyncIterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalAsyncIterableIteratorType(reportErrors) {
            return deferredGlobalAsyncIterableIteratorType || (deferredGlobalAsyncIterableIteratorType = getGlobalType("AsyncIterableIterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalIterableType(reportErrors) {
            return deferredGlobalIterableType || (deferredGlobalIterableType = getGlobalType("Iterable", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalIteratorType(reportErrors) {
            return deferredGlobalIteratorType || (deferredGlobalIteratorType = getGlobalType("Iterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalIterableIteratorType(reportErrors) {
            return deferredGlobalIterableIteratorType || (deferredGlobalIterableIteratorType = getGlobalType("IterableIterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalTypeOrUndefined(name, arity) {
            if (arity === void 0) { arity = 0; }
            var symbol = getGlobalSymbol(name, 67897832 /* Type */, /*diagnostic*/ undefined);
            return symbol && getTypeOfGlobalSymbol(symbol, arity);
        }
        function getGlobalExtractSymbol() {
            return deferredGlobalExtractSymbol || (deferredGlobalExtractSymbol = getGlobalSymbol("Extract", 524288 /* TypeAlias */, ts.Diagnostics.Cannot_find_global_type_0)); // TODO: GH#18217
        }
        function getGlobalOmitSymbol() {
            return deferredGlobalOmitSymbol || (deferredGlobalOmitSymbol = getGlobalSymbol("Omit", 524288 /* TypeAlias */, ts.Diagnostics.Cannot_find_global_type_0)); // TODO: GH#18217
        }
        function getGlobalBigIntType(reportErrors) {
            return deferredGlobalBigIntType || (deferredGlobalBigIntType = getGlobalType("BigInt", /*arity*/ 0, reportErrors)) || emptyObjectType;
        }
        /**
         * Instantiates a global type that is generic with some element type, and returns that instantiation.
         */
        function createTypeFromGenericGlobalType(genericGlobalType, typeArguments) {
            return genericGlobalType !== emptyGenericType ? createTypeReference(genericGlobalType, typeArguments) : emptyObjectType;
        }
        function createTypedPropertyDescriptorType(propertyType) {
            return createTypeFromGenericGlobalType(getGlobalTypedPropertyDescriptorType(), [propertyType]);
        }
        function createAsyncIterableType(iteratedType) {
            return createTypeFromGenericGlobalType(getGlobalAsyncIterableType(/*reportErrors*/ true), [iteratedType]);
        }
        function createAsyncIterableIteratorType(iteratedType) {
            return createTypeFromGenericGlobalType(getGlobalAsyncIterableIteratorType(/*reportErrors*/ true), [iteratedType]);
        }
        function createIterableType(iteratedType) {
            return createTypeFromGenericGlobalType(getGlobalIterableType(/*reportErrors*/ true), [iteratedType]);
        }
        function createIterableIteratorType(iteratedType) {
            return createTypeFromGenericGlobalType(getGlobalIterableIteratorType(/*reportErrors*/ true), [iteratedType]);
        }
        function createArrayType(elementType, readonly) {
            return createTypeFromGenericGlobalType(readonly ? globalReadonlyArrayType : globalArrayType, [elementType]);
        }
        function getTypeFromArrayTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = createArrayType(getTypeFromTypeNode(node.elementType), isReadonlyTypeOperator(node.parent));
            }
            return links.resolvedType;
        }
        function isReadonlyTypeOperator(node) {
            return ts.isTypeOperatorNode(node) && node.operator === 134 /* ReadonlyKeyword */;
        }
        // We represent tuple types as type references to synthesized generic interface types created by
        // this function. The types are of the form:
        //
        //   interface Tuple<T0, T1, T2, ...> extends Array<T0 | T1 | T2 | ...> { 0: T0, 1: T1, 2: T2, ... }
        //
        // Note that the generic type created by this function has no symbol associated with it. The same
        // is true for each of the synthesized type parameters.
        function createTupleTypeOfArity(arity, minLength, hasRestElement, readonly, associatedNames) {
            var typeParameters;
            var properties = [];
            var maxLength = hasRestElement ? arity - 1 : arity;
            if (arity) {
                typeParameters = new Array(arity);
                for (var i = 0; i < arity; i++) {
                    var typeParameter = typeParameters[i] = createTypeParameter();
                    if (i < maxLength) {
                        var property = createSymbol(4 /* Property */ | (i >= minLength ? 16777216 /* Optional */ : 0), "" + i, readonly ? 8 /* Readonly */ : 0);
                        property.type = typeParameter;
                        properties.push(property);
                    }
                }
            }
            var literalTypes = [];
            for (var i = minLength; i <= maxLength; i++)
                literalTypes.push(getLiteralType(i));
            var lengthSymbol = createSymbol(4 /* Property */, "length");
            lengthSymbol.type = hasRestElement ? numberType : getUnionType(literalTypes);
            properties.push(lengthSymbol);
            var type = createObjectType(8 /* Tuple */ | 4 /* Reference */);
            type.typeParameters = typeParameters;
            type.outerTypeParameters = undefined;
            type.localTypeParameters = typeParameters;
            type.instantiations = ts.createMap();
            type.instantiations.set(getTypeListId(type.typeParameters), type);
            type.target = type;
            type.typeArguments = type.typeParameters;
            type.thisType = createTypeParameter();
            type.thisType.isThisType = true;
            type.thisType.constraint = type;
            type.declaredProperties = properties;
            type.declaredCallSignatures = ts.emptyArray;
            type.declaredConstructSignatures = ts.emptyArray;
            type.declaredStringIndexInfo = undefined;
            type.declaredNumberIndexInfo = undefined;
            type.minLength = minLength;
            type.hasRestElement = hasRestElement;
            type.readonly = readonly;
            type.associatedNames = associatedNames;
            return type;
        }
        function getTupleTypeOfArity(arity, minLength, hasRestElement, readonly, associatedNames) {
            var key = arity + (hasRestElement ? "+" : ",") + minLength + (readonly ? "R" : "") + (associatedNames && associatedNames.length ? "," + associatedNames.join(",") : "");
            var type = tupleTypes.get(key);
            if (!type) {
                tupleTypes.set(key, type = createTupleTypeOfArity(arity, minLength, hasRestElement, readonly, associatedNames));
            }
            return type;
        }
        function createTupleType(elementTypes, minLength, hasRestElement, readonly, associatedNames) {
            if (minLength === void 0) { minLength = elementTypes.length; }
            if (hasRestElement === void 0) { hasRestElement = false; }
            if (readonly === void 0) { readonly = false; }
            var arity = elementTypes.length;
            if (arity === 1 && hasRestElement) {
                return createArrayType(elementTypes[0], readonly);
            }
            var tupleType = getTupleTypeOfArity(arity, minLength, arity > 0 && hasRestElement, readonly, associatedNames);
            return elementTypes.length ? createTypeReference(tupleType, elementTypes) : tupleType;
        }
        function getTypeFromTupleTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var lastElement = ts.lastOrUndefined(node.elementTypes);
                var restElement_1 = lastElement && lastElement.kind === 173 /* RestType */ ? lastElement : undefined;
                var minLength = ts.findLastIndex(node.elementTypes, function (n) { return n.kind !== 172 /* OptionalType */ && n !== restElement_1; }) + 1;
                var elementTypes = ts.map(node.elementTypes, function (n) {
                    var type = getTypeFromTypeNode(n);
                    return n === restElement_1 && getIndexTypeOfType(type, 1 /* Number */) || type;
                });
                links.resolvedType = createTupleType(elementTypes, minLength, !!restElement_1, isReadonlyTypeOperator(node.parent));
            }
            return links.resolvedType;
        }
        function sliceTupleType(type, index) {
            var tuple = type.target;
            if (tuple.hasRestElement) {
                // don't slice off rest element
                index = Math.min(index, getTypeReferenceArity(type) - 1);
            }
            return createTupleType((type.typeArguments || ts.emptyArray).slice(index), Math.max(0, tuple.minLength - index), tuple.hasRestElement, tuple.readonly, tuple.associatedNames && tuple.associatedNames.slice(index));
        }
        function getTypeFromOptionalTypeNode(node) {
            var type = getTypeFromTypeNode(node.type);
            return strictNullChecks ? getOptionalType(type) : type;
        }
        function getTypeId(type) {
            return type.id;
        }
        function containsType(types, type) {
            return ts.binarySearch(types, type, getTypeId, ts.compareValues) >= 0;
        }
        function insertType(types, type) {
            var index = ts.binarySearch(types, type, getTypeId, ts.compareValues);
            if (index < 0) {
                types.splice(~index, 0, type);
                return true;
            }
            return false;
        }
        // Return true if the given intersection type contains
        // more than one unit type or,
        // an object type and a nullable type (null or undefined), or
        // a string-like type and a type known to be non-string-like, or
        // a number-like type and a type known to be non-number-like, or
        // a symbol-like type and a type known to be non-symbol-like, or
        // a void-like type and a type known to be non-void-like, or
        // a non-primitive type and a type known to be primitive.
        function isEmptyIntersectionType(type) {
            var combined = 0;
            for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                var t = _a[_i];
                if (t.flags & 109440 /* Unit */ && combined & 109440 /* Unit */) {
                    return true;
                }
                combined |= t.flags;
                if (combined & 98304 /* Nullable */ && combined & (524288 /* Object */ | 67108864 /* NonPrimitive */) ||
                    combined & 67108864 /* NonPrimitive */ && combined & (67238908 /* DisjointDomains */ & ~67108864 /* NonPrimitive */) ||
                    combined & 132 /* StringLike */ && combined & (67238908 /* DisjointDomains */ & ~132 /* StringLike */) ||
                    combined & 296 /* NumberLike */ && combined & (67238908 /* DisjointDomains */ & ~296 /* NumberLike */) ||
                    combined & 2112 /* BigIntLike */ && combined & (67238908 /* DisjointDomains */ & ~2112 /* BigIntLike */) ||
                    combined & 12288 /* ESSymbolLike */ && combined & (67238908 /* DisjointDomains */ & ~12288 /* ESSymbolLike */) ||
                    combined & 49152 /* VoidLike */ && combined & (67238908 /* DisjointDomains */ & ~49152 /* VoidLike */)) {
                    return true;
                }
            }
            return false;
        }
        function addTypeToUnion(typeSet, includes, type) {
            var flags = type.flags;
            if (flags & 1048576 /* Union */) {
                return addTypesToUnion(typeSet, includes, type.types);
            }
            // We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are
            // another form of 'never' (in that they have an empty value domain). We could in theory turn
            // intersections of unit types into 'never' upon construction, but deferring the reduction makes it
            // easier to reason about their origin.
            if (!(flags & 131072 /* Never */ || flags & 2097152 /* Intersection */ && isEmptyIntersectionType(type))) {
                includes |= flags & 1835007 /* IncludesMask */;
                if (flags & 66846720 /* StructuredOrInstantiable */)
                    includes |= 262144 /* IncludesStructuredOrInstantiable */;
                if (type === wildcardType)
                    includes |= 4194304 /* IncludesWildcard */;
                if (!strictNullChecks && flags & 98304 /* Nullable */) {
                    if (!(ts.getObjectFlags(type) & 131072 /* ContainsWideningType */))
                        includes |= 2097152 /* IncludesNonWideningType */;
                }
                else {
                    var len = typeSet.length;
                    var index = len && type.id > typeSet[len - 1].id ? ~len : ts.binarySearch(typeSet, type, getTypeId, ts.compareValues);
                    if (index < 0) {
                        typeSet.splice(~index, 0, type);
                    }
                }
            }
            return includes;
        }
        // Add the given types to the given type set. Order is preserved, duplicates are removed,
        // and nested types of the given kind are flattened into the set.
        function addTypesToUnion(typeSet, includes, types) {
            for (var _i = 0, types_6 = types; _i < types_6.length; _i++) {
                var type = types_6[_i];
                includes = addTypeToUnion(typeSet, includes, type);
            }
            return includes;
        }
        function isSetOfLiteralsFromSameEnum(types) {
            var first = types[0];
            if (first.flags & 1024 /* EnumLiteral */) {
                var firstEnum = getParentOfSymbol(first.symbol);
                for (var i = 1; i < types.length; i++) {
                    var other = types[i];
                    if (!(other.flags & 1024 /* EnumLiteral */) || (firstEnum !== getParentOfSymbol(other.symbol))) {
                        return false;
                    }
                }
                return true;
            }
            return false;
        }
        function removeSubtypes(types, primitivesOnly) {
            var len = types.length;
            if (len === 0 || isSetOfLiteralsFromSameEnum(types)) {
                return true;
            }
            var i = len;
            var count = 0;
            while (i > 0) {
                i--;
                var source = types[i];
                for (var _i = 0, types_7 = types; _i < types_7.length; _i++) {
                    var target = types_7[_i];
                    if (source !== target) {
                        if (count === 100000) {
                            // After 100000 subtype checks we estimate the remaining amount of work by assuming the
                            // same ratio of checks per element. If the estimated number of remaining type checks is
                            // greater than an upper limit we deem the union type too complex to represent. The
                            // upper limit is 25M for unions of primitives only, and 1M otherwise. This for example
                            // caps union types at 5000 unique literal types and 1000 unique object types.
                            var estimatedCount = (count / (len - i)) * len;
                            if (estimatedCount > (primitivesOnly ? 25000000 : 1000000)) {
                                error(currentNode, ts.Diagnostics.Expression_produces_a_union_type_that_is_too_complex_to_represent);
                                return false;
                            }
                        }
                        count++;
                        if (isTypeSubtypeOf(source, target) && (!(ts.getObjectFlags(getTargetType(source)) & 1 /* Class */) ||
                            !(ts.getObjectFlags(getTargetType(target)) & 1 /* Class */) ||
                            isTypeDerivedFrom(source, target))) {
                            ts.orderedRemoveItemAt(types, i);
                            break;
                        }
                    }
                }
            }
            return true;
        }
        function removeRedundantLiteralTypes(types, includes) {
            var i = types.length;
            while (i > 0) {
                i--;
                var t = types[i];
                var remove = t.flags & 128 /* StringLiteral */ && includes & 4 /* String */ ||
                    t.flags & 256 /* NumberLiteral */ && includes & 8 /* Number */ ||
                    t.flags & 2048 /* BigIntLiteral */ && includes & 64 /* BigInt */ ||
                    t.flags & 8192 /* UniqueESSymbol */ && includes & 4096 /* ESSymbol */ ||
                    isFreshLiteralType(t) && containsType(types, t.regularType);
                if (remove) {
                    ts.orderedRemoveItemAt(types, i);
                }
            }
        }
        // We sort and deduplicate the constituent types based on object identity. If the subtypeReduction
        // flag is specified we also reduce the constituent type set to only include types that aren't subtypes
        // of other types. Subtype reduction is expensive for large union types and is possible only when union
        // types are known not to circularly reference themselves (as is the case with union types created by
        // expression constructs such as array literals and the || and ?: operators). Named types can
        // circularly reference themselves and therefore cannot be subtype reduced during their declaration.
        // For example, "type Item = string | (() => Item" is a named type that circularly references itself.
        function getUnionType(types, unionReduction, aliasSymbol, aliasTypeArguments) {
            if (unionReduction === void 0) { unionReduction = 1 /* Literal */; }
            if (types.length === 0) {
                return neverType;
            }
            if (types.length === 1) {
                return types[0];
            }
            var typeSet = [];
            var includes = addTypesToUnion(typeSet, 0, types);
            if (unionReduction !== 0 /* None */) {
                if (includes & 3 /* AnyOrUnknown */) {
                    return includes & 1 /* Any */ ? includes & 4194304 /* IncludesWildcard */ ? wildcardType : anyType : unknownType;
                }
                switch (unionReduction) {
                    case 1 /* Literal */:
                        if (includes & (2944 /* Literal */ | 8192 /* UniqueESSymbol */)) {
                            removeRedundantLiteralTypes(typeSet, includes);
                        }
                        break;
                    case 2 /* Subtype */:
                        if (!removeSubtypes(typeSet, !(includes & 262144 /* IncludesStructuredOrInstantiable */))) {
                            return errorType;
                        }
                        break;
                }
                if (typeSet.length === 0) {
                    return includes & 65536 /* Null */ ? includes & 2097152 /* IncludesNonWideningType */ ? nullType : nullWideningType :
                        includes & 32768 /* Undefined */ ? includes & 2097152 /* IncludesNonWideningType */ ? undefinedType : undefinedWideningType :
                            neverType;
                }
            }
            return getUnionTypeFromSortedList(typeSet, includes & 66994211 /* NotPrimitiveUnion */ ? 0 : 65536 /* PrimitiveUnion */, aliasSymbol, aliasTypeArguments);
        }
        function getUnionTypePredicate(signatures) {
            var first;
            var types = [];
            for (var _i = 0, signatures_2 = signatures; _i < signatures_2.length; _i++) {
                var sig = signatures_2[_i];
                var pred = getTypePredicateOfSignature(sig);
                if (!pred) {
                    continue;
                }
                if (first) {
                    if (!typePredicateKindsMatch(first, pred)) {
                        // No common type predicate.
                        return undefined;
                    }
                }
                else {
                    first = pred;
                }
                types.push(pred.type);
            }
            if (!first) {
                // No union signatures had a type predicate.
                return undefined;
            }
            var unionType = getUnionType(types);
            return ts.isIdentifierTypePredicate(first)
                ? createIdentifierTypePredicate(first.parameterName, first.parameterIndex, unionType)
                : createThisTypePredicate(unionType);
        }
        function typePredicateKindsMatch(a, b) {
            return ts.isIdentifierTypePredicate(a)
                ? ts.isIdentifierTypePredicate(b) && a.parameterIndex === b.parameterIndex
                : !ts.isIdentifierTypePredicate(b);
        }
        // This function assumes the constituent type list is sorted and deduplicated.
        function getUnionTypeFromSortedList(types, objectFlags, aliasSymbol, aliasTypeArguments) {
            if (types.length === 0) {
                return neverType;
            }
            if (types.length === 1) {
                return types[0];
            }
            var id = getTypeListId(types);
            var type = unionTypes.get(id);
            if (!type) {
                type = createType(1048576 /* Union */);
                unionTypes.set(id, type);
                type.objectFlags = objectFlags | getPropagatingFlagsOfTypes(types, /*excludeKinds*/ 98304 /* Nullable */);
                type.types = types;
                /*
                Note: This is the alias symbol (or lack thereof) that we see when we first encounter this union type.
                For aliases of identical unions, eg `type T = A | B; type U = A | B`, the symbol of the first alias encountered is the aliasSymbol.
                (In the language service, the order may depend on the order in which a user takes actions, such as hovering over symbols.)
                It's important that we create equivalent union types only once, so that's an unfortunate side effect.
                */
                type.aliasSymbol = aliasSymbol;
                type.aliasTypeArguments = aliasTypeArguments;
            }
            return type;
        }
        function getTypeFromUnionTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var aliasSymbol = getAliasSymbolForTypeNode(node);
                links.resolvedType = getUnionType(ts.map(node.types, getTypeFromTypeNode), 1 /* Literal */, aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol));
            }
            return links.resolvedType;
        }
        function addTypeToIntersection(typeSet, includes, type) {
            var flags = type.flags;
            if (flags & 2097152 /* Intersection */) {
                return addTypesToIntersection(typeSet, includes, type.types);
            }
            if (isEmptyAnonymousObjectType(type)) {
                if (!(includes & 8388608 /* IncludesEmptyObject */)) {
                    includes |= 8388608 /* IncludesEmptyObject */;
                    typeSet.push(type);
                }
            }
            else {
                includes |= flags & 1835007 /* IncludesMask */;
                if (flags & 3 /* AnyOrUnknown */) {
                    if (type === wildcardType)
                        includes |= 4194304 /* IncludesWildcard */;
                }
                else if ((strictNullChecks || !(flags & 98304 /* Nullable */)) && !ts.contains(typeSet, type)) {
                    typeSet.push(type);
                }
            }
            return includes;
        }
        // Add the given types to the given type set. Order is preserved, freshness is removed from literal
        // types, duplicates are removed, and nested types of the given kind are flattened into the set.
        function addTypesToIntersection(typeSet, includes, types) {
            for (var _i = 0, types_8 = types; _i < types_8.length; _i++) {
                var type = types_8[_i];
                includes = addTypeToIntersection(typeSet, includes, getRegularTypeOfLiteralType(type));
            }
            return includes;
        }
        function removeRedundantPrimitiveTypes(types, includes) {
            var i = types.length;
            while (i > 0) {
                i--;
                var t = types[i];
                var remove = t.flags & 4 /* String */ && includes & 128 /* StringLiteral */ ||
                    t.flags & 8 /* Number */ && includes & 256 /* NumberLiteral */ ||
                    t.flags & 64 /* BigInt */ && includes & 2048 /* BigIntLiteral */ ||
                    t.flags & 4096 /* ESSymbol */ && includes & 8192 /* UniqueESSymbol */;
                if (remove) {
                    ts.orderedRemoveItemAt(types, i);
                }
            }
        }
        // Check that the given type has a match in every union. A given type is matched by
        // an identical type, and a literal type is additionally matched by its corresponding
        // primitive type.
        function eachUnionContains(unionTypes, type) {
            for (var _i = 0, unionTypes_1 = unionTypes; _i < unionTypes_1.length; _i++) {
                var u = unionTypes_1[_i];
                if (!containsType(u.types, type)) {
                    var primitive = type.flags & 128 /* StringLiteral */ ? stringType :
                        type.flags & 256 /* NumberLiteral */ ? numberType :
                            type.flags & 2048 /* BigIntLiteral */ ? bigintType :
                                type.flags & 8192 /* UniqueESSymbol */ ? esSymbolType :
                                    undefined;
                    if (!primitive || !containsType(u.types, primitive)) {
                        return false;
                    }
                }
            }
            return true;
        }
        // If the given list of types contains more than one union of primitive types, replace the
        // first with a union containing an intersection of those primitive types, then remove the
        // other unions and return true. Otherwise, do nothing and return false.
        function intersectUnionsOfPrimitiveTypes(types) {
            var unionTypes;
            var index = ts.findIndex(types, function (t) { return !!(ts.getObjectFlags(t) & 65536 /* PrimitiveUnion */); });
            if (index < 0) {
                return false;
            }
            var i = index + 1;
            // Remove all but the first union of primitive types and collect them in
            // the unionTypes array.
            while (i < types.length) {
                var t = types[i];
                if (ts.getObjectFlags(t) & 65536 /* PrimitiveUnion */) {
                    (unionTypes || (unionTypes = [types[index]])).push(t);
                    ts.orderedRemoveItemAt(types, i);
                }
                else {
                    i++;
                }
            }
            // Return false if there was only one union of primitive types
            if (!unionTypes) {
                return false;
            }
            // We have more than one union of primitive types, now intersect them. For each
            // type in each union we check if the type is matched in every union and if so
            // we include it in the result.
            var checked = [];
            var result = [];
            for (var _i = 0, unionTypes_2 = unionTypes; _i < unionTypes_2.length; _i++) {
                var u = unionTypes_2[_i];
                for (var _a = 0, _b = u.types; _a < _b.length; _a++) {
                    var t = _b[_a];
                    if (insertType(checked, t)) {
                        if (eachUnionContains(unionTypes, t)) {
                            insertType(result, t);
                        }
                    }
                }
            }
            // Finally replace the first union with the result
            types[index] = getUnionTypeFromSortedList(result, 65536 /* PrimitiveUnion */);
            return true;
        }
        function createIntersectionType(types, aliasSymbol, aliasTypeArguments) {
            var result = createType(2097152 /* Intersection */);
            result.objectFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ 98304 /* Nullable */);
            result.types = types;
            result.aliasSymbol = aliasSymbol; // See comment in `getUnionTypeFromSortedList`.
            result.aliasTypeArguments = aliasTypeArguments;
            return result;
        }
        // We normalize combinations of intersection and union types based on the distributive property of the '&'
        // operator. Specifically, because X & (A | B) is equivalent to X & A | X & B, we can transform intersection
        // types with union type constituents into equivalent union types with intersection type constituents and
        // effectively ensure that union types are always at the top level in type representations.
        //
        // We do not perform structural deduplication on intersection types. Intersection types are created only by the &
        // type operator and we can't reduce those because we want to support recursive intersection types. For example,
        // a type alias of the form "type List<T> = T & { next: List<T> }" cannot be reduced during its declaration.
        // Also, unlike union types, the order of the constituent types is preserved in order that overload resolution
        // for intersections of types with signatures can be deterministic.
        function getIntersectionType(types, aliasSymbol, aliasTypeArguments) {
            var typeSet = [];
            var includes = addTypesToIntersection(typeSet, 0, types);
            if (includes & 131072 /* Never */) {
                return neverType;
            }
            if (includes & 1 /* Any */) {
                return includes & 4194304 /* IncludesWildcard */ ? wildcardType : anyType;
            }
            if (!strictNullChecks && includes & 98304 /* Nullable */) {
                return includes & 32768 /* Undefined */ ? undefinedType : nullType;
            }
            if (includes & 4 /* String */ && includes & 128 /* StringLiteral */ ||
                includes & 8 /* Number */ && includes & 256 /* NumberLiteral */ ||
                includes & 64 /* BigInt */ && includes & 2048 /* BigIntLiteral */ ||
                includes & 4096 /* ESSymbol */ && includes & 8192 /* UniqueESSymbol */) {
                removeRedundantPrimitiveTypes(typeSet, includes);
            }
            if (includes & 8388608 /* IncludesEmptyObject */ && includes & 524288 /* Object */) {
                ts.orderedRemoveItemAt(typeSet, ts.findIndex(typeSet, isEmptyAnonymousObjectType));
            }
            if (typeSet.length === 0) {
                return unknownType;
            }
            if (typeSet.length === 1) {
                return typeSet[0];
            }
            var id = getTypeListId(typeSet);
            var result = intersectionTypes.get(id);
            if (!result) {
                if (includes & 1048576 /* Union */) {
                    if (intersectUnionsOfPrimitiveTypes(typeSet)) {
                        // When the intersection creates a reduced set (which might mean that *all* union types have
                        // disappeared), we restart the operation to get a new set of combined flags. Once we have
                        // reduced we'll never reduce again, so this occurs at most once.
                        result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
                    }
                    else {
                        // We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
                        // the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
                        // If the estimated size of the resulting union type exceeds 100000 constituents, report an error.
                        var size = ts.reduceLeft(typeSet, function (n, t) { return n * (t.flags & 1048576 /* Union */ ? t.types.length : 1); }, 1);
                        if (size >= 100000) {
                            error(currentNode, ts.Diagnostics.Expression_produces_a_union_type_that_is_too_complex_to_represent);
                            return errorType;
                        }
                        var unionIndex_1 = ts.findIndex(typeSet, function (t) { return (t.flags & 1048576 /* Union */) !== 0; });
                        var unionType = typeSet[unionIndex_1];
                        result = getUnionType(ts.map(unionType.types, function (t) { return getIntersectionType(ts.replaceElement(typeSet, unionIndex_1, t)); }), 1 /* Literal */, aliasSymbol, aliasTypeArguments);
                    }
                }
                else {
                    result = createIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
                }
                intersectionTypes.set(id, result);
            }
            return result;
        }
        function getTypeFromIntersectionTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var aliasSymbol = getAliasSymbolForTypeNode(node);
                links.resolvedType = getIntersectionType(ts.map(node.types, getTypeFromTypeNode), aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol));
            }
            return links.resolvedType;
        }
        function createIndexType(type, stringsOnly) {
            var result = createType(4194304 /* Index */);
            result.type = type;
            result.stringsOnly = stringsOnly;
            return result;
        }
        function getIndexTypeForGenericType(type, stringsOnly) {
            return stringsOnly ?
                type.resolvedStringIndexType || (type.resolvedStringIndexType = createIndexType(type, /*stringsOnly*/ true)) :
                type.resolvedIndexType || (type.resolvedIndexType = createIndexType(type, /*stringsOnly*/ false));
        }
        function getLiteralTypeFromPropertyName(name) {
            return ts.isIdentifier(name) ? getLiteralType(ts.unescapeLeadingUnderscores(name.escapedText)) :
                getRegularTypeOfLiteralType(ts.isComputedPropertyName(name) ? checkComputedPropertyName(name) : checkExpression(name));
        }
        function getBigIntLiteralType(node) {
            return getLiteralType({
                negative: false,
                base10Value: ts.parsePseudoBigInt(node.text)
            });
        }
        function getLiteralTypeFromProperty(prop, include) {
            if (!(ts.getDeclarationModifierFlagsFromSymbol(prop) & 24 /* NonPublicAccessibilityModifier */)) {
                var type = getLateBoundSymbol(prop).nameType;
                if (!type && !ts.isKnownSymbol(prop)) {
                    if (prop.escapedName === "default" /* Default */) {
                        type = getLiteralType("default");
                    }
                    else {
                        var name = prop.valueDeclaration && ts.getNameOfDeclaration(prop.valueDeclaration);
                        type = name && getLiteralTypeFromPropertyName(name) || getLiteralType(ts.symbolName(prop));
                    }
                }
                if (type && type.flags & include) {
                    return type;
                }
            }
            return neverType;
        }
        function getLiteralTypeFromProperties(type, include) {
            return getUnionType(ts.map(getPropertiesOfType(type), function (p) { return getLiteralTypeFromProperty(p, include); }));
        }
        function getNonEnumNumberIndexInfo(type) {
            var numberIndexInfo = getIndexInfoOfType(type, 1 /* Number */);
            return numberIndexInfo !== enumNumberIndexInfo ? numberIndexInfo : undefined;
        }
        function getIndexType(type, stringsOnly, noIndexSignatures) {
            if (stringsOnly === void 0) { stringsOnly = keyofStringsOnly; }
            return type.flags & 1048576 /* Union */ ? getIntersectionType(ts.map(type.types, function (t) { return getIndexType(t, stringsOnly, noIndexSignatures); })) :
                type.flags & 2097152 /* Intersection */ ? getUnionType(ts.map(type.types, function (t) { return getIndexType(t, stringsOnly, noIndexSignatures); })) :
                    maybeTypeOfKind(type, 58982400 /* InstantiableNonPrimitive */) ? getIndexTypeForGenericType(type, stringsOnly) :
                        ts.getObjectFlags(type) & 32 /* Mapped */ ? filterType(getConstraintTypeFromMappedType(type), function (t) { return !(noIndexSignatures && t.flags & (1 /* Any */ | 4 /* String */)); }) :
                            type === wildcardType ? wildcardType :
                                type.flags & 2 /* Unknown */ ? neverType :
                                    type.flags & (1 /* Any */ | 131072 /* Never */) ? keyofConstraintType :
                                        stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, 0 /* String */) ? stringType : getLiteralTypeFromProperties(type, 128 /* StringLiteral */) :
                                            !noIndexSignatures && getIndexInfoOfType(type, 0 /* String */) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, 8192 /* UniqueESSymbol */)]) :
                                                getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, 128 /* StringLiteral */ | 8192 /* UniqueESSymbol */)]) :
                                                    getLiteralTypeFromProperties(type, 8576 /* StringOrNumberLiteralOrUnique */);
        }
        function getExtractStringType(type) {
            if (keyofStringsOnly) {
                return type;
            }
            var extractTypeAlias = getGlobalExtractSymbol();
            return extractTypeAlias ? getTypeAliasInstantiation(extractTypeAlias, [type, stringType]) : stringType;
        }
        function getIndexTypeOrString(type) {
            var indexType = getExtractStringType(getIndexType(type));
            return indexType.flags & 131072 /* Never */ ? stringType : indexType;
        }
        function getTypeFromTypeOperatorNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                switch (node.operator) {
                    case 130 /* KeyOfKeyword */:
                        links.resolvedType = getIndexType(getTypeFromTypeNode(node.type));
                        break;
                    case 143 /* UniqueKeyword */:
                        links.resolvedType = node.type.kind === 140 /* SymbolKeyword */
                            ? getESSymbolLikeTypeForNode(ts.walkUpParenthesizedTypes(node.parent))
                            : errorType;
                        break;
                    case 134 /* ReadonlyKeyword */:
                        links.resolvedType = getTypeFromTypeNode(node.type);
                        break;
                }
            }
            return links.resolvedType; // TODO: GH#18217
        }
        function createIndexedAccessType(objectType, indexType) {
            var type = createType(8388608 /* IndexedAccess */);
            type.objectType = objectType;
            type.indexType = indexType;
            return type;
        }
        /**
         * Returns if a type is or consists of a JSLiteral object type
         * In addition to objects which are directly literals,
         * * unions where every element is a jsliteral
         * * intersections where at least one element is a jsliteral
         * * and instantiable types constrained to a jsliteral
         * Should all count as literals and not print errors on access or assignment of possibly existing properties.
         * This mirrors the behavior of the index signature propagation, to which this behaves similarly (but doesn't affect assignability or inference).
         */
        function isJSLiteralType(type) {
            if (noImplicitAny) {
                return false; // Flag is meaningless under `noImplicitAny` mode
            }
            if (ts.getObjectFlags(type) & 16384 /* JSLiteral */) {
                return true;
            }
            if (type.flags & 1048576 /* Union */) {
                return ts.every(type.types, isJSLiteralType);
            }
            if (type.flags & 2097152 /* Intersection */) {
                return ts.some(type.types, isJSLiteralType);
            }
            if (type.flags & 63176704 /* Instantiable */) {
                return isJSLiteralType(getResolvedBaseConstraint(type));
            }
            return false;
        }
        function getPropertyTypeForIndexType(originalObjectType, objectType, indexType, fullIndexType, suppressNoImplicitAnyError, accessNode, accessFlags) {
            var accessExpression = accessNode && accessNode.kind === 191 /* ElementAccessExpression */ ? accessNode : undefined;
            var propName = isTypeUsableAsPropertyName(indexType) ?
                getPropertyNameFromType(indexType) :
                accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
                    ts.getPropertyNameForKnownSymbolName(ts.idText(accessExpression.argumentExpression.name)) :
                    accessNode && ts.isPropertyName(accessNode) ?
                        // late bound names are handled in the first branch, so here we only need to handle normal names
                        ts.getPropertyNameForPropertyNameNode(accessNode) :
                        undefined;
            if (propName !== undefined) {
                var prop = getPropertyOfType(objectType, propName);
                if (prop) {
                    if (accessExpression) {
                        markPropertyAsReferenced(prop, accessExpression, /*isThisAccess*/ accessExpression.expression.kind === 101 /* ThisKeyword */);
                        if (ts.isAssignmentTarget(accessExpression) && (isReferenceToReadonlyEntity(accessExpression, prop) || isReferenceThroughNamespaceImport(accessExpression))) {
                            error(accessExpression.argumentExpression, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, symbolToString(prop));
                            return undefined;
                        }
                        if (accessFlags & 4 /* CacheSymbol */) {
                            getNodeLinks(accessNode).resolvedSymbol = prop;
                        }
                    }
                    var propType = getTypeOfSymbol(prop);
                    return accessExpression && ts.getAssignmentTargetKind(accessExpression) !== 1 /* Definite */ ?
                        getFlowTypeOfReference(accessExpression, propType) :
                        propType;
                }
                if (everyType(objectType, isTupleType) && isNumericLiteralName(propName) && +propName >= 0) {
                    if (accessNode && everyType(objectType, function (t) { return !t.target.hasRestElement; })) {
                        var indexNode = getIndexNodeForAccessExpression(accessNode);
                        if (isTupleType(objectType)) {
                            error(indexNode, ts.Diagnostics.Tuple_type_0_of_length_1_has_no_element_at_index_2, typeToString(objectType), getTypeReferenceArity(objectType), ts.unescapeLeadingUnderscores(propName));
                        }
                        else {
                            error(indexNode, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.unescapeLeadingUnderscores(propName), typeToString(objectType));
                        }
                    }
                    errorIfWritingToReadonlyIndex(getIndexInfoOfType(objectType, 1 /* Number */));
                    return mapType(objectType, function (t) { return getRestTypeOfTupleType(t) || undefinedType; });
                }
            }
            if (!(indexType.flags & 98304 /* Nullable */) && isTypeAssignableToKind(indexType, 132 /* StringLike */ | 296 /* NumberLike */ | 12288 /* ESSymbolLike */)) {
                if (objectType.flags & (1 /* Any */ | 131072 /* Never */)) {
                    return objectType;
                }
                var stringIndexInfo = getIndexInfoOfType(objectType, 0 /* String */);
                var indexInfo = isTypeAssignableToKind(indexType, 296 /* NumberLike */) && getIndexInfoOfType(objectType, 1 /* Number */) || stringIndexInfo;
                if (indexInfo) {
                    if (accessFlags & 1 /* NoIndexSignatures */ && indexInfo === stringIndexInfo) {
                        if (accessExpression) {
                            error(accessExpression, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(originalObjectType));
                        }
                        return undefined;
                    }
                    if (accessNode && !isTypeAssignableToKind(indexType, 4 /* String */ | 8 /* Number */)) {
                        var indexNode = getIndexNodeForAccessExpression(accessNode);
                        error(indexNode, ts.Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType));
                        return indexInfo.type;
                    }
                    errorIfWritingToReadonlyIndex(indexInfo);
                    return indexInfo.type;
                }
                if (indexType.flags & 131072 /* Never */) {
                    return neverType;
                }
                if (isJSLiteralType(objectType)) {
                    return anyType;
                }
                if (accessExpression && !isConstEnumObjectType(objectType)) {
                    if (objectType.symbol === globalThisSymbol && propName !== undefined && globalThisSymbol.exports.has(propName) && (globalThisSymbol.exports.get(propName).flags & 418 /* BlockScoped */)) {
                        error(accessExpression, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.unescapeLeadingUnderscores(propName), typeToString(objectType));
                    }
                    else if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors && !suppressNoImplicitAnyError) {
                        if (propName !== undefined && typeHasStaticProperty(propName, objectType)) {
                            error(accessExpression, ts.Diagnostics.Property_0_is_a_static_member_of_type_1, propName, typeToString(objectType));
                        }
                        else if (getIndexTypeOfType(objectType, 1 /* Number */)) {
                            error(accessExpression.argumentExpression, ts.Diagnostics.Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number);
                        }
                        else {
                            var suggestion = void 0;
                            if (propName !== undefined && (suggestion = getSuggestionForNonexistentProperty(propName, objectType))) {
                                if (suggestion !== undefined) {
                                    error(accessExpression.argumentExpression, ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, propName, typeToString(objectType), suggestion);
                                }
                            }
                            else {
                                var suggestion_1 = getSuggestionForNonexistentIndexSignature(objectType, accessExpression);
                                if (suggestion_1 !== undefined) {
                                    error(accessExpression, ts.Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1, typeToString(objectType), suggestion_1);
                                }
                                else {
                                    var errorInfo = void 0;
                                    if (indexType.flags & 1024 /* EnumLiteral */) {
                                        errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, "[" + typeToString(indexType) + "]", typeToString(objectType));
                                    }
                                    else if (indexType.flags & 8192 /* UniqueESSymbol */) {
                                        var symbolName_2 = getFullyQualifiedName(indexType.symbol, accessExpression);
                                        errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, "[" + symbolName_2 + "]", typeToString(objectType));
                                    }
                                    else if (indexType.flags & 128 /* StringLiteral */) {
                                        errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, indexType.value, typeToString(objectType));
                                    }
                                    else if (indexType.flags & 256 /* NumberLiteral */) {
                                        errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, indexType.value, typeToString(objectType));
                                    }
                                    else if (indexType.flags & (8 /* Number */ | 4 /* String */)) {
                                        errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.No_index_signature_with_a_parameter_of_type_0_was_found_on_type_1, typeToString(indexType), typeToString(objectType));
                                    }
                                    errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Element_implicitly_has_an_any_type_because_expression_of_type_0_can_t_be_used_to_index_type_1, typeToString(fullIndexType), typeToString(objectType));
                                    diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(accessExpression, errorInfo));
                                }
                            }
                        }
                    }
                    return undefined;
                }
            }
            if (isJSLiteralType(objectType)) {
                return anyType;
            }
            if (accessNode) {
                var indexNode = getIndexNodeForAccessExpression(accessNode);
                if (indexType.flags & (128 /* StringLiteral */ | 256 /* NumberLiteral */)) {
                    error(indexNode, ts.Diagnostics.Property_0_does_not_exist_on_type_1, "" + indexType.value, typeToString(objectType));
                }
                else if (indexType.flags & (4 /* String */ | 8 /* Number */)) {
                    error(indexNode, ts.Diagnostics.Type_0_has_no_matching_index_signature_for_type_1, typeToString(objectType), typeToString(indexType));
                }
                else {
                    error(indexNode, ts.Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType));
                }
            }
            if (isTypeAny(indexType)) {
                return indexType;
            }
            return undefined;
            function errorIfWritingToReadonlyIndex(indexInfo) {
                if (indexInfo && indexInfo.isReadonly && accessExpression && (ts.isAssignmentTarget(accessExpression) || ts.isDeleteTarget(accessExpression))) {
                    error(accessExpression, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
                }
            }
        }
        function getIndexNodeForAccessExpression(accessNode) {
            return accessNode.kind === 191 /* ElementAccessExpression */
                ? accessNode.argumentExpression
                : accessNode.kind === 181 /* IndexedAccessType */
                    ? accessNode.indexType
                    : accessNode.kind === 150 /* ComputedPropertyName */
                        ? accessNode.expression
                        : accessNode;
        }
        function isGenericObjectType(type) {
            return maybeTypeOfKind(type, 58982400 /* InstantiableNonPrimitive */ | 131072 /* GenericMappedType */);
        }
        function isGenericIndexType(type) {
            return maybeTypeOfKind(type, 58982400 /* InstantiableNonPrimitive */ | 4194304 /* Index */);
        }
        function isThisTypeParameter(type) {
            return !!(type.flags & 262144 /* TypeParameter */ && type.isThisType);
        }
        function getSimplifiedType(type, writing) {
            return type.flags & 8388608 /* IndexedAccess */ ? getSimplifiedIndexedAccessType(type, writing) :
                type.flags & 16777216 /* Conditional */ ? getSimplifiedConditionalType(type, writing) :
                    type;
        }
        function distributeIndexOverObjectType(objectType, indexType, writing) {
            // (T | U)[K] -> T[K] | U[K] (reading)
            // (T | U)[K] -> T[K] & U[K] (writing)
            // (T & U)[K] -> T[K] & U[K]
            if (objectType.flags & 3145728 /* UnionOrIntersection */) {
                var types = ts.map(objectType.types, function (t) { return getSimplifiedType(getIndexedAccessType(t, indexType), writing); });
                return objectType.flags & 2097152 /* Intersection */ || writing ? getIntersectionType(types) : getUnionType(types);
            }
        }
        function distributeObjectOverIndexType(objectType, indexType, writing) {
            // T[A | B] -> T[A] | T[B] (reading)
            // T[A | B] -> T[A] & T[B] (writing)
            if (indexType.flags & 1048576 /* Union */) {
                var types = ts.map(indexType.types, function (t) { return getSimplifiedType(getIndexedAccessType(objectType, t), writing); });
                return writing ? getIntersectionType(types) : getUnionType(types);
            }
        }
        // Transform an indexed access to a simpler form, if possible. Return the simpler form, or return
        // the type itself if no transformation is possible. The writing flag indicates that the type is
        // the target of an assignment.
        function getSimplifiedIndexedAccessType(type, writing) {
            var cache = writing ? "simplifiedForWriting" : "simplifiedForReading";
            if (type[cache]) {
                return type[cache] === circularConstraintType ? type : type[cache];
            }
            type[cache] = circularConstraintType;
            // We recursively simplify the object type as it may in turn be an indexed access type. For example, with
            // '{ [P in T]: { [Q in U]: number } }[T][U]' we want to first simplify the inner indexed access type.
            var objectType = getSimplifiedType(type.objectType, writing);
            var indexType = getSimplifiedType(type.indexType, writing);
            // T[A | B] -> T[A] | T[B] (reading)
            // T[A | B] -> T[A] & T[B] (writing)
            var distributedOverIndex = distributeObjectOverIndexType(objectType, indexType, writing);
            if (distributedOverIndex) {
                return type[cache] = distributedOverIndex;
            }
            // Only do the inner distributions if the index can no longer be instantiated to cause index distribution again
            if (!(indexType.flags & 63176704 /* Instantiable */)) {
                // (T | U)[K] -> T[K] | U[K] (reading)
                // (T | U)[K] -> T[K] & U[K] (writing)
                // (T & U)[K] -> T[K] & U[K]
                var distributedOverObject = distributeIndexOverObjectType(objectType, indexType, writing);
                if (distributedOverObject) {
                    return type[cache] = distributedOverObject;
                }
            }
            // So ultimately (reading):
            // ((A & B) | C)[K1 | K2] -> ((A & B) | C)[K1] | ((A & B) | C)[K2] -> (A & B)[K1] | C[K1] | (A & B)[K2] | C[K2] -> (A[K1] & B[K1]) | C[K1] | (A[K2] & B[K2]) | C[K2]
            // If the object type is a mapped type { [P in K]: E }, where K is generic, instantiate E using a mapper
            // that substitutes the index type for P. For example, for an index access { [P in K]: Box<T[P]> }[X], we
            // construct the type Box<T[X]>.
            if (isGenericMappedType(objectType)) {
                return type[cache] = mapType(substituteIndexedMappedType(objectType, type.indexType), function (t) { return getSimplifiedType(t, writing); });
            }
            return type[cache] = type;
        }
        function getSimplifiedConditionalType(type, writing) {
            var checkType = type.checkType;
            var extendsType = type.extendsType;
            var trueType = getTrueTypeFromConditionalType(type);
            var falseType = getFalseTypeFromConditionalType(type);
            // Simplifications for types of the form `T extends U ? T : never` and `T extends U ? never : T`.
            if (falseType.flags & 131072 /* Never */ && getActualTypeVariable(trueType) === getActualTypeVariable(checkType)) {
                if (checkType.flags & 1 /* Any */ || isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(extendsType))) { // Always true
                    return getSimplifiedType(trueType, writing);
                }
                else if (isIntersectionEmpty(checkType, extendsType)) { // Always false
                    return neverType;
                }
            }
            else if (trueType.flags & 131072 /* Never */ && getActualTypeVariable(falseType) === getActualTypeVariable(checkType)) {
                if (!(checkType.flags & 1 /* Any */) && isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(extendsType))) { // Always true
                    return neverType;
                }
                else if (checkType.flags & 1 /* Any */ || isIntersectionEmpty(checkType, extendsType)) { // Always false
                    return getSimplifiedType(falseType, writing);
                }
            }
            return type;
        }
        /**
         * Invokes union simplification logic to determine if an intersection is considered empty as a union constituent
         */
        function isIntersectionEmpty(type1, type2) {
            return !!(getUnionType([intersectTypes(type1, type2), neverType]).flags & 131072 /* Never */);
        }
        function substituteIndexedMappedType(objectType, index) {
            var mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [index]);
            var templateMapper = combineTypeMappers(objectType.mapper, mapper);
            return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper);
        }
        function getIndexedAccessType(objectType, indexType, accessNode) {
            return getIndexedAccessTypeOrUndefined(objectType, indexType, accessNode, 0 /* None */) || (accessNode ? errorType : unknownType);
        }
        function getIndexedAccessTypeOrUndefined(objectType, indexType, accessNode, accessFlags) {
            if (accessFlags === void 0) { accessFlags = 0 /* None */; }
            if (objectType === wildcardType || indexType === wildcardType) {
                return wildcardType;
            }
            // If the object type has a string index signature and no other members we know that the result will
            // always be the type of that index signature and we can simplify accordingly.
            if (isStringIndexSignatureOnlyType(objectType) && !(indexType.flags & 98304 /* Nullable */) && isTypeAssignableToKind(indexType, 4 /* String */ | 8 /* Number */)) {
                indexType = stringType;
            }
            // If the index type is generic, or if the object type is generic and doesn't originate in an expression,
            // we are performing a higher-order index access where we cannot meaningfully access the properties of the
            // object type. Note that for a generic T and a non-generic K, we eagerly resolve T[K] if it originates in
            // an expression. This is to preserve backwards compatibility. For example, an element access 'this["foo"]'
            // has always been resolved eagerly using the constraint type of 'this' at the given location.
            if (isGenericIndexType(indexType) || !(accessNode && accessNode.kind !== 181 /* IndexedAccessType */) && isGenericObjectType(objectType)) {
                if (objectType.flags & 3 /* AnyOrUnknown */) {
                    return objectType;
                }
                // Defer the operation by creating an indexed access type.
                var id = objectType.id + "," + indexType.id;
                var type = indexedAccessTypes.get(id);
                if (!type) {
                    indexedAccessTypes.set(id, type = createIndexedAccessType(objectType, indexType));
                }
                return type;
            }
            // In the following we resolve T[K] to the type of the property in T selected by K.
            // We treat boolean as different from other unions to improve errors;
            // skipping straight to getPropertyTypeForIndexType gives errors with 'boolean' instead of 'true'.
            var apparentObjectType = getApparentType(objectType);
            if (indexType.flags & 1048576 /* Union */ && !(indexType.flags & 16 /* Boolean */)) {
                var propTypes = [];
                var wasMissingProp = false;
                for (var _i = 0, _a = indexType.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    var propType = getPropertyTypeForIndexType(objectType, apparentObjectType, t, indexType, wasMissingProp, accessNode, accessFlags);
                    if (propType) {
                        propTypes.push(propType);
                    }
                    else if (!accessNode) {
                        // If there's no error node, we can immeditely stop, since error reporting is off
                        return undefined;
                    }
                    else {
                        // Otherwise we set a flag and return at the end of the loop so we still mark all errors
                        wasMissingProp = true;
                    }
                }
                if (wasMissingProp) {
                    return undefined;
                }
                return accessFlags & 2 /* Writing */ ? getIntersectionType(propTypes) : getUnionType(propTypes);
            }
            return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, indexType, /* supressNoImplicitAnyError */ false, accessNode, accessFlags | 4 /* CacheSymbol */);
        }
        function getTypeFromIndexedAccessTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var objectType = getTypeFromTypeNode(node.objectType);
                var indexType = getTypeFromTypeNode(node.indexType);
                var resolved = getIndexedAccessType(objectType, indexType, node);
                links.resolvedType = resolved.flags & 8388608 /* IndexedAccess */ &&
                    resolved.objectType === objectType &&
                    resolved.indexType === indexType ?
                    getConstrainedTypeVariable(resolved, node) : resolved;
            }
            return links.resolvedType;
        }
        function getTypeFromMappedTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var type = createObjectType(32 /* Mapped */, node.symbol);
                type.declaration = node;
                type.aliasSymbol = getAliasSymbolForTypeNode(node);
                type.aliasTypeArguments = getTypeArgumentsForAliasSymbol(type.aliasSymbol);
                links.resolvedType = type;
                // Eagerly resolve the constraint type which forces an error if the constraint type circularly
                // references itself through one or more type aliases.
                getConstraintTypeFromMappedType(type);
            }
            return links.resolvedType;
        }
        function getActualTypeVariable(type) {
            if (type.flags & 33554432 /* Substitution */) {
                return type.typeVariable;
            }
            if (type.flags & 8388608 /* IndexedAccess */ && (type.objectType.flags & 33554432 /* Substitution */ ||
                type.indexType.flags & 33554432 /* Substitution */)) {
                return getIndexedAccessType(getActualTypeVariable(type.objectType), getActualTypeVariable(type.indexType));
            }
            return type;
        }
        function getConditionalType(root, mapper) {
            var checkType = instantiateType(root.checkType, mapper);
            var extendsType = instantiateType(root.extendsType, mapper);
            if (checkType === wildcardType || extendsType === wildcardType) {
                return wildcardType;
            }
            var checkTypeInstantiable = maybeTypeOfKind(checkType, 63176704 /* Instantiable */ | 131072 /* GenericMappedType */);
            var combinedMapper;
            if (root.inferTypeParameters) {
                var context = createInferenceContext(root.inferTypeParameters, /*signature*/ undefined, 0 /* None */);
                if (!checkTypeInstantiable) {
                    // We don't want inferences from constraints as they may cause us to eagerly resolve the
                    // conditional type instead of deferring resolution. Also, we always want strict function
                    // types rules (i.e. proper contravariance) for inferences.
                    inferTypes(context.inferences, checkType, extendsType, 64 /* NoConstraints */ | 128 /* AlwaysStrict */);
                }
                combinedMapper = combineTypeMappers(mapper, context.mapper);
            }
            // Instantiate the extends type including inferences for 'infer T' type parameters
            var inferredExtendsType = combinedMapper ? instantiateType(root.extendsType, combinedMapper) : extendsType;
            // We attempt to resolve the conditional type only when the check and extends types are non-generic
            if (!checkTypeInstantiable && !maybeTypeOfKind(inferredExtendsType, 63176704 /* Instantiable */ | 131072 /* GenericMappedType */)) {
                if (inferredExtendsType.flags & 3 /* AnyOrUnknown */) {
                    return instantiateType(root.trueType, combinedMapper || mapper);
                }
                // Return union of trueType and falseType for 'any' since it matches anything
                if (checkType.flags & 1 /* Any */) {
                    return getUnionType([instantiateType(root.trueType, combinedMapper || mapper), instantiateType(root.falseType, mapper)]);
                }
                // Return falseType for a definitely false extends check. We check an instantiations of the two
                // types with type parameters mapped to the wildcard type, the most permissive instantiations
                // possible (the wildcard type is assignable to and from all types). If those are not related,
                // then no instantiations will be and we can just return the false branch type.
                if (!isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType))) {
                    return instantiateType(root.falseType, mapper);
                }
                // Return trueType for a definitely true extends check. We check instantiations of the two
                // types with type parameters mapped to their restrictive form, i.e. a form of the type parameter
                // that has no constraint. This ensures that, for example, the type
                //   type Foo<T extends { x: any }> = T extends { x: string } ? string : number
                // doesn't immediately resolve to 'string' instead of being deferred.
                if (isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(inferredExtendsType))) {
                    return instantiateType(root.trueType, combinedMapper || mapper);
                }
            }
            // Return a deferred type for a check that is neither definitely true nor definitely false
            var erasedCheckType = getActualTypeVariable(checkType);
            var result = createType(16777216 /* Conditional */);
            result.root = root;
            result.checkType = erasedCheckType;
            result.extendsType = extendsType;
            result.mapper = mapper;
            result.combinedMapper = combinedMapper;
            result.aliasSymbol = root.aliasSymbol;
            result.aliasTypeArguments = instantiateTypes(root.aliasTypeArguments, mapper); // TODO: GH#18217
            return result;
        }
        function getTrueTypeFromConditionalType(type) {
            return type.resolvedTrueType || (type.resolvedTrueType = instantiateType(type.root.trueType, type.mapper));
        }
        function getFalseTypeFromConditionalType(type) {
            return type.resolvedFalseType || (type.resolvedFalseType = instantiateType(type.root.falseType, type.mapper));
        }
        function getInferredTrueTypeFromConditionalType(type) {
            return type.resolvedInferredTrueType || (type.resolvedInferredTrueType = type.combinedMapper ? instantiateType(type.root.trueType, type.combinedMapper) : getTrueTypeFromConditionalType(type));
        }
        function getInferTypeParameters(node) {
            var result;
            if (node.locals) {
                node.locals.forEach(function (symbol) {
                    if (symbol.flags & 262144 /* TypeParameter */) {
                        result = ts.append(result, getDeclaredTypeOfSymbol(symbol));
                    }
                });
            }
            return result;
        }
        function getTypeFromConditionalTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var checkType = getTypeFromTypeNode(node.checkType);
                var aliasSymbol = getAliasSymbolForTypeNode(node);
                var aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol);
                var allOuterTypeParameters = getOuterTypeParameters(node, /*includeThisTypes*/ true);
                var outerTypeParameters = aliasTypeArguments ? allOuterTypeParameters : ts.filter(allOuterTypeParameters, function (tp) { return isTypeParameterPossiblyReferenced(tp, node); });
                var root = {
                    node: node,
                    checkType: checkType,
                    extendsType: getTypeFromTypeNode(node.extendsType),
                    trueType: getTypeFromTypeNode(node.trueType),
                    falseType: getTypeFromTypeNode(node.falseType),
                    isDistributive: !!(checkType.flags & 262144 /* TypeParameter */),
                    inferTypeParameters: getInferTypeParameters(node),
                    outerTypeParameters: outerTypeParameters,
                    instantiations: undefined,
                    aliasSymbol: aliasSymbol,
                    aliasTypeArguments: aliasTypeArguments
                };
                links.resolvedType = getConditionalType(root, /*mapper*/ undefined);
                if (outerTypeParameters) {
                    root.instantiations = ts.createMap();
                    root.instantiations.set(getTypeListId(outerTypeParameters), links.resolvedType);
                }
            }
            return links.resolvedType;
        }
        function getTypeFromInferTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter));
            }
            return links.resolvedType;
        }
        function getIdentifierChain(node) {
            if (ts.isIdentifier(node)) {
                return [node];
            }
            else {
                return ts.append(getIdentifierChain(node.left), node.right);
            }
        }
        function getTypeFromImportTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                if (node.isTypeOf && node.typeArguments) { // Only the non-typeof form can make use of type arguments
                    error(node, ts.Diagnostics.Type_arguments_cannot_be_used_here);
                    links.resolvedSymbol = unknownSymbol;
                    return links.resolvedType = errorType;
                }
                if (!ts.isLiteralImportTypeNode(node)) {
                    error(node.argument, ts.Diagnostics.String_literal_expected);
                    links.resolvedSymbol = unknownSymbol;
                    return links.resolvedType = errorType;
                }
                var targetMeaning = node.isTypeOf ? 67220415 /* Value */ : node.flags & 2097152 /* JSDoc */ ? 67220415 /* Value */ | 67897832 /* Type */ : 67897832 /* Type */;
                // TODO: Future work: support unions/generics/whatever via a deferred import-type
                var innerModuleSymbol = resolveExternalModuleName(node, node.argument.literal);
                if (!innerModuleSymbol) {
                    links.resolvedSymbol = unknownSymbol;
                    return links.resolvedType = errorType;
                }
                var moduleSymbol = resolveExternalModuleSymbol(innerModuleSymbol, /*dontResolveAlias*/ false);
                if (!ts.nodeIsMissing(node.qualifier)) {
                    var nameStack = getIdentifierChain(node.qualifier);
                    var currentNamespace = moduleSymbol;
                    var current = void 0;
                    while (current = nameStack.shift()) {
                        var meaning = nameStack.length ? 1920 /* Namespace */ : targetMeaning;
                        var next = getSymbol(getExportsOfSymbol(getMergedSymbol(resolveSymbol(currentNamespace))), current.escapedText, meaning);
                        if (!next) {
                            error(current, ts.Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(currentNamespace), ts.declarationNameToString(current));
                            return links.resolvedType = errorType;
                        }
                        getNodeLinks(current).resolvedSymbol = next;
                        getNodeLinks(current.parent).resolvedSymbol = next;
                        currentNamespace = next;
                    }
                    resolveImportSymbolType(node, links, currentNamespace, targetMeaning);
                }
                else {
                    if (moduleSymbol.flags & targetMeaning) {
                        resolveImportSymbolType(node, links, moduleSymbol, targetMeaning);
                    }
                    else {
                        var errorMessage = targetMeaning === 67220415 /* Value */
                            ? ts.Diagnostics.Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here
                            : ts.Diagnostics.Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0;
                        error(node, errorMessage, node.argument.literal.text);
                        links.resolvedSymbol = unknownSymbol;
                        links.resolvedType = errorType;
                    }
                }
            }
            return links.resolvedType; // TODO: GH#18217
        }
        function resolveImportSymbolType(node, links, symbol, meaning) {
            var resolvedSymbol = resolveSymbol(symbol);
            links.resolvedSymbol = resolvedSymbol;
            if (meaning === 67220415 /* Value */) {
                return links.resolvedType = getTypeOfSymbol(symbol); // intentionally doesn't use resolved symbol so type is cached as expected on the alias
            }
            else {
                return links.resolvedType = getTypeReferenceType(node, resolvedSymbol); // getTypeReferenceType doesn't handle aliases - it must get the resolved symbol
            }
        }
        function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                // Deferred resolution of members is handled by resolveObjectTypeMembers
                var aliasSymbol = getAliasSymbolForTypeNode(node);
                if (getMembersOfSymbol(node.symbol).size === 0 && !aliasSymbol) {
                    links.resolvedType = emptyTypeLiteralType;
                }
                else {
                    var type = createObjectType(16 /* Anonymous */, node.symbol);
                    type.aliasSymbol = aliasSymbol;
                    type.aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol);
                    if (ts.isJSDocTypeLiteral(node) && node.isArrayType) {
                        type = createArrayType(type);
                    }
                    links.resolvedType = type;
                }
            }
            return links.resolvedType;
        }
        function getAliasSymbolForTypeNode(node) {
            return ts.isTypeAlias(node.parent) ? getSymbolOfNode(node.parent) : undefined;
        }
        function getTypeArgumentsForAliasSymbol(symbol) {
            return symbol ? getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) : undefined;
        }
        function isNonGenericObjectType(type) {
            return !!(type.flags & 524288 /* Object */) && !isGenericMappedType(type);
        }
        /**
         * Since the source of spread types are object literals, which are not binary,
         * this function should be called in a left folding style, with left = previous result of getSpreadType
         * and right = the new element to be spread.
         */
        function getSpreadType(left, right, symbol, objectFlags, readonly) {
            if (left.flags & 1 /* Any */ || right.flags & 1 /* Any */) {
                return anyType;
            }
            if (left.flags & 2 /* Unknown */ || right.flags & 2 /* Unknown */) {
                return unknownType;
            }
            if (left.flags & 131072 /* Never */) {
                return right;
            }
            if (right.flags & 131072 /* Never */) {
                return left;
            }
            if (left.flags & 1048576 /* Union */) {
                return mapType(left, function (t) { return getSpreadType(t, right, symbol, objectFlags, readonly); });
            }
            if (right.flags & 1048576 /* Union */) {
                return mapType(right, function (t) { return getSpreadType(left, t, symbol, objectFlags, readonly); });
            }
            if (right.flags & (528 /* BooleanLike */ | 296 /* NumberLike */ | 2112 /* BigIntLike */ | 132 /* StringLike */ | 1056 /* EnumLike */ | 67108864 /* NonPrimitive */ | 4194304 /* Index */)) {
                return left;
            }
            if (isGenericObjectType(left) || isGenericObjectType(right)) {
                if (isEmptyObjectType(left)) {
                    return right;
                }
                // When the left type is an intersection, we may need to merge the last constituent of the
                // intersection with the right type. For example when the left type is 'T & { a: string }'
                // and the right type is '{ b: string }' we produce 'T & { a: string, b: string }'.
                if (left.flags & 2097152 /* Intersection */) {
                    var types = left.types;
                    var lastLeft = types[types.length - 1];
                    if (isNonGenericObjectType(lastLeft) && isNonGenericObjectType(right)) {
                        return getIntersectionType(ts.concatenate(types.slice(0, types.length - 1), [getSpreadType(lastLeft, right, symbol, objectFlags, readonly)]));
                    }
                }
                return getIntersectionType([left, right]);
            }
            var members = ts.createSymbolTable();
            var skippedPrivateMembers = ts.createUnderscoreEscapedMap();
            var stringIndexInfo;
            var numberIndexInfo;
            if (left === emptyObjectType) {
                // for the first spread element, left === emptyObjectType, so take the right's string indexer
                stringIndexInfo = getIndexInfoOfType(right, 0 /* String */);
                numberIndexInfo = getIndexInfoOfType(right, 1 /* Number */);
            }
            else {
                stringIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, 0 /* String */), getIndexInfoOfType(right, 0 /* String */));
                numberIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, 1 /* Number */), getIndexInfoOfType(right, 1 /* Number */));
            }
            for (var _i = 0, _a = getPropertiesOfType(right); _i < _a.length; _i++) {
                var rightProp = _a[_i];
                if (ts.getDeclarationModifierFlagsFromSymbol(rightProp) & (8 /* Private */ | 16 /* Protected */)) {
                    skippedPrivateMembers.set(rightProp.escapedName, true);
                }
                else if (isSpreadableProperty(rightProp)) {
                    members.set(rightProp.escapedName, getSpreadSymbol(rightProp, readonly));
                }
            }
            for (var _b = 0, _c = getPropertiesOfType(left); _b < _c.length; _b++) {
                var leftProp = _c[_b];
                if (skippedPrivateMembers.has(leftProp.escapedName) || !isSpreadableProperty(leftProp)) {
                    continue;
                }
                if (members.has(leftProp.escapedName)) {
                    var rightProp = members.get(leftProp.escapedName);
                    var rightType = getTypeOfSymbol(rightProp);
                    if (rightProp.flags & 16777216 /* Optional */) {
                        var declarations = ts.concatenate(leftProp.declarations, rightProp.declarations);
                        var flags = 4 /* Property */ | (leftProp.flags & 16777216 /* Optional */);
                        var result = createSymbol(flags, leftProp.escapedName);
                        result.type = getUnionType([getTypeOfSymbol(leftProp), getTypeWithFacts(rightType, 524288 /* NEUndefined */)]);
                        result.leftSpread = leftProp;
                        result.rightSpread = rightProp;
                        result.declarations = declarations;
                        result.nameType = leftProp.nameType;
                        members.set(leftProp.escapedName, result);
                    }
                }
                else {
                    members.set(leftProp.escapedName, getSpreadSymbol(leftProp, readonly));
                }
            }
            var spread = createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, getIndexInfoWithReadonly(stringIndexInfo, readonly), getIndexInfoWithReadonly(numberIndexInfo, readonly));
            spread.objectFlags |= 128 /* ObjectLiteral */ | 262144 /* ContainsObjectLiteral */ | 1024 /* ContainsSpread */ | objectFlags;
            return spread;
        }
        /** We approximate own properties as non-methods plus methods that are inside the object literal */
        function isSpreadableProperty(prop) {
            return !(prop.flags & (8192 /* Method */ | 32768 /* GetAccessor */ | 65536 /* SetAccessor */)) ||
                !prop.declarations.some(function (decl) { return ts.isClassLike(decl.parent); });
        }
        function getSpreadSymbol(prop, readonly) {
            var isSetonlyAccessor = prop.flags & 65536 /* SetAccessor */ && !(prop.flags & 32768 /* GetAccessor */);
            if (!isSetonlyAccessor && readonly === isReadonlySymbol(prop)) {
                return prop;
            }
            var flags = 4 /* Property */ | (prop.flags & 16777216 /* Optional */);
            var result = createSymbol(flags, prop.escapedName, readonly ? 8 /* Readonly */ : 0);
            result.type = isSetonlyAccessor ? undefinedType : getTypeOfSymbol(prop);
            result.declarations = prop.declarations;
            result.nameType = prop.nameType;
            result.syntheticOrigin = prop;
            return result;
        }
        function getIndexInfoWithReadonly(info, readonly) {
            return info && info.isReadonly !== readonly ? createIndexInfo(info.type, readonly, info.declaration) : info;
        }
        function createLiteralType(flags, value, symbol) {
            var type = createType(flags);
            type.symbol = symbol;
            type.value = value;
            return type;
        }
        function getFreshTypeOfLiteralType(type) {
            if (type.flags & 2944 /* Literal */) {
                if (!type.freshType) {
                    var freshType = createLiteralType(type.flags, type.value, type.symbol);
                    freshType.regularType = type;
                    freshType.freshType = freshType;
                    type.freshType = freshType;
                }
                return type.freshType;
            }
            return type;
        }
        function getRegularTypeOfLiteralType(type) {
            return type.flags & 2944 /* Literal */ ? type.regularType :
                type.flags & 1048576 /* Union */ ? getUnionType(ts.sameMap(type.types, getRegularTypeOfLiteralType)) :
                    type;
        }
        function isFreshLiteralType(type) {
            return !!(type.flags & 2944 /* Literal */) && type.freshType === type;
        }
        function getLiteralType(value, enumId, symbol) {
            // We store all literal types in a single map with keys of the form '#NNN' and '@SSS',
            // where NNN is the text representation of a numeric literal and SSS are the characters
            // of a string literal. For literal enum members we use 'EEE#NNN' and 'EEE@SSS', where
            // EEE is a unique id for the containing enum type.
            var qualifier = typeof value === "number" ? "#" : typeof value === "string" ? "@" : "n";
            var key = (enumId ? enumId : "") + qualifier + (typeof value === "object" ? ts.pseudoBigIntToString(value) : value);
            var type = literalTypes.get(key);
            if (!type) {
                var flags = (typeof value === "number" ? 256 /* NumberLiteral */ :
                    typeof value === "string" ? 128 /* StringLiteral */ : 2048 /* BigIntLiteral */) |
                    (enumId ? 1024 /* EnumLiteral */ : 0);
                literalTypes.set(key, type = createLiteralType(flags, value, symbol));
                type.regularType = type;
            }
            return type;
        }
        function getTypeFromLiteralTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getRegularTypeOfLiteralType(checkExpression(node.literal));
            }
            return links.resolvedType;
        }
        function createUniqueESSymbolType(symbol) {
            var type = createType(8192 /* UniqueESSymbol */);
            type.symbol = symbol;
            type.escapedName = "__@" + type.symbol.escapedName + "@" + getSymbolId(type.symbol);
            return type;
        }
        function getESSymbolLikeTypeForNode(node) {
            if (ts.isValidESSymbolDeclaration(node)) {
                var symbol = getSymbolOfNode(node);
                var links = getSymbolLinks(symbol);
                return links.uniqueESSymbolType || (links.uniqueESSymbolType = createUniqueESSymbolType(symbol));
            }
            return esSymbolType;
        }
        function getThisType(node) {
            var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
            var parent = container && container.parent;
            if (parent && (ts.isClassLike(parent) || parent.kind === 242 /* InterfaceDeclaration */)) {
                if (!ts.hasModifier(container, 32 /* Static */) &&
                    (container.kind !== 158 /* Constructor */ || ts.isNodeDescendantOf(node, container.body))) {
                    return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent)).thisType;
                }
            }
            error(node, ts.Diagnostics.A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface);
            return errorType;
        }
        function getTypeFromThisTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getThisType(node);
            }
            return links.resolvedType;
        }
        function getTypeFromTypeNode(node) {
            switch (node.kind) {
                case 121 /* AnyKeyword */:
                case 290 /* JSDocAllType */:
                case 291 /* JSDocUnknownType */:
                    return anyType;
                case 144 /* UnknownKeyword */:
                    return unknownType;
                case 139 /* StringKeyword */:
                    return stringType;
                case 136 /* NumberKeyword */:
                    return numberType;
                case 147 /* BigIntKeyword */:
                    return bigintType;
                case 124 /* BooleanKeyword */:
                    return booleanType;
                case 140 /* SymbolKeyword */:
                    return esSymbolType;
                case 107 /* VoidKeyword */:
                    return voidType;
                case 142 /* UndefinedKeyword */:
                    return undefinedType;
                case 97 /* NullKeyword */:
                    return nullType;
                case 133 /* NeverKeyword */:
                    return neverType;
                case 137 /* ObjectKeyword */:
                    return node.flags & 65536 /* JavaScriptFile */ ? anyType : nonPrimitiveType;
                case 179 /* ThisType */:
                case 101 /* ThisKeyword */:
                    return getTypeFromThisTypeNode(node);
                case 183 /* LiteralType */:
                    return getTypeFromLiteralTypeNode(node);
                case 165 /* TypeReference */:
                    return getTypeFromTypeReference(node);
                case 164 /* TypePredicate */:
                    return booleanType;
                case 212 /* ExpressionWithTypeArguments */:
                    return getTypeFromTypeReference(node);
                case 168 /* TypeQuery */:
                    return getTypeFromTypeQueryNode(node);
                case 170 /* ArrayType */:
                    return getTypeFromArrayTypeNode(node);
                case 171 /* TupleType */:
                    return getTypeFromTupleTypeNode(node);
                case 172 /* OptionalType */:
                    return getTypeFromOptionalTypeNode(node);
                case 174 /* UnionType */:
                    return getTypeFromUnionTypeNode(node);
                case 175 /* IntersectionType */:
                    return getTypeFromIntersectionTypeNode(node);
                case 292 /* JSDocNullableType */:
                    return getTypeFromJSDocNullableTypeNode(node);
                case 294 /* JSDocOptionalType */:
                    return addOptionality(getTypeFromTypeNode(node.type));
                case 178 /* ParenthesizedType */:
                case 173 /* RestType */:
                case 293 /* JSDocNonNullableType */:
                case 289 /* JSDocTypeExpression */:
                    return getTypeFromTypeNode(node.type);
                case 296 /* JSDocVariadicType */:
                    return getTypeFromJSDocVariadicType(node);
                case 166 /* FunctionType */:
                case 167 /* ConstructorType */:
                case 169 /* TypeLiteral */:
                case 298 /* JSDocTypeLiteral */:
                case 295 /* JSDocFunctionType */:
                case 299 /* JSDocSignature */:
                    return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
                case 180 /* TypeOperator */:
                    return getTypeFromTypeOperatorNode(node);
                case 181 /* IndexedAccessType */:
                    return getTypeFromIndexedAccessTypeNode(node);
                case 182 /* MappedType */:
                    return getTypeFromMappedTypeNode(node);
                case 176 /* ConditionalType */:
                    return getTypeFromConditionalTypeNode(node);
                case 177 /* InferType */:
                    return getTypeFromInferTypeNode(node);
                case 184 /* ImportType */:
                    return getTypeFromImportTypeNode(node);
                // This function assumes that an identifier or qualified name is a type expression
                // Callers should first ensure this by calling isTypeNode
                case 73 /* Identifier */:
                case 149 /* QualifiedName */:
                    var symbol = getSymbolAtLocation(node);
                    return symbol ? getDeclaredTypeOfSymbol(symbol) : errorType;
                default:
                    return errorType;
            }
        }
        function instantiateList(items, mapper, instantiator) {
            if (items && items.length) {
                for (var i = 0; i < items.length; i++) {
                    var item = items[i];
                    var mapped = instantiator(item, mapper);
                    if (item !== mapped) {
                        var result = i === 0 ? [] : items.slice(0, i);
                        result.push(mapped);
                        for (i++; i < items.length; i++) {
                            result.push(instantiator(items[i], mapper));
                        }
                        return result;
                    }
                }
            }
            return items;
        }
        function instantiateTypes(types, mapper) {
            return instantiateList(types, mapper, instantiateType);
        }
        function instantiateSignatures(signatures, mapper) {
            return instantiateList(signatures, mapper, instantiateSignature);
        }
        function makeUnaryTypeMapper(source, target) {
            return function (t) { return t === source ? target : t; };
        }
        function makeBinaryTypeMapper(source1, target1, source2, target2) {
            return function (t) { return t === source1 ? target1 : t === source2 ? target2 : t; };
        }
        function makeArrayTypeMapper(sources, targets) {
            return function (t) {
                for (var i = 0; i < sources.length; i++) {
                    if (t === sources[i]) {
                        return targets ? targets[i] : anyType;
                    }
                }
                return t;
            };
        }
        function createTypeMapper(sources, targets) {
            ts.Debug.assert(targets === undefined || sources.length === targets.length);
            return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) :
                sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) :
                    makeArrayTypeMapper(sources, targets);
        }
        function createTypeEraser(sources) {
            return createTypeMapper(sources, /*targets*/ undefined);
        }
        /**
         * Maps forward-references to later types parameters to the empty object type.
         * This is used during inference when instantiating type parameter defaults.
         */
        function createBackreferenceMapper(context, index) {
            return function (t) { return ts.findIndex(context.inferences, function (info) { return info.typeParameter === t; }) >= index ? unknownType : t; };
        }
        function combineTypeMappers(mapper1, mapper2) {
            if (!mapper1)
                return mapper2;
            if (!mapper2)
                return mapper1;
            return function (t) { return instantiateType(mapper1(t), mapper2); };
        }
        function createReplacementMapper(source, target, baseMapper) {
            return function (t) { return t === source ? target : baseMapper(t); };
        }
        function permissiveMapper(type) {
            return type.flags & 262144 /* TypeParameter */ ? wildcardType : type;
        }
        function getRestrictiveTypeParameter(tp) {
            return tp.constraint === unknownType ? tp : tp.restrictiveInstantiation || (tp.restrictiveInstantiation = createTypeParameter(tp.symbol),
                tp.restrictiveInstantiation.constraint = unknownType,
                tp.restrictiveInstantiation);
        }
        function restrictiveMapper(type) {
            return type.flags & 262144 /* TypeParameter */ ? getRestrictiveTypeParameter(type) : type;
        }
        function cloneTypeParameter(typeParameter) {
            var result = createTypeParameter(typeParameter.symbol);
            result.target = typeParameter;
            return result;
        }
        function instantiateTypePredicate(predicate, mapper) {
            if (ts.isIdentifierTypePredicate(predicate)) {
                return {
                    kind: 1 /* Identifier */,
                    parameterName: predicate.parameterName,
                    parameterIndex: predicate.parameterIndex,
                    type: instantiateType(predicate.type, mapper)
                };
            }
            else {
                return {
                    kind: 0 /* This */,
                    type: instantiateType(predicate.type, mapper)
                };
            }
        }
        function instantiateSignature(signature, mapper, eraseTypeParameters) {
            var freshTypeParameters;
            if (signature.typeParameters && !eraseTypeParameters) {
                // First create a fresh set of type parameters, then include a mapping from the old to the
                // new type parameters in the mapper function. Finally store this mapper in the new type
                // parameters such that we can use it when instantiating constraints.
                freshTypeParameters = ts.map(signature.typeParameters, cloneTypeParameter);
                mapper = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), mapper);
                for (var _i = 0, freshTypeParameters_1 = freshTypeParameters; _i < freshTypeParameters_1.length; _i++) {
                    var tp = freshTypeParameters_1[_i];
                    tp.mapper = mapper;
                }
            }
            // Don't compute resolvedReturnType and resolvedTypePredicate now,
            // because using `mapper` now could trigger inferences to become fixed. (See `createInferenceContext`.)
            // See GH#17600.
            var result = createSignature(signature.declaration, freshTypeParameters, signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper), instantiateList(signature.parameters, mapper, instantiateSymbol), 
            /*resolvedReturnType*/ undefined, 
            /*resolvedTypePredicate*/ undefined, signature.minArgumentCount, signature.hasRestParameter, signature.hasLiteralTypes);
            result.target = signature;
            result.mapper = mapper;
            return result;
        }
        function instantiateSymbol(symbol, mapper) {
            var links = getSymbolLinks(symbol);
            if (links.type && !maybeTypeOfKind(links.type, 524288 /* Object */ | 63176704 /* Instantiable */)) {
                // If the type of the symbol is already resolved, and if that type could not possibly
                // be affected by instantiation, simply return the symbol itself.
                return symbol;
            }
            if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) {
                // If symbol being instantiated is itself a instantiation, fetch the original target and combine the
                // type mappers. This ensures that original type identities are properly preserved and that aliases
                // always reference a non-aliases.
                symbol = links.target;
                mapper = combineTypeMappers(links.mapper, mapper);
            }
            // Keep the flags from the symbol we're instantiating.  Mark that is instantiated, and
            // also transient so that we can just store data on it directly.
            var result = createSymbol(symbol.flags, symbol.escapedName, 1 /* Instantiated */ | ts.getCheckFlags(symbol) & (8 /* Readonly */ | 4096 /* Late */ | 16384 /* OptionalParameter */ | 32768 /* RestParameter */));
            result.declarations = symbol.declarations;
            result.parent = symbol.parent;
            result.target = symbol;
            result.mapper = mapper;
            if (symbol.valueDeclaration) {
                result.valueDeclaration = symbol.valueDeclaration;
            }
            if (symbol.nameType) {
                result.nameType = symbol.nameType;
            }
            return result;
        }
        function getAnonymousTypeInstantiation(type, mapper) {
            var target = type.objectFlags & 64 /* Instantiated */ ? type.target : type;
            var symbol = target.symbol;
            var links = getSymbolLinks(symbol);
            var typeParameters = links.outerTypeParameters;
            if (!typeParameters) {
                // The first time an anonymous type is instantiated we compute and store a list of the type
                // parameters that are in scope (and therefore potentially referenced). For type literals that
                // aren't the right hand side of a generic type alias declaration we optimize by reducing the
                // set of type parameters to those that are possibly referenced in the literal.
                var declaration_1 = symbol.declarations[0];
                if (ts.isInJSFile(declaration_1)) {
                    var paramTag = ts.findAncestor(declaration_1, ts.isJSDocParameterTag);
                    if (paramTag) {
                        var paramSymbol = ts.getParameterSymbolFromJSDoc(paramTag);
                        if (paramSymbol) {
                            declaration_1 = paramSymbol.valueDeclaration;
                        }
                    }
                }
                var outerTypeParameters = getOuterTypeParameters(declaration_1, /*includeThisTypes*/ true);
                if (isJSConstructor(declaration_1)) {
                    var templateTagParameters = getTypeParametersFromDeclaration(declaration_1);
                    outerTypeParameters = ts.addRange(outerTypeParameters, templateTagParameters);
                }
                typeParameters = outerTypeParameters || ts.emptyArray;
                typeParameters = symbol.flags & 2048 /* TypeLiteral */ && !target.aliasTypeArguments ?
                    ts.filter(typeParameters, function (tp) { return isTypeParameterPossiblyReferenced(tp, declaration_1); }) :
                    typeParameters;
                links.outerTypeParameters = typeParameters;
                if (typeParameters.length) {
                    links.instantiations = ts.createMap();
                    links.instantiations.set(getTypeListId(typeParameters), target);
                }
            }
            if (typeParameters.length) {
                // We are instantiating an anonymous type that has one or more type parameters in scope. Apply the
                // mapper to the type parameters to produce the effective list of type arguments, and compute the
                // instantiation cache key from the type IDs of the type arguments.
                var combinedMapper = type.objectFlags & 64 /* Instantiated */ ? combineTypeMappers(type.mapper, mapper) : mapper;
                var typeArguments = ts.map(typeParameters, combinedMapper);
                var id = getTypeListId(typeArguments);
                var result = links.instantiations.get(id);
                if (!result) {
                    var newMapper = createTypeMapper(typeParameters, typeArguments);
                    result = target.objectFlags & 32 /* Mapped */ ? instantiateMappedType(target, newMapper) : instantiateAnonymousType(target, newMapper);
                    links.instantiations.set(id, result);
                }
                return result;
            }
            return type;
        }
        function maybeTypeParameterReference(node) {
            return !(node.kind === 149 /* QualifiedName */ ||
                node.parent.kind === 165 /* TypeReference */ && node.parent.typeArguments && node === node.parent.typeName);
        }
        function isTypeParameterPossiblyReferenced(tp, node) {
            // If the type parameter doesn't have exactly one declaration, if there are invening statement blocks
            // between the node and the type parameter declaration, if the node contains actual references to the
            // type parameter, or if the node contains type queries, we consider the type parameter possibly referenced.
            if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) {
                var container = tp.symbol.declarations[0].parent;
                for (var n = node; n !== container; n = n.parent) {
                    if (!n || n.kind === 219 /* Block */ || n.kind === 176 /* ConditionalType */ && ts.forEachChild(n.extendsType, containsReference)) {
                        return true;
                    }
                }
                return !!ts.forEachChild(node, containsReference);
            }
            return true;
            function containsReference(node) {
                switch (node.kind) {
                    case 179 /* ThisType */:
                        return !!tp.isThisType;
                    case 73 /* Identifier */:
                        return !tp.isThisType && ts.isPartOfTypeNode(node) && maybeTypeParameterReference(node) &&
                            getTypeFromTypeNode(node) === tp;
                    case 168 /* TypeQuery */:
                        return true;
                }
                return !!ts.forEachChild(node, containsReference);
            }
        }
        function getHomomorphicTypeVariable(type) {
            var constraintType = getConstraintTypeFromMappedType(type);
            if (constraintType.flags & 4194304 /* Index */) {
                var typeVariable = getActualTypeVariable(constraintType.type);
                if (typeVariable.flags & 262144 /* TypeParameter */) {
                    return typeVariable;
                }
            }
            return undefined;
        }
        function instantiateMappedType(type, mapper) {
            // For a homomorphic mapped type { [P in keyof T]: X }, where T is some type variable, the mapping
            // operation depends on T as follows:
            // * If T is a primitive type no mapping is performed and the result is simply T.
            // * If T is a union type we distribute the mapped type over the union.
            // * If T is an array we map to an array where the element type has been transformed.
            // * If T is a tuple we map to a tuple where the element types have been transformed.
            // * Otherwise we map to an object type where the type of each property has been transformed.
            // For example, when T is instantiated to a union type A | B, we produce { [P in keyof A]: X } |
            // { [P in keyof B]: X }, and when when T is instantiated to a union type A | undefined, we produce
            // { [P in keyof A]: X } | undefined.
            var typeVariable = getHomomorphicTypeVariable(type);
            if (typeVariable) {
                var mappedTypeVariable = instantiateType(typeVariable, mapper);
                if (typeVariable !== mappedTypeVariable) {
                    return mapType(mappedTypeVariable, function (t) {
                        if (t.flags & (3 /* AnyOrUnknown */ | 58982400 /* InstantiableNonPrimitive */ | 524288 /* Object */ | 2097152 /* Intersection */) && t !== wildcardType && t !== errorType) {
                            var replacementMapper = createReplacementMapper(typeVariable, t, mapper);
                            return isArrayType(t) ? instantiateMappedArrayType(t, type, replacementMapper) :
                                isTupleType(t) ? instantiateMappedTupleType(t, type, replacementMapper) :
                                    instantiateAnonymousType(type, replacementMapper);
                        }
                        return t;
                    });
                }
            }
            return instantiateAnonymousType(type, mapper);
        }
        function getModifiedReadonlyState(state, modifiers) {
            return modifiers & 1 /* IncludeReadonly */ ? true : modifiers & 2 /* ExcludeReadonly */ ? false : state;
        }
        function instantiateMappedArrayType(arrayType, mappedType, mapper) {
            var elementType = instantiateMappedTypeTemplate(mappedType, numberType, /*isOptional*/ true, mapper);
            return elementType === errorType ? errorType :
                createArrayType(elementType, getModifiedReadonlyState(isReadonlyArrayType(arrayType), getMappedTypeModifiers(mappedType)));
        }
        function instantiateMappedTupleType(tupleType, mappedType, mapper) {
            var minLength = tupleType.target.minLength;
            var elementTypes = ts.map(tupleType.typeArguments || ts.emptyArray, function (_, i) {
                return instantiateMappedTypeTemplate(mappedType, getLiteralType("" + i), i >= minLength, mapper);
            });
            var modifiers = getMappedTypeModifiers(mappedType);
            var newMinLength = modifiers & 4 /* IncludeOptional */ ? 0 :
                modifiers & 8 /* ExcludeOptional */ ? getTypeReferenceArity(tupleType) - (tupleType.target.hasRestElement ? 1 : 0) :
                    minLength;
            var newReadonly = getModifiedReadonlyState(tupleType.target.readonly, modifiers);
            return ts.contains(elementTypes, errorType) ? errorType :
                createTupleType(elementTypes, newMinLength, tupleType.target.hasRestElement, newReadonly, tupleType.target.associatedNames);
        }
        function instantiateMappedTypeTemplate(type, key, isOptional, mapper) {
            var templateMapper = combineTypeMappers(mapper, createTypeMapper([getTypeParameterFromMappedType(type)], [key]));
            var propType = instantiateType(getTemplateTypeFromMappedType(type.target || type), templateMapper);
            var modifiers = getMappedTypeModifiers(type);
            return strictNullChecks && modifiers & 4 /* IncludeOptional */ && !isTypeAssignableTo(undefinedType, propType) ? getOptionalType(propType) :
                strictNullChecks && modifiers & 8 /* ExcludeOptional */ && isOptional ? getTypeWithFacts(propType, 524288 /* NEUndefined */) :
                    propType;
        }
        function instantiateAnonymousType(type, mapper) {
            var result = createObjectType(type.objectFlags | 64 /* Instantiated */, type.symbol);
            if (type.objectFlags & 32 /* Mapped */) {
                result.declaration = type.declaration;
                // C.f. instantiateSignature
                var origTypeParameter = getTypeParameterFromMappedType(type);
                var freshTypeParameter = cloneTypeParameter(origTypeParameter);
                result.typeParameter = freshTypeParameter;
                mapper = combineTypeMappers(makeUnaryTypeMapper(origTypeParameter, freshTypeParameter), mapper);
                freshTypeParameter.mapper = mapper;
            }
            result.target = type;
            result.mapper = mapper;
            result.aliasSymbol = type.aliasSymbol;
            result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper);
            return result;
        }
        function getConditionalTypeInstantiation(type, mapper) {
            var root = type.root;
            if (root.outerTypeParameters) {
                // We are instantiating a conditional type that has one or more type parameters in scope. Apply the
                // mapper to the type parameters to produce the effective list of type arguments, and compute the
                // instantiation cache key from the type IDs of the type arguments.
                var typeArguments = ts.map(root.outerTypeParameters, mapper);
                var id = getTypeListId(typeArguments);
                var result = root.instantiations.get(id);
                if (!result) {
                    var newMapper = createTypeMapper(root.outerTypeParameters, typeArguments);
                    result = instantiateConditionalType(root, newMapper);
                    root.instantiations.set(id, result);
                }
                return result;
            }
            return type;
        }
        function instantiateConditionalType(root, mapper) {
            // Check if we have a conditional type where the check type is a naked type parameter. If so,
            // the conditional type is distributive over union types and when T is instantiated to a union
            // type A | B, we produce (A extends U ? X : Y) | (B extends U ? X : Y).
            if (root.isDistributive) {
                var checkType_1 = root.checkType;
                var instantiatedType = mapper(checkType_1);
                if (checkType_1 !== instantiatedType && instantiatedType.flags & (1048576 /* Union */ | 131072 /* Never */)) {
                    return mapType(instantiatedType, function (t) { return getConditionalType(root, createReplacementMapper(checkType_1, t, mapper)); });
                }
            }
            return getConditionalType(root, mapper);
        }
        function instantiateType(type, mapper) {
            if (!type || !mapper || mapper === identityMapper) {
                return type;
            }
            if (instantiationDepth === 50) {
                // We have reached 50 recursive type instantiations and there is a very high likelyhood we're dealing
                // with a combination of infinite generic types that perpetually generate new type identities. We stop
                // the recursion here by yielding the error type.
                error(currentNode, ts.Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
                return errorType;
            }
            instantiationDepth++;
            var result = instantiateTypeWorker(type, mapper);
            instantiationDepth--;
            return result;
        }
        function instantiateTypeWorker(type, mapper) {
            var flags = type.flags;
            if (flags & 262144 /* TypeParameter */) {
                return mapper(type);
            }
            if (flags & 524288 /* Object */) {
                var objectFlags = type.objectFlags;
                if (objectFlags & 16 /* Anonymous */) {
                    // If the anonymous type originates in a declaration of a function, method, class, or
                    // interface, in an object type literal, or in an object literal expression, we may need
                    // to instantiate the type because it might reference a type parameter.
                    return couldContainTypeVariables(type) ?
                        getAnonymousTypeInstantiation(type, mapper) : type;
                }
                if (objectFlags & 32 /* Mapped */) {
                    return getAnonymousTypeInstantiation(type, mapper);
                }
                if (objectFlags & 4 /* Reference */) {
                    var typeArguments = type.typeArguments;
                    var newTypeArguments = instantiateTypes(typeArguments, mapper);
                    return newTypeArguments !== typeArguments ? createTypeReference(type.target, newTypeArguments) : type;
                }
                return type;
            }
            if (flags & 1048576 /* Union */ && !(flags & 131068 /* Primitive */)) {
                var types = type.types;
                var newTypes = instantiateTypes(types, mapper);
                return newTypes !== types ? getUnionType(newTypes, 1 /* Literal */, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) : type;
            }
            if (flags & 2097152 /* Intersection */) {
                var types = type.types;
                var newTypes = instantiateTypes(types, mapper);
                return newTypes !== types ? getIntersectionType(newTypes, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) : type;
            }
            if (flags & 4194304 /* Index */) {
                return getIndexType(instantiateType(type.type, mapper));
            }
            if (flags & 8388608 /* IndexedAccess */) {
                return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper));
            }
            if (flags & 16777216 /* Conditional */) {
                return getConditionalTypeInstantiation(type, combineTypeMappers(type.mapper, mapper));
            }
            if (flags & 33554432 /* Substitution */) {
                var maybeVariable = instantiateType(type.typeVariable, mapper);
                if (maybeVariable.flags & 8650752 /* TypeVariable */) {
                    return getSubstitutionType(maybeVariable, instantiateType(type.substitute, mapper));
                }
                else {
                    var sub = instantiateType(type.substitute, mapper);
                    if (sub.flags & 3 /* AnyOrUnknown */ || isTypeAssignableTo(getRestrictiveInstantiation(maybeVariable), getRestrictiveInstantiation(sub))) {
                        return maybeVariable;
                    }
                    return sub;
                }
            }
            return type;
        }
        function getPermissiveInstantiation(type) {
            return type.flags & (131068 /* Primitive */ | 3 /* AnyOrUnknown */ | 131072 /* Never */) ? type :
                type.permissiveInstantiation || (type.permissiveInstantiation = instantiateType(type, permissiveMapper));
        }
        function getRestrictiveInstantiation(type) {
            if (type.flags & (131068 /* Primitive */ | 3 /* AnyOrUnknown */ | 131072 /* Never */)) {
                return type;
            }
            if (type.restrictiveInstantiation) {
                return type.restrictiveInstantiation;
            }
            type.restrictiveInstantiation = instantiateType(type, restrictiveMapper);
            // We set the following so we don't attempt to set the restrictive instance of a restrictive instance
            // which is redundant - we'll produce new type identities, but all type params have already been mapped.
            // This also gives us a way to detect restrictive instances upon comparisons and _disable_ the "distributeive constraint"
            // assignability check for them, which is distinctly unsafe, as once you have a restrctive instance, all the type parameters
            // are constrained to `unknown` and produce tons of false positives/negatives!
            type.restrictiveInstantiation.restrictiveInstantiation = type.restrictiveInstantiation;
            return type.restrictiveInstantiation;
        }
        function instantiateIndexInfo(info, mapper) {
            return info && createIndexInfo(instantiateType(info.type, mapper), info.isReadonly, info.declaration);
        }
        // Returns true if the given expression contains (at any level of nesting) a function or arrow expression
        // that is subject to contextual typing.
        function isContextSensitive(node) {
            ts.Debug.assert(node.kind !== 157 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            switch (node.kind) {
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */:
                case 157 /* MethodDeclaration */:
                    return isContextSensitiveFunctionLikeDeclaration(node);
                case 189 /* ObjectLiteralExpression */:
                    return ts.some(node.properties, isContextSensitive);
                case 188 /* ArrayLiteralExpression */:
                    return ts.some(node.elements, isContextSensitive);
                case 206 /* ConditionalExpression */:
                    return isContextSensitive(node.whenTrue) ||
                        isContextSensitive(node.whenFalse);
                case 205 /* BinaryExpression */:
                    return node.operatorToken.kind === 55 /* BarBarToken */ &&
                        (isContextSensitive(node.left) || isContextSensitive(node.right));
                case 276 /* PropertyAssignment */:
                    return isContextSensitive(node.initializer);
                case 196 /* ParenthesizedExpression */:
                    return isContextSensitive(node.expression);
                case 269 /* JsxAttributes */:
                    return ts.some(node.properties, isContextSensitive) || ts.isJsxOpeningElement(node.parent) && ts.some(node.parent.parent.children, isContextSensitive);
                case 268 /* JsxAttribute */: {
                    // If there is no initializer, JSX attribute has a boolean value of true which is not context sensitive.
                    var initializer = node.initializer;
                    return !!initializer && isContextSensitive(initializer);
                }
                case 271 /* JsxExpression */: {
                    // It is possible to that node.expression is undefined (e.g <div x={} />)
                    var expression = node.expression;
                    return !!expression && isContextSensitive(expression);
                }
            }
            return false;
        }
        function isContextSensitiveFunctionLikeDeclaration(node) {
            // Functions with type parameters are not context sensitive.
            if (node.typeParameters) {
                return false;
            }
            // Functions with any parameters that lack type annotations are context sensitive.
            if (ts.some(node.parameters, function (p) { return !ts.getEffectiveTypeAnnotationNode(p); })) {
                return true;
            }
            if (node.kind !== 198 /* ArrowFunction */) {
                // If the first parameter is not an explicit 'this' parameter, then the function has
                // an implicit 'this' parameter which is subject to contextual typing.
                var parameter = ts.firstOrUndefined(node.parameters);
                if (!(parameter && ts.parameterIsThisKeyword(parameter))) {
                    return true;
                }
            }
            return hasContextSensitiveReturnExpression(node);
        }
        function hasContextSensitiveReturnExpression(node) {
            // TODO(anhans): A block should be context-sensitive if it has a context-sensitive return value.
            return !!node.body && node.body.kind !== 219 /* Block */ && isContextSensitive(node.body);
        }
        function isContextSensitiveFunctionOrObjectLiteralMethod(func) {
            return (ts.isInJSFile(func) && ts.isFunctionDeclaration(func) || isFunctionExpressionOrArrowFunction(func) || ts.isObjectLiteralMethod(func)) &&
                isContextSensitiveFunctionLikeDeclaration(func);
        }
        function getTypeWithoutSignatures(type) {
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                if (resolved.constructSignatures.length || resolved.callSignatures.length) {
                    var result = createObjectType(16 /* Anonymous */, type.symbol);
                    result.members = resolved.members;
                    result.properties = resolved.properties;
                    result.callSignatures = ts.emptyArray;
                    result.constructSignatures = ts.emptyArray;
                    return result;
                }
            }
            else if (type.flags & 2097152 /* Intersection */) {
                return getIntersectionType(ts.map(type.types, getTypeWithoutSignatures));
            }
            return type;
        }
        // TYPE CHECKING
        function isTypeIdenticalTo(source, target) {
            return isTypeRelatedTo(source, target, identityRelation);
        }
        function compareTypesIdentical(source, target) {
            return isTypeRelatedTo(source, target, identityRelation) ? -1 /* True */ : 0 /* False */;
        }
        function compareTypesAssignable(source, target) {
            return isTypeRelatedTo(source, target, assignableRelation) ? -1 /* True */ : 0 /* False */;
        }
        function compareTypesSubtypeOf(source, target) {
            return isTypeRelatedTo(source, target, subtypeRelation) ? -1 /* True */ : 0 /* False */;
        }
        function isTypeSubtypeOf(source, target) {
            return isTypeRelatedTo(source, target, subtypeRelation);
        }
        function isTypeAssignableTo(source, target) {
            return isTypeRelatedTo(source, target, assignableRelation);
        }
        // An object type S is considered to be derived from an object type T if
        // S is a union type and every constituent of S is derived from T,
        // T is a union type and S is derived from at least one constituent of T, or
        // S is a type variable with a base constraint that is derived from T,
        // T is one of the global types Object and Function and S is a subtype of T, or
        // T occurs directly or indirectly in an 'extends' clause of S.
        // Note that this check ignores type parameters and only considers the
        // inheritance hierarchy.
        function isTypeDerivedFrom(source, target) {
            return source.flags & 1048576 /* Union */ ? ts.every(source.types, function (t) { return isTypeDerivedFrom(t, target); }) :
                target.flags & 1048576 /* Union */ ? ts.some(target.types, function (t) { return isTypeDerivedFrom(source, t); }) :
                    source.flags & 58982400 /* InstantiableNonPrimitive */ ? isTypeDerivedFrom(getBaseConstraintOfType(source) || unknownType, target) :
                        target === globalObjectType ? !!(source.flags & (524288 /* Object */ | 67108864 /* NonPrimitive */)) :
                            target === globalFunctionType ? !!(source.flags & 524288 /* Object */) && isFunctionObjectType(source) :
                                hasBaseType(source, getTargetType(target));
        }
        /**
         * This is *not* a bi-directional relationship.
         * If one needs to check both directions for comparability, use a second call to this function or 'checkTypeComparableTo'.
         *
         * A type S is comparable to a type T if some (but not necessarily all) of the possible values of S are also possible values of T.
         * It is used to check following cases:
         *   - the types of the left and right sides of equality/inequality operators (`===`, `!==`, `==`, `!=`).
         *   - the types of `case` clause expressions and their respective `switch` expressions.
         *   - the type of an expression in a type assertion with the type being asserted.
         */
        function isTypeComparableTo(source, target) {
            return isTypeRelatedTo(source, target, comparableRelation);
        }
        function areTypesComparable(type1, type2) {
            return isTypeComparableTo(type1, type2) || isTypeComparableTo(type2, type1);
        }
        function checkTypeAssignableTo(source, target, errorNode, headMessage, containingMessageChain, errorOutputObject) {
            return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain, errorOutputObject);
        }
        /**
         * Like `checkTypeAssignableTo`, but if it would issue an error, instead performs structural comparisons of the types using the given expression node to
         * attempt to issue more specific errors on, for example, specific object literal properties or tuple members.
         */
        function checkTypeAssignableToAndOptionallyElaborate(source, target, errorNode, expr, headMessage, containingMessageChain) {
            return checkTypeRelatedToAndOptionallyElaborate(source, target, assignableRelation, errorNode, expr, headMessage, containingMessageChain);
        }
        function checkTypeRelatedToAndOptionallyElaborate(source, target, relation, errorNode, expr, headMessage, containingMessageChain) {
            if (isTypeRelatedTo(source, target, relation))
                return true;
            if (!errorNode || !elaborateError(expr, source, target, relation, headMessage)) {
                return checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain);
            }
            return false;
        }
        function isOrHasGenericConditional(type) {
            return !!(type.flags & 16777216 /* Conditional */ || (type.flags & 2097152 /* Intersection */ && ts.some(type.types, isOrHasGenericConditional)));
        }
        function elaborateError(node, source, target, relation, headMessage) {
            if (!node || isOrHasGenericConditional(target))
                return false;
            if (!checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined) && elaborateDidYouMeanToCallOrConstruct(node, source, target, relation, headMessage)) {
                return true;
            }
            switch (node.kind) {
                case 271 /* JsxExpression */:
                case 196 /* ParenthesizedExpression */:
                    return elaborateError(node.expression, source, target, relation, headMessage);
                case 205 /* BinaryExpression */:
                    switch (node.operatorToken.kind) {
                        case 60 /* EqualsToken */:
                        case 27 /* CommaToken */:
                            return elaborateError(node.right, source, target, relation, headMessage);
                    }
                    break;
                case 189 /* ObjectLiteralExpression */:
                    return elaborateObjectLiteral(node, source, target, relation);
                case 188 /* ArrayLiteralExpression */:
                    return elaborateArrayLiteral(node, source, target, relation);
                case 269 /* JsxAttributes */:
                    return elaborateJsxComponents(node, source, target, relation);
                case 198 /* ArrowFunction */:
                    return elaborateArrowFunction(node, source, target, relation);
            }
            return false;
        }
        function elaborateDidYouMeanToCallOrConstruct(node, source, target, relation, headMessage) {
            var callSignatures = getSignaturesOfType(source, 0 /* Call */);
            var constructSignatures = getSignaturesOfType(source, 1 /* Construct */);
            for (var _i = 0, _a = [constructSignatures, callSignatures]; _i < _a.length; _i++) {
                var signatures = _a[_i];
                if (ts.some(signatures, function (s) {
                    var returnType = getReturnTypeOfSignature(s);
                    return !(returnType.flags & (1 /* Any */ | 131072 /* Never */)) && checkTypeRelatedTo(returnType, target, relation, /*errorNode*/ undefined);
                })) {
                    var resultObj = {};
                    checkTypeAssignableTo(source, target, node, headMessage, /*containingChain*/ undefined, resultObj);
                    var diagnostic = resultObj.error;
                    ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(node, signatures === constructSignatures ? ts.Diagnostics.Did_you_mean_to_use_new_with_this_expression : ts.Diagnostics.Did_you_mean_to_call_this_expression));
                    return true;
                }
            }
            return false;
        }
        function elaborateArrowFunction(node, source, target, relation) {
            // Don't elaborate blocks
            if (ts.isBlock(node.body)) {
                return false;
            }
            // Or functions with annotated parameter types
            if (ts.some(node.parameters, ts.hasType)) {
                return false;
            }
            var sourceSig = getSingleCallSignature(source);
            if (!sourceSig) {
                return false;
            }
            var targetSignatures = getSignaturesOfType(target, 0 /* Call */);
            if (!ts.length(targetSignatures)) {
                return false;
            }
            var returnExpression = node.body;
            var sourceReturn = getReturnTypeOfSignature(sourceSig);
            var targetReturn = getUnionType(ts.map(targetSignatures, getReturnTypeOfSignature));
            if (!checkTypeRelatedTo(sourceReturn, targetReturn, relation, /*errorNode*/ undefined)) {
                var elaborated = returnExpression && elaborateError(returnExpression, sourceReturn, targetReturn, relation, /*headMessage*/ undefined);
                if (elaborated) {
                    return elaborated;
                }
                var resultObj = {};
                checkTypeRelatedTo(sourceReturn, targetReturn, relation, returnExpression, /*message*/ undefined, /*chain*/ undefined, resultObj);
                if (resultObj.error) {
                    if (target.symbol && ts.length(target.symbol.declarations)) {
                        ts.addRelatedInfo(resultObj.error, ts.createDiagnosticForNode(target.symbol.declarations[0], ts.Diagnostics.The_expected_type_comes_from_the_return_type_of_this_signature));
                    }
                    return true;
                }
            }
            return false;
        }
        /**
         * For every element returned from the iterator, checks that element to issue an error on a property of that element's type
         * If that element would issue an error, we first attempt to dive into that element's inner expression and issue a more specific error by recuring into `elaborateError`
         * Otherwise, we issue an error on _every_ element which fail the assignability check
         */
        function elaborateElementwise(iterator, source, target, relation) {
            // Assignability failure - check each prop individually, and if that fails, fall back on the bad error span
            var reportedError = false;
            for (var status = iterator.next(); !status.done; status = iterator.next()) {
                var _a = status.value, prop = _a.errorNode, next = _a.innerExpression, nameType = _a.nameType, errorMessage = _a.errorMessage;
                var targetPropType = getIndexedAccessTypeOrUndefined(target, nameType);
                if (!targetPropType || targetPropType.flags & 8388608 /* IndexedAccess */)
                    continue; // Don't elaborate on indexes on generic variables
                var sourcePropType = getIndexedAccessTypeOrUndefined(source, nameType);
                if (sourcePropType && !checkTypeRelatedTo(sourcePropType, targetPropType, relation, /*errorNode*/ undefined)) {
                    var elaborated = next && elaborateError(next, sourcePropType, targetPropType, relation, /*headMessage*/ undefined);
                    if (elaborated) {
                        reportedError = true;
                    }
                    else {
                        // Issue error on the prop itself, since the prop couldn't elaborate the error
                        var resultObj = {};
                        // Use the expression type, if available
                        var specificSource = next ? checkExpressionForMutableLocation(next, 0 /* Normal */, sourcePropType) : sourcePropType;
                        var result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage, /*containingChain*/ undefined, resultObj);
                        if (result && specificSource !== sourcePropType) {
                            // If for whatever reason the expression type doesn't yield an error, make sure we still issue an error on the sourcePropType
                            checkTypeRelatedTo(sourcePropType, targetPropType, relation, prop, errorMessage, /*containingChain*/ undefined, resultObj);
                        }
                        if (resultObj.error) {
                            var reportedDiag = resultObj.error;
                            var propertyName = isTypeUsableAsPropertyName(nameType) ? getPropertyNameFromType(nameType) : undefined;
                            var targetProp = propertyName !== undefined ? getPropertyOfType(target, propertyName) : undefined;
                            var issuedElaboration = false;
                            if (!targetProp) {
                                var indexInfo = isTypeAssignableToKind(nameType, 296 /* NumberLike */) && getIndexInfoOfType(target, 1 /* Number */) ||
                                    getIndexInfoOfType(target, 0 /* String */) ||
                                    undefined;
                                if (indexInfo && indexInfo.declaration && !ts.getSourceFileOfNode(indexInfo.declaration).hasNoDefaultLib) {
                                    issuedElaboration = true;
                                    ts.addRelatedInfo(reportedDiag, ts.createDiagnosticForNode(indexInfo.declaration, ts.Diagnostics.The_expected_type_comes_from_this_index_signature));
                                }
                            }
                            if (!issuedElaboration && (targetProp && ts.length(targetProp.declarations) || target.symbol && ts.length(target.symbol.declarations))) {
                                var targetNode = targetProp && ts.length(targetProp.declarations) ? targetProp.declarations[0] : target.symbol.declarations[0];
                                if (!ts.getSourceFileOfNode(targetNode).hasNoDefaultLib) {
                                    ts.addRelatedInfo(reportedDiag, ts.createDiagnosticForNode(targetNode, ts.Diagnostics.The_expected_type_comes_from_property_0_which_is_declared_here_on_type_1, propertyName && !(nameType.flags & 8192 /* UniqueESSymbol */) ? ts.unescapeLeadingUnderscores(propertyName) : typeToString(nameType), typeToString(target)));
                                }
                            }
                        }
                        reportedError = true;
                    }
                }
            }
            return reportedError;
        }
        function generateJsxAttributes(node) {
            var _i, _a, prop;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        if (!ts.length(node.properties))
                            return [2 /*return*/];
                        _i = 0, _a = node.properties;
                        _b.label = 1;
                    case 1:
                        if (!(_i < _a.length)) return [3 /*break*/, 4];
                        prop = _a[_i];
                        if (ts.isJsxSpreadAttribute(prop))
                            return [3 /*break*/, 3];
                        return [4 /*yield*/, { errorNode: prop.name, innerExpression: prop.initializer, nameType: getLiteralType(ts.idText(prop.name)) }];
                    case 2:
                        _b.sent();
                        _b.label = 3;
                    case 3:
                        _i++;
                        return [3 /*break*/, 1];
                    case 4: return [2 /*return*/];
                }
            });
        }
        function generateJsxChildren(node, getInvalidTextDiagnostic) {
            var memberOffset, i, child, nameType, elem;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!ts.length(node.children))
                            return [2 /*return*/];
                        memberOffset = 0;
                        i = 0;
                        _a.label = 1;
                    case 1:
                        if (!(i < node.children.length)) return [3 /*break*/, 5];
                        child = node.children[i];
                        nameType = getLiteralType(i - memberOffset);
                        elem = getElaborationElementForJsxChild(child, nameType, getInvalidTextDiagnostic);
                        if (!elem) return [3 /*break*/, 3];
                        return [4 /*yield*/, elem];
                    case 2:
                        _a.sent();
                        return [3 /*break*/, 4];
                    case 3:
                        memberOffset++;
                        _a.label = 4;
                    case 4:
                        i++;
                        return [3 /*break*/, 1];
                    case 5: return [2 /*return*/];
                }
            });
        }
        function getElaborationElementForJsxChild(child, nameType, getInvalidTextDiagnostic) {
            switch (child.kind) {
                case 271 /* JsxExpression */:
                    // child is of the type of the expression
                    return { errorNode: child, innerExpression: child.expression, nameType: nameType };
                case 11 /* JsxText */:
                    if (child.containsOnlyTriviaWhiteSpaces) {
                        break; // Whitespace only jsx text isn't real jsx text
                    }
                    // child is a string
                    return { errorNode: child, innerExpression: undefined, nameType: nameType, errorMessage: getInvalidTextDiagnostic() };
                case 261 /* JsxElement */:
                case 262 /* JsxSelfClosingElement */:
                case 265 /* JsxFragment */:
                    // child is of type JSX.Element
                    return { errorNode: child, innerExpression: child, nameType: nameType };
                default:
                    return ts.Debug.assertNever(child, "Found invalid jsx child");
            }
        }
        function getSemanticJsxChildren(children) {
            return ts.filter(children, function (i) { return !ts.isJsxText(i) || !i.containsOnlyTriviaWhiteSpaces; });
        }
        function elaborateJsxComponents(node, source, target, relation) {
            var result = elaborateElementwise(generateJsxAttributes(node), source, target, relation);
            var invalidTextDiagnostic;
            if (ts.isJsxOpeningElement(node.parent) && ts.isJsxElement(node.parent.parent)) {
                var containingElement = node.parent.parent;
                var childPropName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node));
                var childrenPropName = childPropName === undefined ? "children" : ts.unescapeLeadingUnderscores(childPropName);
                var childrenNameType = getLiteralType(childrenPropName);
                var childrenTargetType = getIndexedAccessType(target, childrenNameType);
                var validChildren = getSemanticJsxChildren(containingElement.children);
                if (!ts.length(validChildren)) {
                    return result;
                }
                var moreThanOneRealChildren = ts.length(validChildren) > 1;
                var arrayLikeTargetParts = filterType(childrenTargetType, isArrayOrTupleLikeType);
                var nonArrayLikeTargetParts = filterType(childrenTargetType, function (t) { return !isArrayOrTupleLikeType(t); });
                if (moreThanOneRealChildren) {
                    if (arrayLikeTargetParts !== neverType) {
                        var realSource = createTupleType(checkJsxChildren(containingElement, 0 /* Normal */));
                        result = elaborateElementwise(generateJsxChildren(containingElement, getInvalidTextualChildDiagnostic), realSource, arrayLikeTargetParts, relation) || result;
                    }
                    else if (!isTypeRelatedTo(getIndexedAccessType(source, childrenNameType), childrenTargetType, relation)) {
                        // arity mismatch
                        result = true;
                        error(containingElement.openingElement.tagName, ts.Diagnostics.This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided, childrenPropName, typeToString(childrenTargetType));
                    }
                }
                else {
                    if (nonArrayLikeTargetParts !== neverType) {
                        var child = validChildren[0];
                        var elem_1 = getElaborationElementForJsxChild(child, childrenNameType, getInvalidTextualChildDiagnostic);
                        if (elem_1) {
                            result = elaborateElementwise((function () { return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0: return [4 /*yield*/, elem_1];
                                    case 1:
                                        _a.sent();
                                        return [2 /*return*/];
                                }
                            }); })(), source, target, relation) || result;
                        }
                    }
                    else if (!isTypeRelatedTo(getIndexedAccessType(source, childrenNameType), childrenTargetType, relation)) {
                        // arity mismatch
                        result = true;
                        error(containingElement.openingElement.tagName, ts.Diagnostics.This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_provided, childrenPropName, typeToString(childrenTargetType));
                    }
                }
            }
            return result;
            function getInvalidTextualChildDiagnostic() {
                if (!invalidTextDiagnostic) {
                    var tagNameText = ts.getTextOfNode(node.parent.tagName);
                    var childPropName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node));
                    var childrenPropName = childPropName === undefined ? "children" : ts.unescapeLeadingUnderscores(childPropName);
                    var childrenTargetType = getIndexedAccessType(target, getLiteralType(childrenPropName));
                    var diagnostic = ts.Diagnostics._0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_type_of_1_is_2;
                    invalidTextDiagnostic = __assign({}, diagnostic, { key: "!!ALREADY FORMATTED!!", message: ts.formatMessage(/*_dummy*/ undefined, diagnostic, tagNameText, childrenPropName, typeToString(childrenTargetType)) });
                }
                return invalidTextDiagnostic;
            }
        }
        function generateLimitedTupleElements(node, target) {
            var len, i, elem, nameType;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        len = ts.length(node.elements);
                        if (!len)
                            return [2 /*return*/];
                        i = 0;
                        _a.label = 1;
                    case 1:
                        if (!(i < len)) return [3 /*break*/, 4];
                        // Skip elements which do not exist in the target - a length error on the tuple overall is likely better than an error on a mismatched index signature
                        if (isTupleLikeType(target) && !getPropertyOfType(target, ("" + i)))
                            return [3 /*break*/, 3];
                        elem = node.elements[i];
                        if (ts.isOmittedExpression(elem))
                            return [3 /*break*/, 3];
                        nameType = getLiteralType(i);
                        return [4 /*yield*/, { errorNode: elem, innerExpression: elem, nameType: nameType }];
                    case 2:
                        _a.sent();
                        _a.label = 3;
                    case 3:
                        i++;
                        return [3 /*break*/, 1];
                    case 4: return [2 /*return*/];
                }
            });
        }
        function elaborateArrayLiteral(node, source, target, relation) {
            if (target.flags & 131068 /* Primitive */)
                return false;
            if (isTupleLikeType(source)) {
                return elaborateElementwise(generateLimitedTupleElements(node, target), source, target, relation);
            }
            // recreate a tuple from the elements, if possible
            var tupleizedType = checkArrayLiteral(node, 1 /* Contextual */, /*forceTuple*/ true);
            if (isTupleLikeType(tupleizedType)) {
                return elaborateElementwise(generateLimitedTupleElements(node, target), tupleizedType, target, relation);
            }
            return false;
        }
        function generateObjectLiteralElements(node) {
            var _i, _a, prop, type, _b;
            return __generator(this, function (_c) {
                switch (_c.label) {
                    case 0:
                        if (!ts.length(node.properties))
                            return [2 /*return*/];
                        _i = 0, _a = node.properties;
                        _c.label = 1;
                    case 1:
                        if (!(_i < _a.length)) return [3 /*break*/, 8];
                        prop = _a[_i];
                        if (ts.isSpreadAssignment(prop))
                            return [3 /*break*/, 7];
                        type = getLiteralTypeFromProperty(getSymbolOfNode(prop), 8576 /* StringOrNumberLiteralOrUnique */);
                        if (!type || (type.flags & 131072 /* Never */)) {
                            return [3 /*break*/, 7];
                        }
                        _b = prop.kind;
                        switch (_b) {
                            case 160 /* SetAccessor */: return [3 /*break*/, 2];
                            case 159 /* GetAccessor */: return [3 /*break*/, 2];
                            case 157 /* MethodDeclaration */: return [3 /*break*/, 2];
                            case 277 /* ShorthandPropertyAssignment */: return [3 /*break*/, 2];
                            case 276 /* PropertyAssignment */: return [3 /*break*/, 4];
                        }
                        return [3 /*break*/, 6];
                    case 2: return [4 /*yield*/, { errorNode: prop.name, innerExpression: undefined, nameType: type }];
                    case 3:
                        _c.sent();
                        return [3 /*break*/, 7];
                    case 4: return [4 /*yield*/, { errorNode: prop.name, innerExpression: prop.initializer, nameType: type, errorMessage: isComputedNonLiteralName(prop.name) ? ts.Diagnostics.Type_of_computed_property_s_value_is_0_which_is_not_assignable_to_type_1 : undefined }];
                    case 5:
                        _c.sent();
                        return [3 /*break*/, 7];
                    case 6:
                        ts.Debug.assertNever(prop);
                        _c.label = 7;
                    case 7:
                        _i++;
                        return [3 /*break*/, 1];
                    case 8: return [2 /*return*/];
                }
            });
        }
        function elaborateObjectLiteral(node, source, target, relation) {
            if (target.flags & 131068 /* Primitive */)
                return false;
            return elaborateElementwise(generateObjectLiteralElements(node), source, target, relation);
        }
        /**
         * This is *not* a bi-directional relationship.
         * If one needs to check both directions for comparability, use a second call to this function or 'isTypeComparableTo'.
         */
        function checkTypeComparableTo(source, target, errorNode, headMessage, containingMessageChain) {
            return checkTypeRelatedTo(source, target, comparableRelation, errorNode, headMessage, containingMessageChain);
        }
        function isSignatureAssignableTo(source, target, ignoreReturnTypes) {
            return compareSignaturesRelated(source, target, 0 /* None */, ignoreReturnTypes, /*reportErrors*/ false, 
            /*errorReporter*/ undefined, compareTypesAssignable) !== 0 /* False */;
        }
        /**
         * Returns true if `s` is `(...args: any[]) => any` or `(this: any, ...args: any[]) => any`
         */
        function isAnySignature(s) {
            return !s.typeParameters && (!s.thisParameter || isTypeAny(getTypeOfParameter(s.thisParameter))) && s.parameters.length === 1 &&
                s.hasRestParameter && (getTypeOfParameter(s.parameters[0]) === anyArrayType || isTypeAny(getTypeOfParameter(s.parameters[0]))) &&
                isTypeAny(getReturnTypeOfSignature(s));
        }
        /**
         * See signatureRelatedTo, compareSignaturesIdentical
         */
        function compareSignaturesRelated(source, target, callbackCheck, ignoreReturnTypes, reportErrors, errorReporter, compareTypes) {
            // TODO (drosen): De-duplicate code between related functions.
            if (source === target) {
                return -1 /* True */;
            }
            if (isAnySignature(target)) {
                return -1 /* True */;
            }
            var targetCount = getParameterCount(target);
            if (!hasEffectiveRestParameter(target) && getMinArgumentCount(source) > targetCount) {
                return 0 /* False */;
            }
            if (source.typeParameters && source.typeParameters !== target.typeParameters) {
                target = getCanonicalSignature(target);
                source = instantiateSignatureInContextOf(source, target, /*inferenceContext*/ undefined, compareTypes);
            }
            var sourceCount = getParameterCount(source);
            var sourceRestType = getNonArrayRestType(source);
            var targetRestType = getNonArrayRestType(target);
            if (sourceRestType && targetRestType && sourceCount !== targetCount) {
                // We're not able to relate misaligned complex rest parameters
                return 0 /* False */;
            }
            var kind = target.declaration ? target.declaration.kind : 0 /* Unknown */;
            var strictVariance = !callbackCheck && strictFunctionTypes && kind !== 157 /* MethodDeclaration */ &&
                kind !== 156 /* MethodSignature */ && kind !== 158 /* Constructor */;
            var result = -1 /* True */;
            var sourceThisType = getThisTypeOfSignature(source);
            if (sourceThisType && sourceThisType !== voidType) {
                var targetThisType = getThisTypeOfSignature(target);
                if (targetThisType) {
                    // void sources are assignable to anything.
                    var related = !strictVariance && compareTypes(sourceThisType, targetThisType, /*reportErrors*/ false)
                        || compareTypes(targetThisType, sourceThisType, reportErrors);
                    if (!related) {
                        if (reportErrors) {
                            errorReporter(ts.Diagnostics.The_this_types_of_each_signature_are_incompatible);
                        }
                        return 0 /* False */;
                    }
                    result &= related;
                }
            }
            var paramCount = sourceRestType || targetRestType ? Math.min(sourceCount, targetCount) : Math.max(sourceCount, targetCount);
            var restIndex = sourceRestType || targetRestType ? paramCount - 1 : -1;
            for (var i = 0; i < paramCount; i++) {
                var sourceType = i === restIndex ? getRestTypeAtPosition(source, i) : getTypeAtPosition(source, i);
                var targetType = i === restIndex ? getRestTypeAtPosition(target, i) : getTypeAtPosition(target, i);
                // In order to ensure that any generic type Foo<T> is at least co-variant with respect to T no matter
                // how Foo uses T, we need to relate parameters bi-variantly (given that parameters are input positions,
                // they naturally relate only contra-variantly). However, if the source and target parameters both have
                // function types with a single call signature, we know we are relating two callback parameters. In
                // that case it is sufficient to only relate the parameters of the signatures co-variantly because,
                // similar to return values, callback parameters are output positions. This means that a Promise<T>,
                // where T is used only in callback parameter positions, will be co-variant (as opposed to bi-variant)
                // with respect to T.
                var sourceSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(sourceType));
                var targetSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(targetType));
                var callbacks = sourceSig && targetSig && !signatureHasTypePredicate(sourceSig) && !signatureHasTypePredicate(targetSig) &&
                    (getFalsyFlags(sourceType) & 98304 /* Nullable */) === (getFalsyFlags(targetType) & 98304 /* Nullable */);
                var related = callbacks ?
                    // TODO: GH#18217 It will work if they're both `undefined`, but not if only one is
                    compareSignaturesRelated(targetSig, sourceSig, strictVariance ? 2 /* Strict */ : 1 /* Bivariant */, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) :
                    !callbackCheck && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors);
                if (!related) {
                    if (reportErrors) {
                        errorReporter(ts.Diagnostics.Types_of_parameters_0_and_1_are_incompatible, ts.unescapeLeadingUnderscores(getParameterNameAtPosition(source, i)), ts.unescapeLeadingUnderscores(getParameterNameAtPosition(target, i)));
                    }
                    return 0 /* False */;
                }
                result &= related;
            }
            if (!ignoreReturnTypes) {
                // If a signature reolution is already in-flight, skip issuing a circularity error
                // here and just use the `any` type directly
                var targetReturnType = isResolvingReturnTypeOfSignature(target) ? anyType : (target.declaration && isJSConstructor(target.declaration)) ?
                    getJSClassType(target.declaration.symbol) : getReturnTypeOfSignature(target);
                if (targetReturnType === voidType) {
                    return result;
                }
                var sourceReturnType = isResolvingReturnTypeOfSignature(source) ? anyType : (source.declaration && isJSConstructor(source.declaration)) ?
                    getJSClassType(source.declaration.symbol) : getReturnTypeOfSignature(source);
                // The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions
                var targetTypePredicate = getTypePredicateOfSignature(target);
                if (targetTypePredicate) {
                    var sourceTypePredicate = getTypePredicateOfSignature(source);
                    if (sourceTypePredicate) {
                        result &= compareTypePredicateRelatedTo(sourceTypePredicate, targetTypePredicate, reportErrors, errorReporter, compareTypes);
                    }
                    else if (ts.isIdentifierTypePredicate(targetTypePredicate)) {
                        if (reportErrors) {
                            errorReporter(ts.Diagnostics.Signature_0_must_be_a_type_predicate, signatureToString(source));
                        }
                        return 0 /* False */;
                    }
                }
                else {
                    // When relating callback signatures, we still need to relate return types bi-variantly as otherwise
                    // the containing type wouldn't be co-variant. For example, interface Foo<T> { add(cb: () => T): void }
                    // wouldn't be co-variant for T without this rule.
                    result &= callbackCheck === 1 /* Bivariant */ && compareTypes(targetReturnType, sourceReturnType, /*reportErrors*/ false) ||
                        compareTypes(sourceReturnType, targetReturnType, reportErrors);
                }
            }
            return result;
        }
        function compareTypePredicateRelatedTo(source, target, reportErrors, errorReporter, compareTypes) {
            if (source.kind !== target.kind) {
                if (reportErrors) {
                    errorReporter(ts.Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard);
                    errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
                }
                return 0 /* False */;
            }
            if (source.kind === 1 /* Identifier */) {
                if (source.parameterIndex !== target.parameterIndex) {
                    if (reportErrors) {
                        errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, source.parameterName, target.parameterName);
                        errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
                    }
                    return 0 /* False */;
                }
            }
            var related = compareTypes(source.type, target.type, reportErrors);
            if (related === 0 /* False */ && reportErrors) {
                errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
            }
            return related;
        }
        function isImplementationCompatibleWithOverload(implementation, overload) {
            var erasedSource = getErasedSignature(implementation);
            var erasedTarget = getErasedSignature(overload);
            // First see if the return types are compatible in either direction.
            var sourceReturnType = getReturnTypeOfSignature(erasedSource);
            var targetReturnType = getReturnTypeOfSignature(erasedTarget);
            if (targetReturnType === voidType
                || isTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation)
                || isTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation)) {
                return isSignatureAssignableTo(erasedSource, erasedTarget, /*ignoreReturnTypes*/ true);
            }
            return false;
        }
        function isEmptyResolvedType(t) {
            return t.properties.length === 0 &&
                t.callSignatures.length === 0 &&
                t.constructSignatures.length === 0 &&
                !t.stringIndexInfo &&
                !t.numberIndexInfo;
        }
        function isEmptyObjectType(type) {
            return type.flags & 524288 /* Object */ ? !isGenericMappedType(type) && isEmptyResolvedType(resolveStructuredTypeMembers(type)) :
                type.flags & 67108864 /* NonPrimitive */ ? true :
                    type.flags & 1048576 /* Union */ ? ts.some(type.types, isEmptyObjectType) :
                        type.flags & 2097152 /* Intersection */ ? ts.every(type.types, isEmptyObjectType) :
                            false;
        }
        function isEmptyAnonymousObjectType(type) {
            return !!(ts.getObjectFlags(type) & 16 /* Anonymous */) && isEmptyObjectType(type);
        }
        function isStringIndexSignatureOnlyType(type) {
            return type.flags & 524288 /* Object */ && !isGenericMappedType(type) && getPropertiesOfType(type).length === 0 && getIndexInfoOfType(type, 0 /* String */) && !getIndexInfoOfType(type, 1 /* Number */) ||
                type.flags & 3145728 /* UnionOrIntersection */ && ts.every(type.types, isStringIndexSignatureOnlyType) ||
                false;
        }
        function isEnumTypeRelatedTo(sourceSymbol, targetSymbol, errorReporter) {
            if (sourceSymbol === targetSymbol) {
                return true;
            }
            var id = getSymbolId(sourceSymbol) + "," + getSymbolId(targetSymbol);
            var relation = enumRelation.get(id);
            if (relation !== undefined && !(relation === 2 /* Failed */ && errorReporter)) {
                return relation === 1 /* Succeeded */;
            }
            if (sourceSymbol.escapedName !== targetSymbol.escapedName || !(sourceSymbol.flags & 256 /* RegularEnum */) || !(targetSymbol.flags & 256 /* RegularEnum */)) {
                enumRelation.set(id, 3 /* FailedAndReported */);
                return false;
            }
            var targetEnumType = getTypeOfSymbol(targetSymbol);
            for (var _i = 0, _a = getPropertiesOfType(getTypeOfSymbol(sourceSymbol)); _i < _a.length; _i++) {
                var property = _a[_i];
                if (property.flags & 8 /* EnumMember */) {
                    var targetProperty = getPropertyOfType(targetEnumType, property.escapedName);
                    if (!targetProperty || !(targetProperty.flags & 8 /* EnumMember */)) {
                        if (errorReporter) {
                            errorReporter(ts.Diagnostics.Property_0_is_missing_in_type_1, ts.symbolName(property), typeToString(getDeclaredTypeOfSymbol(targetSymbol), /*enclosingDeclaration*/ undefined, 64 /* UseFullyQualifiedType */));
                            enumRelation.set(id, 3 /* FailedAndReported */);
                        }
                        else {
                            enumRelation.set(id, 2 /* Failed */);
                        }
                        return false;
                    }
                }
            }
            enumRelation.set(id, 1 /* Succeeded */);
            return true;
        }
        function isSimpleTypeRelatedTo(source, target, relation, errorReporter) {
            var s = source.flags;
            var t = target.flags;
            if (t & 3 /* AnyOrUnknown */ || s & 131072 /* Never */ || source === wildcardType)
                return true;
            if (t & 131072 /* Never */)
                return false;
            if (s & 132 /* StringLike */ && t & 4 /* String */)
                return true;
            if (s & 128 /* StringLiteral */ && s & 1024 /* EnumLiteral */ &&
                t & 128 /* StringLiteral */ && !(t & 1024 /* EnumLiteral */) &&
                source.value === target.value)
                return true;
            if (s & 296 /* NumberLike */ && t & 8 /* Number */)
                return true;
            if (s & 256 /* NumberLiteral */ && s & 1024 /* EnumLiteral */ &&
                t & 256 /* NumberLiteral */ && !(t & 1024 /* EnumLiteral */) &&
                source.value === target.value)
                return true;
            if (s & 2112 /* BigIntLike */ && t & 64 /* BigInt */)
                return true;
            if (s & 528 /* BooleanLike */ && t & 16 /* Boolean */)
                return true;
            if (s & 12288 /* ESSymbolLike */ && t & 4096 /* ESSymbol */)
                return true;
            if (s & 32 /* Enum */ && t & 32 /* Enum */ && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter))
                return true;
            if (s & 1024 /* EnumLiteral */ && t & 1024 /* EnumLiteral */) {
                if (s & 1048576 /* Union */ && t & 1048576 /* Union */ && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter))
                    return true;
                if (s & 2944 /* Literal */ && t & 2944 /* Literal */ &&
                    source.value === target.value &&
                    isEnumTypeRelatedTo(getParentOfSymbol(source.symbol), getParentOfSymbol(target.symbol), errorReporter))
                    return true;
            }
            if (s & 32768 /* Undefined */ && (!strictNullChecks || t & (32768 /* Undefined */ | 16384 /* Void */)))
                return true;
            if (s & 65536 /* Null */ && (!strictNullChecks || t & 65536 /* Null */))
                return true;
            if (s & 524288 /* Object */ && t & 67108864 /* NonPrimitive */)
                return true;
            if (relation === assignableRelation || relation === comparableRelation) {
                if (s & 1 /* Any */)
                    return true;
                // Type number or any numeric literal type is assignable to any numeric enum type or any
                // numeric enum literal type. This rule exists for backwards compatibility reasons because
                // bit-flag enum types sometimes look like literal enum types with numeric literal values.
                if (s & (8 /* Number */ | 256 /* NumberLiteral */) && !(s & 1024 /* EnumLiteral */) && (t & 32 /* Enum */ || t & 256 /* NumberLiteral */ && t & 1024 /* EnumLiteral */))
                    return true;
            }
            return false;
        }
        function isTypeRelatedTo(source, target, relation) {
            if (isFreshLiteralType(source)) {
                source = source.regularType;
            }
            if (isFreshLiteralType(target)) {
                target = target.regularType;
            }
            if (source === target ||
                relation === comparableRelation && !(target.flags & 131072 /* Never */) && isSimpleTypeRelatedTo(target, source, relation) ||
                relation !== identityRelation && isSimpleTypeRelatedTo(source, target, relation)) {
                return true;
            }
            if (source.flags & 524288 /* Object */ && target.flags & 524288 /* Object */) {
                var related = relation.get(getRelationKey(source, target, relation));
                if (related !== undefined) {
                    return related === 1 /* Succeeded */;
                }
            }
            if (source.flags & 66846720 /* StructuredOrInstantiable */ || target.flags & 66846720 /* StructuredOrInstantiable */) {
                return checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined);
            }
            return false;
        }
        function isIgnoredJsxProperty(source, sourceProp) {
            return ts.getObjectFlags(source) & 4096 /* JsxAttributes */ && !isUnhyphenatedJsxName(sourceProp.escapedName);
        }
        /**
         * Checks if 'source' is related to 'target' (e.g.: is a assignable to).
         * @param source The left-hand-side of the relation.
         * @param target The right-hand-side of the relation.
         * @param relation The relation considered. One of 'identityRelation', 'subtypeRelation', 'assignableRelation', or 'comparableRelation'.
         * Used as both to determine which checks are performed and as a cache of previously computed results.
         * @param errorNode The suggested node upon which all errors will be reported, if defined. This may or may not be the actual node used.
         * @param headMessage If the error chain should be prepended by a head message, then headMessage will be used.
         * @param containingMessageChain A chain of errors to prepend any new errors found.
         */
        function checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain, errorOutputContainer) {
            var errorInfo;
            var relatedInfo;
            var maybeKeys;
            var sourceStack;
            var targetStack;
            var maybeCount = 0;
            var depth = 0;
            var expandingFlags = 0 /* None */;
            var overflow = false;
            var overrideNextErrorInfo;
            ts.Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking");
            var result = isRelatedTo(source, target, /*reportErrors*/ !!errorNode, headMessage);
            if (overflow) {
                error(errorNode, ts.Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target));
            }
            else if (errorInfo) {
                if (containingMessageChain) {
                    var chain = containingMessageChain();
                    if (chain) {
                        errorInfo = ts.concatenateDiagnosticMessageChains(chain, errorInfo);
                    }
                }
                var relatedInformation = void 0;
                // Check if we should issue an extra diagnostic to produce a quickfix for a slightly incorrect import statement
                if (headMessage && errorNode && !result && source.symbol) {
                    var links = getSymbolLinks(source.symbol);
                    if (links.originatingImport && !ts.isImportCall(links.originatingImport)) {
                        var helpfulRetry = checkTypeRelatedTo(getTypeOfSymbol(links.target), target, relation, /*errorNode*/ undefined);
                        if (helpfulRetry) {
                            // Likely an incorrect import. Issue a helpful diagnostic to produce a quickfix to change the import
                            var diag_1 = ts.createDiagnosticForNode(links.originatingImport, ts.Diagnostics.Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead);
                            relatedInformation = ts.append(relatedInformation, diag_1); // Cause the error to appear with the error that triggered it
                        }
                    }
                }
                var diag = ts.createDiagnosticForNodeFromMessageChain(errorNode, errorInfo, relatedInformation);
                if (relatedInfo) {
                    ts.addRelatedInfo.apply(void 0, [diag].concat(relatedInfo));
                }
                if (errorOutputContainer) {
                    errorOutputContainer.error = diag;
                }
                diagnostics.add(diag); // TODO: GH#18217
            }
            return result !== 0 /* False */;
            function reportError(message, arg0, arg1, arg2, arg3) {
                ts.Debug.assert(!!errorNode);
                errorInfo = ts.chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2, arg3);
            }
            function associateRelatedInfo(info) {
                ts.Debug.assert(!!errorInfo);
                if (!relatedInfo) {
                    relatedInfo = [info];
                }
                else {
                    relatedInfo.push(info);
                }
            }
            function reportRelationError(message, source, target) {
                var _a = getTypeNamesForErrorDisplay(source, target), sourceType = _a[0], targetType = _a[1];
                if (target.flags & 262144 /* TypeParameter */ && target.immediateBaseConstraint !== undefined && isTypeAssignableTo(source, target.immediateBaseConstraint)) {
                    reportError(ts.Diagnostics._0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_constraint_2, sourceType, targetType, typeToString(target.immediateBaseConstraint));
                }
                if (!message) {
                    if (relation === comparableRelation) {
                        message = ts.Diagnostics.Type_0_is_not_comparable_to_type_1;
                    }
                    else if (sourceType === targetType) {
                        message = ts.Diagnostics.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated;
                    }
                    else {
                        message = ts.Diagnostics.Type_0_is_not_assignable_to_type_1;
                    }
                }
                reportError(message, sourceType, targetType);
            }
            function tryElaborateErrorsForPrimitivesAndObjects(source, target) {
                var sourceType = typeToString(source);
                var targetType = typeToString(target);
                if ((globalStringType === source && stringType === target) ||
                    (globalNumberType === source && numberType === target) ||
                    (globalBooleanType === source && booleanType === target) ||
                    (getGlobalESSymbolType(/*reportErrors*/ false) === source && esSymbolType === target)) {
                    reportError(ts.Diagnostics._0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible, targetType, sourceType);
                }
            }
            /**
             * Try and elaborate array and tuple errors. Returns false
             * if we have found an elaboration, or we should ignore
             * any other elaborations when relating the `source` and
             * `target` types.
             *
             * @param source
             * @param target
             * @param reportErrors
             */
            function tryElaborateArrayLikeErrors(source, target, reportErrors) {
                if (isTupleLikeType(source)) {
                    var sourceTuple = source.target;
                    if (sourceTuple && sourceTuple.readonly && isArrayOrTupleLikeType(target) &&
                        (!isReadonlyArrayType(target) || isTupleType(target) && !target.target.readonly)) {
                        if (reportErrors) {
                            reportError(ts.Diagnostics.The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1, typeToString(source), typeToString(target));
                        }
                        return false;
                    }
                    return isArrayLikeType(target);
                }
                if (isTupleLikeType(target)) {
                    return isArrayLikeType(source);
                }
                if (isReadonlyArrayType(source) && isArrayType(target) && !isReadonlyArrayType(target)) {
                    if (reportErrors) {
                        reportError(ts.Diagnostics.The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1, typeToString(source), typeToString(target));
                    }
                    return false;
                }
                return true;
            }
            /**
             * Compare two types and return
             * * Ternary.True if they are related with no assumptions,
             * * Ternary.Maybe if they are related with assumptions of other relationships, or
             * * Ternary.False if they are not related.
             */
            function isRelatedTo(source, target, reportErrors, headMessage, isApparentIntersectionConstituent) {
                if (reportErrors === void 0) { reportErrors = false; }
                if (isFreshLiteralType(source)) {
                    source = source.regularType;
                }
                if (isFreshLiteralType(target)) {
                    target = target.regularType;
                }
                if (source.flags & 33554432 /* Substitution */) {
                    source = source.substitute;
                }
                if (target.flags & 33554432 /* Substitution */) {
                    target = target.typeVariable;
                }
                if (source.flags & 25165824 /* Simplifiable */) {
                    source = getSimplifiedType(source, /*writing*/ false);
                }
                if (target.flags & 25165824 /* Simplifiable */) {
                    target = getSimplifiedType(target, /*writing*/ true);
                }
                // Try to see if we're relating something like `Foo` -> `Bar | null | undefined`.
                // If so, reporting the `null` and `undefined` in the type is hardly useful.
                // First, see if we're even relating an object type to a union.
                // Then see if the target is stripped down to a single non-union type.
                // Note
                //  * We actually want to remove null and undefined naively here (rather than using getNonNullableType),
                //    since we don't want to end up with a worse error like "`Foo` is not assignable to `NonNullable<T>`"
                //    when dealing with generics.
                //  * We also don't deal with primitive source types, since we already halt elaboration below.
                if (target.flags & 1048576 /* Union */ && source.flags & 524288 /* Object */ &&
                    target.types.length <= 3 && maybeTypeOfKind(target, 98304 /* Nullable */)) {
                    var nullStrippedTarget = extractTypesOfKind(target, ~98304 /* Nullable */);
                    if (!(nullStrippedTarget.flags & (1048576 /* Union */ | 131072 /* Never */))) {
                        target = nullStrippedTarget;
                    }
                }
                // both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases
                if (source === target)
                    return -1 /* True */;
                if (relation === identityRelation) {
                    return isIdenticalTo(source, target);
                }
                if (relation === comparableRelation && !(target.flags & 131072 /* Never */) && isSimpleTypeRelatedTo(target, source, relation) ||
                    isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined))
                    return -1 /* True */;
                var isComparingJsxAttributes = !!(ts.getObjectFlags(source) & 4096 /* JsxAttributes */);
                var isPerformingExcessPropertyChecks = (isObjectLiteralType(source) && ts.getObjectFlags(source) & 32768 /* FreshLiteral */);
                if (isPerformingExcessPropertyChecks) {
                    var discriminantType = target.flags & 1048576 /* Union */ ? findMatchingDiscriminantType(source, target) : undefined;
                    if (hasExcessProperties(source, target, discriminantType, reportErrors)) {
                        if (reportErrors) {
                            reportRelationError(headMessage, source, target);
                        }
                        return 0 /* False */;
                    }
                }
                if (relation !== comparableRelation && !isApparentIntersectionConstituent &&
                    source.flags & (131068 /* Primitive */ | 524288 /* Object */ | 2097152 /* Intersection */) && source !== globalObjectType &&
                    target.flags & (524288 /* Object */ | 2097152 /* Intersection */) && isWeakType(target) &&
                    (getPropertiesOfType(source).length > 0 || typeHasCallOrConstructSignatures(source)) &&
                    !hasCommonProperties(source, target, isComparingJsxAttributes)) {
                    if (reportErrors) {
                        var calls = getSignaturesOfType(source, 0 /* Call */);
                        var constructs = getSignaturesOfType(source, 1 /* Construct */);
                        if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, /*reportErrors*/ false) ||
                            constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, /*reportErrors*/ false)) {
                            reportError(ts.Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, typeToString(source), typeToString(target));
                        }
                        else {
                            reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target));
                        }
                    }
                    return 0 /* False */;
                }
                var result = 0 /* False */;
                var saveErrorInfo = errorInfo;
                var isIntersectionConstituent = !!isApparentIntersectionConstituent;
                // Note that these checks are specifically ordered to produce correct results. In particular,
                // we need to deconstruct unions before intersections (because unions are always at the top),
                // and we need to handle "each" relations before "some" relations for the same kind of type.
                if (source.flags & 1048576 /* Union */) {
                    result = relation === comparableRelation ?
                        someTypeRelatedToType(source, target, reportErrors && !(source.flags & 131068 /* Primitive */)) :
                        eachTypeRelatedToType(source, target, reportErrors && !(source.flags & 131068 /* Primitive */));
                }
                else {
                    if (target.flags & 1048576 /* Union */) {
                        result = typeRelatedToSomeType(getRegularTypeOfObjectLiteral(source), target, reportErrors && !(source.flags & 131068 /* Primitive */) && !(target.flags & 131068 /* Primitive */));
                        if (result && isPerformingExcessPropertyChecks) {
                            // Validate against excess props using the original `source`
                            var discriminantType = target.flags & 1048576 /* Union */ ? findMatchingDiscriminantType(source, target) : undefined;
                            if (!propertiesRelatedTo(source, discriminantType || target, reportErrors, /*excludedProperties*/ undefined)) {
                                return 0 /* False */;
                            }
                        }
                    }
                    else if (target.flags & 2097152 /* Intersection */) {
                        isIntersectionConstituent = true; // set here to affect the following trio of checks
                        result = typeRelatedToEachType(getRegularTypeOfObjectLiteral(source), target, reportErrors);
                        if (result && isPerformingExcessPropertyChecks) {
                            // Validate against excess props using the original `source`
                            if (!propertiesRelatedTo(source, target, reportErrors, /*excludedProperties*/ undefined)) {
                                return 0 /* False */;
                            }
                        }
                    }
                    else if (source.flags & 2097152 /* Intersection */) {
                        // Check to see if any constituents of the intersection are immediately related to the target.
                        //
                        // Don't report errors though. Checking whether a constituent is related to the source is not actually
                        // useful and leads to some confusing error messages. Instead it is better to let the below checks
                        // take care of this, or to not elaborate at all. For instance,
                        //
                        //    - For an object type (such as 'C = A & B'), users are usually more interested in structural errors.
                        //
                        //    - For a union type (such as '(A | B) = (C & D)'), it's better to hold onto the whole intersection
                        //          than to report that 'D' is not assignable to 'A' or 'B'.
                        //
                        //    - For a primitive type or type parameter (such as 'number = A & B') there is no point in
                        //          breaking the intersection apart.
                        result = someTypeRelatedToType(source, target, /*reportErrors*/ false);
                    }
                    if (!result && (source.flags & 66846720 /* StructuredOrInstantiable */ || target.flags & 66846720 /* StructuredOrInstantiable */)) {
                        if (result = recursiveTypeRelatedTo(source, target, reportErrors, isIntersectionConstituent)) {
                            errorInfo = saveErrorInfo;
                        }
                    }
                }
                if (!result && source.flags & 2097152 /* Intersection */) {
                    // The combined constraint of an intersection type is the intersection of the constraints of
                    // the constituents. When an intersection type contains instantiable types with union type
                    // constraints, there are situations where we need to examine the combined constraint. One is
                    // when the target is a union type. Another is when the intersection contains types belonging
                    // to one of the disjoint domains. For example, given type variables T and U, each with the
                    // constraint 'string | number', the combined constraint of 'T & U' is 'string | number' and
                    // we need to check this constraint against a union on the target side. Also, given a type
                    // variable V constrained to 'string | number', 'V & number' has a combined constraint of
                    // 'string & number | number & number' which reduces to just 'number'.
                    var constraint = getUnionConstraintOfIntersection(source, !!(target.flags & 1048576 /* Union */));
                    if (constraint) {
                        if (result = isRelatedTo(constraint, target, reportErrors, /*headMessage*/ undefined, isIntersectionConstituent)) {
                            errorInfo = saveErrorInfo;
                        }
                    }
                }
                if (!result && reportErrors) {
                    var maybeSuppress = overrideNextErrorInfo;
                    overrideNextErrorInfo = undefined;
                    if (source.flags & 524288 /* Object */ && target.flags & 524288 /* Object */) {
                        var currentError = errorInfo;
                        tryElaborateArrayLikeErrors(source, target, reportErrors);
                        if (errorInfo !== currentError) {
                            maybeSuppress = errorInfo;
                        }
                    }
                    if (source.flags & 524288 /* Object */ && target.flags & 131068 /* Primitive */) {
                        tryElaborateErrorsForPrimitivesAndObjects(source, target);
                    }
                    else if (source.symbol && source.flags & 524288 /* Object */ && globalObjectType === source) {
                        reportError(ts.Diagnostics.The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead);
                    }
                    else if (isComparingJsxAttributes && target.flags & 2097152 /* Intersection */) {
                        var targetTypes = target.types;
                        var intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, errorNode);
                        var intrinsicClassAttributes = getJsxType(JsxNames.IntrinsicClassAttributes, errorNode);
                        if (intrinsicAttributes !== errorType && intrinsicClassAttributes !== errorType &&
                            (ts.contains(targetTypes, intrinsicAttributes) || ts.contains(targetTypes, intrinsicClassAttributes))) {
                            // do not report top error
                            return result;
                        }
                    }
                    if (!headMessage && maybeSuppress) {
                        // Used by, eg, missing property checking to replace the top-level message with a more informative one
                        return result;
                    }
                    reportRelationError(headMessage, source, target);
                }
                return result;
            }
            function isIdenticalTo(source, target) {
                var result;
                var flags = source.flags & target.flags;
                if (flags & 524288 /* Object */ || flags & 8388608 /* IndexedAccess */ || flags & 16777216 /* Conditional */ || flags & 4194304 /* Index */ || flags & 33554432 /* Substitution */) {
                    return recursiveTypeRelatedTo(source, target, /*reportErrors*/ false, /*isIntersectionConstituent*/ false);
                }
                if (flags & (1048576 /* Union */ | 2097152 /* Intersection */)) {
                    if (result = eachTypeRelatedToSomeType(source, target)) {
                        if (result &= eachTypeRelatedToSomeType(target, source)) {
                            return result;
                        }
                    }
                }
                return 0 /* False */;
            }
            function hasExcessProperties(source, target, discriminant, reportErrors) {
                if (!noImplicitAny && ts.getObjectFlags(target) & 16384 /* JSLiteral */) {
                    return false; // Disable excess property checks on JS literals to simulate having an implicit "index signature" - but only outside of noImplicitAny
                }
                if (isExcessPropertyCheckTarget(target)) {
                    var isComparingJsxAttributes = !!(ts.getObjectFlags(source) & 4096 /* JsxAttributes */);
                    if ((relation === assignableRelation || relation === comparableRelation) &&
                        (isTypeSubsetOf(globalObjectType, target) || (!isComparingJsxAttributes && isEmptyObjectType(target)))) {
                        return false;
                    }
                    if (discriminant) {
                        // check excess properties against discriminant type only, not the entire union
                        return hasExcessProperties(source, discriminant, /*discriminant*/ undefined, reportErrors);
                    }
                    var _loop_7 = function (prop) {
                        if (shouldCheckAsExcessProperty(prop, source.symbol) && !isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) {
                            if (reportErrors) {
                                // Report error in terms of object types in the target as those are the only ones
                                // we check in isKnownProperty.
                                var errorTarget = filterType(target, isExcessPropertyCheckTarget);
                                // We know *exactly* where things went wrong when comparing the types.
                                // Use this property as the error node as this will be more helpful in
                                // reasoning about what went wrong.
                                if (!errorNode)
                                    return { value: ts.Debug.fail() };
                                if (ts.isJsxAttributes(errorNode) || ts.isJsxOpeningLikeElement(errorNode) || ts.isJsxOpeningLikeElement(errorNode.parent)) {
                                    // JsxAttributes has an object-literal flag and undergo same type-assignablity check as normal object-literal.
                                    // However, using an object-literal error message will be very confusing to the users so we give different a message.
                                    // TODO: Spelling suggestions for excess jsx attributes (needs new diagnostic messages)
                                    reportError(ts.Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(errorTarget));
                                }
                                else {
                                    // use the property's value declaration if the property is assigned inside the literal itself
                                    var objectLiteralDeclaration_1 = source.symbol && ts.firstOrUndefined(source.symbol.declarations);
                                    var suggestion = void 0;
                                    if (prop.valueDeclaration && ts.findAncestor(prop.valueDeclaration, function (d) { return d === objectLiteralDeclaration_1; })) {
                                        var propDeclaration = prop.valueDeclaration;
                                        ts.Debug.assertNode(propDeclaration, ts.isObjectLiteralElementLike);
                                        errorNode = propDeclaration;
                                        var name = propDeclaration.name;
                                        if (ts.isIdentifier(name)) {
                                            suggestion = getSuggestionForNonexistentProperty(name, errorTarget);
                                        }
                                    }
                                    if (suggestion !== undefined) {
                                        reportError(ts.Diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2, symbolToString(prop), typeToString(errorTarget), suggestion);
                                    }
                                    else {
                                        reportError(ts.Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(prop), typeToString(errorTarget));
                                    }
                                }
                            }
                            return { value: true };
                        }
                    };
                    for (var _i = 0, _a = getPropertiesOfType(source); _i < _a.length; _i++) {
                        var prop = _a[_i];
                        var state_3 = _loop_7(prop);
                        if (typeof state_3 === "object")
                            return state_3.value;
                    }
                }
                return false;
            }
            function shouldCheckAsExcessProperty(prop, container) {
                return prop.valueDeclaration && container.valueDeclaration && prop.valueDeclaration.parent === container.valueDeclaration;
            }
            function eachTypeRelatedToSomeType(source, target) {
                var result = -1 /* True */;
                var sourceTypes = source.types;
                for (var _i = 0, sourceTypes_1 = sourceTypes; _i < sourceTypes_1.length; _i++) {
                    var sourceType = sourceTypes_1[_i];
                    var related = typeRelatedToSomeType(sourceType, target, /*reportErrors*/ false);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function typeRelatedToSomeType(source, target, reportErrors) {
                var targetTypes = target.types;
                if (target.flags & 1048576 /* Union */ && containsType(targetTypes, source)) {
                    return -1 /* True */;
                }
                for (var _i = 0, targetTypes_1 = targetTypes; _i < targetTypes_1.length; _i++) {
                    var type = targetTypes_1[_i];
                    var related = isRelatedTo(source, type, /*reportErrors*/ false);
                    if (related) {
                        return related;
                    }
                }
                if (reportErrors) {
                    var bestMatchingType = findMatchingDiscriminantType(source, target) ||
                        findMatchingTypeReferenceOrTypeAliasReference(source, target) ||
                        findBestTypeForObjectLiteral(source, target) ||
                        findBestTypeForInvokable(source, target) ||
                        findMostOverlappyType(source, target);
                    isRelatedTo(source, bestMatchingType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true);
                }
                return 0 /* False */;
            }
            function findMatchingTypeReferenceOrTypeAliasReference(source, unionTarget) {
                var sourceObjectFlags = ts.getObjectFlags(source);
                if (sourceObjectFlags & (4 /* Reference */ | 16 /* Anonymous */) && unionTarget.flags & 1048576 /* Union */) {
                    return ts.find(unionTarget.types, function (target) {
                        if (target.flags & 524288 /* Object */) {
                            var overlapObjFlags = sourceObjectFlags & ts.getObjectFlags(target);
                            if (overlapObjFlags & 4 /* Reference */) {
                                return source.target === target.target;
                            }
                            if (overlapObjFlags & 16 /* Anonymous */) {
                                return !!source.aliasSymbol && source.aliasSymbol === target.aliasSymbol;
                            }
                        }
                        return false;
                    });
                }
            }
            function findBestTypeForObjectLiteral(source, unionTarget) {
                if (ts.getObjectFlags(source) & 128 /* ObjectLiteral */ && forEachType(unionTarget, isArrayLikeType)) {
                    return ts.find(unionTarget.types, function (t) { return !isArrayLikeType(t); });
                }
            }
            function findBestTypeForInvokable(source, unionTarget) {
                var signatureKind = 0 /* Call */;
                var hasSignatures = getSignaturesOfType(source, signatureKind).length > 0 ||
                    (signatureKind = 1 /* Construct */, getSignaturesOfType(source, signatureKind).length > 0);
                if (hasSignatures) {
                    return ts.find(unionTarget.types, function (t) { return getSignaturesOfType(t, signatureKind).length > 0; });
                }
            }
            function findMostOverlappyType(source, unionTarget) {
                var bestMatch;
                var matchingCount = 0;
                for (var _i = 0, _a = unionTarget.types; _i < _a.length; _i++) {
                    var target_1 = _a[_i];
                    var overlap = getIntersectionType([getIndexType(source), getIndexType(target_1)]);
                    if (overlap.flags & 4194304 /* Index */) {
                        // perfect overlap of keys
                        bestMatch = target_1;
                        matchingCount = Infinity;
                    }
                    else if (overlap.flags & 1048576 /* Union */) {
                        // We only want to account for literal types otherwise.
                        // If we have a union of index types, it seems likely that we
                        // needed to elaborate between two generic mapped types anyway.
                        var len = ts.length(ts.filter(overlap.types, isUnitType));
                        if (len >= matchingCount) {
                            bestMatch = target_1;
                            matchingCount = len;
                        }
                    }
                    else if (isUnitType(overlap) && 1 >= matchingCount) {
                        bestMatch = target_1;
                        matchingCount = 1;
                    }
                }
                return bestMatch;
            }
            // Keep this up-to-date with the same logic within `getApparentTypeOfContextualType`, since they should behave similarly
            function findMatchingDiscriminantType(source, target) {
                if (target.flags & 1048576 /* Union */ && source.flags & (2097152 /* Intersection */ | 524288 /* Object */)) {
                    var sourceProperties = getPropertiesOfType(source);
                    if (sourceProperties) {
                        var sourcePropertiesFiltered = findDiscriminantProperties(sourceProperties, target);
                        if (sourcePropertiesFiltered) {
                            return discriminateTypeByDiscriminableItems(target, ts.map(sourcePropertiesFiltered, function (p) { return [function () { return getTypeOfSymbol(p); }, p.escapedName]; }), isRelatedTo);
                        }
                    }
                }
                return undefined;
            }
            function typeRelatedToEachType(source, target, reportErrors) {
                var result = -1 /* True */;
                var targetTypes = target.types;
                for (var _i = 0, targetTypes_2 = targetTypes; _i < targetTypes_2.length; _i++) {
                    var targetType = targetTypes_2[_i];
                    var related = isRelatedTo(source, targetType, reportErrors, /*headMessage*/ undefined, /*isIntersectionConstituent*/ true);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function someTypeRelatedToType(source, target, reportErrors) {
                var sourceTypes = source.types;
                if (source.flags & 1048576 /* Union */ && containsType(sourceTypes, target)) {
                    return -1 /* True */;
                }
                var len = sourceTypes.length;
                for (var i = 0; i < len; i++) {
                    var related = isRelatedTo(sourceTypes[i], target, reportErrors && i === len - 1);
                    if (related) {
                        return related;
                    }
                }
                return 0 /* False */;
            }
            function eachTypeRelatedToType(source, target, reportErrors) {
                var result = -1 /* True */;
                var sourceTypes = source.types;
                for (var _i = 0, sourceTypes_2 = sourceTypes; _i < sourceTypes_2.length; _i++) {
                    var sourceType = sourceTypes_2[_i];
                    var related = isRelatedTo(sourceType, target, reportErrors);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function typeArgumentsRelatedTo(sources, targets, variances, reportErrors) {
                if (sources === void 0) { sources = ts.emptyArray; }
                if (targets === void 0) { targets = ts.emptyArray; }
                if (variances === void 0) { variances = ts.emptyArray; }
                if (sources.length !== targets.length && relation === identityRelation) {
                    return 0 /* False */;
                }
                var length = sources.length <= targets.length ? sources.length : targets.length;
                var result = -1 /* True */;
                for (var i = 0; i < length; i++) {
                    // When variance information isn't available we default to covariance. This happens
                    // in the process of computing variance information for recursive types and when
                    // comparing 'this' type arguments.
                    var varianceFlags = i < variances.length ? variances[i] : 1 /* Covariant */;
                    var variance = varianceFlags & 7 /* VarianceMask */;
                    // We ignore arguments for independent type parameters (because they're never witnessed).
                    if (variance !== 4 /* Independent */) {
                        var s = sources[i];
                        var t = targets[i];
                        var related = -1 /* True */;
                        if (varianceFlags & 8 /* Unmeasurable */) {
                            // Even an `Unmeasurable` variance works out without a structural check if the source and target are _identical_.
                            // We can't simply assume invariance, because `Unmeasurable` marks nonlinear relations, for example, a relation tained by
                            // the `-?` modifier in a mapped type (where, no matter how the inputs are related, the outputs still might not be)
                            related = relation === identityRelation ? isRelatedTo(s, t, /*reportErrors*/ false) : compareTypesIdentical(s, t);
                        }
                        else if (variance === 1 /* Covariant */) {
                            related = isRelatedTo(s, t, reportErrors);
                        }
                        else if (variance === 2 /* Contravariant */) {
                            related = isRelatedTo(t, s, reportErrors);
                        }
                        else if (variance === 3 /* Bivariant */) {
                            // In the bivariant case we first compare contravariantly without reporting
                            // errors. Then, if that doesn't succeed, we compare covariantly with error
                            // reporting. Thus, error elaboration will be based on the the covariant check,
                            // which is generally easier to reason about.
                            related = isRelatedTo(t, s, /*reportErrors*/ false);
                            if (!related) {
                                related = isRelatedTo(s, t, reportErrors);
                            }
                        }
                        else {
                            // In the invariant case we first compare covariantly, and only when that
                            // succeeds do we proceed to compare contravariantly. Thus, error elaboration
                            // will typically be based on the covariant check.
                            related = isRelatedTo(s, t, reportErrors);
                            if (related) {
                                related &= isRelatedTo(t, s, reportErrors);
                            }
                        }
                        if (!related) {
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
                return result;
            }
            function propagateSidebandVarianceFlags(typeArguments, variances) {
                for (var i = 0; i < variances.length; i++) {
                    var v = variances[i];
                    if (v & 8 /* Unmeasurable */) {
                        instantiateType(typeArguments[i], reportUnmeasurableMarkers);
                    }
                    if (v & 16 /* Unreliable */) {
                        instantiateType(typeArguments[i], reportUnreliableMarkers);
                    }
                }
            }
            // Determine if possibly recursive types are related. First, check if the result is already available in the global cache.
            // Second, check if we have already started a comparison of the given two types in which case we assume the result to be true.
            // Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are
            // equal and infinitely expanding. Fourth, if we have reached a depth of 100 nested comparisons, assume we have runaway recursion
            // and issue an error. Otherwise, actually compare the structure of the two types.
            function recursiveTypeRelatedTo(source, target, reportErrors, isIntersectionConstituent) {
                if (overflow) {
                    return 0 /* False */;
                }
                var id = getRelationKey(source, target, relation);
                var related = relation.get(id);
                if (related !== undefined) {
                    if (reportErrors && related === 2 /* Failed */) {
                        // We are elaborating errors and the cached result is an unreported failure. The result will be reported
                        // as a failure, and should be updated as a reported failure by the bottom of this function.
                    }
                    else {
                        if (outofbandVarianceMarkerHandler) {
                            // We're in the middle of variance checking - integrate any unmeasurable/unreliable flags from this cached component
                            if (source.flags & (524288 /* Object */ | 16777216 /* Conditional */) && source.aliasSymbol &&
                                source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol) {
                                propagateSidebandVarianceFlags(source.aliasTypeArguments, getAliasVariances(source.aliasSymbol));
                            }
                            if (ts.getObjectFlags(source) & 4 /* Reference */ && ts.getObjectFlags(target) & 4 /* Reference */ && source.target === target.target && ts.length(source.typeArguments)) {
                                propagateSidebandVarianceFlags(source.typeArguments, getVariances(source.target));
                            }
                        }
                        return related === 1 /* Succeeded */ ? -1 /* True */ : 0 /* False */;
                    }
                }
                if (!maybeKeys) {
                    maybeKeys = [];
                    sourceStack = [];
                    targetStack = [];
                }
                else {
                    for (var i = 0; i < maybeCount; i++) {
                        // If source and target are already being compared, consider them related with assumptions
                        if (id === maybeKeys[i]) {
                            return 1 /* Maybe */;
                        }
                    }
                    if (depth === 100) {
                        overflow = true;
                        return 0 /* False */;
                    }
                }
                var maybeStart = maybeCount;
                maybeKeys[maybeCount] = id;
                maybeCount++;
                sourceStack[depth] = source;
                targetStack[depth] = target;
                depth++;
                var saveExpandingFlags = expandingFlags;
                if (!(expandingFlags & 1 /* Source */) && isDeeplyNestedType(source, sourceStack, depth))
                    expandingFlags |= 1 /* Source */;
                if (!(expandingFlags & 2 /* Target */) && isDeeplyNestedType(target, targetStack, depth))
                    expandingFlags |= 2 /* Target */;
                var result = expandingFlags !== 3 /* Both */ ? structuredTypeRelatedTo(source, target, reportErrors, isIntersectionConstituent) : 1 /* Maybe */;
                expandingFlags = saveExpandingFlags;
                depth--;
                if (result) {
                    if (result === -1 /* True */ || depth === 0) {
                        // If result is definitely true, record all maybe keys as having succeeded
                        for (var i = maybeStart; i < maybeCount; i++) {
                            relation.set(maybeKeys[i], 1 /* Succeeded */);
                        }
                        maybeCount = maybeStart;
                    }
                }
                else {
                    // A false result goes straight into global cache (when something is false under
                    // assumptions it will also be false without assumptions)
                    relation.set(id, reportErrors ? 3 /* FailedAndReported */ : 2 /* Failed */);
                    maybeCount = maybeStart;
                }
                return result;
            }
            function structuredTypeRelatedTo(source, target, reportErrors, isIntersectionConstituent) {
                var flags = source.flags & target.flags;
                if (relation === identityRelation && !(flags & 524288 /* Object */)) {
                    if (flags & 4194304 /* Index */) {
                        return isRelatedTo(source.type, target.type, /*reportErrors*/ false);
                    }
                    var result_3 = 0 /* False */;
                    if (flags & 8388608 /* IndexedAccess */) {
                        if (result_3 = isRelatedTo(source.objectType, target.objectType, /*reportErrors*/ false)) {
                            if (result_3 &= isRelatedTo(source.indexType, target.indexType, /*reportErrors*/ false)) {
                                return result_3;
                            }
                        }
                    }
                    if (flags & 16777216 /* Conditional */) {
                        if (source.root.isDistributive === target.root.isDistributive) {
                            if (result_3 = isRelatedTo(source.checkType, target.checkType, /*reportErrors*/ false)) {
                                if (result_3 &= isRelatedTo(source.extendsType, target.extendsType, /*reportErrors*/ false)) {
                                    if (result_3 &= isRelatedTo(getTrueTypeFromConditionalType(source), getTrueTypeFromConditionalType(target), /*reportErrors*/ false)) {
                                        if (result_3 &= isRelatedTo(getFalseTypeFromConditionalType(source), getFalseTypeFromConditionalType(target), /*reportErrors*/ false)) {
                                            return result_3;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (flags & 33554432 /* Substitution */) {
                        return isRelatedTo(source.substitute, target.substitute, /*reportErrors*/ false);
                    }
                    return 0 /* False */;
                }
                var result;
                var originalErrorInfo;
                var varianceCheckFailed = false;
                var saveErrorInfo = errorInfo;
                // We limit alias variance probing to only object and conditional types since their alias behavior
                // is more predictable than other, interned types, which may or may not have an alias depending on
                // the order in which things were checked.
                if (source.flags & (524288 /* Object */ | 16777216 /* Conditional */) && source.aliasSymbol &&
                    source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol &&
                    !(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) {
                    var variances = getAliasVariances(source.aliasSymbol);
                    var varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances);
                    if (varianceResult !== undefined) {
                        return varianceResult;
                    }
                }
                if (target.flags & 262144 /* TypeParameter */) {
                    // A source type { [P in Q]: X } is related to a target type T if keyof T is related to Q and X is related to T[Q].
                    if (ts.getObjectFlags(source) & 32 /* Mapped */ && isRelatedTo(getIndexType(target), getConstraintTypeFromMappedType(source))) {
                        if (!(getMappedTypeModifiers(source) & 4 /* IncludeOptional */)) {
                            var templateType = getTemplateTypeFromMappedType(source);
                            var indexedAccessType = getIndexedAccessType(target, getTypeParameterFromMappedType(source));
                            if (result = isRelatedTo(templateType, indexedAccessType, reportErrors)) {
                                return result;
                            }
                        }
                    }
                }
                else if (target.flags & 4194304 /* Index */) {
                    // A keyof S is related to a keyof T if T is related to S.
                    if (source.flags & 4194304 /* Index */) {
                        if (result = isRelatedTo(target.type, source.type, /*reportErrors*/ false)) {
                            return result;
                        }
                    }
                    // A type S is assignable to keyof T if S is assignable to keyof C, where C is the
                    // simplified form of T or, if T doesn't simplify, the constraint of T.
                    var constraint = getSimplifiedTypeOrConstraint(target.type);
                    if (constraint) {
                        // We require Ternary.True here such that circular constraints don't cause
                        // false positives. For example, given 'T extends { [K in keyof T]: string }',
                        // 'keyof T' has itself as its constraint and produces a Ternary.Maybe when
                        // related to other types.
                        if (isRelatedTo(source, getIndexType(constraint, target.stringsOnly), reportErrors) === -1 /* True */) {
                            return -1 /* True */;
                        }
                    }
                }
                else if (target.flags & 8388608 /* IndexedAccess */) {
                    // A type S is related to a type T[K] if S is related to C, where C is the base
                    // constraint of T[K] for writing.
                    if (relation !== identityRelation) {
                        var objectType = target.objectType;
                        var indexType = target.indexType;
                        var baseObjectType = getBaseConstraintOfType(objectType) || objectType;
                        var baseIndexType = getBaseConstraintOfType(indexType) || indexType;
                        if (!isGenericObjectType(baseObjectType) && !isGenericIndexType(baseIndexType)) {
                            var accessFlags = 2 /* Writing */ | (baseObjectType !== objectType ? 1 /* NoIndexSignatures */ : 0);
                            var constraint = getIndexedAccessTypeOrUndefined(baseObjectType, baseIndexType, /*accessNode*/ undefined, accessFlags);
                            if (constraint && (result = isRelatedTo(source, constraint, reportErrors))) {
                                return result;
                            }
                        }
                    }
                }
                else if (isGenericMappedType(target)) {
                    // A source type T is related to a target type { [P in X]: T[P] }
                    var template = getTemplateTypeFromMappedType(target);
                    var modifiers = getMappedTypeModifiers(target);
                    if (!(modifiers & 8 /* ExcludeOptional */)) {
                        if (template.flags & 8388608 /* IndexedAccess */ && template.objectType === source &&
                            template.indexType === getTypeParameterFromMappedType(target)) {
                            return -1 /* True */;
                        }
                        if (!isGenericMappedType(source)) {
                            var targetConstraint = getConstraintTypeFromMappedType(target);
                            var sourceKeys_1 = getIndexType(source, /*stringsOnly*/ undefined, /*noIndexSignatures*/ true);
                            var hasOptionalUnionKeys = modifiers & 4 /* IncludeOptional */ && targetConstraint.flags & 1048576 /* Union */;
                            var filteredByApplicability = hasOptionalUnionKeys ? filterType(targetConstraint, function (t) { return !!isRelatedTo(t, sourceKeys_1); }) : undefined;
                            // A source type T is related to a target type { [P in Q]: X } if Q is related to keyof T and T[Q] is related to X.
                            // A source type T is related to a target type { [P in Q]?: X } if some constituent Q' of Q is related to keyof T and T[Q'] is related to X.
                            if (hasOptionalUnionKeys
                                ? !(filteredByApplicability.flags & 131072 /* Never */)
                                : isRelatedTo(targetConstraint, sourceKeys_1)) {
                                var indexingType = hasOptionalUnionKeys ? filteredByApplicability : getTypeParameterFromMappedType(target);
                                var indexedAccessType = getIndexedAccessType(source, indexingType);
                                var templateType = getTemplateTypeFromMappedType(target);
                                if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) {
                                    return result;
                                }
                            }
                            originalErrorInfo = errorInfo;
                            errorInfo = saveErrorInfo;
                        }
                    }
                }
                if (source.flags & 8650752 /* TypeVariable */) {
                    if (source.flags & 8388608 /* IndexedAccess */ && target.flags & 8388608 /* IndexedAccess */) {
                        // A type S[K] is related to a type T[J] if S is related to T and K is related to J.
                        if (result = isRelatedTo(source.objectType, target.objectType, reportErrors)) {
                            result &= isRelatedTo(source.indexType, target.indexType, reportErrors);
                        }
                        if (result) {
                            errorInfo = saveErrorInfo;
                            return result;
                        }
                    }
                    else {
                        var constraint = getConstraintOfType(source);
                        if (!constraint || (source.flags & 262144 /* TypeParameter */ && constraint.flags & 1 /* Any */)) {
                            // A type variable with no constraint is not related to the non-primitive object type.
                            if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~67108864 /* NonPrimitive */))) {
                                errorInfo = saveErrorInfo;
                                return result;
                            }
                        }
                        // hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed
                        else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, isIntersectionConstituent)) {
                            errorInfo = saveErrorInfo;
                            return result;
                        }
                        // slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example
                        else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors, /*headMessage*/ undefined, isIntersectionConstituent)) {
                            errorInfo = saveErrorInfo;
                            return result;
                        }
                    }
                }
                else if (source.flags & 4194304 /* Index */) {
                    if (result = isRelatedTo(keyofConstraintType, target, reportErrors)) {
                        errorInfo = saveErrorInfo;
                        return result;
                    }
                }
                else if (source.flags & 16777216 /* Conditional */) {
                    if (target.flags & 16777216 /* Conditional */) {
                        // Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if
                        // one of T1 and T2 is related to the other, U1 and U2 are identical types, X1 is related to X2,
                        // and Y1 is related to Y2.
                        if (isTypeIdenticalTo(source.extendsType, target.extendsType) &&
                            (isRelatedTo(source.checkType, target.checkType) || isRelatedTo(target.checkType, source.checkType))) {
                            if (result = isRelatedTo(getTrueTypeFromConditionalType(source), getTrueTypeFromConditionalType(target), reportErrors)) {
                                result &= isRelatedTo(getFalseTypeFromConditionalType(source), getFalseTypeFromConditionalType(target), reportErrors);
                            }
                            if (result) {
                                errorInfo = saveErrorInfo;
                                return result;
                            }
                        }
                    }
                    else {
                        var distributiveConstraint = getConstraintOfDistributiveConditionalType(source);
                        if (distributiveConstraint) {
                            if (result = isRelatedTo(distributiveConstraint, target, reportErrors)) {
                                errorInfo = saveErrorInfo;
                                return result;
                            }
                        }
                        var defaultConstraint = getDefaultConstraintOfConditionalType(source);
                        if (defaultConstraint) {
                            if (result = isRelatedTo(defaultConstraint, target, reportErrors)) {
                                errorInfo = saveErrorInfo;
                                return result;
                            }
                        }
                    }
                }
                else {
                    // An empty object type is related to any mapped type that includes a '?' modifier.
                    if (relation !== subtypeRelation && isPartialMappedType(target) && isEmptyObjectType(source)) {
                        return -1 /* True */;
                    }
                    if (isGenericMappedType(target)) {
                        if (isGenericMappedType(source)) {
                            if (result = mappedTypeRelatedTo(source, target, reportErrors)) {
                                errorInfo = saveErrorInfo;
                                return result;
                            }
                        }
                        return 0 /* False */;
                    }
                    var sourceIsPrimitive = !!(source.flags & 131068 /* Primitive */);
                    if (relation !== identityRelation) {
                        source = getApparentType(source);
                    }
                    if (ts.getObjectFlags(source) & 4 /* Reference */ && ts.getObjectFlags(target) & 4 /* Reference */ && source.target === target.target &&
                        !(ts.getObjectFlags(source) & 8192 /* MarkerType */ || ts.getObjectFlags(target) & 8192 /* MarkerType */)) {
                        // We have type references to the same generic type, and the type references are not marker
                        // type references (which are intended by be compared structurally). Obtain the variance
                        // information for the type parameters and relate the type arguments accordingly.
                        var variances = getVariances(source.target);
                        var varianceResult = relateVariances(source.typeArguments, target.typeArguments, variances);
                        if (varianceResult !== undefined) {
                            return varianceResult;
                        }
                    }
                    else if (isReadonlyArrayType(target) ? isArrayType(source) || isTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) {
                        return isRelatedTo(getIndexTypeOfType(source, 1 /* Number */) || anyType, getIndexTypeOfType(target, 1 /* Number */) || anyType, reportErrors);
                    }
                    // Consider a fresh empty object literal type "closed" under the subtype relationship - this way `{} <- {[idx: string]: any} <- fresh({})`
                    // and not `{} <- fresh({}) <- {[idx: string]: any}`
                    else if (relation === subtypeRelation && isEmptyObjectType(target) && ts.getObjectFlags(target) & 32768 /* FreshLiteral */ && !isEmptyObjectType(source)) {
                        return 0 /* False */;
                    }
                    // Even if relationship doesn't hold for unions, intersections, or generic type references,
                    // it may hold in a structural comparison.
                    // In a check of the form X = A & B, we will have previously checked if A relates to X or B relates
                    // to X. Failing both of those we want to check if the aggregation of A and B's members structurally
                    // relates to X. Thus, we include intersection types on the source side here.
                    if (source.flags & (524288 /* Object */ | 2097152 /* Intersection */) && target.flags & 524288 /* Object */) {
                        // Report structural errors only if we haven't reported any errors yet
                        var reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo && !sourceIsPrimitive;
                        result = propertiesRelatedTo(source, target, reportStructuralErrors, /*excludedProperties*/ undefined);
                        if (result) {
                            result &= signaturesRelatedTo(source, target, 0 /* Call */, reportStructuralErrors);
                            if (result) {
                                result &= signaturesRelatedTo(source, target, 1 /* Construct */, reportStructuralErrors);
                                if (result) {
                                    result &= indexTypesRelatedTo(source, target, 0 /* String */, sourceIsPrimitive, reportStructuralErrors);
                                    if (result) {
                                        result &= indexTypesRelatedTo(source, target, 1 /* Number */, sourceIsPrimitive, reportStructuralErrors);
                                    }
                                }
                            }
                        }
                        if (varianceCheckFailed && result) {
                            errorInfo = originalErrorInfo || errorInfo || saveErrorInfo; // Use variance error (there is no structural one) and return false
                        }
                        else if (result) {
                            return result;
                        }
                    }
                    // If S is an object type and T is a discriminated union, S may be related to T if
                    // there exists a constituent of T for every combination of the discriminants of S
                    // with respect to T. We do not report errors here, as we will use the existing
                    // error result from checking each constituent of the union.
                    if (source.flags & (524288 /* Object */ | 2097152 /* Intersection */) && target.flags & 1048576 /* Union */) {
                        var objectOnlyTarget = extractTypesOfKind(target, 524288 /* Object */);
                        if (objectOnlyTarget.flags & 1048576 /* Union */) {
                            var result_4 = typeRelatedToDiscriminatedType(source, objectOnlyTarget);
                            if (result_4) {
                                return result_4;
                            }
                        }
                    }
                }
                return 0 /* False */;
                function relateVariances(sourceTypeArguments, targetTypeArguments, variances) {
                    if (result = typeArgumentsRelatedTo(sourceTypeArguments, targetTypeArguments, variances, reportErrors)) {
                        return result;
                    }
                    if (ts.some(variances, function (v) { return !!(v & 24 /* AllowsStructuralFallback */); })) {
                        // If some type parameter was `Unmeasurable` or `Unreliable`, and we couldn't pass by assuming it was identical, then we
                        // have to allow a structural fallback check
                        // We elide the variance-based error elaborations, since those might not be too helpful, since we'll potentially
                        // be assuming identity of the type parameter.
                        originalErrorInfo = undefined;
                        errorInfo = saveErrorInfo;
                        return undefined;
                    }
                    var allowStructuralFallback = targetTypeArguments && hasCovariantVoidArgument(targetTypeArguments, variances);
                    varianceCheckFailed = !allowStructuralFallback;
                    // The type arguments did not relate appropriately, but it may be because we have no variance
                    // information (in which case typeArgumentsRelatedTo defaulted to covariance for all type
                    // arguments). It might also be the case that the target type has a 'void' type argument for
                    // a covariant type parameter that is only used in return positions within the generic type
                    // (in which case any type argument is permitted on the source side). In those cases we proceed
                    // with a structural comparison. Otherwise, we know for certain the instantiations aren't
                    // related and we can return here.
                    if (variances !== ts.emptyArray && !allowStructuralFallback) {
                        // In some cases generic types that are covariant in regular type checking mode become
                        // invariant in --strictFunctionTypes mode because one or more type parameters are used in
                        // both co- and contravariant positions. In order to make it easier to diagnose *why* such
                        // types are invariant, if any of the type parameters are invariant we reset the reported
                        // errors and instead force a structural comparison (which will include elaborations that
                        // reveal the reason).
                        // We can switch on `reportErrors` here, since varianceCheckFailed guarantees we return `False`,
                        // we can return `False` early here to skip calculating the structural error message we don't need.
                        if (varianceCheckFailed && !(reportErrors && ts.some(variances, function (v) { return (v & 7 /* VarianceMask */) === 0 /* Invariant */; }))) {
                            return 0 /* False */;
                        }
                        // We remember the original error information so we can restore it in case the structural
                        // comparison unexpectedly succeeds. This can happen when the structural comparison result
                        // is a Ternary.Maybe for example caused by the recursion depth limiter.
                        originalErrorInfo = errorInfo;
                        errorInfo = saveErrorInfo;
                    }
                }
            }
            function reportUnmeasurableMarkers(p) {
                if (outofbandVarianceMarkerHandler && (p === markerSuperType || p === markerSubType || p === markerOtherType)) {
                    outofbandVarianceMarkerHandler(/*onlyUnreliable*/ false);
                }
                return p;
            }
            function reportUnreliableMarkers(p) {
                if (outofbandVarianceMarkerHandler && (p === markerSuperType || p === markerSubType || p === markerOtherType)) {
                    outofbandVarianceMarkerHandler(/*onlyUnreliable*/ true);
                }
                return p;
            }
            // A type [P in S]: X is related to a type [Q in T]: Y if T is related to S and X' is
            // related to Y, where X' is an instantiation of X in which P is replaced with Q. Notice
            // that S and T are contra-variant whereas X and Y are co-variant.
            function mappedTypeRelatedTo(source, target, reportErrors) {
                var modifiersRelated = relation === comparableRelation || (relation === identityRelation ? getMappedTypeModifiers(source) === getMappedTypeModifiers(target) :
                    getCombinedMappedTypeOptionality(source) <= getCombinedMappedTypeOptionality(target));
                if (modifiersRelated) {
                    var result_5;
                    var targetConstraint = getConstraintTypeFromMappedType(target);
                    var sourceConstraint = instantiateType(getConstraintTypeFromMappedType(source), getCombinedMappedTypeOptionality(source) < 0 ? reportUnmeasurableMarkers : reportUnreliableMarkers);
                    if (result_5 = isRelatedTo(targetConstraint, sourceConstraint, reportErrors)) {
                        var mapper = createTypeMapper([getTypeParameterFromMappedType(source)], [getTypeParameterFromMappedType(target)]);
                        return result_5 & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), reportErrors);
                    }
                }
                return 0 /* False */;
            }
            function typeRelatedToDiscriminatedType(source, target) {
                // 1. Generate the combinations of discriminant properties & types 'source' can satisfy.
                //    a. If the number of combinations is above a set limit, the comparison is too complex.
                // 2. Filter 'target' to the subset of types whose discriminants exist in the matrix.
                //    a. If 'target' does not satisfy all discriminants in the matrix, 'source' is not related.
                // 3. For each type in the filtered 'target', determine if all non-discriminant properties of
                //    'target' are related to a property in 'source'.
                //
                // NOTE: See ~/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts
                //       for examples.
                var sourceProperties = getPropertiesOfObjectType(source);
                var sourcePropertiesFiltered = findDiscriminantProperties(sourceProperties, target);
                if (!sourcePropertiesFiltered)
                    return 0 /* False */;
                // Though we could compute the number of combinations as we generate
                // the matrix, this would incur additional memory overhead due to
                // array allocations. To reduce this overhead, we first compute
                // the number of combinations to ensure we will not surpass our
                // fixed limit before incurring the cost of any allocations:
                var numCombinations = 1;
                for (var _i = 0, sourcePropertiesFiltered_1 = sourcePropertiesFiltered; _i < sourcePropertiesFiltered_1.length; _i++) {
                    var sourceProperty = sourcePropertiesFiltered_1[_i];
                    numCombinations *= countTypes(getTypeOfSymbol(sourceProperty));
                    if (numCombinations > 25) {
                        // We've reached the complexity limit.
                        return 0 /* False */;
                    }
                }
                // Compute the set of types for each discriminant property.
                var sourceDiscriminantTypes = new Array(sourcePropertiesFiltered.length);
                var excludedProperties = ts.createUnderscoreEscapedMap();
                for (var i = 0; i < sourcePropertiesFiltered.length; i++) {
                    var sourceProperty = sourcePropertiesFiltered[i];
                    var sourcePropertyType = getTypeOfSymbol(sourceProperty);
                    sourceDiscriminantTypes[i] = sourcePropertyType.flags & 1048576 /* Union */
                        ? sourcePropertyType.types
                        : [sourcePropertyType];
                    excludedProperties.set(sourceProperty.escapedName, true);
                }
                // Match each combination of the cartesian product of discriminant properties to one or more
                // constituents of 'target'. If any combination does not have a match then 'source' is not relatable.
                var discriminantCombinations = ts.cartesianProduct(sourceDiscriminantTypes);
                var matchingTypes = [];
                var _loop_8 = function (combination) {
                    var hasMatch = false;
                    outer: for (var _i = 0, _a = target.types; _i < _a.length; _i++) {
                        var type = _a[_i];
                        var _loop_9 = function (i) {
                            var sourceProperty = sourcePropertiesFiltered[i];
                            var targetProperty = getPropertyOfObjectType(type, sourceProperty.escapedName);
                            if (!targetProperty)
                                return "continue-outer";
                            if (sourceProperty === targetProperty)
                                return "continue";
                            // We compare the source property to the target in the context of a single discriminant type.
                            var related = propertyRelatedTo(source, target, sourceProperty, targetProperty, function (_) { return combination[i]; }, /*reportErrors*/ false);
                            // If the target property could not be found, or if the properties were not related,
                            // then this constituent is not a match.
                            if (!related) {
                                return "continue-outer";
                            }
                        };
                        for (var i = 0; i < sourcePropertiesFiltered.length; i++) {
                            var state_5 = _loop_9(i);
                            switch (state_5) {
                                case "continue-outer": continue outer;
                            }
                        }
                        ts.pushIfUnique(matchingTypes, type, ts.equateValues);
                        hasMatch = true;
                    }
                    if (!hasMatch) {
                        return { value: 0 /* False */ };
                    }
                };
                for (var _a = 0, discriminantCombinations_1 = discriminantCombinations; _a < discriminantCombinations_1.length; _a++) {
                    var combination = discriminantCombinations_1[_a];
                    var state_4 = _loop_8(combination);
                    if (typeof state_4 === "object")
                        return state_4.value;
                }
                // Compare the remaining non-discriminant properties of each match.
                var result = -1 /* True */;
                for (var _b = 0, matchingTypes_1 = matchingTypes; _b < matchingTypes_1.length; _b++) {
                    var type = matchingTypes_1[_b];
                    result &= propertiesRelatedTo(source, type, /*reportErrors*/ false, excludedProperties);
                    if (result) {
                        result &= signaturesRelatedTo(source, type, 0 /* Call */, /*reportStructuralErrors*/ false);
                        if (result) {
                            result &= signaturesRelatedTo(source, type, 1 /* Construct */, /*reportStructuralErrors*/ false);
                            if (result) {
                                result &= indexTypesRelatedTo(source, type, 0 /* String */, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false);
                                if (result) {
                                    result &= indexTypesRelatedTo(source, type, 1 /* Number */, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false);
                                }
                            }
                        }
                    }
                    if (!result) {
                        return result;
                    }
                }
                return result;
            }
            function excludeProperties(properties, excludedProperties) {
                if (!excludedProperties || properties.length === 0)
                    return properties;
                var result;
                for (var i = 0; i < properties.length; i++) {
                    if (!excludedProperties.has(properties[i].escapedName)) {
                        if (result) {
                            result.push(properties[i]);
                        }
                    }
                    else if (!result) {
                        result = properties.slice(0, i);
                    }
                }
                return result || properties;
            }
            function isPropertySymbolTypeRelated(sourceProp, targetProp, getTypeOfSourceProperty, reportErrors) {
                var targetIsOptional = strictNullChecks && !!(ts.getCheckFlags(targetProp) & 48 /* Partial */);
                var source = getTypeOfSourceProperty(sourceProp);
                if (ts.getCheckFlags(targetProp) & 65536 /* DeferredType */ && !getSymbolLinks(targetProp).type) {
                    // Rather than resolving (and normalizing) the type, relate constituent-by-constituent without performing normalization or seconadary passes
                    var links = getSymbolLinks(targetProp);
                    ts.Debug.assertDefined(links.deferralParent);
                    ts.Debug.assertDefined(links.deferralConstituents);
                    var unionParent = !!(links.deferralParent.flags & 1048576 /* Union */);
                    var result_6 = unionParent ? 0 /* False */ : -1 /* True */;
                    var targetTypes = links.deferralConstituents;
                    for (var _i = 0, targetTypes_3 = targetTypes; _i < targetTypes_3.length; _i++) {
                        var targetType = targetTypes_3[_i];
                        var related = isRelatedTo(source, targetType, /*reportErrors*/ false, /*headMessage*/ undefined, /*isIntersectionConstituent*/ !unionParent);
                        if (!unionParent) {
                            if (!related) {
                                // Can't assign to a target individually - have to fallback to assigning to the _whole_ intersection (which forces normalization)
                                return isRelatedTo(source, addOptionality(getTypeOfSymbol(targetProp), targetIsOptional), reportErrors);
                            }
                            result_6 &= related;
                        }
                        else {
                            if (related) {
                                return related;
                            }
                        }
                    }
                    if (unionParent && !result_6 && targetIsOptional) {
                        result_6 = isRelatedTo(source, undefinedType);
                    }
                    if (unionParent && !result_6 && reportErrors) {
                        // The easiest way to get the right errors here is to un-defer (which may be costly)
                        // If it turns out this is too costly too often, we can replicate the error handling logic within
                        // typeRelatedToSomeType without the discriminatable type branch (as that requires a manifest union
                        // type on which to hand discriminable properties, which we are expressly trying to avoid here)
                        return isRelatedTo(source, addOptionality(getTypeOfSymbol(targetProp), targetIsOptional), reportErrors);
                    }
                    return result_6;
                }
                else {
                    return isRelatedTo(source, addOptionality(getTypeOfSymbol(targetProp), targetIsOptional), reportErrors);
                }
            }
            function propertyRelatedTo(source, target, sourceProp, targetProp, getTypeOfSourceProperty, reportErrors) {
                var sourcePropFlags = ts.getDeclarationModifierFlagsFromSymbol(sourceProp);
                var targetPropFlags = ts.getDeclarationModifierFlagsFromSymbol(targetProp);
                if (sourcePropFlags & 8 /* Private */ || targetPropFlags & 8 /* Private */) {
                    var hasDifferingDeclarations = sourceProp.valueDeclaration !== targetProp.valueDeclaration;
                    if (ts.getCheckFlags(sourceProp) & 1024 /* ContainsPrivate */ && hasDifferingDeclarations) {
                        if (reportErrors) {
                            reportError(ts.Diagnostics.Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1, symbolToString(sourceProp), typeToString(source));
                        }
                        return 0 /* False */;
                    }
                    if (hasDifferingDeclarations) {
                        if (reportErrors) {
                            if (sourcePropFlags & 8 /* Private */ && targetPropFlags & 8 /* Private */) {
                                reportError(ts.Diagnostics.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp));
                            }
                            else {
                                reportError(ts.Diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, symbolToString(targetProp), typeToString(sourcePropFlags & 8 /* Private */ ? source : target), typeToString(sourcePropFlags & 8 /* Private */ ? target : source));
                            }
                        }
                        return 0 /* False */;
                    }
                }
                else if (targetPropFlags & 16 /* Protected */) {
                    if (!isValidOverrideOf(sourceProp, targetProp)) {
                        if (reportErrors) {
                            reportError(ts.Diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, symbolToString(targetProp), typeToString(getDeclaringClass(sourceProp) || source), typeToString(getDeclaringClass(targetProp) || target));
                        }
                        return 0 /* False */;
                    }
                }
                else if (sourcePropFlags & 16 /* Protected */) {
                    if (reportErrors) {
                        reportError(ts.Diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target));
                    }
                    return 0 /* False */;
                }
                // If the target comes from a partial union prop, allow `undefined` in the target type
                var related = isPropertySymbolTypeRelated(sourceProp, targetProp, getTypeOfSourceProperty, reportErrors);
                if (!related) {
                    if (reportErrors) {
                        reportError(ts.Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp));
                    }
                    return 0 /* False */;
                }
                // When checking for comparability, be more lenient with optional properties.
                if (relation !== comparableRelation && sourceProp.flags & 16777216 /* Optional */ && !(targetProp.flags & 16777216 /* Optional */)) {
                    // TypeScript 1.0 spec (April 2014): 3.8.3
                    // S is a subtype of a type T, and T is a supertype of S if ...
                    // S' and T are object types and, for each member M in T..
                    // M is a property and S' contains a property N where
                    // if M is a required property, N is also a required property
                    // (M - property in T)
                    // (N - property in S)
                    if (reportErrors) {
                        reportError(ts.Diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target));
                    }
                    return 0 /* False */;
                }
                return related;
            }
            function propertiesRelatedTo(source, target, reportErrors, excludedProperties) {
                if (relation === identityRelation) {
                    return propertiesIdenticalTo(source, target, excludedProperties);
                }
                var requireOptionalProperties = relation === subtypeRelation && !isObjectLiteralType(source) && !isEmptyArrayLiteralType(source) && !isTupleType(source);
                var unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false);
                if (unmatchedProperty) {
                    if (reportErrors) {
                        var props = ts.arrayFrom(getUnmatchedProperties(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false));
                        var shouldSkipElaboration = false;
                        if (!headMessage || (headMessage.code !== ts.Diagnostics.Class_0_incorrectly_implements_interface_1.code &&
                            headMessage.code !== ts.Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass.code)) {
                            shouldSkipElaboration = true; // Retain top-level error for interface implementing issues, otherwise omit it
                        }
                        if (props.length === 1) {
                            var propName = symbolToString(unmatchedProperty);
                            reportError.apply(void 0, [ts.Diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2, propName].concat(getTypeNamesForErrorDisplay(source, target)));
                            if (ts.length(unmatchedProperty.declarations)) {
                                associateRelatedInfo(ts.createDiagnosticForNode(unmatchedProperty.declarations[0], ts.Diagnostics._0_is_declared_here, propName));
                            }
                            if (shouldSkipElaboration) {
                                overrideNextErrorInfo = errorInfo;
                            }
                        }
                        else if (tryElaborateArrayLikeErrors(source, target, /*reportErrors*/ false)) {
                            if (props.length > 5) { // arbitrary cutoff for too-long list form
                                reportError(ts.Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more, typeToString(source), typeToString(target), ts.map(props.slice(0, 4), function (p) { return symbolToString(p); }).join(", "), props.length - 4);
                            }
                            else {
                                reportError(ts.Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, typeToString(source), typeToString(target), ts.map(props, function (p) { return symbolToString(p); }).join(", "));
                            }
                            if (shouldSkipElaboration) {
                                overrideNextErrorInfo = errorInfo;
                            }
                        }
                        // ELSE: No array like or unmatched property error - just issue top level error (errorInfo = undefined)
                    }
                    return 0 /* False */;
                }
                if (isObjectLiteralType(target)) {
                    for (var _i = 0, _a = excludeProperties(getPropertiesOfType(source), excludedProperties); _i < _a.length; _i++) {
                        var sourceProp = _a[_i];
                        if (!getPropertyOfObjectType(target, sourceProp.escapedName)) {
                            var sourceType = getTypeOfSymbol(sourceProp);
                            if (!(sourceType === undefinedType || sourceType === undefinedWideningType)) {
                                if (reportErrors) {
                                    reportError(ts.Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(sourceProp), typeToString(target));
                                }
                                return 0 /* False */;
                            }
                        }
                    }
                }
                var result = -1 /* True */;
                if (isTupleType(target)) {
                    var targetRestType = getRestTypeOfTupleType(target);
                    if (targetRestType) {
                        if (!isTupleType(source)) {
                            return 0 /* False */;
                        }
                        var sourceRestType = getRestTypeOfTupleType(source);
                        if (sourceRestType && !isRelatedTo(sourceRestType, targetRestType, reportErrors)) {
                            if (reportErrors) {
                                reportError(ts.Diagnostics.Rest_signatures_are_incompatible);
                            }
                            return 0 /* False */;
                        }
                        var targetCount = getTypeReferenceArity(target) - 1;
                        var sourceCount = getTypeReferenceArity(source) - (sourceRestType ? 1 : 0);
                        for (var i = targetCount; i < sourceCount; i++) {
                            var related = isRelatedTo(source.typeArguments[i], targetRestType, reportErrors);
                            if (!related) {
                                if (reportErrors) {
                                    reportError(ts.Diagnostics.Property_0_is_incompatible_with_rest_element_type, "" + i);
                                }
                                return 0 /* False */;
                            }
                            result &= related;
                        }
                    }
                }
                // We only call this for union target types when we're attempting to do excess property checking - in those cases, we want to get _all possible props_
                // from the target union, across all members
                var properties = target.flags & 1048576 /* Union */ ? getPossiblePropertiesOfUnionType(target) : getPropertiesOfType(target);
                for (var _b = 0, _c = excludeProperties(properties, excludedProperties); _b < _c.length; _b++) {
                    var targetProp = _c[_b];
                    if (!(targetProp.flags & 4194304 /* Prototype */)) {
                        var sourceProp = getPropertyOfType(source, targetProp.escapedName);
                        if (sourceProp && sourceProp !== targetProp) {
                            var related = propertyRelatedTo(source, target, sourceProp, targetProp, getTypeOfSymbol, reportErrors);
                            if (!related) {
                                return 0 /* False */;
                            }
                            result &= related;
                        }
                    }
                }
                return result;
            }
            function propertiesIdenticalTo(source, target, excludedProperties) {
                if (!(source.flags & 524288 /* Object */ && target.flags & 524288 /* Object */)) {
                    return 0 /* False */;
                }
                var sourceProperties = excludeProperties(getPropertiesOfObjectType(source), excludedProperties);
                var targetProperties = excludeProperties(getPropertiesOfObjectType(target), excludedProperties);
                if (sourceProperties.length !== targetProperties.length) {
                    return 0 /* False */;
                }
                var result = -1 /* True */;
                for (var _i = 0, sourceProperties_1 = sourceProperties; _i < sourceProperties_1.length; _i++) {
                    var sourceProp = sourceProperties_1[_i];
                    var targetProp = getPropertyOfObjectType(target, sourceProp.escapedName);
                    if (!targetProp) {
                        return 0 /* False */;
                    }
                    var related = compareProperties(sourceProp, targetProp, isRelatedTo);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function signaturesRelatedTo(source, target, kind, reportErrors) {
                if (relation === identityRelation) {
                    return signaturesIdenticalTo(source, target, kind);
                }
                if (target === anyFunctionType || source === anyFunctionType) {
                    return -1 /* True */;
                }
                var sourceIsJSConstructor = source.symbol && isJSConstructor(source.symbol.valueDeclaration);
                var targetIsJSConstructor = target.symbol && isJSConstructor(target.symbol.valueDeclaration);
                var sourceSignatures = getSignaturesOfType(source, (sourceIsJSConstructor && kind === 1 /* Construct */) ?
                    0 /* Call */ : kind);
                var targetSignatures = getSignaturesOfType(target, (targetIsJSConstructor && kind === 1 /* Construct */) ?
                    0 /* Call */ : kind);
                if (kind === 1 /* Construct */ && sourceSignatures.length && targetSignatures.length) {
                    if (ts.isAbstractConstructorType(source) && !ts.isAbstractConstructorType(target)) {
                        // An abstract constructor type is not assignable to a non-abstract constructor type
                        // as it would otherwise be possible to new an abstract class. Note that the assignability
                        // check we perform for an extends clause excludes construct signatures from the target,
                        // so this check never proceeds.
                        if (reportErrors) {
                            reportError(ts.Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type);
                        }
                        return 0 /* False */;
                    }
                    if (!constructorVisibilitiesAreCompatible(sourceSignatures[0], targetSignatures[0], reportErrors)) {
                        return 0 /* False */;
                    }
                }
                var result = -1 /* True */;
                var saveErrorInfo = errorInfo;
                if (ts.getObjectFlags(source) & 64 /* Instantiated */ && ts.getObjectFlags(target) & 64 /* Instantiated */ && source.symbol === target.symbol) {
                    // We have instantiations of the same anonymous type (which typically will be the type of a
                    // method). Simply do a pairwise comparison of the signatures in the two signature lists instead
                    // of the much more expensive N * M comparison matrix we explore below. We erase type parameters
                    // as they are known to always be the same.
                    for (var i = 0; i < targetSignatures.length; i++) {
                        var related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors);
                        if (!related) {
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
                else if (sourceSignatures.length === 1 && targetSignatures.length === 1) {
                    // For simple functions (functions with a single signature) we only erase type parameters for
                    // the comparable relation. Otherwise, if the source signature is generic, we instantiate it
                    // in the context of the target signature before checking the relationship. Ideally we'd do
                    // this regardless of the number of signatures, but the potential costs are prohibitive due
                    // to the quadratic nature of the logic below.
                    var eraseGenerics = relation === comparableRelation || !!compilerOptions.noStrictGenericChecks;
                    result = signatureRelatedTo(sourceSignatures[0], targetSignatures[0], eraseGenerics, reportErrors);
                }
                else {
                    outer: for (var _i = 0, targetSignatures_1 = targetSignatures; _i < targetSignatures_1.length; _i++) {
                        var t = targetSignatures_1[_i];
                        // Only elaborate errors from the first failure
                        var shouldElaborateErrors = reportErrors;
                        for (var _a = 0, sourceSignatures_1 = sourceSignatures; _a < sourceSignatures_1.length; _a++) {
                            var s = sourceSignatures_1[_a];
                            var related = signatureRelatedTo(s, t, /*erase*/ true, shouldElaborateErrors);
                            if (related) {
                                result &= related;
                                errorInfo = saveErrorInfo;
                                continue outer;
                            }
                            shouldElaborateErrors = false;
                        }
                        if (shouldElaborateErrors) {
                            reportError(ts.Diagnostics.Type_0_provides_no_match_for_the_signature_1, typeToString(source), signatureToString(t, /*enclosingDeclaration*/ undefined, /*flags*/ undefined, kind));
                        }
                        return 0 /* False */;
                    }
                }
                return result;
            }
            /**
             * See signatureAssignableTo, compareSignaturesIdentical
             */
            function signatureRelatedTo(source, target, erase, reportErrors) {
                return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target, 0 /* None */, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
            }
            function signaturesIdenticalTo(source, target, kind) {
                var sourceSignatures = getSignaturesOfType(source, kind);
                var targetSignatures = getSignaturesOfType(target, kind);
                if (sourceSignatures.length !== targetSignatures.length) {
                    return 0 /* False */;
                }
                var result = -1 /* True */;
                for (var i = 0; i < sourceSignatures.length; i++) {
                    var related = compareSignaturesIdentical(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false, isRelatedTo);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function eachPropertyRelatedTo(source, target, kind, reportErrors) {
                var result = -1 /* True */;
                for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (isIgnoredJsxProperty(source, prop)) {
                        continue;
                    }
                    // Skip over symbol-named members
                    if (prop.nameType && prop.nameType.flags & 8192 /* UniqueESSymbol */) {
                        continue;
                    }
                    if (kind === 0 /* String */ || isNumericLiteralName(prop.escapedName)) {
                        var related = isRelatedTo(getTypeOfSymbol(prop), target, reportErrors);
                        if (!related) {
                            if (reportErrors) {
                                reportError(ts.Diagnostics.Property_0_is_incompatible_with_index_signature, symbolToString(prop));
                            }
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
                return result;
            }
            function indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors) {
                var related = isRelatedTo(sourceInfo.type, targetInfo.type, reportErrors);
                if (!related && reportErrors) {
                    reportError(ts.Diagnostics.Index_signatures_are_incompatible);
                }
                return related;
            }
            function indexTypesRelatedTo(source, target, kind, sourceIsPrimitive, reportErrors) {
                if (relation === identityRelation) {
                    return indexTypesIdenticalTo(source, target, kind);
                }
                var targetInfo = getIndexInfoOfType(target, kind);
                if (!targetInfo || targetInfo.type.flags & 1 /* Any */ && !sourceIsPrimitive) {
                    // Index signature of type any permits assignment from everything but primitives
                    return -1 /* True */;
                }
                var sourceInfo = getIndexInfoOfType(source, kind) ||
                    kind === 1 /* Number */ && getIndexInfoOfType(source, 0 /* String */);
                if (sourceInfo) {
                    return indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors);
                }
                if (isGenericMappedType(source)) {
                    // A generic mapped type { [P in K]: T } is related to an index signature { [x: string]: U }
                    // if T is related to U.
                    return (kind === 0 /* String */ && isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, reportErrors)); // TODO: GH#18217
                }
                if (isObjectTypeWithInferableIndex(source)) {
                    var related = -1 /* True */;
                    if (kind === 0 /* String */) {
                        var sourceNumberInfo = getIndexInfoOfType(source, 1 /* Number */);
                        if (sourceNumberInfo) {
                            related = indexInfoRelatedTo(sourceNumberInfo, targetInfo, reportErrors);
                        }
                    }
                    if (related) {
                        related &= eachPropertyRelatedTo(source, targetInfo.type, kind, reportErrors);
                    }
                    return related;
                }
                if (reportErrors) {
                    reportError(ts.Diagnostics.Index_signature_is_missing_in_type_0, typeToString(source));
                }
                return 0 /* False */;
            }
            function indexTypesIdenticalTo(source, target, indexKind) {
                var targetInfo = getIndexInfoOfType(target, indexKind);
                var sourceInfo = getIndexInfoOfType(source, indexKind);
                if (!sourceInfo && !targetInfo) {
                    return -1 /* True */;
                }
                if (sourceInfo && targetInfo && sourceInfo.isReadonly === targetInfo.isReadonly) {
                    return isRelatedTo(sourceInfo.type, targetInfo.type);
                }
                return 0 /* False */;
            }
            function constructorVisibilitiesAreCompatible(sourceSignature, targetSignature, reportErrors) {
                if (!sourceSignature.declaration || !targetSignature.declaration) {
                    return true;
                }
                var sourceAccessibility = ts.getSelectedModifierFlags(sourceSignature.declaration, 24 /* NonPublicAccessibilityModifier */);
                var targetAccessibility = ts.getSelectedModifierFlags(targetSignature.declaration, 24 /* NonPublicAccessibilityModifier */);
                // A public, protected and private signature is assignable to a private signature.
                if (targetAccessibility === 8 /* Private */) {
                    return true;
                }
                // A public and protected signature is assignable to a protected signature.
                if (targetAccessibility === 16 /* Protected */ && sourceAccessibility !== 8 /* Private */) {
                    return true;
                }
                // Only a public signature is assignable to public signature.
                if (targetAccessibility !== 16 /* Protected */ && !sourceAccessibility) {
                    return true;
                }
                if (reportErrors) {
                    reportError(ts.Diagnostics.Cannot_assign_a_0_constructor_type_to_a_1_constructor_type, visibilityToString(sourceAccessibility), visibilityToString(targetAccessibility));
                }
                return false;
            }
        }
        function discriminateTypeByDiscriminableItems(target, discriminators, related, defaultValue) {
            var match;
            for (var _i = 0, discriminators_1 = discriminators; _i < discriminators_1.length; _i++) {
                var _a = discriminators_1[_i], getDiscriminatingType = _a[0], propertyName = _a[1];
                for (var _b = 0, _c = target.types; _b < _c.length; _b++) {
                    var type = _c[_b];
                    var targetType = getTypeOfPropertyOfType(type, propertyName);
                    if (targetType && related(getDiscriminatingType(), targetType)) {
                        if (match) {
                            if (type === match)
                                continue; // Finding multiple fields which discriminate to the same type is fine
                            return defaultValue;
                        }
                        match = type;
                    }
                }
            }
            return match || defaultValue;
        }
        /**
         * A type is 'weak' if it is an object type with at least one optional property
         * and no required properties, call/construct signatures or index signatures
         */
        function isWeakType(type) {
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 &&
                    !resolved.stringIndexInfo && !resolved.numberIndexInfo &&
                    resolved.properties.length > 0 &&
                    ts.every(resolved.properties, function (p) { return !!(p.flags & 16777216 /* Optional */); });
            }
            if (type.flags & 2097152 /* Intersection */) {
                return ts.every(type.types, isWeakType);
            }
            return false;
        }
        function hasCommonProperties(source, target, isComparingJsxAttributes) {
            for (var _i = 0, _a = getPropertiesOfType(source); _i < _a.length; _i++) {
                var prop = _a[_i];
                if (isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) {
                    return true;
                }
            }
            return false;
        }
        // Return a type reference where the source type parameter is replaced with the target marker
        // type, and flag the result as a marker type reference.
        function getMarkerTypeReference(type, source, target) {
            var result = createTypeReference(type, ts.map(type.typeParameters, function (t) { return t === source ? target : t; }));
            result.objectFlags |= 8192 /* MarkerType */;
            return result;
        }
        function getAliasVariances(symbol) {
            var links = getSymbolLinks(symbol);
            return getVariancesWorker(links.typeParameters, links, function (_links, param, marker) {
                var type = getTypeAliasInstantiation(symbol, instantiateTypes(links.typeParameters, makeUnaryTypeMapper(param, marker)));
                type.aliasTypeArgumentsContainsMarker = true;
                return type;
            });
        }
        // Return an array containing the variance of each type parameter. The variance is effectively
        // a digest of the type comparisons that occur for each type argument when instantiations of the
        // generic type are structurally compared. We infer the variance information by comparing
        // instantiations of the generic type for type arguments with known relations. The function
        // returns the emptyArray singleton if we're not in strictFunctionTypes mode or if the function
        // has been invoked recursively for the given generic type.
        function getVariancesWorker(typeParameters, cache, createMarkerType) {
            if (typeParameters === void 0) { typeParameters = ts.emptyArray; }
            var variances = cache.variances;
            if (!variances) {
                // The emptyArray singleton is used to signal a recursive invocation.
                cache.variances = ts.emptyArray;
                variances = [];
                var _loop_10 = function (tp) {
                    var unmeasurable = false;
                    var unreliable = false;
                    var oldHandler = outofbandVarianceMarkerHandler;
                    outofbandVarianceMarkerHandler = function (onlyUnreliable) { return onlyUnreliable ? unreliable = true : unmeasurable = true; };
                    // We first compare instantiations where the type parameter is replaced with
                    // marker types that have a known subtype relationship. From this we can infer
                    // invariance, covariance, contravariance or bivariance.
                    var typeWithSuper = createMarkerType(cache, tp, markerSuperType);
                    var typeWithSub = createMarkerType(cache, tp, markerSubType);
                    var variance = (isTypeAssignableTo(typeWithSub, typeWithSuper) ? 1 /* Covariant */ : 0) |
                        (isTypeAssignableTo(typeWithSuper, typeWithSub) ? 2 /* Contravariant */ : 0);
                    // If the instantiations appear to be related bivariantly it may be because the
                    // type parameter is independent (i.e. it isn't witnessed anywhere in the generic
                    // type). To determine this we compare instantiations where the type parameter is
                    // replaced with marker types that are known to be unrelated.
                    if (variance === 3 /* Bivariant */ && isTypeAssignableTo(createMarkerType(cache, tp, markerOtherType), typeWithSuper)) {
                        variance = 4 /* Independent */;
                    }
                    outofbandVarianceMarkerHandler = oldHandler;
                    if (unmeasurable || unreliable) {
                        if (unmeasurable) {
                            variance |= 8 /* Unmeasurable */;
                        }
                        if (unreliable) {
                            variance |= 16 /* Unreliable */;
                        }
                    }
                    variances.push(variance);
                };
                for (var _i = 0, typeParameters_1 = typeParameters; _i < typeParameters_1.length; _i++) {
                    var tp = typeParameters_1[_i];
                    _loop_10(tp);
                }
                cache.variances = variances;
            }
            return variances;
        }
        function getVariances(type) {
            // Arrays and tuples are known to be covariant, no need to spend time computing this (emptyArray implies covariance for all parameters)
            if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & 8 /* Tuple */) {
                return ts.emptyArray;
            }
            return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference);
        }
        // Return true if the given type reference has a 'void' type argument for a covariant type parameter.
        // See comment at call in recursiveTypeRelatedTo for when this case matters.
        function hasCovariantVoidArgument(typeArguments, variances) {
            for (var i = 0; i < variances.length; i++) {
                if ((variances[i] & 7 /* VarianceMask */) === 1 /* Covariant */ && typeArguments[i].flags & 16384 /* Void */) {
                    return true;
                }
            }
            return false;
        }
        function isUnconstrainedTypeParameter(type) {
            return type.flags & 262144 /* TypeParameter */ && !getConstraintOfTypeParameter(type);
        }
        function isTypeReferenceWithGenericArguments(type) {
            return !!(ts.getObjectFlags(type) & 4 /* Reference */) && ts.some(type.typeArguments, function (t) { return isUnconstrainedTypeParameter(t) || isTypeReferenceWithGenericArguments(t); });
        }
        /**
         * getTypeReferenceId(A<T, number, U>) returns "111=0-12=1"
         *   where A.id=111 and number.id=12
         */
        function getTypeReferenceId(type, typeParameters, depth) {
            if (depth === void 0) { depth = 0; }
            var result = "" + type.target.id;
            for (var _i = 0, _a = type.typeArguments; _i < _a.length; _i++) {
                var t = _a[_i];
                if (isUnconstrainedTypeParameter(t)) {
                    var index = typeParameters.indexOf(t);
                    if (index < 0) {
                        index = typeParameters.length;
                        typeParameters.push(t);
                    }
                    result += "=" + index;
                }
                else if (depth < 4 && isTypeReferenceWithGenericArguments(t)) {
                    result += "<" + getTypeReferenceId(t, typeParameters, depth + 1) + ">";
                }
                else {
                    result += "-" + t.id;
                }
            }
            return result;
        }
        /**
         * To improve caching, the relation key for two generic types uses the target's id plus ids of the type parameters.
         * For other cases, the types ids are used.
         */
        function getRelationKey(source, target, relation) {
            if (relation === identityRelation && source.id > target.id) {
                var temp = source;
                source = target;
                target = temp;
            }
            if (isTypeReferenceWithGenericArguments(source) && isTypeReferenceWithGenericArguments(target)) {
                var typeParameters = [];
                return getTypeReferenceId(source, typeParameters) + "," + getTypeReferenceId(target, typeParameters);
            }
            return source.id + "," + target.id;
        }
        // Invoke the callback for each underlying property symbol of the given symbol and return the first
        // value that isn't undefined.
        function forEachProperty(prop, callback) {
            if (ts.getCheckFlags(prop) & 6 /* Synthetic */) {
                for (var _i = 0, _a = prop.containingType.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    var p = getPropertyOfType(t, prop.escapedName);
                    var result = p && forEachProperty(p, callback);
                    if (result) {
                        return result;
                    }
                }
                return undefined;
            }
            return callback(prop);
        }
        // Return the declaring class type of a property or undefined if property not declared in class
        function getDeclaringClass(prop) {
            return prop.parent && prop.parent.flags & 32 /* Class */ ? getDeclaredTypeOfSymbol(getParentOfSymbol(prop)) : undefined;
        }
        // Return true if some underlying source property is declared in a class that derives
        // from the given base class.
        function isPropertyInClassDerivedFrom(prop, baseClass) {
            return forEachProperty(prop, function (sp) {
                var sourceClass = getDeclaringClass(sp);
                return sourceClass ? hasBaseType(sourceClass, baseClass) : false;
            });
        }
        // Return true if source property is a valid override of protected parts of target property.
        function isValidOverrideOf(sourceProp, targetProp) {
            return !forEachProperty(targetProp, function (tp) { return ts.getDeclarationModifierFlagsFromSymbol(tp) & 16 /* Protected */ ?
                !isPropertyInClassDerivedFrom(sourceProp, getDeclaringClass(tp)) : false; });
        }
        // Return true if the given class derives from each of the declaring classes of the protected
        // constituents of the given property.
        function isClassDerivedFromDeclaringClasses(checkClass, prop) {
            return forEachProperty(prop, function (p) { return ts.getDeclarationModifierFlagsFromSymbol(p) & 16 /* Protected */ ?
                !hasBaseType(checkClass, getDeclaringClass(p)) : false; }) ? undefined : checkClass;
        }
        // Return true if the given type is deeply nested. We consider this to be the case when structural type comparisons
        // for 5 or more occurrences or instantiations of the type have been recorded on the given stack. It is possible,
        // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely
        // expanding. Effectively, we will generate a false positive when two types are structurally equal to at least 5
        // levels, but unequal at some level beyond that.
        function isDeeplyNestedType(type, stack, depth) {
            // We track all object types that have an associated symbol (representing the origin of the type)
            if (depth >= 5 && type.flags & 524288 /* Object */) {
                var symbol = type.symbol;
                if (symbol) {
                    var count = 0;
                    for (var i = 0; i < depth; i++) {
                        var t = stack[i];
                        if (t.flags & 524288 /* Object */ && t.symbol === symbol) {
                            count++;
                            if (count >= 5)
                                return true;
                        }
                    }
                }
            }
            return false;
        }
        function isPropertyIdenticalTo(sourceProp, targetProp) {
            return compareProperties(sourceProp, targetProp, compareTypesIdentical) !== 0 /* False */;
        }
        function compareProperties(sourceProp, targetProp, compareTypes) {
            // Two members are considered identical when
            // - they are public properties with identical names, optionality, and types,
            // - they are private or protected properties originating in the same declaration and having identical types
            if (sourceProp === targetProp) {
                return -1 /* True */;
            }
            var sourcePropAccessibility = ts.getDeclarationModifierFlagsFromSymbol(sourceProp) & 24 /* NonPublicAccessibilityModifier */;
            var targetPropAccessibility = ts.getDeclarationModifierFlagsFromSymbol(targetProp) & 24 /* NonPublicAccessibilityModifier */;
            if (sourcePropAccessibility !== targetPropAccessibility) {
                return 0 /* False */;
            }
            if (sourcePropAccessibility) {
                if (getTargetSymbol(sourceProp) !== getTargetSymbol(targetProp)) {
                    return 0 /* False */;
                }
            }
            else {
                if ((sourceProp.flags & 16777216 /* Optional */) !== (targetProp.flags & 16777216 /* Optional */)) {
                    return 0 /* False */;
                }
            }
            if (isReadonlySymbol(sourceProp) !== isReadonlySymbol(targetProp)) {
                return 0 /* False */;
            }
            return compareTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
        }
        function isMatchingSignature(source, target, partialMatch) {
            var sourceParameterCount = getParameterCount(source);
            var targetParameterCount = getParameterCount(target);
            var sourceMinArgumentCount = getMinArgumentCount(source);
            var targetMinArgumentCount = getMinArgumentCount(target);
            var sourceHasRestParameter = hasEffectiveRestParameter(source);
            var targetHasRestParameter = hasEffectiveRestParameter(target);
            // A source signature matches a target signature if the two signatures have the same number of required,
            // optional, and rest parameters.
            if (sourceParameterCount === targetParameterCount &&
                sourceMinArgumentCount === targetMinArgumentCount &&
                sourceHasRestParameter === targetHasRestParameter) {
                return true;
            }
            // A source signature partially matches a target signature if the target signature has no fewer required
            // parameters
            if (partialMatch && sourceMinArgumentCount <= targetMinArgumentCount) {
                return true;
            }
            return false;
        }
        /**
         * See signatureRelatedTo, compareSignaturesIdentical
         */
        function compareSignaturesIdentical(source, target, partialMatch, ignoreThisTypes, ignoreReturnTypes, compareTypes) {
            // TODO (drosen): De-duplicate code between related functions.
            if (source === target) {
                return -1 /* True */;
            }
            if (!(isMatchingSignature(source, target, partialMatch))) {
                return 0 /* False */;
            }
            // Check that the two signatures have the same number of type parameters. We might consider
            // also checking that any type parameter constraints match, but that would require instantiating
            // the constraints with a common set of type arguments to get relatable entities in places where
            // type parameters occur in the constraints. The complexity of doing that doesn't seem worthwhile,
            // particularly as we're comparing erased versions of the signatures below.
            if (ts.length(source.typeParameters) !== ts.length(target.typeParameters)) {
                return 0 /* False */;
            }
            // Spec 1.0 Section 3.8.3 & 3.8.4:
            // M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N
            source = getErasedSignature(source);
            target = getErasedSignature(target);
            var result = -1 /* True */;
            if (!ignoreThisTypes) {
                var sourceThisType = getThisTypeOfSignature(source);
                if (sourceThisType) {
                    var targetThisType = getThisTypeOfSignature(target);
                    if (targetThisType) {
                        var related = compareTypes(sourceThisType, targetThisType);
                        if (!related) {
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
            }
            var targetLen = getParameterCount(target);
            for (var i = 0; i < targetLen; i++) {
                var s = getTypeAtPosition(source, i);
                var t = getTypeAtPosition(target, i);
                var related = compareTypes(t, s);
                if (!related) {
                    return 0 /* False */;
                }
                result &= related;
            }
            if (!ignoreReturnTypes) {
                var sourceTypePredicate = getTypePredicateOfSignature(source);
                var targetTypePredicate = getTypePredicateOfSignature(target);
                result &= sourceTypePredicate !== undefined || targetTypePredicate !== undefined
                    ? compareTypePredicatesIdentical(sourceTypePredicate, targetTypePredicate, compareTypes)
                    // If they're both type predicates their return types will both be `boolean`, so no need to compare those.
                    : compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
            }
            return result;
        }
        function compareTypePredicatesIdentical(source, target, compareTypes) {
            return source === undefined || target === undefined || !typePredicateKindsMatch(source, target) ? 0 /* False */ : compareTypes(source.type, target.type);
        }
        function literalTypesWithSameBaseType(types) {
            var commonBaseType;
            for (var _i = 0, types_9 = types; _i < types_9.length; _i++) {
                var t = types_9[_i];
                var baseType = getBaseTypeOfLiteralType(t);
                if (!commonBaseType) {
                    commonBaseType = baseType;
                }
                if (baseType === t || baseType !== commonBaseType) {
                    return false;
                }
            }
            return true;
        }
        // When the candidate types are all literal types with the same base type, return a union
        // of those literal types. Otherwise, return the leftmost type for which no type to the
        // right is a supertype.
        function getSupertypeOrUnion(types) {
            return literalTypesWithSameBaseType(types) ?
                getUnionType(types) :
                ts.reduceLeft(types, function (s, t) { return isTypeSubtypeOf(s, t) ? t : s; });
        }
        function getCommonSupertype(types) {
            if (!strictNullChecks) {
                return getSupertypeOrUnion(types);
            }
            var primaryTypes = ts.filter(types, function (t) { return !(t.flags & 98304 /* Nullable */); });
            return primaryTypes.length ?
                getNullableType(getSupertypeOrUnion(primaryTypes), getFalsyFlagsOfTypes(types) & 98304 /* Nullable */) :
                getUnionType(types, 2 /* Subtype */);
        }
        // Return the leftmost type for which no type to the right is a subtype.
        function getCommonSubtype(types) {
            return ts.reduceLeft(types, function (s, t) { return isTypeSubtypeOf(t, s) ? t : s; });
        }
        function isArrayType(type) {
            return !!(ts.getObjectFlags(type) & 4 /* Reference */) && (type.target === globalArrayType || type.target === globalReadonlyArrayType);
        }
        function isReadonlyArrayType(type) {
            return !!(ts.getObjectFlags(type) & 4 /* Reference */) && type.target === globalReadonlyArrayType;
        }
        function getElementTypeOfArrayType(type) {
            return isArrayType(type) && type.typeArguments ? type.typeArguments[0] : undefined;
        }
        function isArrayLikeType(type) {
            // A type is array-like if it is a reference to the global Array or global ReadonlyArray type,
            // or if it is not the undefined or null type and if it is assignable to ReadonlyArray<any>
            return isArrayType(type) || !(type.flags & 98304 /* Nullable */) && isTypeAssignableTo(type, anyReadonlyArrayType);
        }
        function isEmptyArrayLiteralType(type) {
            var elementType = isArrayType(type) ? type.typeArguments[0] : undefined;
            return elementType === undefinedWideningType || elementType === implicitNeverType;
        }
        function isTupleLikeType(type) {
            return isTupleType(type) || !!getPropertyOfType(type, "0");
        }
        function isArrayOrTupleLikeType(type) {
            return isArrayLikeType(type) || isTupleLikeType(type);
        }
        function getTupleElementType(type, index) {
            var propType = getTypeOfPropertyOfType(type, "" + index);
            if (propType) {
                return propType;
            }
            if (everyType(type, isTupleType) && !everyType(type, function (t) { return !t.target.hasRestElement; })) {
                return mapType(type, function (t) { return getRestTypeOfTupleType(t) || undefinedType; });
            }
            return undefined;
        }
        function isNeitherUnitTypeNorNever(type) {
            return !(type.flags & (109440 /* Unit */ | 131072 /* Never */));
        }
        function isUnitType(type) {
            return !!(type.flags & 109440 /* Unit */);
        }
        function isLiteralType(type) {
            return type.flags & 16 /* Boolean */ ? true :
                type.flags & 1048576 /* Union */ ? type.flags & 1024 /* EnumLiteral */ ? true : ts.every(type.types, isUnitType) :
                    isUnitType(type);
        }
        function getBaseTypeOfLiteralType(type) {
            return type.flags & 1024 /* EnumLiteral */ ? getBaseTypeOfEnumLiteralType(type) :
                type.flags & 128 /* StringLiteral */ ? stringType :
                    type.flags & 256 /* NumberLiteral */ ? numberType :
                        type.flags & 2048 /* BigIntLiteral */ ? bigintType :
                            type.flags & 512 /* BooleanLiteral */ ? booleanType :
                                type.flags & 1048576 /* Union */ ? getUnionType(ts.sameMap(type.types, getBaseTypeOfLiteralType)) :
                                    type;
        }
        function getWidenedLiteralType(type) {
            return type.flags & 1024 /* EnumLiteral */ && isFreshLiteralType(type) ? getBaseTypeOfEnumLiteralType(type) :
                type.flags & 128 /* StringLiteral */ && isFreshLiteralType(type) ? stringType :
                    type.flags & 256 /* NumberLiteral */ && isFreshLiteralType(type) ? numberType :
                        type.flags & 2048 /* BigIntLiteral */ && isFreshLiteralType(type) ? bigintType :
                            type.flags & 512 /* BooleanLiteral */ && isFreshLiteralType(type) ? booleanType :
                                type.flags & 1048576 /* Union */ ? getUnionType(ts.sameMap(type.types, getWidenedLiteralType)) :
                                    type;
        }
        function getWidenedUniqueESSymbolType(type) {
            return type.flags & 8192 /* UniqueESSymbol */ ? esSymbolType :
                type.flags & 1048576 /* Union */ ? getUnionType(ts.sameMap(type.types, getWidenedUniqueESSymbolType)) :
                    type;
        }
        function getWidenedLiteralLikeTypeForContextualType(type, contextualType) {
            if (!isLiteralOfContextualType(type, contextualType)) {
                type = getWidenedUniqueESSymbolType(getWidenedLiteralType(type));
            }
            return type;
        }
        /**
         * Check if a Type was written as a tuple type literal.
         * Prefer using isTupleLikeType() unless the use of `elementTypes` is required.
         */
        function isTupleType(type) {
            return !!(ts.getObjectFlags(type) & 4 /* Reference */ && type.target.objectFlags & 8 /* Tuple */);
        }
        function getRestTypeOfTupleType(type) {
            return type.target.hasRestElement ? type.typeArguments[type.target.typeParameters.length - 1] : undefined;
        }
        function getRestArrayTypeOfTupleType(type) {
            var restType = getRestTypeOfTupleType(type);
            return restType && createArrayType(restType);
        }
        function getLengthOfTupleType(type) {
            return getTypeReferenceArity(type) - (type.target.hasRestElement ? 1 : 0);
        }
        function isZeroBigInt(_a) {
            var value = _a.value;
            return value.base10Value === "0";
        }
        function getFalsyFlagsOfTypes(types) {
            var result = 0;
            for (var _i = 0, types_10 = types; _i < types_10.length; _i++) {
                var t = types_10[_i];
                result |= getFalsyFlags(t);
            }
            return result;
        }
        // Returns the String, Number, Boolean, StringLiteral, NumberLiteral, BooleanLiteral, Void, Undefined, or Null
        // flags for the string, number, boolean, "", 0, false, void, undefined, or null types respectively. Returns
        // no flags for all other types (including non-falsy literal types).
        function getFalsyFlags(type) {
            return type.flags & 1048576 /* Union */ ? getFalsyFlagsOfTypes(type.types) :
                type.flags & 128 /* StringLiteral */ ? type.value === "" ? 128 /* StringLiteral */ : 0 :
                    type.flags & 256 /* NumberLiteral */ ? type.value === 0 ? 256 /* NumberLiteral */ : 0 :
                        type.flags & 2048 /* BigIntLiteral */ ? isZeroBigInt(type) ? 2048 /* BigIntLiteral */ : 0 :
                            type.flags & 512 /* BooleanLiteral */ ? (type === falseType || type === regularFalseType) ? 512 /* BooleanLiteral */ : 0 :
                                type.flags & 117724 /* PossiblyFalsy */;
        }
        function removeDefinitelyFalsyTypes(type) {
            return getFalsyFlags(type) & 117632 /* DefinitelyFalsy */ ?
                filterType(type, function (t) { return !(getFalsyFlags(t) & 117632 /* DefinitelyFalsy */); }) :
                type;
        }
        function extractDefinitelyFalsyTypes(type) {
            return mapType(type, getDefinitelyFalsyPartOfType);
        }
        function getDefinitelyFalsyPartOfType(type) {
            return type.flags & 4 /* String */ ? emptyStringType :
                type.flags & 8 /* Number */ ? zeroType :
                    type.flags & 64 /* BigInt */ ? zeroBigIntType :
                        type === regularFalseType ||
                            type === falseType ||
                            type.flags & (16384 /* Void */ | 32768 /* Undefined */ | 65536 /* Null */) ||
                            type.flags & 128 /* StringLiteral */ && type.value === "" ||
                            type.flags & 256 /* NumberLiteral */ && type.value === 0 ||
                            type.flags & 2048 /* BigIntLiteral */ && isZeroBigInt(type) ? type :
                            neverType;
        }
        /**
         * Add undefined or null or both to a type if they are missing.
         * @param type - type to add undefined and/or null to if not present
         * @param flags - Either TypeFlags.Undefined or TypeFlags.Null, or both
         */
        function getNullableType(type, flags) {
            var missing = (flags & ~type.flags) & (32768 /* Undefined */ | 65536 /* Null */);
            return missing === 0 ? type :
                missing === 32768 /* Undefined */ ? getUnionType([type, undefinedType]) :
                    missing === 65536 /* Null */ ? getUnionType([type, nullType]) :
                        getUnionType([type, undefinedType, nullType]);
        }
        function getOptionalType(type) {
            ts.Debug.assert(strictNullChecks);
            return type.flags & 32768 /* Undefined */ ? type : getUnionType([type, undefinedType]);
        }
        function getGlobalNonNullableTypeInstantiation(type) {
            if (!deferredGlobalNonNullableTypeAlias) {
                deferredGlobalNonNullableTypeAlias = getGlobalSymbol("NonNullable", 524288 /* TypeAlias */, /*diagnostic*/ undefined) || unknownSymbol;
            }
            // Use NonNullable global type alias if available to improve quick info/declaration emit
            if (deferredGlobalNonNullableTypeAlias !== unknownSymbol) {
                return getTypeAliasInstantiation(deferredGlobalNonNullableTypeAlias, [type]);
            }
            return getTypeWithFacts(type, 2097152 /* NEUndefinedOrNull */); // Type alias unavailable, fall back to non-higher-order behavior
        }
        function getNonNullableType(type) {
            return strictNullChecks ? getGlobalNonNullableTypeInstantiation(type) : type;
        }
        /**
         * Is source potentially coercible to target type under `==`.
         * Assumes that `source` is a constituent of a union, hence
         * the boolean literal flag on the LHS, but not on the RHS.
         *
         * This does not fully replicate the semantics of `==`. The
         * intention is to catch cases that are clearly not right.
         *
         * Comparing (string | number) to number should not remove the
         * string element.
         *
         * Comparing (string | number) to 1 will remove the string
         * element, though this is not sound. This is a pragmatic
         * choice.
         *
         * @see narrowTypeByEquality
         *
         * @param source
         * @param target
         */
        function isCoercibleUnderDoubleEquals(source, target) {
            return ((source.flags & (8 /* Number */ | 4 /* String */ | 512 /* BooleanLiteral */)) !== 0)
                && ((target.flags & (8 /* Number */ | 4 /* String */ | 16 /* Boolean */)) !== 0);
        }
        /**
         * Return true if type was inferred from an object literal, written as an object type literal, or is the shape of a module
         * with no call or construct signatures.
         */
        function isObjectTypeWithInferableIndex(type) {
            return type.symbol && (type.symbol.flags & (4096 /* ObjectLiteral */ | 2048 /* TypeLiteral */ | 512 /* ValueModule */)) !== 0 &&
                !typeHasCallOrConstructSignatures(type);
        }
        function createSymbolWithType(source, type) {
            var symbol = createSymbol(source.flags, source.escapedName);
            symbol.declarations = source.declarations;
            symbol.parent = source.parent;
            symbol.type = type;
            symbol.target = source;
            if (source.valueDeclaration) {
                symbol.valueDeclaration = source.valueDeclaration;
            }
            if (source.nameType) {
                symbol.nameType = source.nameType;
            }
            return symbol;
        }
        function transformTypeOfMembers(type, f) {
            var members = ts.createSymbolTable();
            for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) {
                var property = _a[_i];
                var original = getTypeOfSymbol(property);
                var updated = f(original);
                members.set(property.escapedName, updated === original ? property : createSymbolWithType(property, updated));
            }
            return members;
        }
        /**
         * If the the provided object literal is subject to the excess properties check,
         * create a new that is exempt. Recursively mark object literal members as exempt.
         * Leave signatures alone since they are not subject to the check.
         */
        function getRegularTypeOfObjectLiteral(type) {
            if (!(isObjectLiteralType(type) && ts.getObjectFlags(type) & 32768 /* FreshLiteral */)) {
                return type;
            }
            var regularType = type.regularType;
            if (regularType) {
                return regularType;
            }
            var resolved = type;
            var members = transformTypeOfMembers(type, getRegularTypeOfObjectLiteral);
            var regularNew = createAnonymousType(resolved.symbol, members, resolved.callSignatures, resolved.constructSignatures, resolved.stringIndexInfo, resolved.numberIndexInfo);
            regularNew.flags = resolved.flags;
            regularNew.objectFlags |= resolved.objectFlags & ~32768 /* FreshLiteral */;
            type.regularType = regularNew;
            return regularNew;
        }
        function createWideningContext(parent, propertyName, siblings) {
            return { parent: parent, propertyName: propertyName, siblings: siblings, resolvedProperties: undefined };
        }
        function getSiblingsOfContext(context) {
            if (!context.siblings) {
                var siblings_1 = [];
                for (var _i = 0, _a = getSiblingsOfContext(context.parent); _i < _a.length; _i++) {
                    var type = _a[_i];
                    if (isObjectLiteralType(type)) {
                        var prop = getPropertyOfObjectType(type, context.propertyName);
                        if (prop) {
                            forEachType(getTypeOfSymbol(prop), function (t) {
                                siblings_1.push(t);
                            });
                        }
                    }
                }
                context.siblings = siblings_1;
            }
            return context.siblings;
        }
        function getPropertiesOfContext(context) {
            if (!context.resolvedProperties) {
                var names = ts.createMap();
                for (var _i = 0, _a = getSiblingsOfContext(context); _i < _a.length; _i++) {
                    var t = _a[_i];
                    if (isObjectLiteralType(t) && !(ts.getObjectFlags(t) & 1024 /* ContainsSpread */)) {
                        for (var _b = 0, _c = getPropertiesOfType(t); _b < _c.length; _b++) {
                            var prop = _c[_b];
                            names.set(prop.escapedName, prop);
                        }
                    }
                }
                context.resolvedProperties = ts.arrayFrom(names.values());
            }
            return context.resolvedProperties;
        }
        function getWidenedProperty(prop, context) {
            if (!(prop.flags & 4 /* Property */)) {
                // Since get accessors already widen their return value there is no need to
                // widen accessor based properties here.
                return prop;
            }
            var original = getTypeOfSymbol(prop);
            var propContext = context && createWideningContext(context, prop.escapedName, /*siblings*/ undefined);
            var widened = getWidenedTypeWithContext(original, propContext);
            return widened === original ? prop : createSymbolWithType(prop, widened);
        }
        function getUndefinedProperty(prop) {
            var cached = undefinedProperties.get(prop.escapedName);
            if (cached) {
                return cached;
            }
            var result = createSymbolWithType(prop, undefinedType);
            result.flags |= 16777216 /* Optional */;
            undefinedProperties.set(prop.escapedName, result);
            return result;
        }
        function getWidenedTypeOfObjectLiteral(type, context) {
            var members = ts.createSymbolTable();
            for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) {
                var prop = _a[_i];
                members.set(prop.escapedName, getWidenedProperty(prop, context));
            }
            if (context) {
                for (var _b = 0, _c = getPropertiesOfContext(context); _b < _c.length; _b++) {
                    var prop = _c[_b];
                    if (!members.has(prop.escapedName)) {
                        members.set(prop.escapedName, getUndefinedProperty(prop));
                    }
                }
            }
            var stringIndexInfo = getIndexInfoOfType(type, 0 /* String */);
            var numberIndexInfo = getIndexInfoOfType(type, 1 /* Number */);
            var result = createAnonymousType(type.symbol, members, ts.emptyArray, ts.emptyArray, stringIndexInfo && createIndexInfo(getWidenedType(stringIndexInfo.type), stringIndexInfo.isReadonly), numberIndexInfo && createIndexInfo(getWidenedType(numberIndexInfo.type), numberIndexInfo.isReadonly));
            result.objectFlags |= (ts.getObjectFlags(type) & (16384 /* JSLiteral */ | 524288 /* NonInferrableType */)); // Retain js literal flag through widening
            return result;
        }
        function getWidenedType(type) {
            return getWidenedTypeWithContext(type, /*context*/ undefined);
        }
        function getWidenedTypeWithContext(type, context) {
            if (ts.getObjectFlags(type) & 393216 /* RequiresWidening */) {
                if (context === undefined && type.widened) {
                    return type.widened;
                }
                var result = void 0;
                if (type.flags & 98304 /* Nullable */) {
                    result = anyType;
                }
                else if (isObjectLiteralType(type)) {
                    result = getWidenedTypeOfObjectLiteral(type, context);
                }
                else if (type.flags & 1048576 /* Union */) {
                    var unionContext_1 = context || createWideningContext(/*parent*/ undefined, /*propertyName*/ undefined, type.types);
                    var widenedTypes = ts.sameMap(type.types, function (t) { return t.flags & 98304 /* Nullable */ ? t : getWidenedTypeWithContext(t, unionContext_1); });
                    // Widening an empty object literal transitions from a highly restrictive type to
                    // a highly inclusive one. For that reason we perform subtype reduction here if the
                    // union includes empty object types (e.g. reducing {} | string to just {}).
                    result = getUnionType(widenedTypes, ts.some(widenedTypes, isEmptyObjectType) ? 2 /* Subtype */ : 1 /* Literal */);
                }
                else if (type.flags & 2097152 /* Intersection */) {
                    result = getIntersectionType(ts.sameMap(type.types, getWidenedType));
                }
                else if (isArrayType(type) || isTupleType(type)) {
                    result = createTypeReference(type.target, ts.sameMap(type.typeArguments, getWidenedType));
                }
                if (result && context === undefined) {
                    type.widened = result;
                }
                return result || type;
            }
            return type;
        }
        /**
         * Reports implicit any errors that occur as a result of widening 'null' and 'undefined'
         * to 'any'. A call to reportWideningErrorsInType is normally accompanied by a call to
         * getWidenedType. But in some cases getWidenedType is called without reporting errors
         * (type argument inference is an example).
         *
         * The return value indicates whether an error was in fact reported. The particular circumstances
         * are on a best effort basis. Currently, if the null or undefined that causes widening is inside
         * an object literal property (arbitrarily deeply), this function reports an error. If no error is
         * reported, reportImplicitAnyError is a suitable fallback to report a general error.
         */
        function reportWideningErrorsInType(type) {
            var errorReported = false;
            if (ts.getObjectFlags(type) & 131072 /* ContainsWideningType */) {
                if (type.flags & 1048576 /* Union */) {
                    if (ts.some(type.types, isEmptyObjectType)) {
                        errorReported = true;
                    }
                    else {
                        for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                            var t = _a[_i];
                            if (reportWideningErrorsInType(t)) {
                                errorReported = true;
                            }
                        }
                    }
                }
                if (isArrayType(type) || isTupleType(type)) {
                    for (var _b = 0, _c = type.typeArguments; _b < _c.length; _b++) {
                        var t = _c[_b];
                        if (reportWideningErrorsInType(t)) {
                            errorReported = true;
                        }
                    }
                }
                if (isObjectLiteralType(type)) {
                    for (var _d = 0, _e = getPropertiesOfObjectType(type); _d < _e.length; _d++) {
                        var p = _e[_d];
                        var t = getTypeOfSymbol(p);
                        if (ts.getObjectFlags(t) & 131072 /* ContainsWideningType */) {
                            if (!reportWideningErrorsInType(t)) {
                                error(p.valueDeclaration, ts.Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, symbolToString(p), typeToString(getWidenedType(t)));
                            }
                            errorReported = true;
                        }
                    }
                }
            }
            return errorReported;
        }
        function reportImplicitAny(declaration, type) {
            var typeAsString = typeToString(getWidenedType(type));
            if (ts.isInJSFile(declaration) && !ts.isCheckJsEnabledForFile(ts.getSourceFileOfNode(declaration), compilerOptions)) {
                // Only report implicit any errors/suggestions in TS and ts-check JS files
                return;
            }
            var diagnostic;
            switch (declaration.kind) {
                case 205 /* BinaryExpression */:
                case 155 /* PropertyDeclaration */:
                case 154 /* PropertySignature */:
                    diagnostic = noImplicitAny ? ts.Diagnostics.Member_0_implicitly_has_an_1_type : ts.Diagnostics.Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage;
                    break;
                case 152 /* Parameter */:
                    var param = declaration;
                    if (ts.isIdentifier(param.name) &&
                        (ts.isCallSignatureDeclaration(param.parent) || ts.isMethodSignature(param.parent) || ts.isFunctionTypeNode(param.parent)) &&
                        param.parent.parameters.indexOf(param) > -1 &&
                        (resolveName(param, param.name.escapedText, 67897832 /* Type */, undefined, param.name.escapedText, /*isUse*/ true) ||
                            param.name.originalKeywordKind && ts.isTypeNodeKind(param.name.originalKeywordKind))) {
                        var newName = "arg" + param.parent.parameters.indexOf(param);
                        errorOrSuggestion(noImplicitAny, declaration, ts.Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1, newName, ts.declarationNameToString(param.name));
                        return;
                    }
                    diagnostic = declaration.dotDotDotToken ?
                        noImplicitAny ? ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type : ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage :
                        noImplicitAny ? ts.Diagnostics.Parameter_0_implicitly_has_an_1_type : ts.Diagnostics.Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage;
                    break;
                case 187 /* BindingElement */:
                    diagnostic = ts.Diagnostics.Binding_element_0_implicitly_has_an_1_type;
                    if (!noImplicitAny) {
                        // Don't issue a suggestion for binding elements since the codefix doesn't yet support them.
                        return;
                    }
                    break;
                case 295 /* JSDocFunctionType */:
                    error(declaration, ts.Diagnostics.Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString);
                    return;
                case 240 /* FunctionDeclaration */:
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */:
                    if (noImplicitAny && !declaration.name) {
                        error(declaration, ts.Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString);
                        return;
                    }
                    diagnostic = noImplicitAny ? ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type : ts.Diagnostics._0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage;
                    break;
                case 182 /* MappedType */:
                    if (noImplicitAny) {
                        error(declaration, ts.Diagnostics.Mapped_object_type_implicitly_has_an_any_template_type);
                    }
                    return;
                default:
                    diagnostic = noImplicitAny ? ts.Diagnostics.Variable_0_implicitly_has_an_1_type : ts.Diagnostics.Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage;
            }
            errorOrSuggestion(noImplicitAny, declaration, diagnostic, ts.declarationNameToString(ts.getNameOfDeclaration(declaration)), typeAsString);
        }
        function reportErrorsFromWidening(declaration, type) {
            if (produceDiagnostics && noImplicitAny && ts.getObjectFlags(type) & 131072 /* ContainsWideningType */) {
                // Report implicit any error within type if possible, otherwise report error on declaration
                if (!reportWideningErrorsInType(type)) {
                    reportImplicitAny(declaration, type);
                }
            }
        }
        function applyToParameterTypes(source, target, callback) {
            var sourceCount = getParameterCount(source);
            var targetCount = getParameterCount(target);
            var sourceRestType = getEffectiveRestType(source);
            var targetRestType = getEffectiveRestType(target);
            var targetNonRestCount = targetRestType ? targetCount - 1 : targetCount;
            var paramCount = sourceRestType ? targetNonRestCount : Math.min(sourceCount, targetNonRestCount);
            var sourceThisType = getThisTypeOfSignature(source);
            if (sourceThisType) {
                var targetThisType = getThisTypeOfSignature(target);
                if (targetThisType) {
                    callback(sourceThisType, targetThisType);
                }
            }
            for (var i = 0; i < paramCount; i++) {
                callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i));
            }
            if (targetRestType) {
                callback(getRestTypeAtPosition(source, paramCount), targetRestType);
            }
        }
        function applyToReturnTypes(source, target, callback) {
            var sourceTypePredicate = getTypePredicateOfSignature(source);
            var targetTypePredicate = getTypePredicateOfSignature(target);
            if (sourceTypePredicate && targetTypePredicate && sourceTypePredicate.kind === targetTypePredicate.kind &&
                (sourceTypePredicate.kind === 0 /* This */ || sourceTypePredicate.parameterIndex === targetTypePredicate.parameterIndex)) {
                callback(sourceTypePredicate.type, targetTypePredicate.type);
            }
            else {
                callback(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
            }
        }
        function createInferenceContext(typeParameters, signature, flags, compareTypes) {
            return createInferenceContextWorker(typeParameters.map(createInferenceInfo), signature, flags, compareTypes || compareTypesAssignable);
        }
        function cloneInferenceContext(context, extraFlags) {
            if (extraFlags === void 0) { extraFlags = 0; }
            return context && createInferenceContextWorker(ts.map(context.inferences, cloneInferenceInfo), context.signature, context.flags | extraFlags, context.compareTypes);
        }
        function cloneInferredPartOfContext(context) {
            var inferences = ts.filter(context.inferences, hasInferenceCandidates);
            return inferences.length ?
                createInferenceContextWorker(ts.map(inferences, cloneInferenceInfo), context.signature, context.flags, context.compareTypes) :
                undefined;
        }
        function createInferenceContextWorker(inferences, signature, flags, compareTypes) {
            var context = {
                inferences: inferences,
                signature: signature,
                flags: flags,
                compareTypes: compareTypes,
                mapper: function (t) { return mapToInferredType(context, t, /*fix*/ true); },
                nonFixingMapper: function (t) { return mapToInferredType(context, t, /*fix*/ false); },
            };
            return context;
        }
        function mapToInferredType(context, t, fix) {
            var inferences = context.inferences;
            for (var i = 0; i < inferences.length; i++) {
                var inference = inferences[i];
                if (t === inference.typeParameter) {
                    if (fix && !inference.isFixed) {
                        inference.isFixed = true;
                        inference.inferredType = undefined;
                    }
                    return getInferredType(context, i);
                }
            }
            return t;
        }
        function createInferenceInfo(typeParameter) {
            return {
                typeParameter: typeParameter,
                candidates: undefined,
                contraCandidates: undefined,
                inferredType: undefined,
                priority: undefined,
                topLevel: true,
                isFixed: false
            };
        }
        function cloneInferenceInfo(inference) {
            return {
                typeParameter: inference.typeParameter,
                candidates: inference.candidates && inference.candidates.slice(),
                contraCandidates: inference.contraCandidates && inference.contraCandidates.slice(),
                inferredType: inference.inferredType,
                priority: inference.priority,
                topLevel: inference.topLevel,
                isFixed: inference.isFixed
            };
        }
        function getMapperFromContext(context) {
            return context && context.mapper;
        }
        // Return true if the given type could possibly reference a type parameter for which
        // we perform type inference (i.e. a type parameter of a generic function). We cache
        // results for union and intersection types for performance reasons.
        function couldContainTypeVariables(type) {
            var objectFlags = ts.getObjectFlags(type);
            return !!(type.flags & 63176704 /* Instantiable */ ||
                objectFlags & 4 /* Reference */ && ts.forEach(type.typeArguments, couldContainTypeVariables) ||
                objectFlags & 16 /* Anonymous */ && type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) && type.symbol.declarations ||
                objectFlags & 32 /* Mapped */ ||
                type.flags & 3145728 /* UnionOrIntersection */ && couldUnionOrIntersectionContainTypeVariables(type));
        }
        function couldUnionOrIntersectionContainTypeVariables(type) {
            if (type.couldContainTypeVariables === undefined) {
                type.couldContainTypeVariables = ts.some(type.types, couldContainTypeVariables);
            }
            return type.couldContainTypeVariables;
        }
        function isTypeParameterAtTopLevel(type, typeParameter) {
            return type === typeParameter || !!(type.flags & 3145728 /* UnionOrIntersection */) && ts.some(type.types, function (t) { return isTypeParameterAtTopLevel(t, typeParameter); });
        }
        /** Create an object with properties named in the string literal type. Every property has type `any` */
        function createEmptyObjectTypeFromStringLiteral(type) {
            var members = ts.createSymbolTable();
            forEachType(type, function (t) {
                if (!(t.flags & 128 /* StringLiteral */)) {
                    return;
                }
                var name = ts.escapeLeadingUnderscores(t.value);
                var literalProp = createSymbol(4 /* Property */, name);
                literalProp.type = anyType;
                if (t.symbol) {
                    literalProp.declarations = t.symbol.declarations;
                    literalProp.valueDeclaration = t.symbol.valueDeclaration;
                }
                members.set(name, literalProp);
            });
            var indexInfo = type.flags & 4 /* String */ ? createIndexInfo(emptyObjectType, /*isReadonly*/ false) : undefined;
            return createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, indexInfo, undefined);
        }
        /**
         * Infer a suitable input type for a homomorphic mapped type { [P in keyof T]: X }. We construct
         * an object type with the same set of properties as the source type, where the type of each
         * property is computed by inferring from the source property type to X for the type
         * variable T[P] (i.e. we treat the type T[P] as the type variable we're inferring for).
         */
        function inferTypeForHomomorphicMappedType(source, target, constraint) {
            var key = source.id + "," + target.id + "," + constraint.id;
            if (reverseMappedCache.has(key)) {
                return reverseMappedCache.get(key);
            }
            reverseMappedCache.set(key, undefined);
            var type = createReverseMappedType(source, target, constraint);
            reverseMappedCache.set(key, type);
            return type;
        }
        // We consider a type to be partially inferable if it isn't marked non-inferable or if it is
        // an object literal type with at least one property of an inferable type. For example, an object
        // literal { a: 123, b: x => true } is marked non-inferable because it contains a context sensitive
        // arrow function, but is considered partially inferable because property 'a' has an inferable type.
        function isPartiallyInferableType(type) {
            return !(ts.getObjectFlags(type) & 524288 /* NonInferrableType */) ||
                isObjectLiteralType(type) && ts.some(getPropertiesOfType(type), function (prop) { return isPartiallyInferableType(getTypeOfSymbol(prop)); });
        }
        function createReverseMappedType(source, target, constraint) {
            // We consider a source type reverse mappable if it has a string index signature or if
            // it has one or more properties and is of a partially inferable type.
            if (!(getIndexInfoOfType(source, 0 /* String */) || getPropertiesOfType(source).length !== 0 && isPartiallyInferableType(source))) {
                return undefined;
            }
            // For arrays and tuples we infer new arrays and tuples where the reverse mapping has been
            // applied to the element type(s).
            if (isArrayType(source)) {
                return createArrayType(inferReverseMappedType(source.typeArguments[0], target, constraint), isReadonlyArrayType(source));
            }
            if (isTupleType(source)) {
                var elementTypes = ts.map(source.typeArguments || ts.emptyArray, function (t) { return inferReverseMappedType(t, target, constraint); });
                var minLength = getMappedTypeModifiers(target) & 4 /* IncludeOptional */ ?
                    getTypeReferenceArity(source) - (source.target.hasRestElement ? 1 : 0) : source.target.minLength;
                return createTupleType(elementTypes, minLength, source.target.hasRestElement, source.target.readonly, source.target.associatedNames);
            }
            // For all other object types we infer a new object type where the reverse mapping has been
            // applied to the type of each property.
            var reversed = createObjectType(2048 /* ReverseMapped */ | 16 /* Anonymous */, /*symbol*/ undefined);
            reversed.source = source;
            reversed.mappedType = target;
            reversed.constraintType = constraint;
            return reversed;
        }
        function getTypeOfReverseMappedSymbol(symbol) {
            return inferReverseMappedType(symbol.propertyType, symbol.mappedType, symbol.constraintType);
        }
        function inferReverseMappedType(sourceType, target, constraint) {
            var typeParameter = getIndexedAccessType(constraint.type, getTypeParameterFromMappedType(target));
            var templateType = getTemplateTypeFromMappedType(target);
            var inference = createInferenceInfo(typeParameter);
            inferTypes([inference], sourceType, templateType);
            return getTypeFromInference(inference) || unknownType;
        }
        function getUnmatchedProperties(source, target, requireOptionalProperties, matchDiscriminantProperties) {
            var properties, _i, properties_2, targetProp, sourceProp, targetType, sourceType;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        properties = target.flags & 1048576 /* Union */ ? getPossiblePropertiesOfUnionType(target) : getPropertiesOfType(target);
                        _i = 0, properties_2 = properties;
                        _a.label = 1;
                    case 1:
                        if (!(_i < properties_2.length)) return [3 /*break*/, 6];
                        targetProp = properties_2[_i];
                        if (!(requireOptionalProperties || !(targetProp.flags & 16777216 /* Optional */ || ts.getCheckFlags(targetProp) & 48 /* Partial */))) return [3 /*break*/, 5];
                        sourceProp = getPropertyOfType(source, targetProp.escapedName);
                        if (!!sourceProp) return [3 /*break*/, 3];
                        return [4 /*yield*/, targetProp];
                    case 2:
                        _a.sent();
                        return [3 /*break*/, 5];
                    case 3:
                        if (!matchDiscriminantProperties) return [3 /*break*/, 5];
                        targetType = getTypeOfSymbol(targetProp);
                        if (!(targetType.flags & 109440 /* Unit */)) return [3 /*break*/, 5];
                        sourceType = getTypeOfSymbol(sourceProp);
                        if (!!(sourceType.flags & 1 /* Any */ || getRegularTypeOfLiteralType(sourceType) === getRegularTypeOfLiteralType(targetType))) return [3 /*break*/, 5];
                        return [4 /*yield*/, targetProp];
                    case 4:
                        _a.sent();
                        _a.label = 5;
                    case 5:
                        _i++;
                        return [3 /*break*/, 1];
                    case 6: return [2 /*return*/];
                }
            });
        }
        function getUnmatchedProperty(source, target, requireOptionalProperties, matchDiscriminantProperties) {
            return getUnmatchedProperties(source, target, requireOptionalProperties, matchDiscriminantProperties).next().value;
        }
        function tupleTypesDefinitelyUnrelated(source, target) {
            return target.target.minLength > source.target.minLength ||
                !getRestTypeOfTupleType(target) && (!!getRestTypeOfTupleType(source) || getLengthOfTupleType(target) < getLengthOfTupleType(source));
        }
        function typesDefinitelyUnrelated(source, target) {
            // Two tuple types with incompatible arities are definitely unrelated.
            // Two object types that each have a property that is unmatched in the other are definitely unrelated.
            return isTupleType(source) && isTupleType(target) && tupleTypesDefinitelyUnrelated(source, target) ||
                !!getUnmatchedProperty(source, target, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ true) &&
                    !!getUnmatchedProperty(target, source, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ true);
        }
        function getTypeFromInference(inference) {
            return inference.candidates ? getUnionType(inference.candidates, 2 /* Subtype */) :
                inference.contraCandidates ? getIntersectionType(inference.contraCandidates) :
                    undefined;
        }
        function inferTypes(inferences, originalSource, originalTarget, priority, contravariant) {
            if (priority === void 0) { priority = 0; }
            if (contravariant === void 0) { contravariant = false; }
            var symbolStack;
            var visited;
            var bivariant = false;
            var propagationType;
            var allowComplexConstraintInference = true;
            inferFromTypes(originalSource, originalTarget);
            function inferFromTypes(source, target) {
                if (!couldContainTypeVariables(target)) {
                    return;
                }
                if (source === wildcardType) {
                    // We are inferring from an 'any' type. We want to infer this type for every type parameter
                    // referenced in the target type, so we record it as the propagation type and infer from the
                    // target to itself. Then, as we find candidates we substitute the propagation type.
                    var savePropagationType = propagationType;
                    propagationType = source;
                    inferFromTypes(target, target);
                    propagationType = savePropagationType;
                    return;
                }
                if (source.aliasSymbol && source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol) {
                    // Source and target are types originating in the same generic type alias declaration.
                    // Simply infer from source type arguments to target type arguments.
                    var sourceTypes = source.aliasTypeArguments;
                    var targetTypes = target.aliasTypeArguments;
                    for (var i = 0; i < sourceTypes.length; i++) {
                        inferFromTypes(sourceTypes[i], targetTypes[i]);
                    }
                    return;
                }
                if (source.flags & 1048576 /* Union */ && target.flags & 1048576 /* Union */ && !(source.flags & 1024 /* EnumLiteral */ && target.flags & 1024 /* EnumLiteral */) ||
                    source.flags & 2097152 /* Intersection */ && target.flags & 2097152 /* Intersection */) {
                    // Source and target are both unions or both intersections. If source and target
                    // are the same type, just relate each constituent type to itself.
                    if (source === target) {
                        for (var _i = 0, _a = source.types; _i < _a.length; _i++) {
                            var t = _a[_i];
                            inferFromTypes(t, t);
                        }
                        return;
                    }
                    // Find each source constituent type that has an identically matching target constituent
                    // type, and for each such type infer from the type to itself. When inferring from a
                    // type to itself we effectively find all type parameter occurrences within that type
                    // and infer themselves as their type arguments. We have special handling for numeric
                    // and string literals because the number and string types are not represented as unions
                    // of all their possible values.
                    var matchingTypes = void 0;
                    for (var _b = 0, _c = source.types; _b < _c.length; _b++) {
                        var t = _c[_b];
                        if (typeIdenticalToSomeType(t, target.types)) {
                            (matchingTypes || (matchingTypes = [])).push(t);
                            inferFromTypes(t, t);
                        }
                        else if (t.flags & (256 /* NumberLiteral */ | 128 /* StringLiteral */)) {
                            var b = getBaseTypeOfLiteralType(t);
                            if (typeIdenticalToSomeType(b, target.types)) {
                                (matchingTypes || (matchingTypes = [])).push(t, b);
                            }
                        }
                    }
                    // Next, to improve the quality of inferences, reduce the source and target types by
                    // removing the identically matched constituents. For example, when inferring from
                    // 'string | string[]' to 'string | T' we reduce the types to 'string[]' and 'T'.
                    if (matchingTypes) {
                        source = removeTypesFromUnionOrIntersection(source, matchingTypes);
                        target = removeTypesFromUnionOrIntersection(target, matchingTypes);
                    }
                }
                else if (target.flags & (8388608 /* IndexedAccess */ | 33554432 /* Substitution */)) {
                    target = getActualTypeVariable(target);
                }
                if (target.flags & 8650752 /* TypeVariable */) {
                    // If target is a type parameter, make an inference, unless the source type contains
                    // the anyFunctionType (the wildcard type that's used to avoid contextually typing functions).
                    // Because the anyFunctionType is internal, it should not be exposed to the user by adding
                    // it as an inference candidate. Hopefully, a better candidate will come along that does
                    // not contain anyFunctionType when we come back to this argument for its second round
                    // of inference. Also, we exclude inferences for silentNeverType (which is used as a wildcard
                    // when constructing types from type parameters that had no inference candidates).
                    if (ts.getObjectFlags(source) & 524288 /* NonInferrableType */ || source === silentNeverType || (priority & 16 /* ReturnType */ && (source === autoType || source === autoArrayType))) {
                        return;
                    }
                    var inference = getInferenceInfoForType(target);
                    if (inference) {
                        if (!inference.isFixed) {
                            if (inference.priority === undefined || priority < inference.priority) {
                                inference.candidates = undefined;
                                inference.contraCandidates = undefined;
                                inference.topLevel = true;
                                inference.priority = priority;
                            }
                            if (priority === inference.priority) {
                                var candidate = propagationType || source;
                                // We make contravariant inferences only if we are in a pure contravariant position,
                                // i.e. only if we have not descended into a bivariant position.
                                if (contravariant && !bivariant) {
                                    if (!ts.contains(inference.contraCandidates, candidate)) {
                                        inference.contraCandidates = ts.append(inference.contraCandidates, candidate);
                                        inference.inferredType = undefined;
                                    }
                                }
                                else if (!ts.contains(inference.candidates, candidate)) {
                                    inference.candidates = ts.append(inference.candidates, candidate);
                                    inference.inferredType = undefined;
                                }
                            }
                            if (!(priority & 16 /* ReturnType */) && target.flags & 262144 /* TypeParameter */ && inference.topLevel && !isTypeParameterAtTopLevel(originalTarget, target)) {
                                inference.topLevel = false;
                                inference.inferredType = undefined;
                            }
                        }
                        return;
                    }
                    else {
                        // Infer to the simplified version of an indexed access, if possible, to (hopefully) expose more bare type parameters to the inference engine
                        var simplified = getSimplifiedType(target, /*writing*/ false);
                        if (simplified !== target) {
                            inferFromTypesOnce(source, simplified);
                        }
                        else if (target.flags & 8388608 /* IndexedAccess */) {
                            var indexType = getSimplifiedType(target.indexType, /*writing*/ false);
                            // Generally simplifications of instantiable indexes are avoided to keep relationship checking correct, however if our target is an access, we can consider
                            // that key of that access to be "instantiated", since we're looking to find the infernce goal in any way we can.
                            if (indexType.flags & 63176704 /* Instantiable */) {
                                var simplified_1 = distributeIndexOverObjectType(getSimplifiedType(target.objectType, /*writing*/ false), indexType, /*writing*/ false);
                                if (simplified_1 && simplified_1 !== target) {
                                    inferFromTypesOnce(source, simplified_1);
                                }
                            }
                        }
                    }
                }
                if (ts.getObjectFlags(source) & 4 /* Reference */ && ts.getObjectFlags(target) & 4 /* Reference */ && source.target === target.target) {
                    // If source and target are references to the same generic type, infer from type arguments
                    var sourceTypes = source.typeArguments || ts.emptyArray;
                    var targetTypes = target.typeArguments || ts.emptyArray;
                    var count = sourceTypes.length < targetTypes.length ? sourceTypes.length : targetTypes.length;
                    var variances = getVariances(source.target);
                    for (var i = 0; i < count; i++) {
                        if (i < variances.length && (variances[i] & 7 /* VarianceMask */) === 2 /* Contravariant */) {
                            inferFromContravariantTypes(sourceTypes[i], targetTypes[i]);
                        }
                        else {
                            inferFromTypes(sourceTypes[i], targetTypes[i]);
                        }
                    }
                }
                else if (source.flags & 4194304 /* Index */ && target.flags & 4194304 /* Index */) {
                    contravariant = !contravariant;
                    inferFromTypes(source.type, target.type);
                    contravariant = !contravariant;
                }
                else if ((isLiteralType(source) || source.flags & 4 /* String */) && target.flags & 4194304 /* Index */) {
                    var empty = createEmptyObjectTypeFromStringLiteral(source);
                    contravariant = !contravariant;
                    var savePriority = priority;
                    priority |= 32 /* LiteralKeyof */;
                    inferFromTypes(empty, target.type);
                    priority = savePriority;
                    contravariant = !contravariant;
                }
                else if (source.flags & 8388608 /* IndexedAccess */ && target.flags & 8388608 /* IndexedAccess */) {
                    inferFromTypes(source.objectType, target.objectType);
                    inferFromTypes(source.indexType, target.indexType);
                }
                else if (source.flags & 16777216 /* Conditional */ && target.flags & 16777216 /* Conditional */) {
                    inferFromTypes(source.checkType, target.checkType);
                    inferFromTypes(source.extendsType, target.extendsType);
                    inferFromTypes(getTrueTypeFromConditionalType(source), getTrueTypeFromConditionalType(target));
                    inferFromTypes(getFalseTypeFromConditionalType(source), getFalseTypeFromConditionalType(target));
                }
                else if (target.flags & 16777216 /* Conditional */ && !contravariant) {
                    inferFromTypes(source, getTrueTypeFromConditionalType(target));
                    inferFromTypes(source, getFalseTypeFromConditionalType(target));
                }
                else if (target.flags & 3145728 /* UnionOrIntersection */) {
                    // We infer from types that are not naked type variables first so that inferences we
                    // make from nested naked type variables and given slightly higher priority by virtue
                    // of being first in the candidates array.
                    var typeVariableCount = 0;
                    for (var _d = 0, _e = target.types; _d < _e.length; _d++) {
                        var t = _e[_d];
                        if (getInferenceInfoForType(t)) {
                            typeVariableCount++;
                        }
                        else {
                            inferFromTypes(source, t);
                        }
                    }
                    // Inferences directly to naked type variables are given lower priority as they are
                    // less specific. For example, when inferring from Promise<string> to T | Promise<T>,
                    // we want to infer string for T, not Promise<string> | string. For intersection types
                    // we only infer to single naked type variables.
                    if (target.flags & 1048576 /* Union */ ? typeVariableCount !== 0 : typeVariableCount === 1) {
                        var savePriority = priority;
                        priority |= 1 /* NakedTypeVariable */;
                        for (var _f = 0, _g = target.types; _f < _g.length; _f++) {
                            var t = _g[_f];
                            if (getInferenceInfoForType(t)) {
                                inferFromTypes(source, t);
                            }
                        }
                        priority = savePriority;
                    }
                }
                else if (source.flags & 1048576 /* Union */) {
                    // Source is a union or intersection type, infer from each constituent type
                    var sourceTypes = source.types;
                    for (var _h = 0, sourceTypes_3 = sourceTypes; _h < sourceTypes_3.length; _h++) {
                        var sourceType = sourceTypes_3[_h];
                        inferFromTypes(sourceType, target);
                    }
                }
                else {
                    if (!(priority & 64 /* NoConstraints */ && source.flags & (2097152 /* Intersection */ | 63176704 /* Instantiable */))) {
                        var apparentSource = getApparentType(source);
                        // getApparentType can return _any_ type, since an indexed access or conditional may simplify to any other type.
                        // If that occurs and it doesn't simplify to an object or intersection, we'll need to restart `inferFromTypes`
                        // with the simplified source.
                        if (apparentSource !== source && allowComplexConstraintInference && !(apparentSource.flags & (524288 /* Object */ | 2097152 /* Intersection */))) {
                            // TODO: The `allowComplexConstraintInference` flag is a hack! This forbids inference from complex constraints within constraints!
                            // This isn't required algorithmically, but rather is used to lower the memory burden caused by performing inference
                            // that is _too good_ in projects with complicated constraints (eg, fp-ts). In such cases, if we did not limit ourselves
                            // here, we might produce more valid inferences for types, causing us to do more checks and perform more instantiations
                            // (in addition to the extra stack depth here) which, in turn, can push the already close process over its limit.
                            // TL;DR: If we ever become generally more memory efficient (or our resource budget ever increases), we should just
                            // remove this `allowComplexConstraintInference` flag.
                            allowComplexConstraintInference = false;
                            return inferFromTypes(apparentSource, target);
                        }
                        source = apparentSource;
                    }
                    if (source.flags & (524288 /* Object */ | 2097152 /* Intersection */)) {
                        var key = source.id + "," + target.id;
                        if (visited && visited.get(key)) {
                            return;
                        }
                        (visited || (visited = ts.createMap())).set(key, true);
                        // If we are already processing another target type with the same associated symbol (such as
                        // an instantiation of the same generic type), we do not explore this target as it would yield
                        // no further inferences. We exclude the static side of classes from this check since it shares
                        // its symbol with the instance side which would lead to false positives.
                        var isNonConstructorObject = target.flags & 524288 /* Object */ &&
                            !(ts.getObjectFlags(target) & 16 /* Anonymous */ && target.symbol && target.symbol.flags & 32 /* Class */);
                        var symbol = isNonConstructorObject ? target.symbol : undefined;
                        if (symbol) {
                            if (ts.contains(symbolStack, symbol)) {
                                return;
                            }
                            (symbolStack || (symbolStack = [])).push(symbol);
                            inferFromObjectTypes(source, target);
                            symbolStack.pop();
                        }
                        else {
                            inferFromObjectTypes(source, target);
                        }
                    }
                }
                function inferFromTypesOnce(source, target) {
                    var key = source.id + "," + target.id;
                    if (!visited || !visited.get(key)) {
                        (visited || (visited = ts.createMap())).set(key, true);
                        inferFromTypes(source, target);
                    }
                }
            }
            function inferFromContravariantTypes(source, target) {
                if (strictFunctionTypes || priority & 128 /* AlwaysStrict */) {
                    contravariant = !contravariant;
                    inferFromTypes(source, target);
                    contravariant = !contravariant;
                }
                else {
                    inferFromTypes(source, target);
                }
            }
            function getInferenceInfoForType(type) {
                if (type.flags & 8650752 /* TypeVariable */) {
                    for (var _i = 0, inferences_1 = inferences; _i < inferences_1.length; _i++) {
                        var inference = inferences_1[_i];
                        if (type === inference.typeParameter) {
                            return inference;
                        }
                    }
                }
                return undefined;
            }
            function inferToMappedType(source, target, constraintType) {
                if (constraintType.flags & 1048576 /* Union */) {
                    var result = false;
                    for (var _i = 0, _a = constraintType.types; _i < _a.length; _i++) {
                        var type = _a[_i];
                        result = inferToMappedType(source, target, type) || result;
                    }
                    return result;
                }
                if (constraintType.flags & 4194304 /* Index */) {
                    // We're inferring from some source type S to a homomorphic mapped type { [P in keyof T]: X },
                    // where T is a type variable. Use inferTypeForHomomorphicMappedType to infer a suitable source
                    // type and then make a secondary inference from that type to T. We make a secondary inference
                    // such that direct inferences to T get priority over inferences to Partial<T>, for example.
                    var inference = getInferenceInfoForType(constraintType.type);
                    if (inference && !inference.isFixed) {
                        var inferredType = inferTypeForHomomorphicMappedType(source, target, constraintType);
                        if (inferredType) {
                            var savePriority = priority;
                            // We assign a lower priority to inferences made from types containing non-inferrable
                            // types because we may only have a partial result (i.e. we may have failed to make
                            // reverse inferences for some properties).
                            priority |= ts.getObjectFlags(source) & 524288 /* NonInferrableType */ ?
                                4 /* PartialHomomorphicMappedType */ : 2 /* HomomorphicMappedType */;
                            inferFromTypes(inferredType, inference.typeParameter);
                            priority = savePriority;
                        }
                    }
                    return true;
                }
                if (constraintType.flags & 262144 /* TypeParameter */) {
                    // We're inferring from some source type S to a mapped type { [P in K]: X }, where K is a type
                    // parameter. First infer from 'keyof S' to K.
                    var savePriority = priority;
                    priority |= 8 /* MappedTypeConstraint */;
                    inferFromTypes(getIndexType(source), constraintType);
                    priority = savePriority;
                    // If K is constrained to a type C, also infer to C. Thus, for a mapped type { [P in K]: X },
                    // where K extends keyof T, we make the same inferences as for a homomorphic mapped type
                    // { [P in keyof T]: X }. This enables us to make meaningful inferences when the target is a
                    // Pick<T, K>.
                    var extendedConstraint = getConstraintOfType(constraintType);
                    if (extendedConstraint && inferToMappedType(source, target, extendedConstraint)) {
                        return true;
                    }
                    // If no inferences can be made to K's constraint, infer from a union of the property types
                    // in the source to the template type X.
                    var propTypes = ts.map(getPropertiesOfType(source), getTypeOfSymbol);
                    var stringIndexType = getIndexTypeOfType(source, 0 /* String */);
                    var numberIndexInfo = getNonEnumNumberIndexInfo(source);
                    var numberIndexType = numberIndexInfo && numberIndexInfo.type;
                    inferFromTypes(getUnionType(ts.append(ts.append(propTypes, stringIndexType), numberIndexType)), getTemplateTypeFromMappedType(target));
                    return true;
                }
                return false;
            }
            function inferFromObjectTypes(source, target) {
                if (isGenericMappedType(source) && isGenericMappedType(target)) {
                    // The source and target types are generic types { [P in S]: X } and { [P in T]: Y }, so we infer
                    // from S to T and from X to Y.
                    inferFromTypes(getConstraintTypeFromMappedType(source), getConstraintTypeFromMappedType(target));
                    inferFromTypes(getTemplateTypeFromMappedType(source), getTemplateTypeFromMappedType(target));
                }
                if (ts.getObjectFlags(target) & 32 /* Mapped */) {
                    var constraintType = getConstraintTypeFromMappedType(target);
                    if (inferToMappedType(source, target, constraintType)) {
                        return;
                    }
                }
                // Infer from the members of source and target only if the two types are possibly related
                if (!typesDefinitelyUnrelated(source, target)) {
                    inferFromProperties(source, target);
                    inferFromSignatures(source, target, 0 /* Call */);
                    inferFromSignatures(source, target, 1 /* Construct */);
                    inferFromIndexTypes(source, target);
                }
            }
            function inferFromProperties(source, target) {
                if (isArrayType(source) || isTupleType(source)) {
                    if (isTupleType(target)) {
                        var sourceLength = isTupleType(source) ? getLengthOfTupleType(source) : 0;
                        var targetLength = getLengthOfTupleType(target);
                        var sourceRestType = isTupleType(source) ? getRestTypeOfTupleType(source) : getElementTypeOfArrayType(source);
                        var targetRestType = getRestTypeOfTupleType(target);
                        var fixedLength = targetLength < sourceLength || sourceRestType ? targetLength : sourceLength;
                        for (var i = 0; i < fixedLength; i++) {
                            inferFromTypes(i < sourceLength ? source.typeArguments[i] : sourceRestType, target.typeArguments[i]);
                        }
                        if (targetRestType) {
                            var types = fixedLength < sourceLength ? source.typeArguments.slice(fixedLength, sourceLength) : [];
                            if (sourceRestType) {
                                types.push(sourceRestType);
                            }
                            if (types.length) {
                                inferFromTypes(getUnionType(types), targetRestType);
                            }
                        }
                        return;
                    }
                    if (isArrayType(target)) {
                        inferFromIndexTypes(source, target);
                        return;
                    }
                }
                var properties = getPropertiesOfObjectType(target);
                for (var _i = 0, properties_3 = properties; _i < properties_3.length; _i++) {
                    var targetProp = properties_3[_i];
                    var sourceProp = getPropertyOfType(source, targetProp.escapedName);
                    if (sourceProp) {
                        inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
                    }
                }
            }
            function inferFromSignatures(source, target, kind) {
                var sourceSignatures = getSignaturesOfType(source, kind);
                var targetSignatures = getSignaturesOfType(target, kind);
                var sourceLen = sourceSignatures.length;
                var targetLen = targetSignatures.length;
                var len = sourceLen < targetLen ? sourceLen : targetLen;
                var skipParameters = !!(ts.getObjectFlags(source) & 524288 /* NonInferrableType */);
                for (var i = 0; i < len; i++) {
                    inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getBaseSignature(targetSignatures[targetLen - len + i]), skipParameters);
                }
            }
            function inferFromSignature(source, target, skipParameters) {
                if (!skipParameters) {
                    var saveBivariant = bivariant;
                    var kind = target.declaration ? target.declaration.kind : 0 /* Unknown */;
                    // Once we descend into a bivariant signature we remain bivariant for all nested inferences
                    bivariant = bivariant || kind === 157 /* MethodDeclaration */ || kind === 156 /* MethodSignature */ || kind === 158 /* Constructor */;
                    applyToParameterTypes(source, target, inferFromContravariantTypes);
                    bivariant = saveBivariant;
                }
                applyToReturnTypes(source, target, inferFromTypes);
            }
            function inferFromIndexTypes(source, target) {
                var targetStringIndexType = getIndexTypeOfType(target, 0 /* String */);
                if (targetStringIndexType) {
                    var sourceIndexType = getIndexTypeOfType(source, 0 /* String */) ||
                        getImplicitIndexTypeOfType(source, 0 /* String */);
                    if (sourceIndexType) {
                        inferFromTypes(sourceIndexType, targetStringIndexType);
                    }
                }
                var targetNumberIndexType = getIndexTypeOfType(target, 1 /* Number */);
                if (targetNumberIndexType) {
                    var sourceIndexType = getIndexTypeOfType(source, 1 /* Number */) ||
                        getIndexTypeOfType(source, 0 /* String */) ||
                        getImplicitIndexTypeOfType(source, 1 /* Number */);
                    if (sourceIndexType) {
                        inferFromTypes(sourceIndexType, targetNumberIndexType);
                    }
                }
            }
        }
        function typeIdenticalToSomeType(type, types) {
            for (var _i = 0, types_11 = types; _i < types_11.length; _i++) {
                var t = types_11[_i];
                if (isTypeIdenticalTo(t, type)) {
                    return true;
                }
            }
            return false;
        }
        /**
         * Return a new union or intersection type computed by removing a given set of types
         * from a given union or intersection type.
         */
        function removeTypesFromUnionOrIntersection(type, typesToRemove) {
            var reducedTypes = [];
            for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                var t = _a[_i];
                if (!typeIdenticalToSomeType(t, typesToRemove)) {
                    reducedTypes.push(t);
                }
            }
            return type.flags & 1048576 /* Union */ ? getUnionType(reducedTypes) : getIntersectionType(reducedTypes);
        }
        function hasPrimitiveConstraint(type) {
            var constraint = getConstraintOfTypeParameter(type);
            return !!constraint && maybeTypeOfKind(constraint.flags & 16777216 /* Conditional */ ? getDefaultConstraintOfConditionalType(constraint) : constraint, 131068 /* Primitive */ | 4194304 /* Index */);
        }
        function isObjectLiteralType(type) {
            return !!(ts.getObjectFlags(type) & 128 /* ObjectLiteral */);
        }
        function widenObjectLiteralCandidates(candidates) {
            if (candidates.length > 1) {
                var objectLiterals = ts.filter(candidates, isObjectLiteralType);
                if (objectLiterals.length) {
                    var objectLiteralsType = getWidenedType(getUnionType(objectLiterals, 2 /* Subtype */));
                    return ts.concatenate(ts.filter(candidates, function (t) { return !isObjectLiteralType(t); }), [objectLiteralsType]);
                }
            }
            return candidates;
        }
        function getContravariantInference(inference) {
            return inference.priority & 56 /* PriorityImpliesCombination */ ? getIntersectionType(inference.contraCandidates) : getCommonSubtype(inference.contraCandidates);
        }
        function getCovariantInference(inference, signature) {
            // Extract all object literal types and replace them with a single widened and normalized type.
            var candidates = widenObjectLiteralCandidates(inference.candidates);
            // We widen inferred literal types if
            // all inferences were made to top-level occurrences of the type parameter, and
            // the type parameter has no constraint or its constraint includes no primitive or literal types, and
            // the type parameter was fixed during inference or does not occur at top-level in the return type.
            var primitiveConstraint = hasPrimitiveConstraint(inference.typeParameter);
            var widenLiteralTypes = !primitiveConstraint && inference.topLevel &&
                (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter));
            var baseCandidates = primitiveConstraint ? ts.sameMap(candidates, getRegularTypeOfLiteralType) :
                widenLiteralTypes ? ts.sameMap(candidates, getWidenedLiteralType) :
                    candidates;
            // If all inferences were made from a position that implies a combined result, infer a union type.
            // Otherwise, infer a common supertype.
            var unwidenedType = inference.priority & 56 /* PriorityImpliesCombination */ ?
                getUnionType(baseCandidates, 2 /* Subtype */) :
                getCommonSupertype(baseCandidates);
            return getWidenedType(unwidenedType);
        }
        function getInferredType(context, index) {
            var inference = context.inferences[index];
            if (!inference.inferredType) {
                var inferredType = void 0;
                var signature = context.signature;
                if (signature) {
                    var inferredCovariantType = inference.candidates ? getCovariantInference(inference, signature) : undefined;
                    if (inference.contraCandidates) {
                        var inferredContravariantType = getContravariantInference(inference);
                        // If we have both co- and contra-variant inferences, we prefer the contra-variant inference
                        // unless the co-variant inference is a subtype and not 'never'.
                        inferredType = inferredCovariantType && !(inferredCovariantType.flags & 131072 /* Never */) &&
                            isTypeSubtypeOf(inferredCovariantType, inferredContravariantType) ?
                            inferredCovariantType : inferredContravariantType;
                    }
                    else if (inferredCovariantType) {
                        inferredType = inferredCovariantType;
                    }
                    else if (context.flags & 1 /* NoDefault */) {
                        // We use silentNeverType as the wildcard that signals no inferences.
                        inferredType = silentNeverType;
                    }
                    else {
                        // Infer either the default or the empty object type when no inferences were
                        // made. It is important to remember that in this case, inference still
                        // succeeds, meaning there is no error for not having inference candidates. An
                        // inference error only occurs when there are *conflicting* candidates, i.e.
                        // candidates with no common supertype.
                        var defaultType = getDefaultFromTypeParameter(inference.typeParameter);
                        if (defaultType) {
                            // Instantiate the default type. Any forward reference to a type
                            // parameter should be instantiated to the empty object type.
                            inferredType = instantiateType(defaultType, combineTypeMappers(createBackreferenceMapper(context, index), context.nonFixingMapper));
                        }
                    }
                }
                else {
                    inferredType = getTypeFromInference(inference);
                }
                inference.inferredType = inferredType || getDefaultTypeArgumentType(!!(context.flags & 2 /* AnyDefault */));
                var constraint = getConstraintOfTypeParameter(inference.typeParameter);
                if (constraint) {
                    var instantiatedConstraint = instantiateType(constraint, context.nonFixingMapper);
                    if (!inferredType || !context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
                        inference.inferredType = inferredType = instantiatedConstraint;
                    }
                }
            }
            return inference.inferredType;
        }
        function getDefaultTypeArgumentType(isInJavaScriptFile) {
            return isInJavaScriptFile ? anyType : unknownType;
        }
        function getInferredTypes(context) {
            var result = [];
            for (var i = 0; i < context.inferences.length; i++) {
                result.push(getInferredType(context, i));
            }
            return result;
        }
        // EXPRESSION TYPE CHECKING
        function getCannotFindNameDiagnosticForName(node) {
            switch (node.escapedText) {
                case "document":
                case "console":
                    return ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_include_dom;
                case "$":
                    return compilerOptions.types
                        ? ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig
                        : ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery;
                case "describe":
                case "suite":
                case "it":
                case "test":
                    return compilerOptions.types
                        ? ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashjest_or_npm_i_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig
                        : ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashjest_or_npm_i_types_Slashmocha;
                case "process":
                case "require":
                case "Buffer":
                case "module":
                    return compilerOptions.types
                        ? ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig
                        : ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode;
                case "Map":
                case "Set":
                case "Promise":
                case "Symbol":
                case "WeakMap":
                case "WeakSet":
                case "Iterator":
                case "AsyncIterator":
                    return ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later;
                default:
                    if (node.parent.kind === 277 /* ShorthandPropertyAssignment */) {
                        return ts.Diagnostics.No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer;
                    }
                    else {
                        return ts.Diagnostics.Cannot_find_name_0;
                    }
            }
        }
        function getResolvedSymbol(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedSymbol) {
                links.resolvedSymbol = !ts.nodeIsMissing(node) &&
                    resolveName(node, node.escapedText, 67220415 /* Value */ | 1048576 /* ExportValue */, getCannotFindNameDiagnosticForName(node), node, !ts.isWriteOnlyAccess(node), 
                    /*excludeGlobals*/ false, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1) || unknownSymbol;
            }
            return links.resolvedSymbol;
        }
        function isInTypeQuery(node) {
            // TypeScript 1.0 spec (April 2014): 3.6.3
            // A type query consists of the keyword typeof followed by an expression.
            // The expression is restricted to a single identifier or a sequence of identifiers separated by periods
            return !!ts.findAncestor(node, function (n) { return n.kind === 168 /* TypeQuery */ ? true : n.kind === 73 /* Identifier */ || n.kind === 149 /* QualifiedName */ ? false : "quit"; });
        }
        // Return the flow cache key for a "dotted name" (i.e. a sequence of identifiers
        // separated by dots). The key consists of the id of the symbol referenced by the
        // leftmost identifier followed by zero or more property names separated by dots.
        // The result is undefined if the reference isn't a dotted name. We prefix nodes
        // occurring in an apparent type position with '@' because the control flow type
        // of such nodes may be based on the apparent type instead of the declared type.
        function getFlowCacheKey(node, declaredType, initialType, flowContainer) {
            switch (node.kind) {
                case 73 /* Identifier */:
                    var symbol = getResolvedSymbol(node);
                    return symbol !== unknownSymbol ? (flowContainer ? getNodeId(flowContainer) : "-1") + "|" + getTypeId(declaredType) + "|" + getTypeId(initialType) + "|" + (isConstraintPosition(node) ? "@" : "") + getSymbolId(symbol) : undefined;
                case 101 /* ThisKeyword */:
                    return "0";
                case 214 /* NonNullExpression */:
                case 196 /* ParenthesizedExpression */:
                    return getFlowCacheKey(node.expression, declaredType, initialType, flowContainer);
                case 190 /* PropertyAccessExpression */:
                case 191 /* ElementAccessExpression */:
                    var propName = getAccessedPropertyName(node);
                    if (propName !== undefined) {
                        var key = getFlowCacheKey(node.expression, declaredType, initialType, flowContainer);
                        return key && key + "." + propName;
                    }
            }
            return undefined;
        }
        function isMatchingReference(source, target) {
            switch (target.kind) {
                case 196 /* ParenthesizedExpression */:
                case 214 /* NonNullExpression */:
                    return isMatchingReference(source, target.expression);
            }
            switch (source.kind) {
                case 73 /* Identifier */:
                    return target.kind === 73 /* Identifier */ && getResolvedSymbol(source) === getResolvedSymbol(target) ||
                        (target.kind === 238 /* VariableDeclaration */ || target.kind === 187 /* BindingElement */) &&
                            getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(source)) === getSymbolOfNode(target);
                case 101 /* ThisKeyword */:
                    return target.kind === 101 /* ThisKeyword */;
                case 99 /* SuperKeyword */:
                    return target.kind === 99 /* SuperKeyword */;
                case 214 /* NonNullExpression */:
                case 196 /* ParenthesizedExpression */:
                    return isMatchingReference(source.expression, target);
                case 190 /* PropertyAccessExpression */:
                case 191 /* ElementAccessExpression */:
                    return ts.isAccessExpression(target) &&
                        getAccessedPropertyName(source) === getAccessedPropertyName(target) &&
                        isMatchingReference(source.expression, target.expression);
            }
            return false;
        }
        function getAccessedPropertyName(access) {
            return access.kind === 190 /* PropertyAccessExpression */ ? access.name.escapedText :
                ts.isStringLiteral(access.argumentExpression) || ts.isNumericLiteral(access.argumentExpression) ? ts.escapeLeadingUnderscores(access.argumentExpression.text) :
                    undefined;
        }
        function containsMatchingReference(source, target) {
            while (ts.isAccessExpression(source)) {
                source = source.expression;
                if (isMatchingReference(source, target)) {
                    return true;
                }
            }
            return false;
        }
        // Return true if target is a property access xxx.yyy, source is a property access xxx.zzz, the declared
        // type of xxx is a union type, and yyy is a property that is possibly a discriminant. We consider a property
        // a possible discriminant if its type differs in the constituents of containing union type, and if every
        // choice is a unit type or a union of unit types.
        function containsMatchingReferenceDiscriminant(source, target) {
            var name;
            return ts.isAccessExpression(target) &&
                containsMatchingReference(source, target.expression) &&
                (name = getAccessedPropertyName(target)) !== undefined &&
                isDiscriminantProperty(getDeclaredTypeOfReference(target.expression), name);
        }
        function getDeclaredTypeOfReference(expr) {
            if (expr.kind === 73 /* Identifier */) {
                return getTypeOfSymbol(getResolvedSymbol(expr));
            }
            if (ts.isAccessExpression(expr)) {
                var type = getDeclaredTypeOfReference(expr.expression);
                if (type) {
                    var propName = getAccessedPropertyName(expr);
                    return propName !== undefined ? getTypeOfPropertyOfType(type, propName) : undefined;
                }
            }
            return undefined;
        }
        function isDiscriminantType(type) {
            return !!(type.flags & 1048576 /* Union */ &&
                (type.flags & (16 /* Boolean */ | 1024 /* EnumLiteral */) || !isGenericIndexType(type)));
        }
        function isDiscriminantProperty(type, name) {
            if (type && type.flags & 1048576 /* Union */) {
                var prop = getUnionOrIntersectionProperty(type, name);
                if (prop && ts.getCheckFlags(prop) & 2 /* SyntheticProperty */) {
                    if (prop.isDiscriminantProperty === undefined) {
                        prop.isDiscriminantProperty =
                            (prop.checkFlags & 192 /* Discriminant */) === 192 /* Discriminant */ &&
                                isDiscriminantType(getTypeOfSymbol(prop));
                    }
                    return !!prop.isDiscriminantProperty;
                }
            }
            return false;
        }
        function isSyntheticThisPropertyAccess(expr) {
            return ts.isAccessExpression(expr) && expr.expression.kind === 101 /* ThisKeyword */ && !!(expr.expression.flags & 8 /* Synthesized */);
        }
        function findDiscriminantProperties(sourceProperties, target) {
            var result;
            for (var _i = 0, sourceProperties_2 = sourceProperties; _i < sourceProperties_2.length; _i++) {
                var sourceProperty = sourceProperties_2[_i];
                if (isDiscriminantProperty(target, sourceProperty.escapedName)) {
                    if (result) {
                        result.push(sourceProperty);
                        continue;
                    }
                    result = [sourceProperty];
                }
            }
            return result;
        }
        function isOrContainsMatchingReference(source, target) {
            return isMatchingReference(source, target) || containsMatchingReference(source, target);
        }
        function hasMatchingArgument(callExpression, reference) {
            if (callExpression.arguments) {
                for (var _i = 0, _a = callExpression.arguments; _i < _a.length; _i++) {
                    var argument = _a[_i];
                    if (isOrContainsMatchingReference(reference, argument)) {
                        return true;
                    }
                }
            }
            if (callExpression.expression.kind === 190 /* PropertyAccessExpression */ &&
                isOrContainsMatchingReference(reference, callExpression.expression.expression)) {
                return true;
            }
            return false;
        }
        function getFlowNodeId(flow) {
            if (!flow.id) {
                flow.id = nextFlowId;
                nextFlowId++;
            }
            return flow.id;
        }
        function typeMaybeAssignableTo(source, target) {
            if (!(source.flags & 1048576 /* Union */)) {
                return isTypeAssignableTo(source, target);
            }
            for (var _i = 0, _a = source.types; _i < _a.length; _i++) {
                var t = _a[_i];
                if (isTypeAssignableTo(t, target)) {
                    return true;
                }
            }
            return false;
        }
        // Remove those constituent types of declaredType to which no constituent type of assignedType is assignable.
        // For example, when a variable of type number | string | boolean is assigned a value of type number | boolean,
        // we remove type string.
        function getAssignmentReducedType(declaredType, assignedType) {
            if (declaredType !== assignedType) {
                if (assignedType.flags & 131072 /* Never */) {
                    return assignedType;
                }
                var reducedType = filterType(declaredType, function (t) { return typeMaybeAssignableTo(assignedType, t); });
                if (assignedType.flags & 512 /* BooleanLiteral */ && isFreshLiteralType(assignedType)) {
                    reducedType = mapType(reducedType, getFreshTypeOfLiteralType); // Ensure that if the assignment is a fresh type, that we narrow to fresh types
                }
                // Our crude heuristic produces an invalid result in some cases: see GH#26130.
                // For now, when that happens, we give up and don't narrow at all.  (This also
                // means we'll never narrow for erroneous assignments where the assigned type
                // is not assignable to the declared type.)
                if (isTypeAssignableTo(assignedType, reducedType)) {
                    return reducedType;
                }
            }
            return declaredType;
        }
        function getTypeFactsOfTypes(types) {
            var result = 0 /* None */;
            for (var _i = 0, types_12 = types; _i < types_12.length; _i++) {
                var t = types_12[_i];
                result |= getTypeFacts(t);
            }
            return result;
        }
        function isFunctionObjectType(type) {
            // We do a quick check for a "bind" property before performing the more expensive subtype
            // check. This gives us a quicker out in the common case where an object type is not a function.
            var resolved = resolveStructuredTypeMembers(type);
            return !!(resolved.callSignatures.length || resolved.constructSignatures.length ||
                resolved.members.get("bind") && isTypeSubtypeOf(type, globalFunctionType));
        }
        function getTypeFacts(type) {
            var flags = type.flags;
            if (flags & 4 /* String */) {
                return strictNullChecks ? 16317953 /* StringStrictFacts */ : 16776705 /* StringFacts */;
            }
            if (flags & 128 /* StringLiteral */) {
                var isEmpty = type.value === "";
                return strictNullChecks ?
                    isEmpty ? 12123649 /* EmptyStringStrictFacts */ : 7929345 /* NonEmptyStringStrictFacts */ :
                    isEmpty ? 12582401 /* EmptyStringFacts */ : 16776705 /* NonEmptyStringFacts */;
            }
            if (flags & (8 /* Number */ | 32 /* Enum */)) {
                return strictNullChecks ? 16317698 /* NumberStrictFacts */ : 16776450 /* NumberFacts */;
            }
            if (flags & 256 /* NumberLiteral */) {
                var isZero = type.value === 0;
                return strictNullChecks ?
                    isZero ? 12123394 /* ZeroNumberStrictFacts */ : 7929090 /* NonZeroNumberStrictFacts */ :
                    isZero ? 12582146 /* ZeroNumberFacts */ : 16776450 /* NonZeroNumberFacts */;
            }
            if (flags & 64 /* BigInt */) {
                return strictNullChecks ? 16317188 /* BigIntStrictFacts */ : 16775940 /* BigIntFacts */;
            }
            if (flags & 2048 /* BigIntLiteral */) {
                var isZero = isZeroBigInt(type);
                return strictNullChecks ?
                    isZero ? 12122884 /* ZeroBigIntStrictFacts */ : 7928580 /* NonZeroBigIntStrictFacts */ :
                    isZero ? 12581636 /* ZeroBigIntFacts */ : 16775940 /* NonZeroBigIntFacts */;
            }
            if (flags & 16 /* Boolean */) {
                return strictNullChecks ? 16316168 /* BooleanStrictFacts */ : 16774920 /* BooleanFacts */;
            }
            if (flags & 528 /* BooleanLike */) {
                return strictNullChecks ?
                    (type === falseType || type === regularFalseType) ? 12121864 /* FalseStrictFacts */ : 7927560 /* TrueStrictFacts */ :
                    (type === falseType || type === regularFalseType) ? 12580616 /* FalseFacts */ : 16774920 /* TrueFacts */;
            }
            if (flags & 524288 /* Object */) {
                return ts.getObjectFlags(type) & 16 /* Anonymous */ && isEmptyObjectType(type) ?
                    strictNullChecks ? 16318463 /* EmptyObjectStrictFacts */ : 16777215 /* EmptyObjectFacts */ :
                    isFunctionObjectType(type) ?
                        strictNullChecks ? 7880640 /* FunctionStrictFacts */ : 16728000 /* FunctionFacts */ :
                        strictNullChecks ? 7888800 /* ObjectStrictFacts */ : 16736160 /* ObjectFacts */;
            }
            if (flags & (16384 /* Void */ | 32768 /* Undefined */)) {
                return 9830144 /* UndefinedFacts */;
            }
            if (flags & 65536 /* Null */) {
                return 9363232 /* NullFacts */;
            }
            if (flags & 12288 /* ESSymbolLike */) {
                return strictNullChecks ? 7925520 /* SymbolStrictFacts */ : 16772880 /* SymbolFacts */;
            }
            if (flags & 67108864 /* NonPrimitive */) {
                return strictNullChecks ? 7888800 /* ObjectStrictFacts */ : 16736160 /* ObjectFacts */;
            }
            if (flags & 63176704 /* Instantiable */) {
                return getTypeFacts(getBaseConstraintOfType(type) || unknownType);
            }
            if (flags & 3145728 /* UnionOrIntersection */) {
                return getTypeFactsOfTypes(type.types);
            }
            return 16777215 /* All */;
        }
        function getTypeWithFacts(type, include) {
            return filterType(type, function (t) { return (getTypeFacts(t) & include) !== 0; });
        }
        function getTypeWithDefault(type, defaultExpression) {
            if (defaultExpression) {
                var defaultType = getTypeOfExpression(defaultExpression);
                return getUnionType([getTypeWithFacts(type, 524288 /* NEUndefined */), defaultType]);
            }
            return type;
        }
        function getTypeOfDestructuredProperty(type, name) {
            var nameType = getLiteralTypeFromPropertyName(name);
            if (!isTypeUsableAsPropertyName(nameType))
                return errorType;
            var text = getPropertyNameFromType(nameType);
            return getConstraintForLocation(getTypeOfPropertyOfType(type, text), name) ||
                isNumericLiteralName(text) && getIndexTypeOfType(type, 1 /* Number */) ||
                getIndexTypeOfType(type, 0 /* String */) ||
                errorType;
        }
        function getTypeOfDestructuredArrayElement(type, index) {
            return everyType(type, isTupleLikeType) && getTupleElementType(type, index) ||
                checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) ||
                errorType;
        }
        function getTypeOfDestructuredSpreadExpression(type) {
            return createArrayType(checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || errorType);
        }
        function getAssignedTypeOfBinaryExpression(node) {
            var isDestructuringDefaultAssignment = node.parent.kind === 188 /* ArrayLiteralExpression */ && isDestructuringAssignmentTarget(node.parent) ||
                node.parent.kind === 276 /* PropertyAssignment */ && isDestructuringAssignmentTarget(node.parent.parent);
            return isDestructuringDefaultAssignment ?
                getTypeWithDefault(getAssignedType(node), node.right) :
                getTypeOfExpression(node.right);
        }
        function isDestructuringAssignmentTarget(parent) {
            return parent.parent.kind === 205 /* BinaryExpression */ && parent.parent.left === parent ||
                parent.parent.kind === 228 /* ForOfStatement */ && parent.parent.initializer === parent;
        }
        function getAssignedTypeOfArrayLiteralElement(node, element) {
            return getTypeOfDestructuredArrayElement(getAssignedType(node), node.elements.indexOf(element));
        }
        function getAssignedTypeOfSpreadExpression(node) {
            return getTypeOfDestructuredSpreadExpression(getAssignedType(node.parent));
        }
        function getAssignedTypeOfPropertyAssignment(node) {
            return getTypeOfDestructuredProperty(getAssignedType(node.parent), node.name);
        }
        function getAssignedTypeOfShorthandPropertyAssignment(node) {
            return getTypeWithDefault(getAssignedTypeOfPropertyAssignment(node), node.objectAssignmentInitializer);
        }
        function getAssignedType(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 227 /* ForInStatement */:
                    return stringType;
                case 228 /* ForOfStatement */:
                    return checkRightHandSideOfForOf(parent.expression, parent.awaitModifier) || errorType;
                case 205 /* BinaryExpression */:
                    return getAssignedTypeOfBinaryExpression(parent);
                case 199 /* DeleteExpression */:
                    return undefinedType;
                case 188 /* ArrayLiteralExpression */:
                    return getAssignedTypeOfArrayLiteralElement(parent, node);
                case 209 /* SpreadElement */:
                    return getAssignedTypeOfSpreadExpression(parent);
                case 276 /* PropertyAssignment */:
                    return getAssignedTypeOfPropertyAssignment(parent);
                case 277 /* ShorthandPropertyAssignment */:
                    return getAssignedTypeOfShorthandPropertyAssignment(parent);
            }
            return errorType;
        }
        function getInitialTypeOfBindingElement(node) {
            var pattern = node.parent;
            var parentType = getInitialType(pattern.parent);
            var type = pattern.kind === 185 /* ObjectBindingPattern */ ?
                getTypeOfDestructuredProperty(parentType, node.propertyName || node.name) :
                !node.dotDotDotToken ?
                    getTypeOfDestructuredArrayElement(parentType, pattern.elements.indexOf(node)) :
                    getTypeOfDestructuredSpreadExpression(parentType);
            return getTypeWithDefault(type, node.initializer);
        }
        function getTypeOfInitializer(node) {
            // Return the cached type if one is available. If the type of the variable was inferred
            // from its initializer, we'll already have cached the type. Otherwise we compute it now
            // without caching such that transient types are reflected.
            var links = getNodeLinks(node);
            return links.resolvedType || getTypeOfExpression(node);
        }
        function getInitialTypeOfVariableDeclaration(node) {
            if (node.initializer) {
                return getTypeOfInitializer(node.initializer);
            }
            if (node.parent.parent.kind === 227 /* ForInStatement */) {
                return stringType;
            }
            if (node.parent.parent.kind === 228 /* ForOfStatement */) {
                return checkRightHandSideOfForOf(node.parent.parent.expression, node.parent.parent.awaitModifier) || errorType;
            }
            return errorType;
        }
        function getInitialType(node) {
            return node.kind === 238 /* VariableDeclaration */ ?
                getInitialTypeOfVariableDeclaration(node) :
                getInitialTypeOfBindingElement(node);
        }
        function getInitialOrAssignedType(node, reference) {
            return getConstraintForLocation(node.kind === 238 /* VariableDeclaration */ || node.kind === 187 /* BindingElement */ ?
                getInitialType(node) :
                getAssignedType(node), reference);
        }
        function isEmptyArrayAssignment(node) {
            return node.kind === 238 /* VariableDeclaration */ && node.initializer &&
                isEmptyArrayLiteral(node.initializer) ||
                node.kind !== 187 /* BindingElement */ && node.parent.kind === 205 /* BinaryExpression */ &&
                    isEmptyArrayLiteral(node.parent.right);
        }
        function getReferenceCandidate(node) {
            switch (node.kind) {
                case 196 /* ParenthesizedExpression */:
                    return getReferenceCandidate(node.expression);
                case 205 /* BinaryExpression */:
                    switch (node.operatorToken.kind) {
                        case 60 /* EqualsToken */:
                            return getReferenceCandidate(node.left);
                        case 27 /* CommaToken */:
                            return getReferenceCandidate(node.right);
                    }
            }
            return node;
        }
        function getReferenceRoot(node) {
            var parent = node.parent;
            return parent.kind === 196 /* ParenthesizedExpression */ ||
                parent.kind === 205 /* BinaryExpression */ && parent.operatorToken.kind === 60 /* EqualsToken */ && parent.left === node ||
                parent.kind === 205 /* BinaryExpression */ && parent.operatorToken.kind === 27 /* CommaToken */ && parent.right === node ?
                getReferenceRoot(parent) : node;
        }
        function getTypeOfSwitchClause(clause) {
            if (clause.kind === 272 /* CaseClause */) {
                return getRegularTypeOfLiteralType(getTypeOfExpression(clause.expression));
            }
            return neverType;
        }
        function getSwitchClauseTypes(switchStatement) {
            var links = getNodeLinks(switchStatement);
            if (!links.switchTypes) {
                links.switchTypes = [];
                for (var _i = 0, _a = switchStatement.caseBlock.clauses; _i < _a.length; _i++) {
                    var clause = _a[_i];
                    links.switchTypes.push(getTypeOfSwitchClause(clause));
                }
            }
            return links.switchTypes;
        }
        // Get the types from all cases in a switch on `typeof`. An
        // `undefined` element denotes an explicit `default` clause.
        function getSwitchClauseTypeOfWitnesses(switchStatement) {
            var witnesses = [];
            for (var _i = 0, _a = switchStatement.caseBlock.clauses; _i < _a.length; _i++) {
                var clause = _a[_i];
                if (clause.kind === 272 /* CaseClause */) {
                    if (clause.expression.kind === 10 /* StringLiteral */) {
                        witnesses.push(clause.expression.text);
                        continue;
                    }
                    return ts.emptyArray;
                }
                witnesses.push(/*explicitDefaultStatement*/ undefined);
            }
            return witnesses;
        }
        function eachTypeContainedIn(source, types) {
            return source.flags & 1048576 /* Union */ ? !ts.forEach(source.types, function (t) { return !ts.contains(types, t); }) : ts.contains(types, source);
        }
        function isTypeSubsetOf(source, target) {
            return source === target || target.flags & 1048576 /* Union */ && isTypeSubsetOfUnion(source, target);
        }
        function isTypeSubsetOfUnion(source, target) {
            if (source.flags & 1048576 /* Union */) {
                for (var _i = 0, _a = source.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    if (!containsType(target.types, t)) {
                        return false;
                    }
                }
                return true;
            }
            if (source.flags & 1024 /* EnumLiteral */ && getBaseTypeOfEnumLiteralType(source) === target) {
                return true;
            }
            return containsType(target.types, source);
        }
        function forEachType(type, f) {
            return type.flags & 1048576 /* Union */ ? ts.forEach(type.types, f) : f(type);
        }
        function everyType(type, f) {
            return type.flags & 1048576 /* Union */ ? ts.every(type.types, f) : f(type);
        }
        function filterType(type, f) {
            if (type.flags & 1048576 /* Union */) {
                var types = type.types;
                var filtered = ts.filter(types, f);
                return filtered === types ? type : getUnionTypeFromSortedList(filtered, type.objectFlags);
            }
            return f(type) ? type : neverType;
        }
        function countTypes(type) {
            return type.flags & 1048576 /* Union */ ? type.types.length : 1;
        }
        function mapType(type, mapper, noReductions) {
            if (type.flags & 131072 /* Never */) {
                return type;
            }
            if (!(type.flags & 1048576 /* Union */)) {
                return mapper(type);
            }
            var mappedTypes;
            for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                var t = _a[_i];
                var mapped = mapper(t);
                if (mapped) {
                    if (!mappedTypes) {
                        mappedTypes = [mapped];
                    }
                    else {
                        mappedTypes.push(mapped);
                    }
                }
            }
            return mappedTypes && getUnionType(mappedTypes, noReductions ? 0 /* None */ : 1 /* Literal */);
        }
        function extractTypesOfKind(type, kind) {
            return filterType(type, function (t) { return (t.flags & kind) !== 0; });
        }
        // Return a new type in which occurrences of the string and number primitive types in
        // typeWithPrimitives have been replaced with occurrences of string literals and numeric
        // literals in typeWithLiterals, respectively.
        function replacePrimitivesWithLiterals(typeWithPrimitives, typeWithLiterals) {
            if (isTypeSubsetOf(stringType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, 128 /* StringLiteral */) ||
                isTypeSubsetOf(numberType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, 256 /* NumberLiteral */) ||
                isTypeSubsetOf(bigintType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, 2048 /* BigIntLiteral */)) {
                return mapType(typeWithPrimitives, function (t) {
                    return t.flags & 4 /* String */ ? extractTypesOfKind(typeWithLiterals, 4 /* String */ | 128 /* StringLiteral */) :
                        t.flags & 8 /* Number */ ? extractTypesOfKind(typeWithLiterals, 8 /* Number */ | 256 /* NumberLiteral */) :
                            t.flags & 64 /* BigInt */ ? extractTypesOfKind(typeWithLiterals, 64 /* BigInt */ | 2048 /* BigIntLiteral */) :
                                t;
                });
            }
            return typeWithPrimitives;
        }
        function isIncomplete(flowType) {
            return flowType.flags === 0;
        }
        function getTypeFromFlowType(flowType) {
            return flowType.flags === 0 ? flowType.type : flowType;
        }
        function createFlowType(type, incomplete) {
            return incomplete ? { flags: 0, type: type } : type;
        }
        // An evolving array type tracks the element types that have so far been seen in an
        // 'x.push(value)' or 'x[n] = value' operation along the control flow graph. Evolving
        // array types are ultimately converted into manifest array types (using getFinalArrayType)
        // and never escape the getFlowTypeOfReference function.
        function createEvolvingArrayType(elementType) {
            var result = createObjectType(256 /* EvolvingArray */);
            result.elementType = elementType;
            return result;
        }
        function getEvolvingArrayType(elementType) {
            return evolvingArrayTypes[elementType.id] || (evolvingArrayTypes[elementType.id] = createEvolvingArrayType(elementType));
        }
        // When adding evolving array element types we do not perform subtype reduction. Instead,
        // we defer subtype reduction until the evolving array type is finalized into a manifest
        // array type.
        function addEvolvingArrayElementType(evolvingArrayType, node) {
            var elementType = getBaseTypeOfLiteralType(getContextFreeTypeOfExpression(node));
            return isTypeSubsetOf(elementType, evolvingArrayType.elementType) ? evolvingArrayType : getEvolvingArrayType(getUnionType([evolvingArrayType.elementType, elementType]));
        }
        function createFinalArrayType(elementType) {
            return elementType.flags & 131072 /* Never */ ?
                autoArrayType :
                createArrayType(elementType.flags & 1048576 /* Union */ ?
                    getUnionType(elementType.types, 2 /* Subtype */) :
                    elementType);
        }
        // We perform subtype reduction upon obtaining the final array type from an evolving array type.
        function getFinalArrayType(evolvingArrayType) {
            return evolvingArrayType.finalArrayType || (evolvingArrayType.finalArrayType = createFinalArrayType(evolvingArrayType.elementType));
        }
        function finalizeEvolvingArrayType(type) {
            return ts.getObjectFlags(type) & 256 /* EvolvingArray */ ? getFinalArrayType(type) : type;
        }
        function getElementTypeOfEvolvingArrayType(type) {
            return ts.getObjectFlags(type) & 256 /* EvolvingArray */ ? type.elementType : neverType;
        }
        function isEvolvingArrayTypeList(types) {
            var hasEvolvingArrayType = false;
            for (var _i = 0, types_13 = types; _i < types_13.length; _i++) {
                var t = types_13[_i];
                if (!(t.flags & 131072 /* Never */)) {
                    if (!(ts.getObjectFlags(t) & 256 /* EvolvingArray */)) {
                        return false;
                    }
                    hasEvolvingArrayType = true;
                }
            }
            return hasEvolvingArrayType;
        }
        // At flow control branch or loop junctions, if the type along every antecedent code path
        // is an evolving array type, we construct a combined evolving array type. Otherwise we
        // finalize all evolving array types.
        function getUnionOrEvolvingArrayType(types, subtypeReduction) {
            return isEvolvingArrayTypeList(types) ?
                getEvolvingArrayType(getUnionType(ts.map(types, getElementTypeOfEvolvingArrayType))) :
                getUnionType(ts.sameMap(types, finalizeEvolvingArrayType), subtypeReduction);
        }
        // Return true if the given node is 'x' in an 'x.length', x.push(value)', 'x.unshift(value)' or
        // 'x[n] = value' operation, where 'n' is an expression of type any, undefined, or a number-like type.
        function isEvolvingArrayOperationTarget(node) {
            var root = getReferenceRoot(node);
            var parent = root.parent;
            var isLengthPushOrUnshift = parent.kind === 190 /* PropertyAccessExpression */ && (parent.name.escapedText === "length" ||
                parent.parent.kind === 192 /* CallExpression */ && ts.isPushOrUnshiftIdentifier(parent.name));
            var isElementAssignment = parent.kind === 191 /* ElementAccessExpression */ &&
                parent.expression === root &&
                parent.parent.kind === 205 /* BinaryExpression */ &&
                parent.parent.operatorToken.kind === 60 /* EqualsToken */ &&
                parent.parent.left === parent &&
                !ts.isAssignmentTarget(parent.parent) &&
                isTypeAssignableToKind(getTypeOfExpression(parent.argumentExpression), 296 /* NumberLike */);
            return isLengthPushOrUnshift || isElementAssignment;
        }
        function maybeTypePredicateCall(node) {
            var links = getNodeLinks(node);
            if (links.maybeTypePredicate === undefined) {
                links.maybeTypePredicate = getMaybeTypePredicate(node);
            }
            return links.maybeTypePredicate;
        }
        function getMaybeTypePredicate(node) {
            if (node.expression.kind !== 99 /* SuperKeyword */) {
                var funcType = checkNonNullExpression(node.expression);
                if (funcType !== silentNeverType) {
                    var apparentType = getApparentType(funcType);
                    return apparentType !== errorType && ts.some(getSignaturesOfType(apparentType, 0 /* Call */), signatureHasTypePredicate);
                }
            }
            return false;
        }
        function reportFlowControlError(node) {
            var block = ts.findAncestor(node, ts.isFunctionOrModuleBlock);
            var sourceFile = ts.getSourceFileOfNode(node);
            var span = ts.getSpanOfTokenAtPosition(sourceFile, block.statements.pos);
            diagnostics.add(ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.The_containing_function_or_module_body_is_too_large_for_control_flow_analysis));
        }
        function getFlowTypeOfReference(reference, declaredType, initialType, flowContainer, couldBeUninitialized) {
            if (initialType === void 0) { initialType = declaredType; }
            var key;
            var keySet = false;
            var flowDepth = 0;
            if (flowAnalysisDisabled) {
                return errorType;
            }
            if (!reference.flowNode || !couldBeUninitialized && !(declaredType.flags & 133970943 /* Narrowable */)) {
                return declaredType;
            }
            var sharedFlowStart = sharedFlowCount;
            var evolvedType = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode));
            sharedFlowCount = sharedFlowStart;
            // When the reference is 'x' in an 'x.length', 'x.push(value)', 'x.unshift(value)' or x[n] = value' operation,
            // we give type 'any[]' to 'x' instead of using the type determined by control flow analysis such that operations
            // on empty arrays are possible without implicit any errors and new element types can be inferred without
            // type mismatch errors.
            var resultType = ts.getObjectFlags(evolvedType) & 256 /* EvolvingArray */ && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType);
            if (reference.parent && reference.parent.kind === 214 /* NonNullExpression */ && getTypeWithFacts(resultType, 2097152 /* NEUndefinedOrNull */).flags & 131072 /* Never */) {
                return declaredType;
            }
            return resultType;
            function getOrSetCacheKey() {
                if (keySet) {
                    return key;
                }
                keySet = true;
                return key = getFlowCacheKey(reference, declaredType, initialType, flowContainer);
            }
            function getTypeAtFlowNode(flow) {
                if (flowDepth === 2000) {
                    // We have made 2000 recursive invocations. To avoid overflowing the call stack we report an error
                    // and disable further control flow analysis in the containing function or module body.
                    flowAnalysisDisabled = true;
                    reportFlowControlError(reference);
                    return errorType;
                }
                flowDepth++;
                while (true) {
                    var flags = flow.flags;
                    if (flags & 8192 /* Cached */) {
                        var key_2 = getOrSetCacheKey();
                        if (key_2) {
                            var id = getFlowNodeId(flow);
                            if (flowAssignmentKeys[id] === key_2) {
                                return flowAssignmentTypes[id];
                            }
                        }
                    }
                    if (flags & 1024 /* Shared */) {
                        // We cache results of flow type resolution for shared nodes that were previously visited in
                        // the same getFlowTypeOfReference invocation. A node is considered shared when it is the
                        // antecedent of more than one node.
                        for (var i = sharedFlowStart; i < sharedFlowCount; i++) {
                            if (sharedFlowNodes[i] === flow) {
                                flowDepth--;
                                return sharedFlowTypes[i];
                            }
                        }
                    }
                    var type = void 0;
                    if (flags & 4096 /* AfterFinally */) {
                        // block flow edge: finally -> pre-try (for larger explanation check comment in binder.ts - bindTryStatement
                        flow.locked = true;
                        type = getTypeAtFlowNode(flow.antecedent);
                        flow.locked = false;
                    }
                    else if (flags & 2048 /* PreFinally */) {
                        // locked pre-finally flows are filtered out in getTypeAtFlowBranchLabel
                        // so here just redirect to antecedent
                        flow = flow.antecedent;
                        continue;
                    }
                    else if (flags & 16 /* Assignment */) {
                        type = getTypeAtFlowAssignment(flow);
                        if (!type) {
                            flow = flow.antecedent;
                            continue;
                        }
                        else if (flowLoopCount === flowLoopStart) { // Only cache assignments when not within loop analysis
                            var key_3 = getOrSetCacheKey();
                            if (key_3 && !isIncomplete(type)) {
                                flow.flags |= 8192 /* Cached */;
                                var id = getFlowNodeId(flow);
                                flowAssignmentKeys[id] = key_3;
                                flowAssignmentTypes[id] = type;
                            }
                        }
                    }
                    else if (flags & 96 /* Condition */) {
                        type = getTypeAtFlowCondition(flow);
                    }
                    else if (flags & 128 /* SwitchClause */) {
                        type = getTypeAtSwitchClause(flow);
                    }
                    else if (flags & 12 /* Label */) {
                        if (flow.antecedents.length === 1) {
                            flow = flow.antecedents[0];
                            continue;
                        }
                        type = flags & 4 /* BranchLabel */ ?
                            getTypeAtFlowBranchLabel(flow) :
                            getTypeAtFlowLoopLabel(flow);
                    }
                    else if (flags & 256 /* ArrayMutation */) {
                        type = getTypeAtFlowArrayMutation(flow);
                        if (!type) {
                            flow = flow.antecedent;
                            continue;
                        }
                    }
                    else if (flags & 2 /* Start */) {
                        // Check if we should continue with the control flow of the containing function.
                        var container = flow.container;
                        if (container && container !== flowContainer &&
                            reference.kind !== 190 /* PropertyAccessExpression */ &&
                            reference.kind !== 191 /* ElementAccessExpression */ &&
                            reference.kind !== 101 /* ThisKeyword */) {
                            flow = container.flowNode;
                            continue;
                        }
                        // At the top of the flow we have the initial type.
                        type = initialType;
                    }
                    else {
                        // Unreachable code errors are reported in the binding phase. Here we
                        // simply return the non-auto declared type to reduce follow-on errors.
                        type = convertAutoToAny(declaredType);
                    }
                    if (flags & 1024 /* Shared */) {
                        // Record visited node and the associated type in the cache.
                        sharedFlowNodes[sharedFlowCount] = flow;
                        sharedFlowTypes[sharedFlowCount] = type;
                        sharedFlowCount++;
                    }
                    flowDepth--;
                    return type;
                }
            }
            function getTypeAtFlowAssignment(flow) {
                var node = flow.node;
                // Assignments only narrow the computed type if the declared type is a union type. Thus, we
                // only need to evaluate the assigned type if the declared type is a union type.
                if (isMatchingReference(reference, node)) {
                    if (ts.getAssignmentTargetKind(node) === 2 /* Compound */) {
                        var flowType = getTypeAtFlowNode(flow.antecedent);
                        return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType));
                    }
                    if (declaredType === autoType || declaredType === autoArrayType) {
                        if (isEmptyArrayAssignment(node)) {
                            return getEvolvingArrayType(neverType);
                        }
                        var assignedType = getBaseTypeOfLiteralType(getInitialOrAssignedType(node, reference));
                        return isTypeAssignableTo(assignedType, declaredType) ? assignedType : anyArrayType;
                    }
                    if (declaredType.flags & 1048576 /* Union */) {
                        return getAssignmentReducedType(declaredType, getInitialOrAssignedType(node, reference));
                    }
                    return declaredType;
                }
                // We didn't have a direct match. However, if the reference is a dotted name, this
                // may be an assignment to a left hand part of the reference. For example, for a
                // reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case,
                // return the declared type.
                if (containsMatchingReference(reference, node)) {
                    // A matching dotted name might also be an expando property on a function *expression*,
                    // in which case we continue control flow analysis back to the function's declaration
                    if (ts.isVariableDeclaration(node) && (ts.isInJSFile(node) || ts.isVarConst(node))) {
                        var init = ts.getDeclaredExpandoInitializer(node);
                        if (init && (init.kind === 197 /* FunctionExpression */ || init.kind === 198 /* ArrowFunction */)) {
                            return getTypeAtFlowNode(flow.antecedent);
                        }
                    }
                    return declaredType;
                }
                // for (const _ in ref) acts as a nonnull on ref
                if (ts.isVariableDeclaration(node) && node.parent.parent.kind === 227 /* ForInStatement */ && isMatchingReference(reference, node.parent.parent.expression)) {
                    return getNonNullableTypeIfNeeded(getTypeFromFlowType(getTypeAtFlowNode(flow.antecedent)));
                }
                // Assignment doesn't affect reference
                return undefined;
            }
            function getTypeAtFlowArrayMutation(flow) {
                if (declaredType === autoType || declaredType === autoArrayType) {
                    var node = flow.node;
                    var expr = node.kind === 192 /* CallExpression */ ?
                        node.expression.expression :
                        node.left.expression;
                    if (isMatchingReference(reference, getReferenceCandidate(expr))) {
                        var flowType = getTypeAtFlowNode(flow.antecedent);
                        var type = getTypeFromFlowType(flowType);
                        if (ts.getObjectFlags(type) & 256 /* EvolvingArray */) {
                            var evolvedType_1 = type;
                            if (node.kind === 192 /* CallExpression */) {
                                for (var _i = 0, _a = node.arguments; _i < _a.length; _i++) {
                                    var arg = _a[_i];
                                    evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, arg);
                                }
                            }
                            else {
                                // We must get the context free expression type so as to not recur in an uncached fashion on the LHS (which causes exponential blowup in compile time)
                                var indexType = getContextFreeTypeOfExpression(node.left.argumentExpression);
                                if (isTypeAssignableToKind(indexType, 296 /* NumberLike */)) {
                                    evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, node.right);
                                }
                            }
                            return evolvedType_1 === type ? flowType : createFlowType(evolvedType_1, isIncomplete(flowType));
                        }
                        return flowType;
                    }
                }
                return undefined;
            }
            function getTypeAtFlowCondition(flow) {
                var flowType = getTypeAtFlowNode(flow.antecedent);
                var type = getTypeFromFlowType(flowType);
                if (type.flags & 131072 /* Never */) {
                    return flowType;
                }
                // If we have an antecedent type (meaning we're reachable in some way), we first
                // attempt to narrow the antecedent type. If that produces the never type, and if
                // the antecedent type is incomplete (i.e. a transient type in a loop), then we
                // take the type guard as an indication that control *could* reach here once we
                // have the complete type. We proceed by switching to the silent never type which
                // doesn't report errors when operators are applied to it. Note that this is the
                // *only* place a silent never type is ever generated.
                var assumeTrue = (flow.flags & 32 /* TrueCondition */) !== 0;
                var nonEvolvingType = finalizeEvolvingArrayType(type);
                var narrowedType = narrowType(nonEvolvingType, flow.expression, assumeTrue);
                if (narrowedType === nonEvolvingType) {
                    return flowType;
                }
                var incomplete = isIncomplete(flowType);
                var resultType = incomplete && narrowedType.flags & 131072 /* Never */ ? silentNeverType : narrowedType;
                return createFlowType(resultType, incomplete);
            }
            function getTypeAtSwitchClause(flow) {
                var expr = flow.switchStatement.expression;
                var flowType = getTypeAtFlowNode(flow.antecedent);
                var type = getTypeFromFlowType(flowType);
                if (isMatchingReference(reference, expr)) {
                    type = narrowTypeBySwitchOnDiscriminant(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd);
                }
                else if (isMatchingReferenceDiscriminant(expr, type)) {
                    type = narrowTypeByDiscriminant(type, expr, function (t) { return narrowTypeBySwitchOnDiscriminant(t, flow.switchStatement, flow.clauseStart, flow.clauseEnd); });
                }
                else if (expr.kind === 200 /* TypeOfExpression */ && isMatchingReference(reference, expr.expression)) {
                    type = narrowBySwitchOnTypeOf(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd);
                }
                else if (containsMatchingReferenceDiscriminant(reference, expr)) {
                    type = declaredType;
                }
                return createFlowType(type, isIncomplete(flowType));
            }
            function getTypeAtFlowBranchLabel(flow) {
                var antecedentTypes = [];
                var subtypeReduction = false;
                var seenIncomplete = false;
                for (var _i = 0, _a = flow.antecedents; _i < _a.length; _i++) {
                    var antecedent = _a[_i];
                    if (antecedent.flags & 2048 /* PreFinally */ && antecedent.lock.locked) {
                        // if flow correspond to branch from pre-try to finally and this branch is locked - this means that
                        // we initially have started following the flow outside the finally block.
                        // in this case we should ignore this branch.
                        continue;
                    }
                    var flowType = getTypeAtFlowNode(antecedent);
                    var type = getTypeFromFlowType(flowType);
                    // If the type at a particular antecedent path is the declared type and the
                    // reference is known to always be assigned (i.e. when declared and initial types
                    // are the same), there is no reason to process more antecedents since the only
                    // possible outcome is subtypes that will be removed in the final union type anyway.
                    if (type === declaredType && declaredType === initialType) {
                        return type;
                    }
                    ts.pushIfUnique(antecedentTypes, type);
                    // If an antecedent type is not a subset of the declared type, we need to perform
                    // subtype reduction. This happens when a "foreign" type is injected into the control
                    // flow using the instanceof operator or a user defined type predicate.
                    if (!isTypeSubsetOf(type, declaredType)) {
                        subtypeReduction = true;
                    }
                    if (isIncomplete(flowType)) {
                        seenIncomplete = true;
                    }
                }
                return createFlowType(getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction ? 2 /* Subtype */ : 1 /* Literal */), seenIncomplete);
            }
            function getTypeAtFlowLoopLabel(flow) {
                // If we have previously computed the control flow type for the reference at
                // this flow loop junction, return the cached type.
                var id = getFlowNodeId(flow);
                var cache = flowLoopCaches[id] || (flowLoopCaches[id] = ts.createMap());
                var key = getOrSetCacheKey();
                if (!key) {
                    // No cache key is generated when binding patterns are in unnarrowable situations
                    return declaredType;
                }
                var cached = cache.get(key);
                if (cached) {
                    return cached;
                }
                // If this flow loop junction and reference are already being processed, return
                // the union of the types computed for each branch so far, marked as incomplete.
                // It is possible to see an empty array in cases where loops are nested and the
                // back edge of the outer loop reaches an inner loop that is already being analyzed.
                // In such cases we restart the analysis of the inner loop, which will then see
                // a non-empty in-process array for the outer loop and eventually terminate because
                // the first antecedent of a loop junction is always the non-looping control flow
                // path that leads to the top.
                for (var i = flowLoopStart; i < flowLoopCount; i++) {
                    if (flowLoopNodes[i] === flow && flowLoopKeys[i] === key && flowLoopTypes[i].length) {
                        return createFlowType(getUnionOrEvolvingArrayType(flowLoopTypes[i], 1 /* Literal */), /*incomplete*/ true);
                    }
                }
                // Add the flow loop junction and reference to the in-process stack and analyze
                // each antecedent code path.
                var antecedentTypes = [];
                var subtypeReduction = false;
                var firstAntecedentType;
                flowLoopNodes[flowLoopCount] = flow;
                flowLoopKeys[flowLoopCount] = key;
                flowLoopTypes[flowLoopCount] = antecedentTypes;
                for (var _i = 0, _a = flow.antecedents; _i < _a.length; _i++) {
                    var antecedent = _a[_i];
                    flowLoopCount++;
                    var flowType = getTypeAtFlowNode(antecedent);
                    flowLoopCount--;
                    if (!firstAntecedentType) {
                        firstAntecedentType = flowType;
                    }
                    var type = getTypeFromFlowType(flowType);
                    // If we see a value appear in the cache it is a sign that control flow analysis
                    // was restarted and completed by checkExpressionCached. We can simply pick up
                    // the resulting type and bail out.
                    var cached_1 = cache.get(key);
                    if (cached_1) {
                        return cached_1;
                    }
                    ts.pushIfUnique(antecedentTypes, type);
                    // If an antecedent type is not a subset of the declared type, we need to perform
                    // subtype reduction. This happens when a "foreign" type is injected into the control
                    // flow using the instanceof operator or a user defined type predicate.
                    if (!isTypeSubsetOf(type, declaredType)) {
                        subtypeReduction = true;
                    }
                    // If the type at a particular antecedent path is the declared type there is no
                    // reason to process more antecedents since the only possible outcome is subtypes
                    // that will be removed in the final union type anyway.
                    if (type === declaredType) {
                        break;
                    }
                }
                // The result is incomplete if the first antecedent (the non-looping control flow path)
                // is incomplete.
                var result = getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction ? 2 /* Subtype */ : 1 /* Literal */);
                if (isIncomplete(firstAntecedentType)) {
                    return createFlowType(result, /*incomplete*/ true);
                }
                cache.set(key, result);
                return result;
            }
            function isMatchingReferenceDiscriminant(expr, computedType) {
                if (!(computedType.flags & 1048576 /* Union */) || !ts.isAccessExpression(expr)) {
                    return false;
                }
                var name = getAccessedPropertyName(expr);
                if (name === undefined) {
                    return false;
                }
                return isMatchingReference(reference, expr.expression) && isDiscriminantProperty(computedType, name);
            }
            function narrowTypeByDiscriminant(type, access, narrowType) {
                var propName = getAccessedPropertyName(access);
                if (propName === undefined) {
                    return type;
                }
                var propType = getTypeOfPropertyOfType(type, propName);
                var narrowedPropType = propType && narrowType(propType);
                return propType === narrowedPropType ? type : filterType(type, function (t) { return isTypeComparableTo(getTypeOfPropertyOrIndexSignature(t, propName), narrowedPropType); });
            }
            function narrowTypeByTruthiness(type, expr, assumeTrue) {
                if (isMatchingReference(reference, expr)) {
                    return getTypeWithFacts(type, assumeTrue ? 4194304 /* Truthy */ : 8388608 /* Falsy */);
                }
                if (isMatchingReferenceDiscriminant(expr, declaredType)) {
                    return narrowTypeByDiscriminant(type, expr, function (t) { return getTypeWithFacts(t, assumeTrue ? 4194304 /* Truthy */ : 8388608 /* Falsy */); });
                }
                if (containsMatchingReferenceDiscriminant(reference, expr)) {
                    return declaredType;
                }
                return type;
            }
            function isTypePresencePossible(type, propName, assumeTrue) {
                if (getIndexInfoOfType(type, 0 /* String */)) {
                    return true;
                }
                var prop = getPropertyOfType(type, propName);
                if (prop) {
                    return prop.flags & 16777216 /* Optional */ ? true : assumeTrue;
                }
                return !assumeTrue;
            }
            function narrowByInKeyword(type, literal, assumeTrue) {
                if (type.flags & (1048576 /* Union */ | 524288 /* Object */) || isThisTypeParameter(type)) {
                    var propName_1 = ts.escapeLeadingUnderscores(literal.text);
                    return filterType(type, function (t) { return isTypePresencePossible(t, propName_1, assumeTrue); });
                }
                return type;
            }
            function narrowTypeByBinaryExpression(type, expr, assumeTrue) {
                switch (expr.operatorToken.kind) {
                    case 60 /* EqualsToken */:
                        return narrowTypeByTruthiness(narrowType(type, expr.right, assumeTrue), expr.left, assumeTrue);
                    case 33 /* EqualsEqualsToken */:
                    case 34 /* ExclamationEqualsToken */:
                    case 35 /* EqualsEqualsEqualsToken */:
                    case 36 /* ExclamationEqualsEqualsToken */:
                        var operator_1 = expr.operatorToken.kind;
                        var left_1 = getReferenceCandidate(expr.left);
                        var right_1 = getReferenceCandidate(expr.right);
                        if (left_1.kind === 200 /* TypeOfExpression */ && ts.isStringLiteralLike(right_1)) {
                            return narrowTypeByTypeof(type, left_1, operator_1, right_1, assumeTrue);
                        }
                        if (right_1.kind === 200 /* TypeOfExpression */ && ts.isStringLiteralLike(left_1)) {
                            return narrowTypeByTypeof(type, right_1, operator_1, left_1, assumeTrue);
                        }
                        if (isMatchingReference(reference, left_1)) {
                            return narrowTypeByEquality(type, operator_1, right_1, assumeTrue);
                        }
                        if (isMatchingReference(reference, right_1)) {
                            return narrowTypeByEquality(type, operator_1, left_1, assumeTrue);
                        }
                        if (isMatchingReferenceDiscriminant(left_1, declaredType)) {
                            return narrowTypeByDiscriminant(type, left_1, function (t) { return narrowTypeByEquality(t, operator_1, right_1, assumeTrue); });
                        }
                        if (isMatchingReferenceDiscriminant(right_1, declaredType)) {
                            return narrowTypeByDiscriminant(type, right_1, function (t) { return narrowTypeByEquality(t, operator_1, left_1, assumeTrue); });
                        }
                        if (containsMatchingReferenceDiscriminant(reference, left_1) || containsMatchingReferenceDiscriminant(reference, right_1)) {
                            return declaredType;
                        }
                        break;
                    case 95 /* InstanceOfKeyword */:
                        return narrowTypeByInstanceof(type, expr, assumeTrue);
                    case 94 /* InKeyword */:
                        var target = getReferenceCandidate(expr.right);
                        if (ts.isStringLiteralLike(expr.left) && isMatchingReference(reference, target)) {
                            return narrowByInKeyword(type, expr.left, assumeTrue);
                        }
                        break;
                    case 27 /* CommaToken */:
                        return narrowType(type, expr.right, assumeTrue);
                }
                return type;
            }
            function narrowTypeByEquality(type, operator, value, assumeTrue) {
                if (type.flags & 1 /* Any */) {
                    return type;
                }
                if (operator === 34 /* ExclamationEqualsToken */ || operator === 36 /* ExclamationEqualsEqualsToken */) {
                    assumeTrue = !assumeTrue;
                }
                var valueType = getTypeOfExpression(value);
                if ((type.flags & 2 /* Unknown */) && (operator === 35 /* EqualsEqualsEqualsToken */) && assumeTrue) {
                    if (valueType.flags & (131068 /* Primitive */ | 67108864 /* NonPrimitive */)) {
                        return valueType;
                    }
                    if (valueType.flags & 524288 /* Object */) {
                        return nonPrimitiveType;
                    }
                    return type;
                }
                if (valueType.flags & 98304 /* Nullable */) {
                    if (!strictNullChecks) {
                        return type;
                    }
                    var doubleEquals = operator === 33 /* EqualsEqualsToken */ || operator === 34 /* ExclamationEqualsToken */;
                    var facts = doubleEquals ?
                        assumeTrue ? 262144 /* EQUndefinedOrNull */ : 2097152 /* NEUndefinedOrNull */ :
                        valueType.flags & 65536 /* Null */ ?
                            assumeTrue ? 131072 /* EQNull */ : 1048576 /* NENull */ :
                            assumeTrue ? 65536 /* EQUndefined */ : 524288 /* NEUndefined */;
                    return getTypeWithFacts(type, facts);
                }
                if (type.flags & 67637251 /* NotUnionOrUnit */) {
                    return type;
                }
                if (assumeTrue) {
                    var filterFn = operator === 33 /* EqualsEqualsToken */ ?
                        (function (t) { return areTypesComparable(t, valueType) || isCoercibleUnderDoubleEquals(t, valueType); }) :
                        function (t) { return areTypesComparable(t, valueType); };
                    var narrowedType = filterType(type, filterFn);
                    return narrowedType.flags & 131072 /* Never */ ? type : replacePrimitivesWithLiterals(narrowedType, valueType);
                }
                if (isUnitType(valueType)) {
                    var regularType_1 = getRegularTypeOfLiteralType(valueType);
                    return filterType(type, function (t) { return getRegularTypeOfLiteralType(t) !== regularType_1; });
                }
                return type;
            }
            function narrowTypeByTypeof(type, typeOfExpr, operator, literal, assumeTrue) {
                // We have '==', '!=', '====', or !==' operator with 'typeof xxx' and string literal operands
                var target = getReferenceCandidate(typeOfExpr.expression);
                if (!isMatchingReference(reference, target)) {
                    // For a reference of the form 'x.y', a 'typeof x === ...' type guard resets the
                    // narrowed type of 'y' to its declared type.
                    if (containsMatchingReference(reference, target)) {
                        return declaredType;
                    }
                    return type;
                }
                if (operator === 34 /* ExclamationEqualsToken */ || operator === 36 /* ExclamationEqualsEqualsToken */) {
                    assumeTrue = !assumeTrue;
                }
                if (type.flags & 1 /* Any */ && literal.text === "function") {
                    return type;
                }
                var facts = assumeTrue ?
                    typeofEQFacts.get(literal.text) || 128 /* TypeofEQHostObject */ :
                    typeofNEFacts.get(literal.text) || 32768 /* TypeofNEHostObject */;
                return getTypeWithFacts(assumeTrue ? mapType(type, narrowTypeForTypeof) : type, facts);
                function narrowTypeForTypeof(type) {
                    if (type.flags & 2 /* Unknown */ && literal.text === "object") {
                        return getUnionType([nonPrimitiveType, nullType]);
                    }
                    // We narrow a non-union type to an exact primitive type if the non-union type
                    // is a supertype of that primitive type. For example, type 'any' can be narrowed
                    // to one of the primitive types.
                    var targetType = literal.text === "function" ? globalFunctionType : typeofTypesByName.get(literal.text);
                    if (targetType) {
                        if (isTypeSubtypeOf(type, targetType)) {
                            return type;
                        }
                        if (isTypeSubtypeOf(targetType, type)) {
                            return targetType;
                        }
                        if (type.flags & 63176704 /* Instantiable */) {
                            var constraint = getBaseConstraintOfType(type) || anyType;
                            if (isTypeSubtypeOf(targetType, constraint)) {
                                return getIntersectionType([type, targetType]);
                            }
                        }
                    }
                    return type;
                }
            }
            function narrowTypeBySwitchOnDiscriminant(type, switchStatement, clauseStart, clauseEnd) {
                // We only narrow if all case expressions specify
                // values with unit types, except for the case where
                // `type` is unknown. In this instance we map object
                // types to the nonPrimitive type and narrow with that.
                var switchTypes = getSwitchClauseTypes(switchStatement);
                if (!switchTypes.length) {
                    return type;
                }
                var clauseTypes = switchTypes.slice(clauseStart, clauseEnd);
                var hasDefaultClause = clauseStart === clauseEnd || ts.contains(clauseTypes, neverType);
                if ((type.flags & 2 /* Unknown */) && !hasDefaultClause) {
                    var groundClauseTypes = void 0;
                    for (var i = 0; i < clauseTypes.length; i += 1) {
                        var t = clauseTypes[i];
                        if (t.flags & (131068 /* Primitive */ | 67108864 /* NonPrimitive */)) {
                            if (groundClauseTypes !== undefined) {
                                groundClauseTypes.push(t);
                            }
                        }
                        else if (t.flags & 524288 /* Object */) {
                            if (groundClauseTypes === undefined) {
                                groundClauseTypes = clauseTypes.slice(0, i);
                            }
                            groundClauseTypes.push(nonPrimitiveType);
                        }
                        else {
                            return type;
                        }
                    }
                    return getUnionType(groundClauseTypes === undefined ? clauseTypes : groundClauseTypes);
                }
                var discriminantType = getUnionType(clauseTypes);
                var caseType = discriminantType.flags & 131072 /* Never */ ? neverType :
                    replacePrimitivesWithLiterals(filterType(type, function (t) { return areTypesComparable(discriminantType, t); }), discriminantType);
                if (!hasDefaultClause) {
                    return caseType;
                }
                var defaultType = filterType(type, function (t) { return !(isUnitType(t) && ts.contains(switchTypes, getRegularTypeOfLiteralType(t))); });
                return caseType.flags & 131072 /* Never */ ? defaultType : getUnionType([caseType, defaultType]);
            }
            function getImpliedTypeFromTypeofCase(type, text) {
                switch (text) {
                    case "function":
                        return type.flags & 1 /* Any */ ? type : globalFunctionType;
                    case "object":
                        return type.flags & 2 /* Unknown */ ? getUnionType([nonPrimitiveType, nullType]) : type;
                    default:
                        return typeofTypesByName.get(text) || type;
                }
            }
            function narrowTypeForTypeofSwitch(candidate) {
                return function (type) {
                    if (isTypeSubtypeOf(candidate, type)) {
                        return candidate;
                    }
                    if (type.flags & 63176704 /* Instantiable */) {
                        var constraint = getBaseConstraintOfType(type) || anyType;
                        if (isTypeSubtypeOf(candidate, constraint)) {
                            return getIntersectionType([type, candidate]);
                        }
                    }
                    return type;
                };
            }
            function narrowBySwitchOnTypeOf(type, switchStatement, clauseStart, clauseEnd) {
                var switchWitnesses = getSwitchClauseTypeOfWitnesses(switchStatement);
                if (!switchWitnesses.length) {
                    return type;
                }
                //  Equal start and end denotes implicit fallthrough; undefined marks explicit default clause
                var defaultCaseLocation = ts.findIndex(switchWitnesses, function (elem) { return elem === undefined; });
                var hasDefaultClause = clauseStart === clauseEnd || (defaultCaseLocation >= clauseStart && defaultCaseLocation < clauseEnd);
                var clauseWitnesses;
                var switchFacts;
                if (defaultCaseLocation > -1) {
                    // We no longer need the undefined denoting an
                    // explicit default case. Remove the undefined and
                    // fix-up clauseStart and clauseEnd.  This means
                    // that we don't have to worry about undefined
                    // in the witness array.
                    var witnesses = switchWitnesses.filter(function (witness) { return witness !== undefined; });
                    // The adjusted clause start and end after removing the `default` statement.
                    var fixedClauseStart = defaultCaseLocation < clauseStart ? clauseStart - 1 : clauseStart;
                    var fixedClauseEnd = defaultCaseLocation < clauseEnd ? clauseEnd - 1 : clauseEnd;
                    clauseWitnesses = witnesses.slice(fixedClauseStart, fixedClauseEnd);
                    switchFacts = getFactsFromTypeofSwitch(fixedClauseStart, fixedClauseEnd, witnesses, hasDefaultClause);
                }
                else {
                    clauseWitnesses = switchWitnesses.slice(clauseStart, clauseEnd);
                    switchFacts = getFactsFromTypeofSwitch(clauseStart, clauseEnd, switchWitnesses, hasDefaultClause);
                }
                if (hasDefaultClause) {
                    return filterType(type, function (t) { return (getTypeFacts(t) & switchFacts) === switchFacts; });
                }
                /*
                  The implied type is the raw type suggested by a
                  value being caught in this clause.

                  When the clause contains a default case we ignore
                  the implied type and try to narrow using any facts
                  we can learn: see `switchFacts`.

                  Example:
                  switch (typeof x) {
                      case 'number':
                      case 'string': break;
                      default: break;
                      case 'number':
                      case 'boolean': break
                  }

                  In the first clause (case `number` and `string`) the
                  implied type is number | string.

                  In the default clause we de not compute an implied type.

                  In the third clause (case `number` and `boolean`)
                  the naive implied type is number | boolean, however
                  we use the type facts to narrow the implied type to
                  boolean. We know that number cannot be selected
                  because it is caught in the first clause.
                */
                var impliedType = getTypeWithFacts(getUnionType(clauseWitnesses.map(function (text) { return getImpliedTypeFromTypeofCase(type, text); })), switchFacts);
                if (impliedType.flags & 1048576 /* Union */) {
                    impliedType = getAssignmentReducedType(impliedType, getBaseConstraintOrType(type));
                }
                return getTypeWithFacts(mapType(type, narrowTypeForTypeofSwitch(impliedType)), switchFacts);
            }
            function narrowTypeByInstanceof(type, expr, assumeTrue) {
                var left = getReferenceCandidate(expr.left);
                if (!isMatchingReference(reference, left)) {
                    // For a reference of the form 'x.y', an 'x instanceof T' type guard resets the
                    // narrowed type of 'y' to its declared type. We do this because preceding 'x.y'
                    // references might reference a different 'y' property. However, we make an exception
                    // for property accesses where x is a synthetic 'this' expression, indicating that we
                    // were called from isPropertyInitializedInConstructor. Without this exception,
                    // initializations of 'this' properties that occur before a 'this instanceof XXX'
                    // check would not be considered.
                    if (containsMatchingReference(reference, left) && !isSyntheticThisPropertyAccess(reference)) {
                        return declaredType;
                    }
                    return type;
                }
                // Check that right operand is a function type with a prototype property
                var rightType = getTypeOfExpression(expr.right);
                if (!isTypeDerivedFrom(rightType, globalFunctionType)) {
                    return type;
                }
                var targetType;
                var prototypeProperty = getPropertyOfType(rightType, "prototype");
                if (prototypeProperty) {
                    // Target type is type of the prototype property
                    var prototypePropertyType = getTypeOfSymbol(prototypeProperty);
                    if (!isTypeAny(prototypePropertyType)) {
                        targetType = prototypePropertyType;
                    }
                }
                // Don't narrow from 'any' if the target type is exactly 'Object' or 'Function'
                if (isTypeAny(type) && (targetType === globalObjectType || targetType === globalFunctionType)) {
                    return type;
                }
                if (!targetType) {
                    var constructSignatures = getSignaturesOfType(rightType, 1 /* Construct */);
                    targetType = constructSignatures.length ?
                        getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); })) :
                        emptyObjectType;
                }
                return getNarrowedType(type, targetType, assumeTrue, isTypeDerivedFrom);
            }
            function getNarrowedType(type, candidate, assumeTrue, isRelated) {
                if (!assumeTrue) {
                    return filterType(type, function (t) { return !isRelated(t, candidate); });
                }
                // If the current type is a union type, remove all constituents that couldn't be instances of
                // the candidate type. If one or more constituents remain, return a union of those.
                if (type.flags & 1048576 /* Union */) {
                    var assignableType = filterType(type, function (t) { return isRelated(t, candidate); });
                    if (!(assignableType.flags & 131072 /* Never */)) {
                        return assignableType;
                    }
                }
                // If the candidate type is a subtype of the target type, narrow to the candidate type.
                // Otherwise, if the target type is assignable to the candidate type, keep the target type.
                // Otherwise, if the candidate type is assignable to the target type, narrow to the candidate
                // type. Otherwise, the types are completely unrelated, so narrow to an intersection of the
                // two types.
                return isTypeSubtypeOf(candidate, type) ? candidate :
                    isTypeAssignableTo(type, candidate) ? type :
                        isTypeAssignableTo(candidate, type) ? candidate :
                            getIntersectionType([type, candidate]);
            }
            function narrowTypeByTypePredicate(type, callExpression, assumeTrue) {
                if (!hasMatchingArgument(callExpression, reference) || !maybeTypePredicateCall(callExpression)) {
                    return type;
                }
                var signature = getResolvedSignature(callExpression);
                var predicate = getTypePredicateOfSignature(signature);
                if (!predicate) {
                    return type;
                }
                // Don't narrow from 'any' if the predicate type is exactly 'Object' or 'Function'
                if (isTypeAny(type) && (predicate.type === globalObjectType || predicate.type === globalFunctionType)) {
                    return type;
                }
                if (ts.isIdentifierTypePredicate(predicate)) {
                    var predicateArgument = callExpression.arguments[predicate.parameterIndex];
                    if (predicateArgument) {
                        if (isMatchingReference(reference, predicateArgument)) {
                            return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf);
                        }
                        if (containsMatchingReference(reference, predicateArgument)) {
                            return declaredType;
                        }
                    }
                }
                else {
                    var invokedExpression = ts.skipParentheses(callExpression.expression);
                    if (ts.isAccessExpression(invokedExpression)) {
                        var possibleReference = ts.skipParentheses(invokedExpression.expression);
                        if (isMatchingReference(reference, possibleReference)) {
                            return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf);
                        }
                        if (containsMatchingReference(reference, possibleReference)) {
                            return declaredType;
                        }
                    }
                }
                return type;
            }
            // Narrow the given type based on the given expression having the assumed boolean value. The returned type
            // will be a subtype or the same type as the argument.
            function narrowType(type, expr, assumeTrue) {
                switch (expr.kind) {
                    case 73 /* Identifier */:
                    case 101 /* ThisKeyword */:
                    case 99 /* SuperKeyword */:
                    case 190 /* PropertyAccessExpression */:
                    case 191 /* ElementAccessExpression */:
                        return narrowTypeByTruthiness(type, expr, assumeTrue);
                    case 192 /* CallExpression */:
                        return narrowTypeByTypePredicate(type, expr, assumeTrue);
                    case 196 /* ParenthesizedExpression */:
                        return narrowType(type, expr.expression, assumeTrue);
                    case 205 /* BinaryExpression */:
                        return narrowTypeByBinaryExpression(type, expr, assumeTrue);
                    case 203 /* PrefixUnaryExpression */:
                        if (expr.operator === 52 /* ExclamationToken */) {
                            return narrowType(type, expr.operand, !assumeTrue);
                        }
                        break;
                }
                return type;
            }
        }
        function getTypeOfSymbolAtLocation(symbol, location) {
            symbol = symbol.exportSymbol || symbol;
            // If we have an identifier or a property access at the given location, if the location is
            // an dotted name expression, and if the location is not an assignment target, obtain the type
            // of the expression (which will reflect control flow analysis). If the expression indeed
            // resolved to the given symbol, return the narrowed type.
            if (location.kind === 73 /* Identifier */) {
                if (ts.isRightSideOfQualifiedNameOrPropertyAccess(location)) {
                    location = location.parent;
                }
                if (ts.isExpressionNode(location) && !ts.isAssignmentTarget(location)) {
                    var type = getTypeOfExpression(location);
                    if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) {
                        return type;
                    }
                }
            }
            // The location isn't a reference to the given symbol, meaning we're being asked
            // a hypothetical question of what type the symbol would have if there was a reference
            // to it at the given location. Since we have no control flow information for the
            // hypothetical reference (control flow information is created and attached by the
            // binder), we simply return the declared type of the symbol.
            return getTypeOfSymbol(symbol);
        }
        function getControlFlowContainer(node) {
            return ts.findAncestor(node.parent, function (node) {
                return ts.isFunctionLike(node) && !ts.getImmediatelyInvokedFunctionExpression(node) ||
                    node.kind === 246 /* ModuleBlock */ ||
                    node.kind === 285 /* SourceFile */ ||
                    node.kind === 155 /* PropertyDeclaration */;
            });
        }
        // Check if a parameter is assigned anywhere within its declaring function.
        function isParameterAssigned(symbol) {
            var func = ts.getRootDeclaration(symbol.valueDeclaration).parent;
            var links = getNodeLinks(func);
            if (!(links.flags & 8388608 /* AssignmentsMarked */)) {
                links.flags |= 8388608 /* AssignmentsMarked */;
                if (!hasParentWithAssignmentsMarked(func)) {
                    markParameterAssignments(func);
                }
            }
            return symbol.isAssigned || false;
        }
        function hasParentWithAssignmentsMarked(node) {
            return !!ts.findAncestor(node.parent, function (node) { return ts.isFunctionLike(node) && !!(getNodeLinks(node).flags & 8388608 /* AssignmentsMarked */); });
        }
        function markParameterAssignments(node) {
            if (node.kind === 73 /* Identifier */) {
                if (ts.isAssignmentTarget(node)) {
                    var symbol = getResolvedSymbol(node);
                    if (symbol.valueDeclaration && ts.getRootDeclaration(symbol.valueDeclaration).kind === 152 /* Parameter */) {
                        symbol.isAssigned = true;
                    }
                }
            }
            else {
                ts.forEachChild(node, markParameterAssignments);
            }
        }
        function isConstVariable(symbol) {
            return symbol.flags & 3 /* Variable */ && (getDeclarationNodeFlagsFromSymbol(symbol) & 2 /* Const */) !== 0 && getTypeOfSymbol(symbol) !== autoArrayType;
        }
        /** remove undefined from the annotated type of a parameter when there is an initializer (that doesn't include undefined) */
        function removeOptionalityFromDeclaredType(declaredType, declaration) {
            var annotationIncludesUndefined = strictNullChecks &&
                declaration.kind === 152 /* Parameter */ &&
                declaration.initializer &&
                getFalsyFlags(declaredType) & 32768 /* Undefined */ &&
                !(getFalsyFlags(checkExpression(declaration.initializer)) & 32768 /* Undefined */);
            return annotationIncludesUndefined ? getTypeWithFacts(declaredType, 524288 /* NEUndefined */) : declaredType;
        }
        function isConstraintPosition(node) {
            var parent = node.parent;
            return parent.kind === 190 /* PropertyAccessExpression */ ||
                parent.kind === 192 /* CallExpression */ && parent.expression === node ||
                parent.kind === 191 /* ElementAccessExpression */ && parent.expression === node ||
                parent.kind === 187 /* BindingElement */ && parent.name === node && !!parent.initializer;
        }
        function typeHasNullableConstraint(type) {
            return type.flags & 58982400 /* InstantiableNonPrimitive */ && maybeTypeOfKind(getBaseConstraintOfType(type) || unknownType, 98304 /* Nullable */);
        }
        function getConstraintForLocation(type, node) {
            // When a node is the left hand expression of a property access, element access, or call expression,
            // and the type of the node includes type variables with constraints that are nullable, we fetch the
            // apparent type of the node *before* performing control flow analysis such that narrowings apply to
            // the constraint type.
            if (type && isConstraintPosition(node) && forEachType(type, typeHasNullableConstraint)) {
                return mapType(getWidenedType(type), getBaseConstraintOrType);
            }
            return type;
        }
        function markAliasReferenced(symbol, location) {
            if (isNonLocalAlias(symbol, /*excludes*/ 67220415 /* Value */) && !isInTypeQuery(location) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol))) {
                markAliasSymbolAsReferenced(symbol);
            }
        }
        function checkIdentifier(node) {
            var symbol = getResolvedSymbol(node);
            if (symbol === unknownSymbol) {
                return errorType;
            }
            // As noted in ECMAScript 6 language spec, arrow functions never have an arguments objects.
            // Although in down-level emit of arrow function, we emit it using function expression which means that
            // arguments objects will be bound to the inner object; emitting arrow function natively in ES6, arguments objects
            // will be bound to non-arrow function that contain this arrow function. This results in inconsistent behavior.
            // To avoid that we will give an error to users if they use arguments objects in arrow function so that they
            // can explicitly bound arguments objects
            if (symbol === argumentsSymbol) {
                var container = ts.getContainingFunction(node);
                if (languageVersion < 2 /* ES2015 */) {
                    if (container.kind === 198 /* ArrowFunction */) {
                        error(node, ts.Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression);
                    }
                    else if (ts.hasModifier(container, 256 /* Async */)) {
                        error(node, ts.Diagnostics.The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method);
                    }
                }
                getNodeLinks(container).flags |= 8192 /* CaptureArguments */;
                return getTypeOfSymbol(symbol);
            }
            // We should only mark aliases as referenced if there isn't a local value declaration
            // for the symbol. Also, don't mark any property access expression LHS - checkPropertyAccessExpression will handle that
            if (!(node.parent && ts.isPropertyAccessExpression(node.parent) && node.parent.expression === node)) {
                markAliasReferenced(symbol, node);
            }
            var localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol);
            var declaration = localOrExportSymbol.valueDeclaration;
            if (localOrExportSymbol.flags & 32 /* Class */) {
                // Due to the emit for class decorators, any reference to the class from inside of the class body
                // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
                // behavior of class names in ES6.
                if (declaration.kind === 241 /* ClassDeclaration */
                    && ts.nodeIsDecorated(declaration)) {
                    var container = ts.getContainingClass(node);
                    while (container !== undefined) {
                        if (container === declaration && container.name !== node) {
                            getNodeLinks(declaration).flags |= 16777216 /* ClassWithConstructorReference */;
                            getNodeLinks(node).flags |= 33554432 /* ConstructorReferenceInClass */;
                            break;
                        }
                        container = ts.getContainingClass(container);
                    }
                }
                else if (declaration.kind === 210 /* ClassExpression */) {
                    // When we emit a class expression with static members that contain a reference
                    // to the constructor in the initializer, we will need to substitute that
                    // binding with an alias as the class name is not in scope.
                    var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
                    while (container.kind !== 285 /* SourceFile */) {
                        if (container.parent === declaration) {
                            if (container.kind === 155 /* PropertyDeclaration */ && ts.hasModifier(container, 32 /* Static */)) {
                                getNodeLinks(declaration).flags |= 16777216 /* ClassWithConstructorReference */;
                                getNodeLinks(node).flags |= 33554432 /* ConstructorReferenceInClass */;
                            }
                            break;
                        }
                        container = ts.getThisContainer(container, /*includeArrowFunctions*/ false);
                    }
                }
            }
            checkNestedBlockScopedBinding(node, symbol);
            var type = getConstraintForLocation(getTypeOfSymbol(localOrExportSymbol), node);
            var assignmentKind = ts.getAssignmentTargetKind(node);
            if (assignmentKind) {
                if (!(localOrExportSymbol.flags & 3 /* Variable */) &&
                    !(ts.isInJSFile(node) && localOrExportSymbol.flags & 512 /* ValueModule */)) {
                    error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_not_a_variable, symbolToString(symbol));
                    return errorType;
                }
                if (isReadonlySymbol(localOrExportSymbol)) {
                    if (localOrExportSymbol.flags & 3 /* Variable */) {
                        error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_constant, symbolToString(symbol));
                    }
                    else {
                        error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, symbolToString(symbol));
                    }
                    return errorType;
                }
            }
            var isAlias = localOrExportSymbol.flags & 2097152 /* Alias */;
            // We only narrow variables and parameters occurring in a non-assignment position. For all other
            // entities we simply return the declared type.
            if (localOrExportSymbol.flags & 3 /* Variable */) {
                if (assignmentKind === 1 /* Definite */) {
                    return type;
                }
            }
            else if (isAlias) {
                declaration = ts.find(symbol.declarations, isSomeImportDeclaration);
            }
            else {
                return type;
            }
            if (!declaration) {
                return type;
            }
            // The declaration container is the innermost function that encloses the declaration of the variable
            // or parameter. The flow container is the innermost function starting with which we analyze the control
            // flow graph to determine the control flow based type.
            var isParameter = ts.getRootDeclaration(declaration).kind === 152 /* Parameter */;
            var declarationContainer = getControlFlowContainer(declaration);
            var flowContainer = getControlFlowContainer(node);
            var isOuterVariable = flowContainer !== declarationContainer;
            var isSpreadDestructuringAssignmentTarget = node.parent && node.parent.parent && ts.isSpreadAssignment(node.parent) && isDestructuringAssignmentTarget(node.parent.parent);
            var isModuleExports = symbol.flags & 134217728 /* ModuleExports */;
            // When the control flow originates in a function expression or arrow function and we are referencing
            // a const variable or parameter from an outer function, we extend the origin of the control flow
            // analysis to include the immediately enclosing function.
            while (flowContainer !== declarationContainer && (flowContainer.kind === 197 /* FunctionExpression */ ||
                flowContainer.kind === 198 /* ArrowFunction */ || ts.isObjectLiteralOrClassExpressionMethod(flowContainer)) &&
                (isConstVariable(localOrExportSymbol) || isParameter && !isParameterAssigned(localOrExportSymbol))) {
                flowContainer = getControlFlowContainer(flowContainer);
            }
            // We only look for uninitialized variables in strict null checking mode, and only when we can analyze
            // the entire control flow graph from the variable's declaration (i.e. when the flow container and
            // declaration container are the same).
            var assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || ts.isBindingElement(declaration) ||
                type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & 3 /* AnyOrUnknown */) !== 0 ||
                    isInTypeQuery(node) || node.parent.kind === 258 /* ExportSpecifier */) ||
                node.parent.kind === 214 /* NonNullExpression */ ||
                declaration.kind === 238 /* VariableDeclaration */ && declaration.exclamationToken ||
                declaration.flags & 4194304 /* Ambient */;
            var initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, declaration) : type) :
                type === autoType || type === autoArrayType ? undefinedType :
                    getOptionalType(type);
            var flowType = getFlowTypeOfReference(node, type, initialType, flowContainer, !assumeInitialized);
            // A variable is considered uninitialized when it is possible to analyze the entire control flow graph
            // from declaration to use, and when the variable's declared type doesn't include undefined but the
            // control flow based type does include undefined.
            if (!isEvolvingArrayOperationTarget(node) && (type === autoType || type === autoArrayType)) {
                if (flowType === autoType || flowType === autoArrayType) {
                    if (noImplicitAny) {
                        error(ts.getNameOfDeclaration(declaration), ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(flowType));
                        error(node, ts.Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType));
                    }
                    return convertAutoToAny(flowType);
                }
            }
            else if (!assumeInitialized && !(getFalsyFlags(type) & 32768 /* Undefined */) && getFalsyFlags(flowType) & 32768 /* Undefined */) {
                error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol));
                // Return the declared type to reduce follow-on errors
                return type;
            }
            return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType;
        }
        function isInsideFunction(node, threshold) {
            return !!ts.findAncestor(node, function (n) { return n === threshold ? "quit" : ts.isFunctionLike(n); });
        }
        function getPartOfForStatementContainingNode(node, container) {
            return ts.findAncestor(node, function (n) { return n === container ? "quit" : n === container.initializer || n === container.condition || n === container.incrementor || n === container.statement; });
        }
        function checkNestedBlockScopedBinding(node, symbol) {
            if (languageVersion >= 2 /* ES2015 */ ||
                (symbol.flags & (2 /* BlockScopedVariable */ | 32 /* Class */)) === 0 ||
                ts.isSourceFile(symbol.valueDeclaration) ||
                symbol.valueDeclaration.parent.kind === 275 /* CatchClause */) {
                return;
            }
            // 1. walk from the use site up to the declaration and check
            // if there is anything function like between declaration and use-site (is binding/class is captured in function).
            // 2. walk from the declaration up to the boundary of lexical environment and check
            // if there is an iteration statement in between declaration and boundary (is binding/class declared inside iteration statement)
            var container = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration);
            var usedInFunction = isInsideFunction(node.parent, container);
            var current = container;
            var containedInIterationStatement = false;
            while (current && !ts.nodeStartsNewLexicalEnvironment(current)) {
                if (ts.isIterationStatement(current, /*lookInLabeledStatements*/ false)) {
                    containedInIterationStatement = true;
                    break;
                }
                current = current.parent;
            }
            if (containedInIterationStatement) {
                if (usedInFunction) {
                    // mark iteration statement as containing block-scoped binding captured in some function
                    var capturesBlockScopeBindingInLoopBody = true;
                    if (ts.isForStatement(container) &&
                        ts.getAncestor(symbol.valueDeclaration, 239 /* VariableDeclarationList */).parent === container) {
                        var part = getPartOfForStatementContainingNode(node.parent, container);
                        if (part) {
                            var links = getNodeLinks(part);
                            links.flags |= 131072 /* ContainsCapturedBlockScopeBinding */;
                            var capturedBindings = links.capturedBlockScopeBindings || (links.capturedBlockScopeBindings = []);
                            ts.pushIfUnique(capturedBindings, symbol);
                            if (part === container.initializer) {
                                capturesBlockScopeBindingInLoopBody = false; // Initializer is outside of loop body
                            }
                        }
                    }
                    if (capturesBlockScopeBindingInLoopBody) {
                        getNodeLinks(current).flags |= 65536 /* LoopWithCapturedBlockScopedBinding */;
                    }
                }
                // mark variables that are declared in loop initializer and reassigned inside the body of ForStatement.
                // if body of ForStatement will be converted to function then we'll need a extra machinery to propagate reassigned values back.
                if (container.kind === 226 /* ForStatement */ &&
                    ts.getAncestor(symbol.valueDeclaration, 239 /* VariableDeclarationList */).parent === container &&
                    isAssignedInBodyOfForStatement(node, container)) {
                    getNodeLinks(symbol.valueDeclaration).flags |= 4194304 /* NeedsLoopOutParameter */;
                }
                // set 'declared inside loop' bit on the block-scoped binding
                getNodeLinks(symbol.valueDeclaration).flags |= 524288 /* BlockScopedBindingInLoop */;
            }
            if (usedInFunction) {
                getNodeLinks(symbol.valueDeclaration).flags |= 262144 /* CapturedBlockScopedBinding */;
            }
        }
        function isBindingCapturedByNode(node, decl) {
            var links = getNodeLinks(node);
            return !!links && ts.contains(links.capturedBlockScopeBindings, getSymbolOfNode(decl));
        }
        function isAssignedInBodyOfForStatement(node, container) {
            // skip parenthesized nodes
            var current = node;
            while (current.parent.kind === 196 /* ParenthesizedExpression */) {
                current = current.parent;
            }
            // check if node is used as LHS in some assignment expression
            var isAssigned = false;
            if (ts.isAssignmentTarget(current)) {
                isAssigned = true;
            }
            else if ((current.parent.kind === 203 /* PrefixUnaryExpression */ || current.parent.kind === 204 /* PostfixUnaryExpression */)) {
                var expr = current.parent;
                isAssigned = expr.operator === 44 /* PlusPlusToken */ || expr.operator === 45 /* MinusMinusToken */;
            }
            if (!isAssigned) {
                return false;
            }
            // at this point we know that node is the target of assignment
            // now check that modification happens inside the statement part of the ForStatement
            return !!ts.findAncestor(current, function (n) { return n === container ? "quit" : n === container.statement; });
        }
        function captureLexicalThis(node, container) {
            getNodeLinks(node).flags |= 2 /* LexicalThis */;
            if (container.kind === 155 /* PropertyDeclaration */ || container.kind === 158 /* Constructor */) {
                var classNode = container.parent;
                getNodeLinks(classNode).flags |= 4 /* CaptureThis */;
            }
            else {
                getNodeLinks(container).flags |= 4 /* CaptureThis */;
            }
        }
        function findFirstSuperCall(n) {
            if (ts.isSuperCall(n)) {
                return n;
            }
            else if (ts.isFunctionLike(n)) {
                return undefined;
            }
            return ts.forEachChild(n, findFirstSuperCall);
        }
        /**
         * Return a cached result if super-statement is already found.
         * Otherwise, find a super statement in a given constructor function and cache the result in the node-links of the constructor
         *
         * @param constructor constructor-function to look for super statement
         */
        function getSuperCallInConstructor(constructor) {
            var links = getNodeLinks(constructor);
            // Only trying to find super-call if we haven't yet tried to find one.  Once we try, we will record the result
            if (links.hasSuperCall === undefined) {
                links.superCall = findFirstSuperCall(constructor.body);
                links.hasSuperCall = links.superCall ? true : false;
            }
            return links.superCall;
        }
        /**
         * Check if the given class-declaration extends null then return true.
         * Otherwise, return false
         * @param classDecl a class declaration to check if it extends null
         */
        function classDeclarationExtendsNull(classDecl) {
            var classSymbol = getSymbolOfNode(classDecl);
            var classInstanceType = getDeclaredTypeOfSymbol(classSymbol);
            var baseConstructorType = getBaseConstructorTypeOfClass(classInstanceType);
            return baseConstructorType === nullWideningType;
        }
        function checkThisBeforeSuper(node, container, diagnosticMessage) {
            var containingClassDecl = container.parent;
            var baseTypeNode = ts.getClassExtendsHeritageElement(containingClassDecl);
            // If a containing class does not have extends clause or the class extends null
            // skip checking whether super statement is called before "this" accessing.
            if (baseTypeNode && !classDeclarationExtendsNull(containingClassDecl)) {
                var superCall = getSuperCallInConstructor(container);
                // We should give an error in the following cases:
                //      - No super-call
                //      - "this" is accessing before super-call.
                //          i.e super(this)
                //              this.x; super();
                // We want to make sure that super-call is done before accessing "this" so that
                // "this" is not accessed as a parameter of the super-call.
                if (!superCall || superCall.end > node.pos) {
                    // In ES6, super inside constructor of class-declaration has to precede "this" accessing
                    error(node, diagnosticMessage);
                }
            }
        }
        function checkThisExpression(node) {
            // Stop at the first arrow function so that we can
            // tell whether 'this' needs to be captured.
            var container = ts.getThisContainer(node, /* includeArrowFunctions */ true);
            var capturedByArrowFunction = false;
            if (container.kind === 158 /* Constructor */) {
                checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
            }
            // Now skip arrow functions to get the "real" owner of 'this'.
            if (container.kind === 198 /* ArrowFunction */) {
                container = ts.getThisContainer(container, /* includeArrowFunctions */ false);
                capturedByArrowFunction = true;
            }
            switch (container.kind) {
                case 245 /* ModuleDeclaration */:
                    error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_module_or_namespace_body);
                    // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    break;
                case 244 /* EnumDeclaration */:
                    error(node, ts.Diagnostics.this_cannot_be_referenced_in_current_location);
                    // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    break;
                case 158 /* Constructor */:
                    if (isInConstructorArgumentInitializer(node, container)) {
                        error(node, ts.Diagnostics.this_cannot_be_referenced_in_constructor_arguments);
                        // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    }
                    break;
                case 155 /* PropertyDeclaration */:
                case 154 /* PropertySignature */:
                    if (ts.hasModifier(container, 32 /* Static */)) {
                        error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer);
                        // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    }
                    break;
                case 150 /* ComputedPropertyName */:
                    error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_computed_property_name);
                    break;
            }
            // When targeting es6, mark that we'll need to capture `this` in its lexically bound scope.
            if (capturedByArrowFunction && languageVersion < 2 /* ES2015 */) {
                captureLexicalThis(node, container);
            }
            var type = tryGetThisTypeAt(node, /*includeGlobalThis*/ true, container);
            if (noImplicitThis) {
                var globalThisType_1 = getTypeOfSymbol(globalThisSymbol);
                if (type === globalThisType_1 && capturedByArrowFunction) {
                    error(node, ts.Diagnostics.The_containing_arrow_function_captures_the_global_value_of_this);
                }
                else if (!type) {
                    // With noImplicitThis, functions may not reference 'this' if it has type 'any'
                    var diag = error(node, ts.Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation);
                    if (!ts.isSourceFile(container)) {
                        var outsideThis = tryGetThisTypeAt(container);
                        if (outsideThis && outsideThis !== globalThisType_1) {
                            ts.addRelatedInfo(diag, ts.createDiagnosticForNode(container, ts.Diagnostics.An_outer_value_of_this_is_shadowed_by_this_container));
                        }
                    }
                }
            }
            return type || anyType;
        }
        function tryGetThisTypeAt(node, includeGlobalThis, container) {
            if (includeGlobalThis === void 0) { includeGlobalThis = true; }
            if (container === void 0) { container = ts.getThisContainer(node, /*includeArrowFunctions*/ false); }
            var isInJS = ts.isInJSFile(node);
            if (ts.isFunctionLike(container) &&
                (!isInParameterInitializerBeforeContainingFunction(node) || ts.getThisParameter(container))) {
                // Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
                // If this is a function in a JS file, it might be a class method.
                var className = getClassNameFromPrototypeMethod(container);
                if (isInJS && className) {
                    var classSymbol = checkExpression(className).symbol;
                    if (classSymbol && classSymbol.members && (classSymbol.flags & 16 /* Function */)) {
                        var classType = getJSClassType(classSymbol);
                        if (classType) {
                            return getFlowTypeOfReference(node, classType);
                        }
                    }
                }
                // Check if it's a constructor definition, can be either a variable decl or function decl
                // i.e.
                //   * /** @constructor */ function [name]() { ... }
                //   * /** @constructor */ var x = function() { ... }
                else if (isInJS &&
                    (container.kind === 197 /* FunctionExpression */ || container.kind === 240 /* FunctionDeclaration */) &&
                    ts.getJSDocClassTag(container)) {
                    var classType = getJSClassType(getMergedSymbol(container.symbol));
                    if (classType) {
                        return getFlowTypeOfReference(node, classType);
                    }
                }
                var thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container);
                if (thisType) {
                    return getFlowTypeOfReference(node, thisType);
                }
            }
            if (ts.isClassLike(container.parent)) {
                var symbol = getSymbolOfNode(container.parent);
                var type = ts.hasModifier(container, 32 /* Static */) ? getTypeOfSymbol(symbol) : getDeclaredTypeOfSymbol(symbol).thisType;
                return getFlowTypeOfReference(node, type);
            }
            if (isInJS) {
                var type = getTypeForThisExpressionFromJSDoc(container);
                if (type && type !== errorType) {
                    return getFlowTypeOfReference(node, type);
                }
            }
            if (ts.isSourceFile(container)) {
                // look up in the source file's locals or exports
                if (container.commonJsModuleIndicator) {
                    var fileSymbol = getSymbolOfNode(container);
                    return fileSymbol && getTypeOfSymbol(fileSymbol);
                }
                else if (includeGlobalThis) {
                    return getTypeOfSymbol(globalThisSymbol);
                }
            }
        }
        function getClassNameFromPrototypeMethod(container) {
            // Check if it's the RHS of a x.prototype.y = function [name]() { .... }
            if (container.kind === 197 /* FunctionExpression */ &&
                ts.isBinaryExpression(container.parent) &&
                ts.getAssignmentDeclarationKind(container.parent) === 3 /* PrototypeProperty */) {
                // Get the 'x' of 'x.prototype.y = container'
                return container.parent // x.prototype.y = container
                    .left // x.prototype.y
                    .expression // x.prototype
                    .expression; // x
            }
            // x.prototype = { method() { } }
            else if (container.kind === 157 /* MethodDeclaration */ &&
                container.parent.kind === 189 /* ObjectLiteralExpression */ &&
                ts.isBinaryExpression(container.parent.parent) &&
                ts.getAssignmentDeclarationKind(container.parent.parent) === 6 /* Prototype */) {
                return container.parent.parent.left.expression;
            }
            // x.prototype = { method: function() { } }
            else if (container.kind === 197 /* FunctionExpression */ &&
                container.parent.kind === 276 /* PropertyAssignment */ &&
                container.parent.parent.kind === 189 /* ObjectLiteralExpression */ &&
                ts.isBinaryExpression(container.parent.parent.parent) &&
                ts.getAssignmentDeclarationKind(container.parent.parent.parent) === 6 /* Prototype */) {
                return container.parent.parent.parent.left.expression;
            }
            // Object.defineProperty(x, "method", { value: function() { } });
            // Object.defineProperty(x, "method", { set: (x: () => void) => void });
            // Object.defineProperty(x, "method", { get: () => function() { }) });
            else if (container.kind === 197 /* FunctionExpression */ &&
                ts.isPropertyAssignment(container.parent) &&
                ts.isIdentifier(container.parent.name) &&
                (container.parent.name.escapedText === "value" || container.parent.name.escapedText === "get" || container.parent.name.escapedText === "set") &&
                ts.isObjectLiteralExpression(container.parent.parent) &&
                ts.isCallExpression(container.parent.parent.parent) &&
                container.parent.parent.parent.arguments[2] === container.parent.parent &&
                ts.getAssignmentDeclarationKind(container.parent.parent.parent) === 9 /* ObjectDefinePrototypeProperty */) {
                return container.parent.parent.parent.arguments[0].expression;
            }
            // Object.defineProperty(x, "method", { value() { } });
            // Object.defineProperty(x, "method", { set(x: () => void) {} });
            // Object.defineProperty(x, "method", { get() { return () => {} } });
            else if (ts.isMethodDeclaration(container) &&
                ts.isIdentifier(container.name) &&
                (container.name.escapedText === "value" || container.name.escapedText === "get" || container.name.escapedText === "set") &&
                ts.isObjectLiteralExpression(container.parent) &&
                ts.isCallExpression(container.parent.parent) &&
                container.parent.parent.arguments[2] === container.parent &&
                ts.getAssignmentDeclarationKind(container.parent.parent) === 9 /* ObjectDefinePrototypeProperty */) {
                return container.parent.parent.arguments[0].expression;
            }
        }
        function getTypeForThisExpressionFromJSDoc(node) {
            var jsdocType = ts.getJSDocType(node);
            if (jsdocType && jsdocType.kind === 295 /* JSDocFunctionType */) {
                var jsDocFunctionType = jsdocType;
                if (jsDocFunctionType.parameters.length > 0 &&
                    jsDocFunctionType.parameters[0].name &&
                    jsDocFunctionType.parameters[0].name.escapedText === "this" /* This */) {
                    return getTypeFromTypeNode(jsDocFunctionType.parameters[0].type);
                }
            }
            var thisTag = ts.getJSDocThisTag(node);
            if (thisTag && thisTag.typeExpression) {
                return getTypeFromTypeNode(thisTag.typeExpression);
            }
        }
        function isInConstructorArgumentInitializer(node, constructorDecl) {
            return !!ts.findAncestor(node, function (n) { return ts.isFunctionLikeDeclaration(n) ? "quit" : n.kind === 152 /* Parameter */ && n.parent === constructorDecl; });
        }
        function checkSuperExpression(node) {
            var isCallExpression = node.parent.kind === 192 /* CallExpression */ && node.parent.expression === node;
            var container = ts.getSuperContainer(node, /*stopOnFunctions*/ true);
            var needToCaptureLexicalThis = false;
            // adjust the container reference in case if super is used inside arrow functions with arbitrarily deep nesting
            if (!isCallExpression) {
                while (container && container.kind === 198 /* ArrowFunction */) {
                    container = ts.getSuperContainer(container, /*stopOnFunctions*/ true);
                    needToCaptureLexicalThis = languageVersion < 2 /* ES2015 */;
                }
            }
            var canUseSuperExpression = isLegalUsageOfSuperExpression(container);
            var nodeCheckFlag = 0;
            if (!canUseSuperExpression) {
                // issue more specific error if super is used in computed property name
                // class A { foo() { return "1" }}
                // class B {
                //     [super.foo()]() {}
                // }
                var current = ts.findAncestor(node, function (n) { return n === container ? "quit" : n.kind === 150 /* ComputedPropertyName */; });
                if (current && current.kind === 150 /* ComputedPropertyName */) {
                    error(node, ts.Diagnostics.super_cannot_be_referenced_in_a_computed_property_name);
                }
                else if (isCallExpression) {
                    error(node, ts.Diagnostics.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors);
                }
                else if (!container || !container.parent || !(ts.isClassLike(container.parent) || container.parent.kind === 189 /* ObjectLiteralExpression */)) {
                    error(node, ts.Diagnostics.super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions);
                }
                else {
                    error(node, ts.Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class);
                }
                return errorType;
            }
            if (!isCallExpression && container.kind === 158 /* Constructor */) {
                checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class);
            }
            if (ts.hasModifier(container, 32 /* Static */) || isCallExpression) {
                nodeCheckFlag = 512 /* SuperStatic */;
            }
            else {
                nodeCheckFlag = 256 /* SuperInstance */;
            }
            getNodeLinks(node).flags |= nodeCheckFlag;
            // Due to how we emit async functions, we need to specialize the emit for an async method that contains a `super` reference.
            // This is due to the fact that we emit the body of an async function inside of a generator function. As generator
            // functions cannot reference `super`, we emit a helper inside of the method body, but outside of the generator. This helper
            // uses an arrow function, which is permitted to reference `super`.
            //
            // There are two primary ways we can access `super` from within an async method. The first is getting the value of a property
            // or indexed access on super, either as part of a right-hand-side expression or call expression. The second is when setting the value
            // of a property or indexed access, either as part of an assignment expression or destructuring assignment.
            //
            // The simplest case is reading a value, in which case we will emit something like the following:
            //
            //  // ts
            //  ...
            //  async asyncMethod() {
            //    let x = await super.asyncMethod();
            //    return x;
            //  }
            //  ...
            //
            //  // js
            //  ...
            //  asyncMethod() {
            //      const _super = Object.create(null, {
            //        asyncMethod: { get: () => super.asyncMethod },
            //      });
            //      return __awaiter(this, arguments, Promise, function *() {
            //          let x = yield _super.asyncMethod.call(this);
            //          return x;
            //      });
            //  }
            //  ...
            //
            // The more complex case is when we wish to assign a value, especially as part of a destructuring assignment. As both cases
            // are legal in ES6, but also likely less frequent, we only emit setters if there is an assignment:
            //
            //  // ts
            //  ...
            //  async asyncMethod(ar: Promise<any[]>) {
            //      [super.a, super.b] = await ar;
            //  }
            //  ...
            //
            //  // js
            //  ...
            //  asyncMethod(ar) {
            //      const _super = Object.create(null, {
            //        a: { get: () => super.a, set: (v) => super.a = v },
            //        b: { get: () => super.b, set: (v) => super.b = v }
            //      };
            //      return __awaiter(this, arguments, Promise, function *() {
            //          [_super.a, _super.b] = yield ar;
            //      });
            //  }
            //  ...
            //
            // Creating an object that has getter and setters instead of just an accessor function is required for destructuring assignments
            // as a call expression cannot be used as the target of a destructuring assignment while a property access can.
            //
            // For element access expressions (`super[x]`), we emit a generic helper that forwards the element access in both situations.
            if (container.kind === 157 /* MethodDeclaration */ && ts.hasModifier(container, 256 /* Async */)) {
                if (ts.isSuperProperty(node.parent) && ts.isAssignmentTarget(node.parent)) {
                    getNodeLinks(container).flags |= 4096 /* AsyncMethodWithSuperBinding */;
                }
                else {
                    getNodeLinks(container).flags |= 2048 /* AsyncMethodWithSuper */;
                }
            }
            if (needToCaptureLexicalThis) {
                // call expressions are allowed only in constructors so they should always capture correct 'this'
                // super property access expressions can also appear in arrow functions -
                // in this case they should also use correct lexical this
                captureLexicalThis(node.parent, container);
            }
            if (container.parent.kind === 189 /* ObjectLiteralExpression */) {
                if (languageVersion < 2 /* ES2015 */) {
                    error(node, ts.Diagnostics.super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher);
                    return errorType;
                }
                else {
                    // for object literal assume that type of 'super' is 'any'
                    return anyType;
                }
            }
            // at this point the only legal case for parent is ClassLikeDeclaration
            var classLikeDeclaration = container.parent;
            if (!ts.getClassExtendsHeritageElement(classLikeDeclaration)) {
                error(node, ts.Diagnostics.super_can_only_be_referenced_in_a_derived_class);
                return errorType;
            }
            var classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classLikeDeclaration));
            var baseClassType = classType && getBaseTypes(classType)[0];
            if (!baseClassType) {
                return errorType;
            }
            if (container.kind === 158 /* Constructor */ && isInConstructorArgumentInitializer(node, container)) {
                // issue custom error message for super property access in constructor arguments (to be aligned with old compiler)
                error(node, ts.Diagnostics.super_cannot_be_referenced_in_constructor_arguments);
                return errorType;
            }
            return nodeCheckFlag === 512 /* SuperStatic */
                ? getBaseConstructorTypeOfClass(classType)
                : getTypeWithThisArgument(baseClassType, classType.thisType);
            function isLegalUsageOfSuperExpression(container) {
                if (!container) {
                    return false;
                }
                if (isCallExpression) {
                    // TS 1.0 SPEC (April 2014): 4.8.1
                    // Super calls are only permitted in constructors of derived classes
                    return container.kind === 158 /* Constructor */;
                }
                else {
                    // TS 1.0 SPEC (April 2014)
                    // 'super' property access is allowed
                    // - In a constructor, instance member function, instance member accessor, or instance member variable initializer where this references a derived class instance
                    // - In a static member function or static member accessor
                    // topmost container must be something that is directly nested in the class declaration\object literal expression
                    if (ts.isClassLike(container.parent) || container.parent.kind === 189 /* ObjectLiteralExpression */) {
                        if (ts.hasModifier(container, 32 /* Static */)) {
                            return container.kind === 157 /* MethodDeclaration */ ||
                                container.kind === 156 /* MethodSignature */ ||
                                container.kind === 159 /* GetAccessor */ ||
                                container.kind === 160 /* SetAccessor */;
                        }
                        else {
                            return container.kind === 157 /* MethodDeclaration */ ||
                                container.kind === 156 /* MethodSignature */ ||
                                container.kind === 159 /* GetAccessor */ ||
                                container.kind === 160 /* SetAccessor */ ||
                                container.kind === 155 /* PropertyDeclaration */ ||
                                container.kind === 154 /* PropertySignature */ ||
                                container.kind === 158 /* Constructor */;
                        }
                    }
                }
                return false;
            }
        }
        function getContainingObjectLiteral(func) {
            return (func.kind === 157 /* MethodDeclaration */ ||
                func.kind === 159 /* GetAccessor */ ||
                func.kind === 160 /* SetAccessor */) && func.parent.kind === 189 /* ObjectLiteralExpression */ ? func.parent :
                func.kind === 197 /* FunctionExpression */ && func.parent.kind === 276 /* PropertyAssignment */ ? func.parent.parent :
                    undefined;
        }
        function getThisTypeArgument(type) {
            return ts.getObjectFlags(type) & 4 /* Reference */ && type.target === globalThisType ? type.typeArguments[0] : undefined;
        }
        function getThisTypeFromContextualType(type) {
            return mapType(type, function (t) {
                return t.flags & 2097152 /* Intersection */ ? ts.forEach(t.types, getThisTypeArgument) : getThisTypeArgument(t);
            });
        }
        function getContextualThisParameterType(func) {
            if (func.kind === 198 /* ArrowFunction */) {
                return undefined;
            }
            if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
                var contextualSignature = getContextualSignature(func);
                if (contextualSignature) {
                    var thisParameter = contextualSignature.thisParameter;
                    if (thisParameter) {
                        return getTypeOfSymbol(thisParameter);
                    }
                }
            }
            var inJs = ts.isInJSFile(func);
            if (noImplicitThis || inJs) {
                var containingLiteral = getContainingObjectLiteral(func);
                if (containingLiteral) {
                    // We have an object literal method. Check if the containing object literal has a contextual type
                    // that includes a ThisType<T>. If so, T is the contextual type for 'this'. We continue looking in
                    // any directly enclosing object literals.
                    var contextualType = getApparentTypeOfContextualType(containingLiteral);
                    var literal = containingLiteral;
                    var type = contextualType;
                    while (type) {
                        var thisType = getThisTypeFromContextualType(type);
                        if (thisType) {
                            return instantiateType(thisType, getMapperFromContext(getInferenceContext(containingLiteral)));
                        }
                        if (literal.parent.kind !== 276 /* PropertyAssignment */) {
                            break;
                        }
                        literal = literal.parent.parent;
                        type = getApparentTypeOfContextualType(literal);
                    }
                    // There was no contextual ThisType<T> for the containing object literal, so the contextual type
                    // for 'this' is the non-null form of the contextual type for the containing object literal or
                    // the type of the object literal itself.
                    return contextualType ? getNonNullableType(contextualType) : checkExpressionCached(containingLiteral);
                }
                // In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the
                // contextual type for 'this' is 'obj'.
                var parent = func.parent;
                if (parent.kind === 205 /* BinaryExpression */ && parent.operatorToken.kind === 60 /* EqualsToken */) {
                    var target = parent.left;
                    if (target.kind === 190 /* PropertyAccessExpression */ || target.kind === 191 /* ElementAccessExpression */) {
                        var expression = target.expression;
                        // Don't contextually type `this` as `exports` in `exports.Point = function(x, y) { this.x = x; this.y = y; }`
                        if (inJs && ts.isIdentifier(expression)) {
                            var sourceFile = ts.getSourceFileOfNode(parent);
                            if (sourceFile.commonJsModuleIndicator && getResolvedSymbol(expression) === sourceFile.symbol) {
                                return undefined;
                            }
                        }
                        return checkExpressionCached(expression);
                    }
                }
            }
            return undefined;
        }
        // Return contextual type of parameter or undefined if no contextual type is available
        function getContextuallyTypedParameterType(parameter) {
            var func = parameter.parent;
            if (!isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
                return undefined;
            }
            var iife = ts.getImmediatelyInvokedFunctionExpression(func);
            if (iife && iife.arguments) {
                var args = getEffectiveCallArguments(iife);
                var indexOfParameter = func.parameters.indexOf(parameter);
                if (parameter.dotDotDotToken) {
                    return getSpreadArgumentType(args, indexOfParameter, args.length, anyType, /*context*/ undefined);
                }
                var links = getNodeLinks(iife);
                var cached = links.resolvedSignature;
                links.resolvedSignature = anySignature;
                var type = indexOfParameter < args.length ?
                    getWidenedLiteralType(checkExpression(args[indexOfParameter])) :
                    parameter.initializer ? undefined : undefinedWideningType;
                links.resolvedSignature = cached;
                return type;
            }
            var contextualSignature = getContextualSignature(func);
            if (contextualSignature) {
                var index = func.parameters.indexOf(parameter) - (ts.getThisParameter(func) ? 1 : 0);
                return parameter.dotDotDotToken && ts.lastOrUndefined(func.parameters) === parameter ?
                    getRestTypeAtPosition(contextualSignature, index) :
                    tryGetTypeAtPosition(contextualSignature, index);
            }
        }
        function getContextualTypeForVariableLikeDeclaration(declaration) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(declaration);
            if (typeNode) {
                return getTypeFromTypeNode(typeNode);
            }
            switch (declaration.kind) {
                case 152 /* Parameter */:
                    return getContextuallyTypedParameterType(declaration);
                case 187 /* BindingElement */:
                    return getContextualTypeForBindingElement(declaration);
                // By default, do nothing and return undefined - only parameters and binding elements have context implied by a parent
            }
        }
        function getContextualTypeForBindingElement(declaration) {
            var parentDeclaration = declaration.parent.parent;
            var name = declaration.propertyName || declaration.name;
            var parentType = getContextualTypeForVariableLikeDeclaration(parentDeclaration);
            if (parentType && !ts.isBindingPattern(name) && !isComputedNonLiteralName(name)) {
                var nameType = getLiteralTypeFromPropertyName(name);
                if (isTypeUsableAsPropertyName(nameType)) {
                    var text = getPropertyNameFromType(nameType);
                    return getTypeOfPropertyOfType(parentType, text);
                }
            }
        }
        // In a variable, parameter or property declaration with a type annotation,
        //   the contextual type of an initializer expression is the type of the variable, parameter or property.
        // Otherwise, in a parameter declaration of a contextually typed function expression,
        //   the contextual type of an initializer expression is the contextual type of the parameter.
        // Otherwise, in a variable or parameter declaration with a binding pattern name,
        //   the contextual type of an initializer expression is the type implied by the binding pattern.
        // Otherwise, in a binding pattern inside a variable or parameter declaration,
        //   the contextual type of an initializer expression is the type annotation of the containing declaration, if present.
        function getContextualTypeForInitializerExpression(node) {
            var declaration = node.parent;
            if (ts.hasInitializer(declaration) && node === declaration.initializer) {
                var result = getContextualTypeForVariableLikeDeclaration(declaration);
                if (result) {
                    return result;
                }
                if (ts.isBindingPattern(declaration.name)) { // This is less a contextual type and more an implied shape - in some cases, this may be undesirable
                    return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true, /*reportErrors*/ false);
                }
            }
            return undefined;
        }
        function getContextualTypeForReturnExpression(node) {
            var func = ts.getContainingFunction(node);
            if (func) {
                var functionFlags = ts.getFunctionFlags(func);
                if (functionFlags & 1 /* Generator */) { // AsyncGenerator function or Generator function
                    return undefined;
                }
                var contextualReturnType = getContextualReturnType(func);
                if (contextualReturnType) {
                    if (functionFlags & 2 /* Async */) { // Async function
                        var contextualAwaitedType = getAwaitedTypeOfPromise(contextualReturnType);
                        return contextualAwaitedType && getUnionType([contextualAwaitedType, createPromiseLikeType(contextualAwaitedType)]);
                    }
                    return contextualReturnType; // Regular function
                }
            }
            return undefined;
        }
        function getContextualTypeForAwaitOperand(node) {
            var contextualType = getContextualType(node);
            if (contextualType) {
                var contextualAwaitedType = getAwaitedType(contextualType);
                return contextualAwaitedType && getUnionType([contextualAwaitedType, createPromiseLikeType(contextualAwaitedType)]);
            }
            return undefined;
        }
        function getContextualTypeForYieldOperand(node) {
            var func = ts.getContainingFunction(node);
            if (func) {
                var functionFlags = ts.getFunctionFlags(func);
                var contextualReturnType = getContextualReturnType(func);
                if (contextualReturnType) {
                    return node.asteriskToken
                        ? contextualReturnType
                        : getIteratedTypeOfGenerator(contextualReturnType, (functionFlags & 2 /* Async */) !== 0);
                }
            }
            return undefined;
        }
        function isInParameterInitializerBeforeContainingFunction(node) {
            var inBindingInitializer = false;
            while (node.parent && !ts.isFunctionLike(node.parent)) {
                if (ts.isParameter(node.parent) && (inBindingInitializer || node.parent.initializer === node)) {
                    return true;
                }
                if (ts.isBindingElement(node.parent) && node.parent.initializer === node) {
                    inBindingInitializer = true;
                }
                node = node.parent;
            }
            return false;
        }
        function getContextualReturnType(functionDecl) {
            // If the containing function has a return type annotation, is a constructor, or is a get accessor whose
            // corresponding set accessor has a type annotation, return statements in the function are contextually typed
            var returnType = getReturnTypeFromAnnotation(functionDecl);
            if (returnType) {
                return returnType;
            }
            // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature
            // and that call signature is non-generic, return statements are contextually typed by the return type of the signature
            var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl);
            if (signature && !isResolvingReturnTypeOfSignature(signature)) {
                return getReturnTypeOfSignature(signature);
            }
            return undefined;
        }
        // In a typed function call, an argument or substitution expression is contextually typed by the type of the corresponding parameter.
        function getContextualTypeForArgument(callTarget, arg) {
            var args = getEffectiveCallArguments(callTarget);
            var argIndex = args.indexOf(arg); // -1 for e.g. the expression of a CallExpression, or the tag of a TaggedTemplateExpression
            return argIndex === -1 ? undefined : getContextualTypeForArgumentAtIndex(callTarget, argIndex);
        }
        function getContextualTypeForArgumentAtIndex(callTarget, argIndex) {
            // If we're already in the process of resolving the given signature, don't resolve again as
            // that could cause infinite recursion. Instead, return anySignature.
            var signature = getNodeLinks(callTarget).resolvedSignature === resolvingSignature ? resolvingSignature : getResolvedSignature(callTarget);
            if (ts.isJsxOpeningLikeElement(callTarget) && argIndex === 0) {
                return getEffectiveFirstArgumentForJsxSignature(signature, callTarget);
            }
            return getTypeAtPosition(signature, argIndex);
        }
        function getContextualTypeForSubstitutionExpression(template, substitutionExpression) {
            if (template.parent.kind === 194 /* TaggedTemplateExpression */) {
                return getContextualTypeForArgument(template.parent, substitutionExpression);
            }
            return undefined;
        }
        function getContextualTypeForBinaryOperand(node, contextFlags) {
            var binaryExpression = node.parent;
            var left = binaryExpression.left, operatorToken = binaryExpression.operatorToken, right = binaryExpression.right;
            switch (operatorToken.kind) {
                case 60 /* EqualsToken */:
                    if (node !== right) {
                        return undefined;
                    }
                    var contextSensitive = getIsContextSensitiveAssignmentOrContextType(binaryExpression);
                    if (!contextSensitive) {
                        return undefined;
                    }
                    return contextSensitive === true ? getTypeOfExpression(left) : contextSensitive;
                case 55 /* BarBarToken */:
                    // When an || expression has a contextual type, the operands are contextually typed by that type. When an ||
                    // expression has no contextual type, the right operand is contextually typed by the type of the left operand,
                    // except for the special case of Javascript declarations of the form `namespace.prop = namespace.prop || {}`
                    var type = getContextualType(binaryExpression, contextFlags);
                    return !type && node === right && !ts.isDefaultedExpandoInitializer(binaryExpression) ?
                        getTypeOfExpression(left) : type;
                case 54 /* AmpersandAmpersandToken */:
                case 27 /* CommaToken */:
                    return node === right ? getContextualType(binaryExpression, contextFlags) : undefined;
                default:
                    return undefined;
            }
        }
        // In an assignment expression, the right operand is contextually typed by the type of the left operand.
        // Don't do this for assignment declarations unless there is a type tag on the assignment, to avoid circularity from checking the right operand.
        function getIsContextSensitiveAssignmentOrContextType(binaryExpression) {
            var kind = ts.getAssignmentDeclarationKind(binaryExpression);
            switch (kind) {
                case 0 /* None */:
                    return true;
                case 5 /* Property */:
                case 1 /* ExportsProperty */:
                case 6 /* Prototype */:
                case 3 /* PrototypeProperty */:
                    // If `binaryExpression.left` was assigned a symbol, then this is a new declaration; otherwise it is an assignment to an existing declaration.
                    // See `bindStaticPropertyAssignment` in `binder.ts`.
                    if (!binaryExpression.left.symbol) {
                        return true;
                    }
                    else {
                        var decl = binaryExpression.left.symbol.valueDeclaration;
                        if (!decl) {
                            return false;
                        }
                        var lhs = binaryExpression.left;
                        var overallAnnotation = ts.getEffectiveTypeAnnotationNode(decl);
                        if (overallAnnotation) {
                            return getTypeFromTypeNode(overallAnnotation);
                        }
                        else if (ts.isIdentifier(lhs.expression)) {
                            var id = lhs.expression;
                            var parentSymbol = resolveName(id, id.escapedText, 67220415 /* Value */, undefined, id.escapedText, /*isUse*/ true);
                            if (parentSymbol) {
                                var annotated = ts.getEffectiveTypeAnnotationNode(parentSymbol.valueDeclaration);
                                if (annotated) {
                                    var type = getTypeOfPropertyOfContextualType(getTypeFromTypeNode(annotated), lhs.name.escapedText);
                                    return type || false;
                                }
                                return false;
                            }
                        }
                        return !ts.isInJSFile(decl);
                    }
                case 2 /* ModuleExports */:
                case 4 /* ThisProperty */:
                    if (!binaryExpression.symbol)
                        return true;
                    if (binaryExpression.symbol.valueDeclaration) {
                        var annotated = ts.getEffectiveTypeAnnotationNode(binaryExpression.symbol.valueDeclaration);
                        if (annotated) {
                            var type = getTypeFromTypeNode(annotated);
                            if (type) {
                                return type;
                            }
                        }
                    }
                    if (kind === 2 /* ModuleExports */)
                        return false;
                    var thisAccess = binaryExpression.left;
                    if (!ts.isObjectLiteralMethod(ts.getThisContainer(thisAccess.expression, /*includeArrowFunctions*/ false))) {
                        return false;
                    }
                    var thisType = checkThisExpression(thisAccess.expression);
                    return thisType && getTypeOfPropertyOfContextualType(thisType, thisAccess.name.escapedText) || false;
                case 7 /* ObjectDefinePropertyValue */:
                case 8 /* ObjectDefinePropertyExports */:
                case 9 /* ObjectDefinePrototypeProperty */:
                    return ts.Debug.fail("Does not apply");
                default:
                    return ts.Debug.assertNever(kind);
            }
        }
        function getTypeOfPropertyOfContextualType(type, name) {
            return mapType(type, function (t) {
                if (isGenericMappedType(t)) {
                    var constraint = getConstraintTypeFromMappedType(t);
                    var constraintOfConstraint = getBaseConstraintOfType(constraint) || constraint;
                    var propertyNameType = getLiteralType(ts.unescapeLeadingUnderscores(name));
                    if (isTypeAssignableTo(propertyNameType, constraintOfConstraint)) {
                        return substituteIndexedMappedType(t, propertyNameType);
                    }
                }
                else if (t.flags & 3670016 /* StructuredType */) {
                    var prop = getPropertyOfType(t, name);
                    if (prop) {
                        return getTypeOfSymbol(prop);
                    }
                    if (isTupleType(t)) {
                        var restType = getRestTypeOfTupleType(t);
                        if (restType && isNumericLiteralName(name) && +name >= 0) {
                            return restType;
                        }
                    }
                    return isNumericLiteralName(name) && getIndexTypeOfContextualType(t, 1 /* Number */) ||
                        getIndexTypeOfContextualType(t, 0 /* String */);
                }
                return undefined;
            }, /*noReductions*/ true);
        }
        function getIndexTypeOfContextualType(type, kind) {
            return mapType(type, function (t) { return getIndexTypeOfStructuredType(t, kind); }, /*noReductions*/ true);
        }
        // In an object literal contextually typed by a type T, the contextual type of a property assignment is the type of
        // the matching property in T, if one exists. Otherwise, it is the type of the numeric index signature in T, if one
        // exists. Otherwise, it is the type of the string index signature in T, if one exists.
        function getContextualTypeForObjectLiteralMethod(node, contextFlags) {
            ts.Debug.assert(ts.isObjectLiteralMethod(node));
            if (node.flags & 8388608 /* InWithStatement */) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return undefined;
            }
            return getContextualTypeForObjectLiteralElement(node, contextFlags);
        }
        function getContextualTypeForObjectLiteralElement(element, contextFlags) {
            var objectLiteral = element.parent;
            var type = getApparentTypeOfContextualType(objectLiteral, contextFlags);
            if (type) {
                if (!hasNonBindableDynamicName(element)) {
                    // For a (non-symbol) computed property, there is no reason to look up the name
                    // in the type. It will just be "__computed", which does not appear in any
                    // SymbolTable.
                    var symbolName_3 = getSymbolOfNode(element).escapedName;
                    var propertyType = getTypeOfPropertyOfContextualType(type, symbolName_3);
                    if (propertyType) {
                        return propertyType;
                    }
                }
                return isNumericName(element.name) && getIndexTypeOfContextualType(type, 1 /* Number */) ||
                    getIndexTypeOfContextualType(type, 0 /* String */);
            }
            return undefined;
        }
        // In an array literal contextually typed by a type T, the contextual type of an element expression at index N is
        // the type of the property with the numeric name N in T, if one exists. Otherwise, if T has a numeric index signature,
        // it is the type of the numeric index signature in T. Otherwise, in ES6 and higher, the contextual type is the iterated
        // type of T.
        function getContextualTypeForElementExpression(arrayContextualType, index) {
            return arrayContextualType && (getTypeOfPropertyOfContextualType(arrayContextualType, "" + index)
                || getIteratedTypeOrElementType(arrayContextualType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false, /*checkAssignability*/ false));
        }
        // In a contextually typed conditional expression, the true/false expressions are contextually typed by the same type.
        function getContextualTypeForConditionalOperand(node, contextFlags) {
            var conditional = node.parent;
            return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional, contextFlags) : undefined;
        }
        function getContextualTypeForChildJsxExpression(node, child) {
            var attributesType = getApparentTypeOfContextualType(node.openingElement.tagName);
            // JSX expression is in children of JSX Element, we will look for an "children" atttribute (we get the name from JSX.ElementAttributesProperty)
            var jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node));
            if (!(attributesType && !isTypeAny(attributesType) && jsxChildrenPropertyName && jsxChildrenPropertyName !== "")) {
                return undefined;
            }
            var realChildren = getSemanticJsxChildren(node.children);
            var childIndex = realChildren.indexOf(child);
            var childFieldType = getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName);
            return childFieldType && (realChildren.length === 1 ? childFieldType : mapType(childFieldType, function (t) {
                if (isArrayLikeType(t)) {
                    return getIndexedAccessType(t, getLiteralType(childIndex));
                }
                else {
                    return t;
                }
            }, /*noReductions*/ true));
        }
        function getContextualTypeForJsxExpression(node) {
            var exprParent = node.parent;
            return ts.isJsxAttributeLike(exprParent)
                ? getContextualType(node)
                : ts.isJsxElement(exprParent)
                    ? getContextualTypeForChildJsxExpression(exprParent, node)
                    : undefined;
        }
        function getContextualTypeForJsxAttribute(attribute) {
            // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type
            // which is a type of the parameter of the signature we are trying out.
            // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName
            if (ts.isJsxAttribute(attribute)) {
                var attributesType = getApparentTypeOfContextualType(attribute.parent);
                if (!attributesType || isTypeAny(attributesType)) {
                    return undefined;
                }
                return getTypeOfPropertyOfContextualType(attributesType, attribute.name.escapedText);
            }
            else {
                return getContextualType(attribute.parent);
            }
        }
        // Return true if the given expression is possibly a discriminant value. We limit the kinds of
        // expressions we check to those that don't depend on their contextual type in order not to cause
        // recursive (and possibly infinite) invocations of getContextualType.
        function isPossiblyDiscriminantValue(node) {
            switch (node.kind) {
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 103 /* TrueKeyword */:
                case 88 /* FalseKeyword */:
                case 97 /* NullKeyword */:
                case 73 /* Identifier */:
                case 142 /* UndefinedKeyword */:
                    return true;
                case 190 /* PropertyAccessExpression */:
                case 196 /* ParenthesizedExpression */:
                    return isPossiblyDiscriminantValue(node.expression);
                case 271 /* JsxExpression */:
                    return !node.expression || isPossiblyDiscriminantValue(node.expression);
            }
            return false;
        }
        function discriminateContextualTypeByObjectMembers(node, contextualType) {
            return discriminateTypeByDiscriminableItems(contextualType, ts.map(ts.filter(node.properties, function (p) { return !!p.symbol && p.kind === 276 /* PropertyAssignment */ && isPossiblyDiscriminantValue(p.initializer) && isDiscriminantProperty(contextualType, p.symbol.escapedName); }), function (prop) { return [function () { return checkExpression(prop.initializer); }, prop.symbol.escapedName]; }), isTypeAssignableTo, contextualType);
        }
        function discriminateContextualTypeByJSXAttributes(node, contextualType) {
            return discriminateTypeByDiscriminableItems(contextualType, ts.map(ts.filter(node.properties, function (p) { return !!p.symbol && p.kind === 268 /* JsxAttribute */ && isDiscriminantProperty(contextualType, p.symbol.escapedName) && (!p.initializer || isPossiblyDiscriminantValue(p.initializer)); }), function (prop) { return [!prop.initializer ? (function () { return trueType; }) : (function () { return checkExpression(prop.initializer); }), prop.symbol.escapedName]; }), isTypeAssignableTo, contextualType);
        }
        // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
        // be "pushed" onto a node using the contextualType property.
        function getApparentTypeOfContextualType(node, contextFlags) {
            var contextualType = instantiateContextualType(getContextualType(node, contextFlags), node, contextFlags);
            if (contextualType) {
                var apparentType = mapType(contextualType, getApparentType, /*noReductions*/ true);
                if (apparentType.flags & 1048576 /* Union */) {
                    if (ts.isObjectLiteralExpression(node)) {
                        return discriminateContextualTypeByObjectMembers(node, apparentType);
                    }
                    else if (ts.isJsxAttributes(node)) {
                        return discriminateContextualTypeByJSXAttributes(node, apparentType);
                    }
                }
                return apparentType;
            }
        }
        // If the given contextual type contains instantiable types and if a mapper representing
        // return type inferences is available, instantiate those types using that mapper.
        function instantiateContextualType(contextualType, node, contextFlags) {
            if (contextualType && maybeTypeOfKind(contextualType, 63176704 /* Instantiable */)) {
                var inferenceContext = getInferenceContext(node);
                // If no inferences have been made, nothing is gained from instantiating as type parameters
                // would just be replaced with their defaults similar to the apparent type.
                if (inferenceContext && ts.some(inferenceContext.inferences, hasInferenceCandidates)) {
                    // For contextual signatures we incorporate all inferences made so far, e.g. from return
                    // types as well as arguments to the left in a function call.
                    if (contextFlags && contextFlags & 1 /* Signature */) {
                        return instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper);
                    }
                    // For other purposes (e.g. determining whether to produce literal types) we only
                    // incorporate inferences made from the return type in a function call.
                    if (inferenceContext.returnMapper) {
                        return instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper);
                    }
                }
            }
            return contextualType;
        }
        // This function is similar to instantiateType, except that (a) it only instantiates types that
        // are classified as instantiable (i.e. it doesn't instantiate object types), and (b) it performs
        // no reductions on instantiated union types.
        function instantiateInstantiableTypes(type, mapper) {
            if (type.flags & 63176704 /* Instantiable */) {
                return instantiateType(type, mapper);
            }
            if (type.flags & 1048576 /* Union */) {
                return getUnionType(ts.map(type.types, function (t) { return instantiateInstantiableTypes(t, mapper); }), 0 /* None */);
            }
            if (type.flags & 2097152 /* Intersection */) {
                return getIntersectionType(ts.map(type.types, function (t) { return instantiateInstantiableTypes(t, mapper); }));
            }
            return type;
        }
        /**
         * Woah! Do you really want to use this function?
         *
         * Unless you're trying to get the *non-apparent* type for a
         * value-literal type or you're authoring relevant portions of this algorithm,
         * you probably meant to use 'getApparentTypeOfContextualType'.
         * Otherwise this may not be very useful.
         *
         * In cases where you *are* working on this function, you should understand
         * when it is appropriate to use 'getContextualType' and 'getApparentTypeOfContextualType'.
         *
         *   - Use 'getContextualType' when you are simply going to propagate the result to the expression.
         *   - Use 'getApparentTypeOfContextualType' when you're going to need the members of the type.
         *
         * @param node the expression whose contextual type will be returned.
         * @returns the contextual type of an expression.
         */
        function getContextualType(node, contextFlags) {
            if (node.flags & 8388608 /* InWithStatement */) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return undefined;
            }
            if (node.contextualType) {
                return node.contextualType;
            }
            var parent = node.parent;
            switch (parent.kind) {
                case 238 /* VariableDeclaration */:
                case 152 /* Parameter */:
                case 155 /* PropertyDeclaration */:
                case 154 /* PropertySignature */:
                case 187 /* BindingElement */:
                    return getContextualTypeForInitializerExpression(node);
                case 198 /* ArrowFunction */:
                case 231 /* ReturnStatement */:
                    return getContextualTypeForReturnExpression(node);
                case 208 /* YieldExpression */:
                    return getContextualTypeForYieldOperand(parent);
                case 202 /* AwaitExpression */:
                    return getContextualTypeForAwaitOperand(parent);
                case 192 /* CallExpression */:
                case 193 /* NewExpression */:
                    return getContextualTypeForArgument(parent, node);
                case 195 /* TypeAssertionExpression */:
                case 213 /* AsExpression */:
                    return ts.isConstTypeReference(parent.type) ? undefined : getTypeFromTypeNode(parent.type);
                case 205 /* BinaryExpression */:
                    return getContextualTypeForBinaryOperand(node, contextFlags);
                case 276 /* PropertyAssignment */:
                case 277 /* ShorthandPropertyAssignment */:
                    return getContextualTypeForObjectLiteralElement(parent, contextFlags);
                case 278 /* SpreadAssignment */:
                    return getApparentTypeOfContextualType(parent.parent, contextFlags);
                case 188 /* ArrayLiteralExpression */: {
                    var arrayLiteral = parent;
                    var type = getApparentTypeOfContextualType(arrayLiteral, contextFlags);
                    return getContextualTypeForElementExpression(type, ts.indexOfNode(arrayLiteral.elements, node));
                }
                case 206 /* ConditionalExpression */:
                    return getContextualTypeForConditionalOperand(node, contextFlags);
                case 217 /* TemplateSpan */:
                    ts.Debug.assert(parent.parent.kind === 207 /* TemplateExpression */);
                    return getContextualTypeForSubstitutionExpression(parent.parent, node);
                case 196 /* ParenthesizedExpression */: {
                    // Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast.
                    var tag = ts.isInJSFile(parent) ? ts.getJSDocTypeTag(parent) : undefined;
                    return tag ? getTypeFromTypeNode(tag.typeExpression.type) : getContextualType(parent, contextFlags);
                }
                case 271 /* JsxExpression */:
                    return getContextualTypeForJsxExpression(parent);
                case 268 /* JsxAttribute */:
                case 270 /* JsxSpreadAttribute */:
                    return getContextualTypeForJsxAttribute(parent);
                case 263 /* JsxOpeningElement */:
                case 262 /* JsxSelfClosingElement */:
                    return getContextualJsxElementAttributesType(parent);
            }
            return undefined;
        }
        function getInferenceContext(node) {
            var ancestor = ts.findAncestor(node, function (n) { return !!n.inferenceContext; });
            return ancestor && ancestor.inferenceContext;
        }
        function getContextualJsxElementAttributesType(node) {
            if (ts.isJsxOpeningElement(node) && node.parent.contextualType) {
                // Contextually applied type is moved from attributes up to the outer jsx attributes so when walking up from the children they get hit
                // _However_ to hit them from the _attributes_ we must look for them here; otherwise we'll used the declared type
                // (as below) instead!
                return node.parent.contextualType;
            }
            return getContextualTypeForArgumentAtIndex(node, 0);
        }
        function getEffectiveFirstArgumentForJsxSignature(signature, node) {
            return getJsxReferenceKind(node) !== 0 /* Component */ ? getJsxPropsTypeFromCallSignature(signature, node) : getJsxPropsTypeFromClassType(signature, node);
        }
        function getJsxPropsTypeFromCallSignature(sig, context) {
            var propsType = getTypeOfFirstParameterOfSignatureWithFallback(sig, unknownType);
            propsType = getJsxManagedAttributesFromLocatedAttributes(context, getJsxNamespaceAt(context), propsType);
            var intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context);
            if (intrinsicAttribs !== errorType) {
                propsType = intersectTypes(intrinsicAttribs, propsType);
            }
            return propsType;
        }
        function getJsxPropsTypeForSignatureFromMember(sig, forcedLookupLocation) {
            if (sig.unionSignatures) {
                // JSX Elements using the legacy `props`-field based lookup (eg, react class components) need to treat the `props` member as an input
                // instead of an output position when resolving the signature. We need to go back to the input signatures of the composite signature,
                // get the type of `props` on each return type individually, and then _intersect them_, rather than union them (as would normally occur
                // for a union signature). It's an unfortunate quirk of looking in the output of the signature for the type we want to use for the input.
                // The default behavior of `getTypeOfFirstParameterOfSignatureWithFallback` when no `props` member name is defined is much more sane.
                var results = [];
                for (var _i = 0, _a = sig.unionSignatures; _i < _a.length; _i++) {
                    var signature = _a[_i];
                    var instance = getReturnTypeOfSignature(signature);
                    if (isTypeAny(instance)) {
                        return instance;
                    }
                    var propType = getTypeOfPropertyOfType(instance, forcedLookupLocation);
                    if (!propType) {
                        return;
                    }
                    results.push(propType);
                }
                return getIntersectionType(results);
            }
            var instanceType = getReturnTypeOfSignature(sig);
            return isTypeAny(instanceType) ? instanceType : getTypeOfPropertyOfType(instanceType, forcedLookupLocation);
        }
        function getStaticTypeOfReferencedJsxConstructor(context) {
            if (isJsxIntrinsicIdentifier(context.tagName)) {
                var result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(context);
                var fakeSignature = createSignatureForJSXIntrinsic(context, result);
                return getOrCreateTypeFromSignature(fakeSignature);
            }
            var tagType = checkExpressionCached(context.tagName);
            if (tagType.flags & 128 /* StringLiteral */) {
                var result = getIntrinsicAttributesTypeFromStringLiteralType(tagType, context);
                if (!result) {
                    return errorType;
                }
                var fakeSignature = createSignatureForJSXIntrinsic(context, result);
                return getOrCreateTypeFromSignature(fakeSignature);
            }
            return tagType;
        }
        function getJsxManagedAttributesFromLocatedAttributes(context, ns, attributesType) {
            var managedSym = getJsxLibraryManagedAttributes(ns);
            if (managedSym) {
                var declaredManagedType = getDeclaredTypeOfSymbol(managedSym);
                var ctorType = getStaticTypeOfReferencedJsxConstructor(context);
                if (ts.length(declaredManagedType.typeParameters) >= 2) {
                    var args = fillMissingTypeArguments([ctorType, attributesType], declaredManagedType.typeParameters, 2, ts.isInJSFile(context));
                    return createTypeReference(declaredManagedType, args);
                }
                else if (ts.length(declaredManagedType.aliasTypeArguments) >= 2) {
                    var args = fillMissingTypeArguments([ctorType, attributesType], declaredManagedType.aliasTypeArguments, 2, ts.isInJSFile(context));
                    return getTypeAliasInstantiation(declaredManagedType.aliasSymbol, args);
                }
            }
            return attributesType;
        }
        function getJsxPropsTypeFromClassType(sig, context) {
            var ns = getJsxNamespaceAt(context);
            var forcedLookupLocation = getJsxElementPropertiesName(ns);
            var attributesType = forcedLookupLocation === undefined
                // If there is no type ElementAttributesProperty, return the type of the first parameter of the signature, which should be the props type
                ? getTypeOfFirstParameterOfSignatureWithFallback(sig, unknownType)
                : forcedLookupLocation === ""
                    // If there is no e.g. 'props' member in ElementAttributesProperty, use the element class type instead
                    ? getReturnTypeOfSignature(sig)
                    // Otherwise get the type of the property on the signature return type
                    : getJsxPropsTypeForSignatureFromMember(sig, forcedLookupLocation);
            if (!attributesType) {
                // There is no property named 'props' on this instance type
                if (!!forcedLookupLocation && !!ts.length(context.attributes.properties)) {
                    error(context, ts.Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, ts.unescapeLeadingUnderscores(forcedLookupLocation));
                }
                return unknownType;
            }
            attributesType = getJsxManagedAttributesFromLocatedAttributes(context, ns, attributesType);
            if (isTypeAny(attributesType)) {
                // Props is of type 'any' or unknown
                return attributesType;
            }
            else {
                // Normal case -- add in IntrinsicClassElements<T> and IntrinsicElements
                var apparentAttributesType = attributesType;
                var intrinsicClassAttribs = getJsxType(JsxNames.IntrinsicClassAttributes, context);
                if (intrinsicClassAttribs !== errorType) {
                    var typeParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(intrinsicClassAttribs.symbol);
                    var hostClassType = getReturnTypeOfSignature(sig);
                    apparentAttributesType = intersectTypes(typeParams
                        ? createTypeReference(intrinsicClassAttribs, fillMissingTypeArguments([hostClassType], typeParams, getMinTypeArgumentCount(typeParams), ts.isInJSFile(context)))
                        : intrinsicClassAttribs, apparentAttributesType);
                }
                var intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context);
                if (intrinsicAttribs !== errorType) {
                    apparentAttributesType = intersectTypes(intrinsicAttribs, apparentAttributesType);
                }
                return apparentAttributesType;
            }
        }
        // If the given type is an object or union type with a single signature, and if that signature has at
        // least as many parameters as the given function, return the signature. Otherwise return undefined.
        function getContextualCallSignature(type, node) {
            var signatures = getSignaturesOfType(type, 0 /* Call */);
            if (signatures.length === 1) {
                var signature = signatures[0];
                if (!isAritySmaller(signature, node)) {
                    return signature;
                }
            }
        }
        /** If the contextual signature has fewer parameters than the function expression, do not use it */
        function isAritySmaller(signature, target) {
            var targetParameterCount = 0;
            for (; targetParameterCount < target.parameters.length; targetParameterCount++) {
                var param = target.parameters[targetParameterCount];
                if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) {
                    break;
                }
            }
            if (target.parameters.length && ts.parameterIsThisKeyword(target.parameters[0])) {
                targetParameterCount--;
            }
            return !hasEffectiveRestParameter(signature) && getParameterCount(signature) < targetParameterCount;
        }
        function isFunctionExpressionOrArrowFunction(node) {
            return node.kind === 197 /* FunctionExpression */ || node.kind === 198 /* ArrowFunction */;
        }
        function getContextualSignatureForFunctionLikeDeclaration(node) {
            // Only function expressions, arrow functions, and object literal methods are contextually typed.
            return isFunctionExpressionOrArrowFunction(node) || ts.isObjectLiteralMethod(node)
                ? getContextualSignature(node)
                : undefined;
        }
        // Return the contextual signature for a given expression node. A contextual type provides a
        // contextual signature if it has a single call signature and if that call signature is non-generic.
        // If the contextual type is a union type, get the signature from each type possible and if they are
        // all identical ignoring their return type, the result is same signature but with return type as
        // union type of return types from these signatures
        function getContextualSignature(node) {
            ts.Debug.assert(node.kind !== 157 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            var typeTagSignature = getSignatureOfTypeTag(node);
            if (typeTagSignature) {
                return typeTagSignature;
            }
            var type = ts.isObjectLiteralMethod(node) ?
                getContextualTypeForObjectLiteralMethod(node, 1 /* Signature */) :
                getApparentTypeOfContextualType(node, 1 /* Signature */);
            if (!type) {
                return undefined;
            }
            if (!(type.flags & 1048576 /* Union */)) {
                return getContextualCallSignature(type, node);
            }
            var signatureList;
            var types = type.types;
            for (var _i = 0, types_14 = types; _i < types_14.length; _i++) {
                var current = types_14[_i];
                var signature = getContextualCallSignature(current, node);
                if (signature) {
                    if (!signatureList) {
                        // This signature will contribute to contextual union signature
                        signatureList = [signature];
                    }
                    else if (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true, compareTypesIdentical)) {
                        // Signatures aren't identical, do not use
                        return undefined;
                    }
                    else {
                        // Use this signature for contextual union signature
                        signatureList.push(signature);
                    }
                }
            }
            // Result is union of signatures collected (return type is union of return types of this signature set)
            return signatureList && createUnionSignature(signatureList[0], signatureList);
        }
        function checkSpreadExpression(node, checkMode) {
            if (languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
                checkExternalEmitHelpers(node, 1536 /* SpreadIncludes */);
            }
            var arrayOrIterableType = checkExpression(node.expression, checkMode);
            return checkIteratedTypeOrElementType(arrayOrIterableType, node.expression, /*allowStringInput*/ false, /*allowAsyncIterables*/ false);
        }
        function hasDefaultValue(node) {
            return (node.kind === 187 /* BindingElement */ && !!node.initializer) ||
                (node.kind === 205 /* BinaryExpression */ && node.operatorToken.kind === 60 /* EqualsToken */);
        }
        function checkArrayLiteral(node, checkMode, forceTuple) {
            var elements = node.elements;
            var elementCount = elements.length;
            var hasNonEndingSpreadElement = false;
            var elementTypes = [];
            var inDestructuringPattern = ts.isAssignmentTarget(node);
            var contextualType = getApparentTypeOfContextualType(node);
            var inConstContext = isConstContext(node);
            for (var index = 0; index < elementCount; index++) {
                var e = elements[index];
                if (inDestructuringPattern && e.kind === 209 /* SpreadElement */) {
                    // Given the following situation:
                    //    var c: {};
                    //    [...c] = ["", 0];
                    //
                    // c is represented in the tree as a spread element in an array literal.
                    // But c really functions as a rest element, and its purpose is to provide
                    // a contextual type for the right hand side of the assignment. Therefore,
                    // instead of calling checkExpression on "...c", which will give an error
                    // if c is not iterable/array-like, we need to act as if we are trying to
                    // get the contextual element type from it. So we do something similar to
                    // getContextualTypeForElementExpression, which will crucially not error
                    // if there is no index type / iterated type.
                    var restArrayType = checkExpression(e.expression, checkMode, forceTuple);
                    var restElementType = getIndexTypeOfType(restArrayType, 1 /* Number */) ||
                        getIteratedTypeOrElementType(restArrayType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false, /*checkAssignability*/ false);
                    if (restElementType) {
                        elementTypes.push(restElementType);
                    }
                }
                else {
                    var elementContextualType = getContextualTypeForElementExpression(contextualType, index);
                    var type = checkExpressionForMutableLocation(e, checkMode, elementContextualType, forceTuple);
                    elementTypes.push(type);
                }
                if (index < elementCount - 1 && e.kind === 209 /* SpreadElement */) {
                    hasNonEndingSpreadElement = true;
                }
            }
            if (!hasNonEndingSpreadElement) {
                var hasRestElement = elementCount > 0 && elements[elementCount - 1].kind === 209 /* SpreadElement */;
                var minLength = elementCount - (hasRestElement ? 1 : 0);
                // If array literal is actually a destructuring pattern, mark it as an implied type. We do this such
                // that we get the same behavior for "var [x, y] = []" and "[x, y] = []".
                var tupleResult = void 0;
                if (inDestructuringPattern && minLength > 0) {
                    var type = cloneTypeReference(createTupleType(elementTypes, minLength, hasRestElement));
                    type.pattern = node;
                    return type;
                }
                else if (tupleResult = getArrayLiteralTupleTypeIfApplicable(elementTypes, contextualType, hasRestElement, elementCount, inConstContext)) {
                    return tupleResult;
                }
                else if (forceTuple) {
                    return createTupleType(elementTypes, minLength, hasRestElement);
                }
            }
            return createArrayType(elementTypes.length ?
                getUnionType(elementTypes, 2 /* Subtype */) :
                strictNullChecks ? implicitNeverType : undefinedWideningType, inConstContext);
        }
        function getArrayLiteralTupleTypeIfApplicable(elementTypes, contextualType, hasRestElement, elementCount, readonly) {
            if (elementCount === void 0) { elementCount = elementTypes.length; }
            if (readonly === void 0) { readonly = false; }
            // Infer a tuple type when the contextual type is or contains a tuple-like type
            if (readonly || (contextualType && forEachType(contextualType, isTupleLikeType))) {
                var minLength = elementCount - (hasRestElement ? 1 : 0);
                var pattern = contextualType && contextualType.pattern;
                // If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
                // tuple type with the corresponding binding or assignment element types to make the lengths equal.
                if (!hasRestElement && pattern && (pattern.kind === 186 /* ArrayBindingPattern */ || pattern.kind === 188 /* ArrayLiteralExpression */)) {
                    var patternElements = pattern.elements;
                    for (var i = elementCount; i < patternElements.length; i++) {
                        var e = patternElements[i];
                        if (hasDefaultValue(e)) {
                            elementTypes.push(contextualType.typeArguments[i]);
                        }
                        else if (i < patternElements.length - 1 || !(e.kind === 187 /* BindingElement */ && e.dotDotDotToken || e.kind === 209 /* SpreadElement */)) {
                            if (e.kind !== 211 /* OmittedExpression */) {
                                error(e, ts.Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
                            }
                            elementTypes.push(strictNullChecks ? implicitNeverType : undefinedWideningType);
                        }
                    }
                }
                return createTupleType(elementTypes, minLength, hasRestElement, readonly);
            }
        }
        function isNumericName(name) {
            switch (name.kind) {
                case 150 /* ComputedPropertyName */:
                    return isNumericComputedName(name);
                case 73 /* Identifier */:
                    return isNumericLiteralName(name.escapedText);
                case 8 /* NumericLiteral */:
                case 10 /* StringLiteral */:
                    return isNumericLiteralName(name.text);
                default:
                    return false;
            }
        }
        function isNumericComputedName(name) {
            // It seems odd to consider an expression of type Any to result in a numeric name,
            // but this behavior is consistent with checkIndexedAccess
            return isTypeAssignableToKind(checkComputedPropertyName(name), 296 /* NumberLike */);
        }
        function isInfinityOrNaNString(name) {
            return name === "Infinity" || name === "-Infinity" || name === "NaN";
        }
        function isNumericLiteralName(name) {
            // The intent of numeric names is that
            //     - they are names with text in a numeric form, and that
            //     - setting properties/indexing with them is always equivalent to doing so with the numeric literal 'numLit',
            //         acquired by applying the abstract 'ToNumber' operation on the name's text.
            //
            // The subtlety is in the latter portion, as we cannot reliably say that anything that looks like a numeric literal is a numeric name.
            // In fact, it is the case that the text of the name must be equal to 'ToString(numLit)' for this to hold.
            //
            // Consider the property name '"0xF00D"'. When one indexes with '0xF00D', they are actually indexing with the value of 'ToString(0xF00D)'
            // according to the ECMAScript specification, so it is actually as if the user indexed with the string '"61453"'.
            // Thus, the text of all numeric literals equivalent to '61543' such as '0xF00D', '0xf00D', '0170015', etc. are not valid numeric names
            // because their 'ToString' representation is not equal to their original text.
            // This is motivated by ECMA-262 sections 9.3.1, 9.8.1, 11.1.5, and 11.2.1.
            //
            // Here, we test whether 'ToString(ToNumber(name))' is exactly equal to 'name'.
            // The '+' prefix operator is equivalent here to applying the abstract ToNumber operation.
            // Applying the 'toString()' method on a number gives us the abstract ToString operation on a number.
            //
            // Note that this accepts the values 'Infinity', '-Infinity', and 'NaN', and that this is intentional.
            // This is desired behavior, because when indexing with them as numeric entities, you are indexing
            // with the strings '"Infinity"', '"-Infinity"', and '"NaN"' respectively.
            return (+name).toString() === name;
        }
        function checkComputedPropertyName(node) {
            var links = getNodeLinks(node.expression);
            if (!links.resolvedType) {
                links.resolvedType = checkExpression(node.expression);
                // This will allow types number, string, symbol or any. It will also allow enums, the unknown
                // type, and any union of these types (like string | number).
                if (links.resolvedType.flags & 98304 /* Nullable */ ||
                    !isTypeAssignableToKind(links.resolvedType, 132 /* StringLike */ | 296 /* NumberLike */ | 12288 /* ESSymbolLike */) &&
                        !isTypeAssignableTo(links.resolvedType, stringNumberSymbolType)) {
                    error(node, ts.Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any);
                }
                else {
                    checkThatExpressionIsProperSymbolReference(node.expression, links.resolvedType, /*reportError*/ true);
                }
            }
            return links.resolvedType;
        }
        function getObjectLiteralIndexInfo(node, offset, properties, kind) {
            var propTypes = [];
            for (var i = 0; i < properties.length; i++) {
                if (kind === 0 /* String */ || isNumericName(node.properties[i + offset].name)) {
                    propTypes.push(getTypeOfSymbol(properties[i]));
                }
            }
            var unionType = propTypes.length ? getUnionType(propTypes, 2 /* Subtype */) : undefinedType;
            return createIndexInfo(unionType, isConstContext(node));
        }
        function getImmediateAliasedSymbol(symbol) {
            ts.Debug.assert((symbol.flags & 2097152 /* Alias */) !== 0, "Should only get Alias here.");
            var links = getSymbolLinks(symbol);
            if (!links.immediateTarget) {
                var node = getDeclarationOfAliasSymbol(symbol);
                if (!node)
                    return ts.Debug.fail();
                links.immediateTarget = getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/ true);
            }
            return links.immediateTarget;
        }
        function checkObjectLiteral(node, checkMode) {
            var inDestructuringPattern = ts.isAssignmentTarget(node);
            // Grammar checking
            checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
            var propertiesTable;
            var propertiesArray = [];
            var spread = emptyObjectType;
            var contextualType = getApparentTypeOfContextualType(node);
            var contextualTypeHasPattern = contextualType && contextualType.pattern &&
                (contextualType.pattern.kind === 185 /* ObjectBindingPattern */ || contextualType.pattern.kind === 189 /* ObjectLiteralExpression */);
            var inConstContext = isConstContext(node);
            var checkFlags = inConstContext ? 8 /* Readonly */ : 0;
            var isInJavascript = ts.isInJSFile(node) && !ts.isInJsonFile(node);
            var enumTag = ts.getJSDocEnumTag(node);
            var isJSObjectLiteral = !contextualType && isInJavascript && !enumTag;
            var objectFlags = freshObjectLiteralFlag;
            var patternWithComputedProperties = false;
            var hasComputedStringProperty = false;
            var hasComputedNumberProperty = false;
            propertiesTable = ts.createSymbolTable();
            var offset = 0;
            for (var i = 0; i < node.properties.length; i++) {
                var memberDecl = node.properties[i];
                var member = getSymbolOfNode(memberDecl);
                var computedNameType = memberDecl.name && memberDecl.name.kind === 150 /* ComputedPropertyName */ && !ts.isWellKnownSymbolSyntactically(memberDecl.name.expression) ?
                    checkComputedPropertyName(memberDecl.name) : undefined;
                if (memberDecl.kind === 276 /* PropertyAssignment */ ||
                    memberDecl.kind === 277 /* ShorthandPropertyAssignment */ ||
                    ts.isObjectLiteralMethod(memberDecl)) {
                    var type = memberDecl.kind === 276 /* PropertyAssignment */ ? checkPropertyAssignment(memberDecl, checkMode) :
                        memberDecl.kind === 277 /* ShorthandPropertyAssignment */ ? checkExpressionForMutableLocation(memberDecl.name, checkMode) :
                            checkObjectLiteralMethod(memberDecl, checkMode);
                    if (isInJavascript) {
                        var jsDocType = getTypeForDeclarationFromJSDocComment(memberDecl);
                        if (jsDocType) {
                            checkTypeAssignableTo(type, jsDocType, memberDecl);
                            type = jsDocType;
                        }
                        else if (enumTag && enumTag.typeExpression) {
                            checkTypeAssignableTo(type, getTypeFromTypeNode(enumTag.typeExpression), memberDecl);
                        }
                    }
                    objectFlags |= ts.getObjectFlags(type) & 917504 /* PropagatingFlags */;
                    var nameType = computedNameType && isTypeUsableAsPropertyName(computedNameType) ? computedNameType : undefined;
                    var prop = nameType ?
                        createSymbol(4 /* Property */ | member.flags, getPropertyNameFromType(nameType), checkFlags | 4096 /* Late */) :
                        createSymbol(4 /* Property */ | member.flags, member.escapedName, checkFlags);
                    if (nameType) {
                        prop.nameType = nameType;
                    }
                    if (inDestructuringPattern) {
                        // If object literal is an assignment pattern and if the assignment pattern specifies a default value
                        // for the property, make the property optional.
                        var isOptional = (memberDecl.kind === 276 /* PropertyAssignment */ && hasDefaultValue(memberDecl.initializer)) ||
                            (memberDecl.kind === 277 /* ShorthandPropertyAssignment */ && memberDecl.objectAssignmentInitializer);
                        if (isOptional) {
                            prop.flags |= 16777216 /* Optional */;
                        }
                    }
                    else if (contextualTypeHasPattern && !(ts.getObjectFlags(contextualType) & 512 /* ObjectLiteralPatternWithComputedProperties */)) {
                        // If object literal is contextually typed by the implied type of a binding pattern, and if the
                        // binding pattern specifies a default value for the property, make the property optional.
                        var impliedProp = getPropertyOfType(contextualType, member.escapedName);
                        if (impliedProp) {
                            prop.flags |= impliedProp.flags & 16777216 /* Optional */;
                        }
                        else if (!compilerOptions.suppressExcessPropertyErrors && !getIndexInfoOfType(contextualType, 0 /* String */)) {
                            error(memberDecl.name, ts.Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(member), typeToString(contextualType));
                        }
                    }
                    prop.declarations = member.declarations;
                    prop.parent = member.parent;
                    if (member.valueDeclaration) {
                        prop.valueDeclaration = member.valueDeclaration;
                    }
                    prop.type = type;
                    prop.target = member;
                    member = prop;
                }
                else if (memberDecl.kind === 278 /* SpreadAssignment */) {
                    if (languageVersion < 2 /* ES2015 */) {
                        checkExternalEmitHelpers(memberDecl, 2 /* Assign */);
                    }
                    if (propertiesArray.length > 0) {
                        spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext);
                        propertiesArray = [];
                        propertiesTable = ts.createSymbolTable();
                        hasComputedStringProperty = false;
                        hasComputedNumberProperty = false;
                    }
                    var type = checkExpression(memberDecl.expression);
                    if (!isValidSpreadType(type)) {
                        error(memberDecl, ts.Diagnostics.Spread_types_may_only_be_created_from_object_types);
                        return errorType;
                    }
                    spread = getSpreadType(spread, type, node.symbol, objectFlags, inConstContext);
                    offset = i + 1;
                    continue;
                }
                else {
                    // TypeScript 1.0 spec (April 2014)
                    // A get accessor declaration is processed in the same manner as
                    // an ordinary function declaration(section 6.1) with no parameters.
                    // A set accessor declaration is processed in the same manner
                    // as an ordinary function declaration with a single parameter and a Void return type.
                    ts.Debug.assert(memberDecl.kind === 159 /* GetAccessor */ || memberDecl.kind === 160 /* SetAccessor */);
                    checkNodeDeferred(memberDecl);
                }
                if (computedNameType && !(computedNameType.flags & 8576 /* StringOrNumberLiteralOrUnique */)) {
                    if (isTypeAssignableTo(computedNameType, stringNumberSymbolType)) {
                        if (isTypeAssignableTo(computedNameType, numberType)) {
                            hasComputedNumberProperty = true;
                        }
                        else {
                            hasComputedStringProperty = true;
                        }
                        if (inDestructuringPattern) {
                            patternWithComputedProperties = true;
                        }
                    }
                }
                else {
                    propertiesTable.set(member.escapedName, member);
                }
                propertiesArray.push(member);
            }
            // If object literal is contextually typed by the implied type of a binding pattern, augment the result
            // type with those properties for which the binding pattern specifies a default value.
            if (contextualTypeHasPattern) {
                for (var _i = 0, _a = getPropertiesOfType(contextualType); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (!propertiesTable.get(prop.escapedName) && !(spread && getPropertyOfType(spread, prop.escapedName))) {
                        if (!(prop.flags & 16777216 /* Optional */)) {
                            error(prop.valueDeclaration || prop.bindingElement, ts.Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
                        }
                        propertiesTable.set(prop.escapedName, prop);
                        propertiesArray.push(prop);
                    }
                }
            }
            if (spread !== emptyObjectType) {
                if (propertiesArray.length > 0) {
                    spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext);
                }
                return spread;
            }
            return createObjectLiteralType();
            function createObjectLiteralType() {
                var stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, 0 /* String */) : undefined;
                var numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, 1 /* Number */) : undefined;
                var result = createAnonymousType(node.symbol, propertiesTable, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
                result.objectFlags |= objectFlags | 128 /* ObjectLiteral */ | 262144 /* ContainsObjectLiteral */;
                if (isJSObjectLiteral) {
                    result.objectFlags |= 16384 /* JSLiteral */;
                }
                if (patternWithComputedProperties) {
                    result.objectFlags |= 512 /* ObjectLiteralPatternWithComputedProperties */;
                }
                if (inDestructuringPattern) {
                    result.pattern = node;
                }
                return result;
            }
        }
        function isValidSpreadType(type) {
            return !!(type.flags & (3 /* AnyOrUnknown */ | 67108864 /* NonPrimitive */ | 524288 /* Object */ | 58982400 /* InstantiableNonPrimitive */) ||
                getFalsyFlags(type) & 117632 /* DefinitelyFalsy */ && isValidSpreadType(removeDefinitelyFalsyTypes(type)) ||
                type.flags & 3145728 /* UnionOrIntersection */ && ts.every(type.types, isValidSpreadType));
        }
        function checkJsxSelfClosingElementDeferred(node) {
            checkJsxOpeningLikeElementOrOpeningFragment(node);
        }
        function checkJsxSelfClosingElement(node, _checkMode) {
            checkNodeDeferred(node);
            return getJsxElementTypeAt(node) || anyType;
        }
        function checkJsxElementDeferred(node) {
            // Check attributes
            checkJsxOpeningLikeElementOrOpeningFragment(node.openingElement);
            // Perform resolution on the closing tag so that rename/go to definition/etc work
            if (isJsxIntrinsicIdentifier(node.closingElement.tagName)) {
                getIntrinsicTagSymbol(node.closingElement);
            }
            else {
                checkExpression(node.closingElement.tagName);
            }
            checkJsxChildren(node);
        }
        function checkJsxElement(node, _checkMode) {
            checkNodeDeferred(node);
            return getJsxElementTypeAt(node) || anyType;
        }
        function checkJsxFragment(node) {
            checkJsxOpeningLikeElementOrOpeningFragment(node.openingFragment);
            if (compilerOptions.jsx === 2 /* React */ && (compilerOptions.jsxFactory || ts.getSourceFileOfNode(node).pragmas.has("jsx"))) {
                error(node, compilerOptions.jsxFactory
                    ? ts.Diagnostics.JSX_fragment_is_not_supported_when_using_jsxFactory
                    : ts.Diagnostics.JSX_fragment_is_not_supported_when_using_an_inline_JSX_factory_pragma);
            }
            checkJsxChildren(node);
            return getJsxElementTypeAt(node) || anyType;
        }
        /**
         * Returns true iff the JSX element name would be a valid JS identifier, ignoring restrictions about keywords not being identifiers
         */
        function isUnhyphenatedJsxName(name) {
            // - is the only character supported in JSX attribute names that isn't valid in JavaScript identifiers
            return !ts.stringContains(name, "-");
        }
        /**
         * Returns true iff React would emit this tag name as a string rather than an identifier or qualified name
         */
        function isJsxIntrinsicIdentifier(tagName) {
            return tagName.kind === 73 /* Identifier */ && ts.isIntrinsicJsxName(tagName.escapedText);
        }
        function checkJsxAttribute(node, checkMode) {
            return node.initializer
                ? checkExpressionForMutableLocation(node.initializer, checkMode)
                : trueType; // <Elem attr /> is sugar for <Elem attr={true} />
        }
        /**
         * Get attributes type of the JSX opening-like element. The result is from resolving "attributes" property of the opening-like element.
         *
         * @param openingLikeElement a JSX opening-like element
         * @param filter a function to remove attributes that will not participate in checking whether attributes are assignable
         * @return an anonymous type (similar to the one returned by checkObjectLiteral) in which its properties are attributes property.
         * @remarks Because this function calls getSpreadType, it needs to use the same checks as checkObjectLiteral,
         * which also calls getSpreadType.
         */
        function createJsxAttributesTypeFromAttributesProperty(openingLikeElement, checkMode) {
            var attributes = openingLikeElement.attributes;
            var attributesTable = ts.createSymbolTable();
            var spread = emptyJsxObjectType;
            var hasSpreadAnyType = false;
            var typeToIntersect;
            var explicitlySpecifyChildrenAttribute = false;
            var objectFlags = 4096 /* JsxAttributes */;
            var jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(openingLikeElement));
            for (var _i = 0, _a = attributes.properties; _i < _a.length; _i++) {
                var attributeDecl = _a[_i];
                var member = attributeDecl.symbol;
                if (ts.isJsxAttribute(attributeDecl)) {
                    var exprType = checkJsxAttribute(attributeDecl, checkMode);
                    objectFlags |= ts.getObjectFlags(exprType) & 917504 /* PropagatingFlags */;
                    var attributeSymbol = createSymbol(4 /* Property */ | 33554432 /* Transient */ | member.flags, member.escapedName);
                    attributeSymbol.declarations = member.declarations;
                    attributeSymbol.parent = member.parent;
                    if (member.valueDeclaration) {
                        attributeSymbol.valueDeclaration = member.valueDeclaration;
                    }
                    attributeSymbol.type = exprType;
                    attributeSymbol.target = member;
                    attributesTable.set(attributeSymbol.escapedName, attributeSymbol);
                    if (attributeDecl.name.escapedText === jsxChildrenPropertyName) {
                        explicitlySpecifyChildrenAttribute = true;
                    }
                }
                else {
                    ts.Debug.assert(attributeDecl.kind === 270 /* JsxSpreadAttribute */);
                    if (attributesTable.size > 0) {
                        spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false);
                        attributesTable = ts.createSymbolTable();
                    }
                    var exprType = checkExpressionCached(attributeDecl.expression, checkMode);
                    if (isTypeAny(exprType)) {
                        hasSpreadAnyType = true;
                    }
                    if (isValidSpreadType(exprType)) {
                        spread = getSpreadType(spread, exprType, attributes.symbol, objectFlags, /*readonly*/ false);
                    }
                    else {
                        typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType;
                    }
                }
            }
            if (!hasSpreadAnyType) {
                if (attributesTable.size > 0) {
                    spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false);
                }
            }
            // Handle children attribute
            var parent = openingLikeElement.parent.kind === 261 /* JsxElement */ ? openingLikeElement.parent : undefined;
            // We have to check that openingElement of the parent is the one we are visiting as this may not be true for selfClosingElement
            if (parent && parent.openingElement === openingLikeElement && parent.children.length > 0) {
                var childrenTypes = checkJsxChildren(parent, checkMode);
                if (!hasSpreadAnyType && jsxChildrenPropertyName && jsxChildrenPropertyName !== "") {
                    // Error if there is a attribute named "children" explicitly specified and children element.
                    // This is because children element will overwrite the value from attributes.
                    // Note: we will not warn "children" attribute overwritten if "children" attribute is specified in object spread.
                    if (explicitlySpecifyChildrenAttribute) {
                        error(attributes, ts.Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, ts.unescapeLeadingUnderscores(jsxChildrenPropertyName));
                    }
                    var contextualType = getApparentTypeOfContextualType(openingLikeElement.attributes);
                    var childrenContextualType = contextualType && getTypeOfPropertyOfContextualType(contextualType, jsxChildrenPropertyName);
                    // If there are children in the body of JSX element, create dummy attribute "children" with the union of children types so that it will pass the attribute checking process
                    var childrenPropSymbol = createSymbol(4 /* Property */ | 33554432 /* Transient */, jsxChildrenPropertyName);
                    childrenPropSymbol.type = childrenTypes.length === 1 ?
                        childrenTypes[0] :
                        (getArrayLiteralTupleTypeIfApplicable(childrenTypes, childrenContextualType, /*hasRestElement*/ false) || createArrayType(getUnionType(childrenTypes)));
                    // Fake up a property declaration for the children
                    childrenPropSymbol.valueDeclaration = ts.createPropertySignature(/*modifiers*/ undefined, ts.unescapeLeadingUnderscores(jsxChildrenPropertyName), /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined);
                    childrenPropSymbol.valueDeclaration.parent = attributes;
                    childrenPropSymbol.valueDeclaration.symbol = childrenPropSymbol;
                    var childPropMap = ts.createSymbolTable();
                    childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol);
                    spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined), attributes.symbol, objectFlags, /*readonly*/ false);
                }
            }
            if (hasSpreadAnyType) {
                return anyType;
            }
            if (typeToIntersect && spread !== emptyJsxObjectType) {
                return getIntersectionType([typeToIntersect, spread]);
            }
            return typeToIntersect || (spread === emptyJsxObjectType ? createJsxAttributesType() : spread);
            /**
             * Create anonymous type from given attributes symbol table.
             * @param symbol a symbol of JsxAttributes containing attributes corresponding to attributesTable
             * @param attributesTable a symbol table of attributes property
             */
            function createJsxAttributesType() {
                objectFlags |= freshObjectLiteralFlag;
                var result = createAnonymousType(attributes.symbol, attributesTable, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
                result.objectFlags |= objectFlags | 128 /* ObjectLiteral */ | 262144 /* ContainsObjectLiteral */;
                return result;
            }
        }
        function checkJsxChildren(node, checkMode) {
            var childrenTypes = [];
            for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
                var child = _a[_i];
                // In React, JSX text that contains only whitespaces will be ignored so we don't want to type-check that
                // because then type of children property will have constituent of string type.
                if (child.kind === 11 /* JsxText */) {
                    if (!child.containsOnlyTriviaWhiteSpaces) {
                        childrenTypes.push(stringType);
                    }
                }
                else {
                    childrenTypes.push(checkExpressionForMutableLocation(child, checkMode));
                }
            }
            return childrenTypes;
        }
        /**
         * Check attributes property of opening-like element. This function is called during chooseOverload to get call signature of a JSX opening-like element.
         * (See "checkApplicableSignatureForJsxOpeningLikeElement" for how the function is used)
         * @param node a JSXAttributes to be resolved of its type
         */
        function checkJsxAttributes(node, checkMode) {
            return createJsxAttributesTypeFromAttributesProperty(node.parent, checkMode);
        }
        function getJsxType(name, location) {
            var namespace = getJsxNamespaceAt(location);
            var exports = namespace && getExportsOfSymbol(namespace);
            var typeSymbol = exports && getSymbol(exports, name, 67897832 /* Type */);
            return typeSymbol ? getDeclaredTypeOfSymbol(typeSymbol) : errorType;
        }
        /**
         * Looks up an intrinsic tag name and returns a symbol that either points to an intrinsic
         * property (in which case nodeLinks.jsxFlags will be IntrinsicNamedElement) or an intrinsic
         * string index signature (in which case nodeLinks.jsxFlags will be IntrinsicIndexedElement).
         * May also return unknownSymbol if both of these lookups fail.
         */
        function getIntrinsicTagSymbol(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedSymbol) {
                var intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, node);
                if (intrinsicElementsType !== errorType) {
                    // Property case
                    if (!ts.isIdentifier(node.tagName))
                        return ts.Debug.fail();
                    var intrinsicProp = getPropertyOfType(intrinsicElementsType, node.tagName.escapedText);
                    if (intrinsicProp) {
                        links.jsxFlags |= 1 /* IntrinsicNamedElement */;
                        return links.resolvedSymbol = intrinsicProp;
                    }
                    // Intrinsic string indexer case
                    var indexSignatureType = getIndexTypeOfType(intrinsicElementsType, 0 /* String */);
                    if (indexSignatureType) {
                        links.jsxFlags |= 2 /* IntrinsicIndexedElement */;
                        return links.resolvedSymbol = intrinsicElementsType.symbol;
                    }
                    // Wasn't found
                    error(node, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.idText(node.tagName), "JSX." + JsxNames.IntrinsicElements);
                    return links.resolvedSymbol = unknownSymbol;
                }
                else {
                    if (noImplicitAny) {
                        error(node, ts.Diagnostics.JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists, ts.unescapeLeadingUnderscores(JsxNames.IntrinsicElements));
                    }
                    return links.resolvedSymbol = unknownSymbol;
                }
            }
            return links.resolvedSymbol;
        }
        function getJsxNamespaceAt(location) {
            var links = location && getNodeLinks(location);
            if (links && links.jsxNamespace) {
                return links.jsxNamespace;
            }
            if (!links || links.jsxNamespace !== false) {
                var namespaceName = getJsxNamespace(location);
                var resolvedNamespace = resolveName(location, namespaceName, 1920 /* Namespace */, /*diagnosticMessage*/ undefined, namespaceName, /*isUse*/ false);
                if (resolvedNamespace) {
                    var candidate = resolveSymbol(getSymbol(getExportsOfSymbol(resolveSymbol(resolvedNamespace)), JsxNames.JSX, 1920 /* Namespace */));
                    if (candidate) {
                        if (links) {
                            links.jsxNamespace = candidate;
                        }
                        return candidate;
                    }
                    if (links) {
                        links.jsxNamespace = false;
                    }
                }
            }
            // JSX global fallback
            return getGlobalSymbol(JsxNames.JSX, 1920 /* Namespace */, /*diagnosticMessage*/ undefined); // TODO: GH#18217
        }
        /**
         * Look into JSX namespace and then look for container with matching name as nameOfAttribPropContainer.
         * Get a single property from that container if existed. Report an error if there are more than one property.
         *
         * @param nameOfAttribPropContainer a string of value JsxNames.ElementAttributesPropertyNameContainer or JsxNames.ElementChildrenAttributeNameContainer
         *          if other string is given or the container doesn't exist, return undefined.
         */
        function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer, jsxNamespace) {
            // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [symbol]
            var jsxElementAttribPropInterfaceSym = jsxNamespace && getSymbol(jsxNamespace.exports, nameOfAttribPropContainer, 67897832 /* Type */);
            // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [type]
            var jsxElementAttribPropInterfaceType = jsxElementAttribPropInterfaceSym && getDeclaredTypeOfSymbol(jsxElementAttribPropInterfaceSym);
            // The properties of JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute
            var propertiesOfJsxElementAttribPropInterface = jsxElementAttribPropInterfaceType && getPropertiesOfType(jsxElementAttribPropInterfaceType);
            if (propertiesOfJsxElementAttribPropInterface) {
                // Element Attributes has zero properties, so the element attributes type will be the class instance type
                if (propertiesOfJsxElementAttribPropInterface.length === 0) {
                    return "";
                }
                // Element Attributes has one property, so the element attributes type will be the type of the corresponding
                // property of the class instance type
                else if (propertiesOfJsxElementAttribPropInterface.length === 1) {
                    return propertiesOfJsxElementAttribPropInterface[0].escapedName;
                }
                else if (propertiesOfJsxElementAttribPropInterface.length > 1) {
                    // More than one property on ElementAttributesProperty is an error
                    error(jsxElementAttribPropInterfaceSym.declarations[0], ts.Diagnostics.The_global_type_JSX_0_may_not_have_more_than_one_property, ts.unescapeLeadingUnderscores(nameOfAttribPropContainer));
                }
            }
            return undefined;
        }
        function getJsxLibraryManagedAttributes(jsxNamespace) {
            // JSX.LibraryManagedAttributes [symbol]
            return jsxNamespace && getSymbol(jsxNamespace.exports, JsxNames.LibraryManagedAttributes, 67897832 /* Type */);
        }
        /// e.g. "props" for React.d.ts,
        /// or 'undefined' if ElementAttributesProperty doesn't exist (which means all
        ///     non-intrinsic elements' attributes type is 'any'),
        /// or '' if it has 0 properties (which means every
        ///     non-intrinsic elements' attributes type is the element instance type)
        function getJsxElementPropertiesName(jsxNamespace) {
            return getNameFromJsxElementAttributesContainer(JsxNames.ElementAttributesPropertyNameContainer, jsxNamespace);
        }
        function getJsxElementChildrenPropertyName(jsxNamespace) {
            return getNameFromJsxElementAttributesContainer(JsxNames.ElementChildrenAttributeNameContainer, jsxNamespace);
        }
        function getUninstantiatedJsxSignaturesOfType(elementType, caller) {
            if (elementType.flags & 4 /* String */) {
                return [anySignature];
            }
            else if (elementType.flags & 128 /* StringLiteral */) {
                var intrinsicType = getIntrinsicAttributesTypeFromStringLiteralType(elementType, caller);
                if (!intrinsicType) {
                    error(caller, ts.Diagnostics.Property_0_does_not_exist_on_type_1, elementType.value, "JSX." + JsxNames.IntrinsicElements);
                    return ts.emptyArray;
                }
                else {
                    var fakeSignature = createSignatureForJSXIntrinsic(caller, intrinsicType);
                    return [fakeSignature];
                }
            }
            var apparentElemType = getApparentType(elementType);
            // Resolve the signatures, preferring constructor
            var signatures = getSignaturesOfType(apparentElemType, 1 /* Construct */);
            if (signatures.length === 0) {
                // No construct signatures, try call signatures
                signatures = getSignaturesOfType(apparentElemType, 0 /* Call */);
            }
            if (signatures.length === 0 && apparentElemType.flags & 1048576 /* Union */) {
                // If each member has some combination of new/call signatures; make a union signature list for those
                signatures = getUnionSignatures(ts.map(apparentElemType.types, function (t) { return getUninstantiatedJsxSignaturesOfType(t, caller); }));
            }
            return signatures;
        }
        function getIntrinsicAttributesTypeFromStringLiteralType(type, location) {
            // If the elemType is a stringLiteral type, we can then provide a check to make sure that the string literal type is one of the Jsx intrinsic element type
            // For example:
            //      var CustomTag: "h1" = "h1";
            //      <CustomTag> Hello World </CustomTag>
            var intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, location);
            if (intrinsicElementsType !== errorType) {
                var stringLiteralTypeName = type.value;
                var intrinsicProp = getPropertyOfType(intrinsicElementsType, ts.escapeLeadingUnderscores(stringLiteralTypeName));
                if (intrinsicProp) {
                    return getTypeOfSymbol(intrinsicProp);
                }
                var indexSignatureType = getIndexTypeOfType(intrinsicElementsType, 0 /* String */);
                if (indexSignatureType) {
                    return indexSignatureType;
                }
                return undefined;
            }
            // If we need to report an error, we already done so here. So just return any to prevent any more error downstream
            return anyType;
        }
        function checkJsxReturnAssignableToAppropriateBound(refKind, elemInstanceType, openingLikeElement) {
            if (refKind === 1 /* Function */) {
                var sfcReturnConstraint = getJsxStatelessElementTypeAt(openingLikeElement);
                if (sfcReturnConstraint) {
                    checkTypeRelatedTo(elemInstanceType, sfcReturnConstraint, assignableRelation, openingLikeElement, ts.Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements);
                }
            }
            else if (refKind === 0 /* Component */) {
                var classConstraint = getJsxElementClassTypeAt(openingLikeElement);
                if (classConstraint) {
                    // Issue an error if this return type isn't assignable to JSX.ElementClass or JSX.Element, failing that
                    checkTypeRelatedTo(elemInstanceType, classConstraint, assignableRelation, openingLikeElement, ts.Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements);
                }
            }
            else { // Mixed
                var sfcReturnConstraint = getJsxStatelessElementTypeAt(openingLikeElement);
                var classConstraint = getJsxElementClassTypeAt(openingLikeElement);
                if (!sfcReturnConstraint || !classConstraint) {
                    return;
                }
                var combined = getUnionType([sfcReturnConstraint, classConstraint]);
                checkTypeRelatedTo(elemInstanceType, combined, assignableRelation, openingLikeElement, ts.Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements);
            }
        }
        /**
         * Get attributes type of the given intrinsic opening-like Jsx element by resolving the tag name.
         * The function is intended to be called from a function which has checked that the opening element is an intrinsic element.
         * @param node an intrinsic JSX opening-like element
         */
        function getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node) {
            ts.Debug.assert(isJsxIntrinsicIdentifier(node.tagName));
            var links = getNodeLinks(node);
            if (!links.resolvedJsxElementAttributesType) {
                var symbol = getIntrinsicTagSymbol(node);
                if (links.jsxFlags & 1 /* IntrinsicNamedElement */) {
                    return links.resolvedJsxElementAttributesType = getTypeOfSymbol(symbol);
                }
                else if (links.jsxFlags & 2 /* IntrinsicIndexedElement */) {
                    return links.resolvedJsxElementAttributesType = getIndexInfoOfSymbol(symbol, 0 /* String */).type;
                }
                else {
                    return links.resolvedJsxElementAttributesType = errorType;
                }
            }
            return links.resolvedJsxElementAttributesType;
        }
        function getJsxElementClassTypeAt(location) {
            var type = getJsxType(JsxNames.ElementClass, location);
            if (type === errorType)
                return undefined;
            return type;
        }
        function getJsxElementTypeAt(location) {
            return getJsxType(JsxNames.Element, location);
        }
        function getJsxStatelessElementTypeAt(location) {
            var jsxElementType = getJsxElementTypeAt(location);
            if (jsxElementType) {
                return getUnionType([jsxElementType, nullType]);
            }
        }
        /**
         * Returns all the properties of the Jsx.IntrinsicElements interface
         */
        function getJsxIntrinsicTagNamesAt(location) {
            var intrinsics = getJsxType(JsxNames.IntrinsicElements, location);
            return intrinsics ? getPropertiesOfType(intrinsics) : ts.emptyArray;
        }
        function checkJsxPreconditions(errorNode) {
            // Preconditions for using JSX
            if ((compilerOptions.jsx || 0 /* None */) === 0 /* None */) {
                error(errorNode, ts.Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided);
            }
            if (getJsxElementTypeAt(errorNode) === undefined) {
                if (noImplicitAny) {
                    error(errorNode, ts.Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist);
                }
            }
        }
        function checkJsxOpeningLikeElementOrOpeningFragment(node) {
            var isNodeOpeningLikeElement = ts.isJsxOpeningLikeElement(node);
            if (isNodeOpeningLikeElement) {
                checkGrammarJsxElement(node);
            }
            checkJsxPreconditions(node);
            // The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import.
            // And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error.
            var reactRefErr = diagnostics && compilerOptions.jsx === 2 /* React */ ? ts.Diagnostics.Cannot_find_name_0 : undefined;
            var reactNamespace = getJsxNamespace(node);
            var reactLocation = isNodeOpeningLikeElement ? node.tagName : node;
            var reactSym = resolveName(reactLocation, reactNamespace, 67220415 /* Value */, reactRefErr, reactNamespace, /*isUse*/ true);
            if (reactSym) {
                // Mark local symbol as referenced here because it might not have been marked
                // if jsx emit was not react as there wont be error being emitted
                reactSym.isReferenced = 67108863 /* All */;
                // If react symbol is alias, mark it as referenced
                if (reactSym.flags & 2097152 /* Alias */ && !isConstEnumOrConstEnumOnlyModule(resolveAlias(reactSym))) {
                    markAliasSymbolAsReferenced(reactSym);
                }
            }
            if (isNodeOpeningLikeElement) {
                var sig = getResolvedSignature(node);
                checkJsxReturnAssignableToAppropriateBound(getJsxReferenceKind(node), getReturnTypeOfSignature(sig), node);
            }
        }
        /**
         * Check if a property with the given name is known anywhere in the given type. In an object type, a property
         * is considered known if
         * 1. the object type is empty and the check is for assignability, or
         * 2. if the object type has index signatures, or
         * 3. if the property is actually declared in the object type
         *    (this means that 'toString', for example, is not usually a known property).
         * 4. In a union or intersection type,
         *    a property is considered known if it is known in any constituent type.
         * @param targetType a type to search a given name in
         * @param name a property name to search
         * @param isComparingJsxAttributes a boolean flag indicating whether we are searching in JsxAttributesType
         */
        function isKnownProperty(targetType, name, isComparingJsxAttributes) {
            if (targetType.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(targetType);
                if (resolved.stringIndexInfo ||
                    resolved.numberIndexInfo && isNumericLiteralName(name) ||
                    getPropertyOfObjectType(targetType, name) ||
                    isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) {
                    // For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known.
                    return true;
                }
            }
            else if (targetType.flags & 3145728 /* UnionOrIntersection */ && isExcessPropertyCheckTarget(targetType)) {
                for (var _i = 0, _a = targetType.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    if (isKnownProperty(t, name, isComparingJsxAttributes)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function isExcessPropertyCheckTarget(type) {
            return !!(type.flags & 524288 /* Object */ && !(ts.getObjectFlags(type) & 512 /* ObjectLiteralPatternWithComputedProperties */) ||
                type.flags & 67108864 /* NonPrimitive */ ||
                type.flags & 1048576 /* Union */ && ts.some(type.types, isExcessPropertyCheckTarget) ||
                type.flags & 2097152 /* Intersection */ && ts.every(type.types, isExcessPropertyCheckTarget));
        }
        function checkJsxExpression(node, checkMode) {
            if (node.expression) {
                var type = checkExpression(node.expression, checkMode);
                if (node.dotDotDotToken && type !== anyType && !isArrayType(type)) {
                    error(node, ts.Diagnostics.JSX_spread_child_must_be_an_array_type);
                }
                return type;
            }
            else {
                return errorType;
            }
        }
        function getDeclarationNodeFlagsFromSymbol(s) {
            return s.valueDeclaration ? ts.getCombinedNodeFlags(s.valueDeclaration) : 0;
        }
        /**
         * Return whether this symbol is a member of a prototype somewhere
         * Note that this is not tracked well within the compiler, so the answer may be incorrect.
         */
        function isPrototypeProperty(symbol) {
            if (symbol.flags & 8192 /* Method */ || ts.getCheckFlags(symbol) & 4 /* SyntheticMethod */) {
                return true;
            }
            if (ts.isInJSFile(symbol.valueDeclaration)) {
                var parent = symbol.valueDeclaration.parent;
                return parent && ts.isBinaryExpression(parent) &&
                    ts.getAssignmentDeclarationKind(parent) === 3 /* PrototypeProperty */;
            }
        }
        /**
         * Check whether the requested property access is valid.
         * Returns true if node is a valid property access, and false otherwise.
         * @param node The node to be checked.
         * @param isSuper True if the access is from `super.`.
         * @param type The type of the object whose property is being accessed. (Not the type of the property.)
         * @param prop The symbol for the property being accessed.
         */
        function checkPropertyAccessibility(node, isSuper, type, prop) {
            var flags = ts.getDeclarationModifierFlagsFromSymbol(prop);
            var errorNode = node.kind === 149 /* QualifiedName */ ? node.right : node.kind === 184 /* ImportType */ ? node : node.name;
            if (ts.getCheckFlags(prop) & 1024 /* ContainsPrivate */) {
                // Synthetic property with private constituent property
                error(errorNode, ts.Diagnostics.Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1, symbolToString(prop), typeToString(type));
                return false;
            }
            if (isSuper) {
                // TS 1.0 spec (April 2014): 4.8.2
                // - In a constructor, instance member function, instance member accessor, or
                //   instance member variable initializer where this references a derived class instance,
                //   a super property access is permitted and must specify a public instance member function of the base class.
                // - In a static member function or static member accessor
                //   where this references the constructor function object of a derived class,
                //   a super property access is permitted and must specify a public static member function of the base class.
                if (languageVersion < 2 /* ES2015 */) {
                    if (symbolHasNonMethodDeclaration(prop)) {
                        error(errorNode, ts.Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword);
                        return false;
                    }
                }
                if (flags & 128 /* Abstract */) {
                    // A method cannot be accessed in a super property access if the method is abstract.
                    // This error could mask a private property access error. But, a member
                    // cannot simultaneously be private and abstract, so this will trigger an
                    // additional error elsewhere.
                    error(errorNode, ts.Diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression, symbolToString(prop), typeToString(getDeclaringClass(prop)));
                    return false;
                }
            }
            // Referencing abstract properties within their own constructors is not allowed
            if ((flags & 128 /* Abstract */) && ts.isThisProperty(node) && symbolHasNonMethodDeclaration(prop)) {
                var declaringClassDeclaration = ts.getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop));
                if (declaringClassDeclaration && isNodeUsedDuringClassInitialization(node)) {
                    error(errorNode, ts.Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), ts.getTextOfIdentifierOrLiteral(declaringClassDeclaration.name)); // TODO: GH#18217
                    return false;
                }
            }
            // Public properties are otherwise accessible.
            if (!(flags & 24 /* NonPublicAccessibilityModifier */)) {
                return true;
            }
            // Property is known to be private or protected at this point
            // Private property is accessible if the property is within the declaring class
            if (flags & 8 /* Private */) {
                var declaringClassDeclaration = ts.getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop));
                if (!isNodeWithinClass(node, declaringClassDeclaration)) {
                    error(errorNode, ts.Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, symbolToString(prop), typeToString(getDeclaringClass(prop)));
                    return false;
                }
                return true;
            }
            // Property is known to be protected at this point
            // All protected properties of a supertype are accessible in a super access
            if (isSuper) {
                return true;
            }
            // Find the first enclosing class that has the declaring classes of the protected constituents
            // of the property as base classes
            var enclosingClass = forEachEnclosingClass(node, function (enclosingDeclaration) {
                var enclosingClass = getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingDeclaration));
                return isClassDerivedFromDeclaringClasses(enclosingClass, prop) ? enclosingClass : undefined;
            });
            // A protected property is accessible if the property is within the declaring class or classes derived from it
            if (!enclosingClass) {
                // allow PropertyAccessibility if context is in function with this parameter
                // static member access is disallow
                var thisParameter = void 0;
                if (flags & 32 /* Static */ || !(thisParameter = getThisParameterFromNodeContext(node)) || !thisParameter.type) {
                    error(errorNode, ts.Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, symbolToString(prop), typeToString(getDeclaringClass(prop) || type));
                    return false;
                }
                var thisType = getTypeFromTypeNode(thisParameter.type);
                enclosingClass = ((thisType.flags & 262144 /* TypeParameter */) ? getConstraintOfTypeParameter(thisType) : thisType);
            }
            // No further restrictions for static properties
            if (flags & 32 /* Static */) {
                return true;
            }
            if (type.flags & 262144 /* TypeParameter */) {
                // get the original type -- represented as the type constraint of the 'this' type
                type = type.isThisType ? getConstraintOfTypeParameter(type) : getBaseConstraintOfType(type); // TODO: GH#18217 Use a different variable that's allowed to be undefined
            }
            if (!type || !hasBaseType(type, enclosingClass)) {
                error(errorNode, ts.Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1, symbolToString(prop), typeToString(enclosingClass));
                return false;
            }
            return true;
        }
        function getThisParameterFromNodeContext(node) {
            var thisContainer = ts.getThisContainer(node, /* includeArrowFunctions */ false);
            return thisContainer && ts.isFunctionLike(thisContainer) ? ts.getThisParameter(thisContainer) : undefined;
        }
        function symbolHasNonMethodDeclaration(symbol) {
            return !!forEachProperty(symbol, function (prop) { return !(prop.flags & 8192 /* Method */); });
        }
        function checkNonNullExpression(node, nullDiagnostic, undefinedDiagnostic, nullOrUndefinedDiagnostic) {
            return checkNonNullType(checkExpression(node), node, nullDiagnostic, undefinedDiagnostic, nullOrUndefinedDiagnostic);
        }
        function getNonNullableTypeIfNeeded(type) {
            var kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & 98304 /* Nullable */;
            if (kind) {
                return getNonNullableType(type);
            }
            return type;
        }
        function checkNonNullType(type, node, nullDiagnostic, undefinedDiagnostic, nullOrUndefinedDiagnostic) {
            if (strictNullChecks && type.flags & 2 /* Unknown */) {
                error(node, ts.Diagnostics.Object_is_of_type_unknown);
                return errorType;
            }
            var kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & 98304 /* Nullable */;
            if (kind) {
                error(node, kind & 32768 /* Undefined */ ? kind & 65536 /* Null */ ?
                    (nullOrUndefinedDiagnostic || ts.Diagnostics.Object_is_possibly_null_or_undefined) :
                    (undefinedDiagnostic || ts.Diagnostics.Object_is_possibly_undefined) :
                    (nullDiagnostic || ts.Diagnostics.Object_is_possibly_null));
                var t = getNonNullableType(type);
                return t.flags & (98304 /* Nullable */ | 131072 /* Never */) ? errorType : t;
            }
            return type;
        }
        function checkNonNullNonVoidType(type, node) {
            var nonNullType = checkNonNullType(type, node);
            if (nonNullType !== errorType && nonNullType.flags & 16384 /* Void */) {
                error(node, ts.Diagnostics.Object_is_possibly_undefined);
            }
            return nonNullType;
        }
        function checkPropertyAccessExpression(node) {
            return checkPropertyAccessExpressionOrQualifiedName(node, node.expression, node.name);
        }
        function checkQualifiedName(node) {
            return checkPropertyAccessExpressionOrQualifiedName(node, node.left, node.right);
        }
        function checkPropertyAccessExpressionOrQualifiedName(node, left, right) {
            var propType;
            var leftType = checkNonNullExpression(left);
            var parentSymbol = getNodeLinks(left).resolvedSymbol;
            var apparentType = getApparentType(getWidenedType(leftType));
            if (isTypeAny(apparentType) || apparentType === silentNeverType) {
                if (ts.isIdentifier(left) && parentSymbol) {
                    markAliasReferenced(parentSymbol, node);
                }
                return apparentType;
            }
            var assignmentKind = ts.getAssignmentTargetKind(node);
            var prop = getPropertyOfType(apparentType, right.escapedText);
            if (ts.isIdentifier(left) && parentSymbol && !(prop && isConstEnumOrConstEnumOnlyModule(prop))) {
                markAliasReferenced(parentSymbol, node);
            }
            if (!prop) {
                var indexInfo = assignmentKind === 0 /* None */ || !isGenericObjectType(leftType) ? getIndexInfoOfType(apparentType, 0 /* String */) : undefined;
                if (!(indexInfo && indexInfo.type)) {
                    if (isJSLiteralType(leftType)) {
                        return anyType;
                    }
                    if (leftType.symbol === globalThisSymbol) {
                        if (globalThisSymbol.exports.has(right.escapedText) && (globalThisSymbol.exports.get(right.escapedText).flags & 418 /* BlockScoped */)) {
                            error(right, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.unescapeLeadingUnderscores(right.escapedText), typeToString(leftType));
                        }
                        else if (noImplicitAny) {
                            error(right, ts.Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(leftType));
                        }
                        return anyType;
                    }
                    if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) {
                        reportNonexistentProperty(right, isThisTypeParameter(leftType) ? apparentType : leftType);
                    }
                    return errorType;
                }
                if (indexInfo.isReadonly && (ts.isAssignmentTarget(node) || ts.isDeleteTarget(node))) {
                    error(node, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(apparentType));
                }
                propType = indexInfo.type;
            }
            else {
                checkPropertyNotUsedBeforeDeclaration(prop, node, right);
                markPropertyAsReferenced(prop, node, left.kind === 101 /* ThisKeyword */);
                getNodeLinks(node).resolvedSymbol = prop;
                checkPropertyAccessibility(node, left.kind === 99 /* SuperKeyword */, apparentType, prop);
                if (assignmentKind) {
                    if (isReferenceToReadonlyEntity(node, prop) || isReferenceThroughNamespaceImport(node)) {
                        error(right, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, ts.idText(right));
                        return errorType;
                    }
                }
                propType = getConstraintForLocation(getTypeOfSymbol(prop), node);
            }
            // Only compute control flow type if this is a property access expression that isn't an
            // assignment target, and the referenced property was declared as a variable, property,
            // accessor, or optional method.
            if (node.kind !== 190 /* PropertyAccessExpression */ ||
                assignmentKind === 1 /* Definite */ ||
                prop && !(prop.flags & (3 /* Variable */ | 4 /* Property */ | 98304 /* Accessor */)) && !(prop.flags & 8192 /* Method */ && propType.flags & 1048576 /* Union */)) {
                return propType;
            }
            // If strict null checks and strict property initialization checks are enabled, if we have
            // a this.xxx property access, if the property is an instance property without an initializer,
            // and if we are in a constructor of the same class as the property declaration, assume that
            // the property is uninitialized at the top of the control flow.
            var assumeUninitialized = false;
            if (strictNullChecks && strictPropertyInitialization && left.kind === 101 /* ThisKeyword */) {
                var declaration = prop && prop.valueDeclaration;
                if (declaration && isInstancePropertyWithoutInitializer(declaration)) {
                    var flowContainer = getControlFlowContainer(node);
                    if (flowContainer.kind === 158 /* Constructor */ && flowContainer.parent === declaration.parent) {
                        assumeUninitialized = true;
                    }
                }
            }
            else if (strictNullChecks && prop && prop.valueDeclaration &&
                ts.isPropertyAccessExpression(prop.valueDeclaration) &&
                ts.getAssignmentDeclarationPropertyAccessKind(prop.valueDeclaration) &&
                getControlFlowContainer(node) === getControlFlowContainer(prop.valueDeclaration)) {
                assumeUninitialized = true;
            }
            var flowType = getFlowTypeOfReference(node, propType, assumeUninitialized ? getOptionalType(propType) : propType);
            if (assumeUninitialized && !(getFalsyFlags(propType) & 32768 /* Undefined */) && getFalsyFlags(flowType) & 32768 /* Undefined */) {
                error(right, ts.Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop)); // TODO: GH#18217
                // Return the declared type to reduce follow-on errors
                return propType;
            }
            return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType;
        }
        function checkPropertyNotUsedBeforeDeclaration(prop, node, right) {
            var valueDeclaration = prop.valueDeclaration;
            if (!valueDeclaration) {
                return;
            }
            var diagnosticMessage;
            var declarationName = ts.idText(right);
            if (isInPropertyInitializer(node) &&
                !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)
                && !isPropertyDeclaredInAncestorClass(prop)) {
                diagnosticMessage = error(right, ts.Diagnostics.Property_0_is_used_before_its_initialization, declarationName);
            }
            else if (valueDeclaration.kind === 241 /* ClassDeclaration */ &&
                node.parent.kind !== 165 /* TypeReference */ &&
                !(valueDeclaration.flags & 4194304 /* Ambient */) &&
                !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)) {
                diagnosticMessage = error(right, ts.Diagnostics.Class_0_used_before_its_declaration, declarationName);
            }
            if (diagnosticMessage) {
                ts.addRelatedInfo(diagnosticMessage, ts.createDiagnosticForNode(valueDeclaration, ts.Diagnostics._0_is_declared_here, declarationName));
            }
        }
        function isInPropertyInitializer(node) {
            return !!ts.findAncestor(node, function (node) {
                switch (node.kind) {
                    case 155 /* PropertyDeclaration */:
                        return true;
                    case 276 /* PropertyAssignment */:
                    case 157 /* MethodDeclaration */:
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                    case 278 /* SpreadAssignment */:
                    case 150 /* ComputedPropertyName */:
                    case 217 /* TemplateSpan */:
                    case 271 /* JsxExpression */:
                    case 268 /* JsxAttribute */:
                    case 269 /* JsxAttributes */:
                    case 270 /* JsxSpreadAttribute */:
                    case 263 /* JsxOpeningElement */:
                    case 212 /* ExpressionWithTypeArguments */:
                    case 274 /* HeritageClause */:
                        return false;
                    default:
                        return ts.isExpressionNode(node) ? false : "quit";
                }
            });
        }
        /**
         * It's possible that "prop.valueDeclaration" is a local declaration, but the property was also declared in a superclass.
         * In that case we won't consider it used before its declaration, because it gets its value from the superclass' declaration.
         */
        function isPropertyDeclaredInAncestorClass(prop) {
            if (!(prop.parent.flags & 32 /* Class */)) {
                return false;
            }
            var classType = getTypeOfSymbol(prop.parent);
            while (true) {
                classType = classType.symbol && getSuperClass(classType);
                if (!classType) {
                    return false;
                }
                var superProperty = getPropertyOfType(classType, prop.escapedName);
                if (superProperty && superProperty.valueDeclaration) {
                    return true;
                }
            }
        }
        function getSuperClass(classType) {
            var x = getBaseTypes(classType);
            if (x.length === 0) {
                return undefined;
            }
            return getIntersectionType(x);
        }
        function reportNonexistentProperty(propNode, containingType) {
            var errorInfo;
            var relatedInfo;
            if (containingType.flags & 1048576 /* Union */ && !(containingType.flags & 131068 /* Primitive */)) {
                for (var _i = 0, _a = containingType.types; _i < _a.length; _i++) {
                    var subtype = _a[_i];
                    if (!getPropertyOfType(subtype, propNode.escapedText)) {
                        errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(subtype));
                        break;
                    }
                }
            }
            if (typeHasStaticProperty(propNode.escapedText, containingType)) {
                errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_is_a_static_member_of_type_1, ts.declarationNameToString(propNode), typeToString(containingType));
            }
            else {
                var promisedType = getPromisedTypeOfPromise(containingType);
                if (promisedType && getPropertyOfType(promisedType, propNode.escapedText)) {
                    errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await, ts.declarationNameToString(propNode), typeToString(containingType));
                }
                else {
                    var suggestion = getSuggestedSymbolForNonexistentProperty(propNode, containingType);
                    if (suggestion !== undefined) {
                        var suggestedName = ts.symbolName(suggestion);
                        errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, ts.declarationNameToString(propNode), typeToString(containingType), suggestedName);
                        relatedInfo = suggestion.valueDeclaration && ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestedName);
                    }
                    else {
                        errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(containingType));
                    }
                }
            }
            var resultDiagnostic = ts.createDiagnosticForNodeFromMessageChain(propNode, errorInfo);
            if (relatedInfo) {
                ts.addRelatedInfo(resultDiagnostic, relatedInfo);
            }
            diagnostics.add(resultDiagnostic);
        }
        function typeHasStaticProperty(propName, containingType) {
            var prop = containingType.symbol && getPropertyOfType(getTypeOfSymbol(containingType.symbol), propName);
            return prop !== undefined && prop.valueDeclaration && ts.hasModifier(prop.valueDeclaration, 32 /* Static */);
        }
        function getSuggestedSymbolForNonexistentProperty(name, containingType) {
            return getSpellingSuggestionForName(ts.isString(name) ? name : ts.idText(name), getPropertiesOfType(containingType), 67220415 /* Value */);
        }
        function getSuggestionForNonexistentProperty(name, containingType) {
            var suggestion = getSuggestedSymbolForNonexistentProperty(name, containingType);
            return suggestion && ts.symbolName(suggestion);
        }
        function getSuggestedSymbolForNonexistentSymbol(location, outerName, meaning) {
            ts.Debug.assert(outerName !== undefined, "outername should always be defined");
            var result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, /*excludeGlobals*/ false, function (symbols, name, meaning) {
                ts.Debug.assertEqual(outerName, name, "name should equal outerName");
                var symbol = getSymbol(symbols, name, meaning);
                // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function
                // So the table *contains* `x` but `x` isn't actually in scope.
                // However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion.
                return symbol || getSpellingSuggestionForName(ts.unescapeLeadingUnderscores(name), ts.arrayFrom(symbols.values()), meaning);
            });
            return result;
        }
        function getSuggestionForNonexistentSymbol(location, outerName, meaning) {
            var symbolResult = getSuggestedSymbolForNonexistentSymbol(location, outerName, meaning);
            return symbolResult && ts.symbolName(symbolResult);
        }
        function getSuggestedSymbolForNonexistentModule(name, targetModule) {
            return targetModule.exports && getSpellingSuggestionForName(ts.idText(name), getExportsOfModuleAsArray(targetModule), 2623475 /* ModuleMember */);
        }
        function getSuggestionForNonexistentExport(name, targetModule) {
            var suggestion = getSuggestedSymbolForNonexistentModule(name, targetModule);
            return suggestion && ts.symbolName(suggestion);
        }
        function getSuggestionForNonexistentIndexSignature(objectType, expr) {
            // check if object type has setter or getter
            var hasProp = function (name, argCount) {
                if (argCount === void 0) { argCount = 1; }
                var prop = getPropertyOfObjectType(objectType, name);
                if (prop) {
                    var s = getSingleCallSignature(getTypeOfSymbol(prop));
                    if (s && getMinArgumentCount(s) === argCount && typeToString(getTypeAtPosition(s, 0)) === "string") {
                        return true;
                    }
                }
                return false;
            };
            var suggestedMethod = ts.isAssignmentTarget(expr) ? "set" : "get";
            if (!hasProp(suggestedMethod)) {
                return undefined;
            }
            var suggestion = ts.tryGetPropertyAccessOrIdentifierToString(expr);
            if (suggestion === undefined) {
                suggestion = suggestedMethod;
            }
            else {
                suggestion += "." + suggestedMethod;
            }
            return suggestion;
        }
        /**
         * Given a name and a list of symbols whose names are *not* equal to the name, return a spelling suggestion if there is one that is close enough.
         * Names less than length 3 only check for case-insensitive equality, not levenshtein distance.
         *
         * If there is a candidate that's the same except for case, return that.
         * If there is a candidate that's within one edit of the name, return that.
         * Otherwise, return the candidate with the smallest Levenshtein distance,
         *    except for candidates:
         *      * With no name
         *      * Whose meaning doesn't match the `meaning` parameter.
         *      * Whose length differs from the target name by more than 0.34 of the length of the name.
         *      * Whose levenshtein distance is more than 0.4 of the length of the name
         *        (0.4 allows 1 substitution/transposition for every 5 characters,
         *         and 1 insertion/deletion at 3 characters)
         */
        function getSpellingSuggestionForName(name, symbols, meaning) {
            return ts.getSpellingSuggestion(name, symbols, getCandidateName);
            function getCandidateName(candidate) {
                var candidateName = ts.symbolName(candidate);
                return !ts.startsWith(candidateName, "\"") && candidate.flags & meaning ? candidateName : undefined;
            }
        }
        function markPropertyAsReferenced(prop, nodeForCheckWriteOnly, isThisAccess) {
            if (!prop || !(prop.flags & 106500 /* ClassMember */) || !prop.valueDeclaration || !ts.hasModifier(prop.valueDeclaration, 8 /* Private */)) {
                return;
            }
            if (nodeForCheckWriteOnly && ts.isWriteOnlyAccess(nodeForCheckWriteOnly) && !(prop.flags & 65536 /* SetAccessor */ && !(prop.flags & 32768 /* GetAccessor */))) {
                return;
            }
            if (isThisAccess) {
                // Find any FunctionLikeDeclaration because those create a new 'this' binding. But this should only matter for methods (or getters/setters).
                var containingMethod = ts.findAncestor(nodeForCheckWriteOnly, ts.isFunctionLikeDeclaration);
                if (containingMethod && containingMethod.symbol === prop) {
                    return;
                }
            }
            (ts.getCheckFlags(prop) & 1 /* Instantiated */ ? getSymbolLinks(prop).target : prop).isReferenced = 67108863 /* All */;
        }
        function isValidPropertyAccess(node, propertyName) {
            switch (node.kind) {
                case 190 /* PropertyAccessExpression */:
                    return isValidPropertyAccessWithType(node, node.expression.kind === 99 /* SuperKeyword */, propertyName, getWidenedType(checkExpression(node.expression)));
                case 149 /* QualifiedName */:
                    return isValidPropertyAccessWithType(node, /*isSuper*/ false, propertyName, getWidenedType(checkExpression(node.left)));
                case 184 /* ImportType */:
                    return isValidPropertyAccessWithType(node, /*isSuper*/ false, propertyName, getTypeFromTypeNode(node));
            }
        }
        function isValidPropertyAccessForCompletions(node, type, property) {
            return isValidPropertyAccessWithType(node, node.kind === 190 /* PropertyAccessExpression */ && node.expression.kind === 99 /* SuperKeyword */, property.escapedName, type);
            // Previously we validated the 'this' type of methods but this adversely affected performance. See #31377 for more context.
        }
        function isValidPropertyAccessWithType(node, isSuper, propertyName, type) {
            if (type === errorType || isTypeAny(type)) {
                return true;
            }
            var prop = getPropertyOfType(type, propertyName);
            return prop ? checkPropertyAccessibility(node, isSuper, type, prop)
                // In js files properties of unions are allowed in completion
                : ts.isInJSFile(node) && (type.flags & 1048576 /* Union */) !== 0 && type.types.some(function (elementType) { return isValidPropertyAccessWithType(node, isSuper, propertyName, elementType); });
        }
        /**
         * Return the symbol of the for-in variable declared or referenced by the given for-in statement.
         */
        function getForInVariableSymbol(node) {
            var initializer = node.initializer;
            if (initializer.kind === 239 /* VariableDeclarationList */) {
                var variable = initializer.declarations[0];
                if (variable && !ts.isBindingPattern(variable.name)) {
                    return getSymbolOfNode(variable);
                }
            }
            else if (initializer.kind === 73 /* Identifier */) {
                return getResolvedSymbol(initializer);
            }
            return undefined;
        }
        /**
         * Return true if the given type is considered to have numeric property names.
         */
        function hasNumericPropertyNames(type) {
            return getIndexTypeOfType(type, 1 /* Number */) && !getIndexTypeOfType(type, 0 /* String */);
        }
        /**
         * Return true if given node is an expression consisting of an identifier (possibly parenthesized)
         * that references a for-in variable for an object with numeric property names.
         */
        function isForInVariableForNumericPropertyNames(expr) {
            var e = ts.skipParentheses(expr);
            if (e.kind === 73 /* Identifier */) {
                var symbol = getResolvedSymbol(e);
                if (symbol.flags & 3 /* Variable */) {
                    var child = expr;
                    var node = expr.parent;
                    while (node) {
                        if (node.kind === 227 /* ForInStatement */ &&
                            child === node.statement &&
                            getForInVariableSymbol(node) === symbol &&
                            hasNumericPropertyNames(getTypeOfExpression(node.expression))) {
                            return true;
                        }
                        child = node;
                        node = node.parent;
                    }
                }
            }
            return false;
        }
        function checkIndexedAccess(node) {
            var objectType = checkNonNullExpression(node.expression);
            var indexExpression = node.argumentExpression;
            if (!indexExpression) {
                var sourceFile = ts.getSourceFileOfNode(node);
                if (node.parent.kind === 193 /* NewExpression */ && node.parent.expression === node) {
                    var start = ts.skipTrivia(sourceFile.text, node.expression.end);
                    var end = node.end;
                    grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead);
                }
                else {
                    var start = node.end - "]".length;
                    var end = node.end;
                    grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.Expression_expected);
                }
                return errorType;
            }
            var indexType = checkExpression(indexExpression);
            if (objectType === errorType || objectType === silentNeverType) {
                return objectType;
            }
            if (isConstEnumObjectType(objectType) && indexExpression.kind !== 10 /* StringLiteral */) {
                error(indexExpression, ts.Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal);
                return errorType;
            }
            var effectiveIndexType = isForInVariableForNumericPropertyNames(indexExpression) ? numberType : indexType;
            var accessFlags = ts.isAssignmentTarget(node) ?
                2 /* Writing */ | (isGenericObjectType(objectType) && !isThisTypeParameter(objectType) ? 1 /* NoIndexSignatures */ : 0) :
                0 /* None */;
            var indexedAccessType = getIndexedAccessTypeOrUndefined(objectType, effectiveIndexType, node, accessFlags) || errorType;
            return checkIndexedAccessIndexType(indexedAccessType, node);
        }
        function checkThatExpressionIsProperSymbolReference(expression, expressionType, reportError) {
            if (expressionType === errorType) {
                // There is already an error, so no need to report one.
                return false;
            }
            if (!ts.isWellKnownSymbolSyntactically(expression)) {
                return false;
            }
            // Make sure the property type is the primitive symbol type
            if ((expressionType.flags & 12288 /* ESSymbolLike */) === 0) {
                if (reportError) {
                    error(expression, ts.Diagnostics.A_computed_property_name_of_the_form_0_must_be_of_type_symbol, ts.getTextOfNode(expression));
                }
                return false;
            }
            // The name is Symbol.<someName>, so make sure Symbol actually resolves to the
            // global Symbol object
            var leftHandSide = expression.expression;
            var leftHandSideSymbol = getResolvedSymbol(leftHandSide);
            if (!leftHandSideSymbol) {
                return false;
            }
            var globalESSymbol = getGlobalESSymbolConstructorSymbol(/*reportErrors*/ true);
            if (!globalESSymbol) {
                // Already errored when we tried to look up the symbol
                return false;
            }
            if (leftHandSideSymbol !== globalESSymbol) {
                if (reportError) {
                    error(leftHandSide, ts.Diagnostics.Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object);
                }
                return false;
            }
            return true;
        }
        function callLikeExpressionMayHaveTypeArguments(node) {
            return ts.isCallOrNewExpression(node) || ts.isTaggedTemplateExpression(node) || ts.isJsxOpeningLikeElement(node);
        }
        function resolveUntypedCall(node) {
            if (callLikeExpressionMayHaveTypeArguments(node)) {
                // Check type arguments even though we will give an error that untyped calls may not accept type arguments.
                // This gets us diagnostics for the type arguments and marks them as referenced.
                ts.forEach(node.typeArguments, checkSourceElement);
            }
            if (node.kind === 194 /* TaggedTemplateExpression */) {
                checkExpression(node.template);
            }
            else if (ts.isJsxOpeningLikeElement(node)) {
                checkExpression(node.attributes);
            }
            else if (node.kind !== 153 /* Decorator */) {
                ts.forEach(node.arguments, function (argument) {
                    checkExpression(argument);
                });
            }
            return anySignature;
        }
        function resolveErrorCall(node) {
            resolveUntypedCall(node);
            return unknownSignature;
        }
        // Re-order candidate signatures into the result array. Assumes the result array to be empty.
        // The candidate list orders groups in reverse, but within a group signatures are kept in declaration order
        // A nit here is that we reorder only signatures that belong to the same symbol,
        // so order how inherited signatures are processed is still preserved.
        // interface A { (x: string): void }
        // interface B extends A { (x: 'foo'): string }
        // const b: B;
        // b('foo') // <- here overloads should be processed as [(x:'foo'): string, (x: string): void]
        function reorderCandidates(signatures, result) {
            var lastParent;
            var lastSymbol;
            var cutoffIndex = 0;
            var index;
            var specializedIndex = -1;
            var spliceIndex;
            ts.Debug.assert(!result.length);
            for (var _i = 0, signatures_3 = signatures; _i < signatures_3.length; _i++) {
                var signature = signatures_3[_i];
                var symbol = signature.declaration && getSymbolOfNode(signature.declaration);
                var parent = signature.declaration && signature.declaration.parent;
                if (!lastSymbol || symbol === lastSymbol) {
                    if (lastParent && parent === lastParent) {
                        index = index + 1;
                    }
                    else {
                        lastParent = parent;
                        index = cutoffIndex;
                    }
                }
                else {
                    // current declaration belongs to a different symbol
                    // set cutoffIndex so re-orderings in the future won't change result set from 0 to cutoffIndex
                    index = cutoffIndex = result.length;
                    lastParent = parent;
                }
                lastSymbol = symbol;
                // specialized signatures always need to be placed before non-specialized signatures regardless
                // of the cutoff position; see GH#1133
                if (signature.hasLiteralTypes) {
                    specializedIndex++;
                    spliceIndex = specializedIndex;
                    // The cutoff index always needs to be greater than or equal to the specialized signature index
                    // in order to prevent non-specialized signatures from being added before a specialized
                    // signature.
                    cutoffIndex++;
                }
                else {
                    spliceIndex = index;
                }
                result.splice(spliceIndex, 0, signature);
            }
        }
        function isSpreadArgument(arg) {
            return !!arg && (arg.kind === 209 /* SpreadElement */ || arg.kind === 216 /* SyntheticExpression */ && arg.isSpread);
        }
        function getSpreadArgumentIndex(args) {
            return ts.findIndex(args, isSpreadArgument);
        }
        function acceptsVoid(t) {
            return !!(t.flags & 16384 /* Void */);
        }
        function hasCorrectArity(node, args, signature, signatureHelpTrailingComma) {
            if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; }
            var argCount;
            var callIsIncomplete = false; // In incomplete call we want to be lenient when we have too few arguments
            var effectiveParameterCount = getParameterCount(signature);
            var effectiveMinimumArguments = getMinArgumentCount(signature);
            if (node.kind === 194 /* TaggedTemplateExpression */) {
                argCount = args.length;
                if (node.template.kind === 207 /* TemplateExpression */) {
                    // If a tagged template expression lacks a tail literal, the call is incomplete.
                    // Specifically, a template only can end in a TemplateTail or a Missing literal.
                    var lastSpan = ts.last(node.template.templateSpans); // we should always have at least one span.
                    callIsIncomplete = ts.nodeIsMissing(lastSpan.literal) || !!lastSpan.literal.isUnterminated;
                }
                else {
                    // If the template didn't end in a backtick, or its beginning occurred right prior to EOF,
                    // then this might actually turn out to be a TemplateHead in the future;
                    // so we consider the call to be incomplete.
                    var templateLiteral = node.template;
                    ts.Debug.assert(templateLiteral.kind === 14 /* NoSubstitutionTemplateLiteral */);
                    callIsIncomplete = !!templateLiteral.isUnterminated;
                }
            }
            else if (node.kind === 153 /* Decorator */) {
                argCount = getDecoratorArgumentCount(node, signature);
            }
            else if (ts.isJsxOpeningLikeElement(node)) {
                callIsIncomplete = node.attributes.end === node.end;
                if (callIsIncomplete) {
                    return true;
                }
                argCount = effectiveMinimumArguments === 0 ? args.length : 1;
                effectiveParameterCount = args.length === 0 ? effectiveParameterCount : 1; // class may have argumentless ctor functions - still resolve ctor and compare vs props member type
                effectiveMinimumArguments = Math.min(effectiveMinimumArguments, 1); // sfc may specify context argument - handled by framework and not typechecked
            }
            else {
                if (!node.arguments) {
                    // This only happens when we have something of the form: 'new C'
                    ts.Debug.assert(node.kind === 193 /* NewExpression */);
                    return getMinArgumentCount(signature) === 0;
                }
                argCount = signatureHelpTrailingComma ? args.length + 1 : args.length;
                // If we are missing the close parenthesis, the call is incomplete.
                callIsIncomplete = node.arguments.end === node.end;
                // If a spread argument is present, check that it corresponds to a rest parameter or at least that it's in the valid range.
                var spreadArgIndex = getSpreadArgumentIndex(args);
                if (spreadArgIndex >= 0) {
                    return spreadArgIndex >= getMinArgumentCount(signature) && (hasEffectiveRestParameter(signature) || spreadArgIndex < getParameterCount(signature));
                }
            }
            // Too many arguments implies incorrect arity.
            if (!hasEffectiveRestParameter(signature) && argCount > effectiveParameterCount) {
                return false;
            }
            // If the call is incomplete, we should skip the lower bound check.
            // JSX signatures can have extra parameters provided by the library which we don't check
            if (callIsIncomplete || argCount >= effectiveMinimumArguments) {
                return true;
            }
            for (var i = argCount; i < effectiveMinimumArguments; i++) {
                var type = getTypeAtPosition(signature, i);
                if (filterType(type, acceptsVoid).flags & 131072 /* Never */) {
                    return false;
                }
            }
            return true;
        }
        function hasCorrectTypeArgumentArity(signature, typeArguments) {
            // If the user supplied type arguments, but the number of type arguments does not match
            // the declared number of type parameters, the call has an incorrect arity.
            var numTypeParameters = ts.length(signature.typeParameters);
            var minTypeArgumentCount = getMinTypeArgumentCount(signature.typeParameters);
            return !typeArguments ||
                (typeArguments.length >= minTypeArgumentCount && typeArguments.length <= numTypeParameters);
        }
        // If type has a single call signature and no other members, return that signature. Otherwise, return undefined.
        function getSingleCallSignature(type) {
            return getSingleSignature(type, 0 /* Call */, /*allowMembers*/ false);
        }
        function getSingleCallOrConstructSignature(type) {
            return getSingleSignature(type, 0 /* Call */, /*allowMembers*/ false) ||
                getSingleSignature(type, 1 /* Construct */, /*allowMembers*/ false);
        }
        function getSingleSignature(type, kind, allowMembers) {
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                if (allowMembers || resolved.properties.length === 0 && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
                    if (kind === 0 /* Call */ && resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0) {
                        return resolved.callSignatures[0];
                    }
                    if (kind === 1 /* Construct */ && resolved.constructSignatures.length === 1 && resolved.callSignatures.length === 0) {
                        return resolved.constructSignatures[0];
                    }
                }
            }
            return undefined;
        }
        // Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
        function instantiateSignatureInContextOf(signature, contextualSignature, inferenceContext, compareTypes) {
            var context = createInferenceContext(signature.typeParameters, signature, 0 /* None */, compareTypes);
            // We clone the inferenceContext to avoid fixing. For example, when the source signature is <T>(x: T) => T[] and
            // the contextual signature is (...args: A) => B, we want to infer the element type of A's constraint (say 'any')
            // for T but leave it possible to later infer '[any]' back to A.
            var restType = getEffectiveRestType(contextualSignature);
            var mapper = inferenceContext && (restType && restType.flags & 262144 /* TypeParameter */ ? inferenceContext.nonFixingMapper : inferenceContext.mapper);
            var sourceSignature = mapper ? instantiateSignature(contextualSignature, mapper) : contextualSignature;
            applyToParameterTypes(sourceSignature, signature, function (source, target) {
                // Type parameters from outer context referenced by source type are fixed by instantiation of the source type
                inferTypes(context.inferences, source, target);
            });
            if (!inferenceContext) {
                applyToReturnTypes(contextualSignature, signature, function (source, target) {
                    inferTypes(context.inferences, source, target, 16 /* ReturnType */);
                });
            }
            return getSignatureInstantiation(signature, getInferredTypes(context), ts.isInJSFile(contextualSignature.declaration));
        }
        function inferJsxTypeArguments(node, signature, checkMode, context) {
            var paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
            var checkAttrType = checkExpressionWithContextualType(node.attributes, paramType, context, checkMode);
            inferTypes(context.inferences, checkAttrType, paramType);
            return getInferredTypes(context);
        }
        function inferTypeArguments(node, signature, args, checkMode, context) {
            if (ts.isJsxOpeningLikeElement(node)) {
                return inferJsxTypeArguments(node, signature, checkMode, context);
            }
            // If a contextual type is available, infer from that type to the return type of the call expression. For
            // example, given a 'function wrap<T, U>(cb: (x: T) => U): (x: T) => U' and a call expression
            // 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type of 'f' to the
            // return type of 'wrap'.
            if (node.kind !== 153 /* Decorator */) {
                var contextualType = getContextualType(node);
                if (contextualType) {
                    // We clone the inference context to avoid disturbing a resolution in progress for an
                    // outer call expression. Effectively we just want a snapshot of whatever has been
                    // inferred for any outer call expression so far.
                    var outerMapper = getMapperFromContext(cloneInferenceContext(getInferenceContext(node), 1 /* NoDefault */));
                    var instantiatedType = instantiateType(contextualType, outerMapper);
                    // If the contextual type is a generic function type with a single call signature, we
                    // instantiate the type with its own type parameters and type arguments. This ensures that
                    // the type parameters are not erased to type any during type inference such that they can
                    // be inferred as actual types from the contextual type. For example:
                    //   declare function arrayMap<T, U>(f: (x: T) => U): (a: T[]) => U[];
                    //   const boxElements: <A>(a: A[]) => { value: A }[] = arrayMap(value => ({ value }));
                    // Above, the type of the 'value' parameter is inferred to be 'A'.
                    var contextualSignature = getSingleCallSignature(instantiatedType);
                    var inferenceSourceType = contextualSignature && contextualSignature.typeParameters ?
                        getOrCreateTypeFromSignature(getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters)) :
                        instantiatedType;
                    var inferenceTargetType = getReturnTypeOfSignature(signature);
                    // Inferences made from return types have lower priority than all other inferences.
                    inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, 16 /* ReturnType */);
                    // Create a type mapper for instantiating generic contextual types using the inferences made
                    // from the return type.
                    context.returnMapper = getMapperFromContext(cloneInferredPartOfContext(context));
                }
            }
            var thisType = getThisTypeOfSignature(signature);
            if (thisType) {
                var thisArgumentNode = getThisArgumentOfCall(node);
                var thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
                inferTypes(context.inferences, thisArgumentType, thisType);
            }
            var restType = getNonArrayRestType(signature);
            var argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length;
            for (var i = 0; i < argCount; i++) {
                var arg = args[i];
                if (arg.kind !== 211 /* OmittedExpression */) {
                    var paramType = getTypeAtPosition(signature, i);
                    var argType = checkExpressionWithContextualType(arg, paramType, context, checkMode);
                    inferTypes(context.inferences, argType, paramType);
                }
            }
            if (restType) {
                var spreadType = getSpreadArgumentType(args, argCount, args.length, restType, context);
                inferTypes(context.inferences, spreadType, restType);
            }
            return getInferredTypes(context);
        }
        function getArrayifiedType(type) {
            if (forEachType(type, function (t) { return !(t.flags & (1 /* Any */ | 63176704 /* Instantiable */) || isArrayType(t) || isTupleType(t)); })) {
                return createArrayType(getIndexedAccessType(type, numberType));
            }
            return type;
        }
        function getSpreadArgumentType(args, index, argCount, restType, context) {
            if (index >= argCount - 1) {
                var arg = args[argCount - 1];
                if (isSpreadArgument(arg)) {
                    // We are inferring from a spread expression in the last argument position, i.e. both the parameter
                    // and the argument are ...x forms.
                    return arg.kind === 216 /* SyntheticExpression */ ?
                        createArrayType(arg.type) :
                        getArrayifiedType(checkExpressionWithContextualType(arg.expression, restType, context, 0 /* Normal */));
                }
            }
            var types = [];
            var spreadIndex = -1;
            for (var i = index; i < argCount; i++) {
                var contextualType = getIndexedAccessType(restType, getLiteralType(i - index));
                var argType = checkExpressionWithContextualType(args[i], contextualType, context, 0 /* Normal */);
                if (spreadIndex < 0 && isSpreadArgument(args[i])) {
                    spreadIndex = i - index;
                }
                var hasPrimitiveContextualType = maybeTypeOfKind(contextualType, 131068 /* Primitive */ | 4194304 /* Index */);
                types.push(hasPrimitiveContextualType ? getRegularTypeOfLiteralType(argType) : getWidenedLiteralType(argType));
            }
            return spreadIndex < 0 ?
                createTupleType(types) :
                createTupleType(ts.append(types.slice(0, spreadIndex), getUnionType(types.slice(spreadIndex))), spreadIndex, /*hasRestElement*/ true);
        }
        function checkTypeArguments(signature, typeArgumentNodes, reportErrors, headMessage) {
            var isJavascript = ts.isInJSFile(signature.declaration);
            var typeParameters = signature.typeParameters;
            var typeArgumentTypes = fillMissingTypeArguments(ts.map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript);
            var mapper;
            for (var i = 0; i < typeArgumentNodes.length; i++) {
                ts.Debug.assert(typeParameters[i] !== undefined, "Should not call checkTypeArguments with too many type arguments");
                var constraint = getConstraintOfTypeParameter(typeParameters[i]);
                if (constraint) {
                    var errorInfo = reportErrors && headMessage ? (function () { return ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1); }) : undefined;
                    var typeArgumentHeadMessage = headMessage || ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1;
                    if (!mapper) {
                        mapper = createTypeMapper(typeParameters, typeArgumentTypes);
                    }
                    var typeArgument = typeArgumentTypes[i];
                    if (!checkTypeAssignableTo(typeArgument, getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), reportErrors ? typeArgumentNodes[i] : undefined, typeArgumentHeadMessage, errorInfo)) {
                        return undefined;
                    }
                }
            }
            return typeArgumentTypes;
        }
        function getJsxReferenceKind(node) {
            if (isJsxIntrinsicIdentifier(node.tagName)) {
                return 2 /* Mixed */;
            }
            var tagType = getApparentType(checkExpression(node.tagName));
            if (ts.length(getSignaturesOfType(tagType, 1 /* Construct */))) {
                return 0 /* Component */;
            }
            if (ts.length(getSignaturesOfType(tagType, 0 /* Call */))) {
                return 1 /* Function */;
            }
            return 2 /* Mixed */;
        }
        /**
         * Check if the given signature can possibly be a signature called by the JSX opening-like element.
         * @param node a JSX opening-like element we are trying to figure its call signature
         * @param signature a candidate signature we are trying whether it is a call signature
         * @param relation a relationship to check parameter and argument type
         */
        function checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, checkMode, reportErrors) {
            // Stateless function components can have maximum of three arguments: "props", "context", and "updater".
            // However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props,
            // can be specified by users through attributes property.
            var paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
            var attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*inferenceContext*/ undefined, checkMode);
            return checkTypeRelatedToAndOptionallyElaborate(attributesType, paramType, relation, reportErrors ? node.tagName : undefined, node.attributes);
        }
        function checkApplicableSignature(node, args, signature, relation, checkMode, reportErrors) {
            if (ts.isJsxOpeningLikeElement(node)) {
                return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, checkMode, reportErrors);
            }
            var thisType = getThisTypeOfSignature(signature);
            if (thisType && thisType !== voidType && node.kind !== 193 /* NewExpression */) {
                // If the called expression is not of the form `x.f` or `x["f"]`, then sourceType = voidType
                // If the signature's 'this' type is voidType, then the check is skipped -- anything is compatible.
                // If the expression is a new expression, then the check is skipped.
                var thisArgumentNode = getThisArgumentOfCall(node);
                var thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
                var errorNode = reportErrors ? (thisArgumentNode || node) : undefined;
                var headMessage_1 = ts.Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1;
                if (!checkTypeRelatedTo(thisArgumentType, thisType, relation, errorNode, headMessage_1)) {
                    return false;
                }
            }
            var headMessage = ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1;
            var restType = getNonArrayRestType(signature);
            var argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length;
            for (var i = 0; i < argCount; i++) {
                var arg = args[i];
                if (arg.kind !== 211 /* OmittedExpression */) {
                    var paramType = getTypeAtPosition(signature, i);
                    var argType = checkExpressionWithContextualType(arg, paramType, /*inferenceContext*/ undefined, checkMode);
                    // If one or more arguments are still excluded (as indicated by CheckMode.SkipContextSensitive),
                    // we obtain the regular type of any object literal arguments because we may not have inferred complete
                    // parameter types yet and therefore excess property checks may yield false positives (see #17041).
                    var checkArgType = checkMode & 4 /* SkipContextSensitive */ ? getRegularTypeOfObjectLiteral(argType) : argType;
                    if (!checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? arg : undefined, arg, headMessage)) {
                        return false;
                    }
                }
            }
            if (restType) {
                var spreadType = getSpreadArgumentType(args, argCount, args.length, restType, /*context*/ undefined);
                var errorNode = reportErrors ? argCount < args.length ? args[argCount] : node : undefined;
                return checkTypeRelatedTo(spreadType, restType, relation, errorNode, headMessage);
            }
            return true;
        }
        /**
         * Returns the this argument in calls like x.f(...) and x[f](...). Undefined otherwise.
         */
        function getThisArgumentOfCall(node) {
            if (node.kind === 192 /* CallExpression */) {
                var callee = ts.skipOuterExpressions(node.expression);
                if (callee.kind === 190 /* PropertyAccessExpression */ || callee.kind === 191 /* ElementAccessExpression */) {
                    return callee.expression;
                }
            }
        }
        function createSyntheticExpression(parent, type, isSpread) {
            var result = ts.createNode(216 /* SyntheticExpression */, parent.pos, parent.end);
            result.parent = parent;
            result.type = type;
            result.isSpread = isSpread || false;
            return result;
        }
        /**
         * Returns the effective arguments for an expression that works like a function invocation.
         */
        function getEffectiveCallArguments(node) {
            if (node.kind === 194 /* TaggedTemplateExpression */) {
                var template = node.template;
                var args_3 = [createSyntheticExpression(template, getGlobalTemplateStringsArrayType())];
                if (template.kind === 207 /* TemplateExpression */) {
                    ts.forEach(template.templateSpans, function (span) {
                        args_3.push(span.expression);
                    });
                }
                return args_3;
            }
            if (node.kind === 153 /* Decorator */) {
                return getEffectiveDecoratorArguments(node);
            }
            if (ts.isJsxOpeningLikeElement(node)) {
                return node.attributes.properties.length > 0 || (ts.isJsxOpeningElement(node) && node.parent.children.length > 0) ? [node.attributes] : ts.emptyArray;
            }
            var args = node.arguments || ts.emptyArray;
            var length = args.length;
            if (length && isSpreadArgument(args[length - 1]) && getSpreadArgumentIndex(args) === length - 1) {
                // We have a spread argument in the last position and no other spread arguments. If the type
                // of the argument is a tuple type, spread the tuple elements into the argument list. We can
                // call checkExpressionCached because spread expressions never have a contextual type.
                var spreadArgument_1 = args[length - 1];
                var type = flowLoopCount ? checkExpression(spreadArgument_1.expression) : checkExpressionCached(spreadArgument_1.expression);
                if (isTupleType(type)) {
                    var typeArguments = type.typeArguments || ts.emptyArray;
                    var restIndex_2 = type.target.hasRestElement ? typeArguments.length - 1 : -1;
                    var syntheticArgs = ts.map(typeArguments, function (t, i) { return createSyntheticExpression(spreadArgument_1, t, /*isSpread*/ i === restIndex_2); });
                    return ts.concatenate(args.slice(0, length - 1), syntheticArgs);
                }
            }
            return args;
        }
        /**
         * Returns the synthetic argument list for a decorator invocation.
         */
        function getEffectiveDecoratorArguments(node) {
            var parent = node.parent;
            var expr = node.expression;
            switch (parent.kind) {
                case 241 /* ClassDeclaration */:
                case 210 /* ClassExpression */:
                    // For a class decorator, the `target` is the type of the class (e.g. the
                    // "static" or "constructor" side of the class).
                    return [
                        createSyntheticExpression(expr, getTypeOfSymbol(getSymbolOfNode(parent)))
                    ];
                case 152 /* Parameter */:
                    // A parameter declaration decorator will have three arguments (see
                    // `ParameterDecorator` in core.d.ts).
                    var func = parent.parent;
                    return [
                        createSyntheticExpression(expr, parent.parent.kind === 158 /* Constructor */ ? getTypeOfSymbol(getSymbolOfNode(func)) : errorType),
                        createSyntheticExpression(expr, anyType),
                        createSyntheticExpression(expr, numberType)
                    ];
                case 155 /* PropertyDeclaration */:
                case 157 /* MethodDeclaration */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    // A method or accessor declaration decorator will have two or three arguments (see
                    // `PropertyDecorator` and `MethodDecorator` in core.d.ts). If we are emitting decorators
                    // for ES3, we will only pass two arguments.
                    var hasPropDesc = parent.kind !== 155 /* PropertyDeclaration */ && languageVersion !== 0 /* ES3 */;
                    return [
                        createSyntheticExpression(expr, getParentTypeOfClassElement(parent)),
                        createSyntheticExpression(expr, getClassElementPropertyKeyType(parent)),
                        createSyntheticExpression(expr, hasPropDesc ? createTypedPropertyDescriptorType(getTypeOfNode(parent)) : anyType)
                    ];
            }
            return ts.Debug.fail();
        }
        /**
         * Returns the argument count for a decorator node that works like a function invocation.
         */
        function getDecoratorArgumentCount(node, signature) {
            switch (node.parent.kind) {
                case 241 /* ClassDeclaration */:
                case 210 /* ClassExpression */:
                    return 1;
                case 155 /* PropertyDeclaration */:
                    return 2;
                case 157 /* MethodDeclaration */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    // For ES3 or decorators with only two parameters we supply only two arguments
                    return languageVersion === 0 /* ES3 */ || signature.parameters.length <= 2 ? 2 : 3;
                case 152 /* Parameter */:
                    return 3;
                default:
                    return ts.Debug.fail();
            }
        }
        function getArgumentArityError(node, signatures, args) {
            var min = Number.POSITIVE_INFINITY;
            var max = Number.NEGATIVE_INFINITY;
            var belowArgCount = Number.NEGATIVE_INFINITY;
            var aboveArgCount = Number.POSITIVE_INFINITY;
            var argCount = args.length;
            var closestSignature;
            for (var _i = 0, signatures_4 = signatures; _i < signatures_4.length; _i++) {
                var sig = signatures_4[_i];
                var minCount = getMinArgumentCount(sig);
                var maxCount = getParameterCount(sig);
                if (minCount < argCount && minCount > belowArgCount)
                    belowArgCount = minCount;
                if (argCount < maxCount && maxCount < aboveArgCount)
                    aboveArgCount = maxCount;
                if (minCount < min) {
                    min = minCount;
                    closestSignature = sig;
                }
                max = Math.max(max, maxCount);
            }
            var hasRestParameter = ts.some(signatures, hasEffectiveRestParameter);
            var paramRange = hasRestParameter ? min :
                min < max ? min + "-" + max :
                    min;
            var hasSpreadArgument = getSpreadArgumentIndex(args) > -1;
            if (argCount <= max && hasSpreadArgument) {
                argCount--;
            }
            var spanArray;
            var related;
            var error = hasRestParameter || hasSpreadArgument ? hasRestParameter && hasSpreadArgument ? ts.Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more :
                hasRestParameter ? ts.Diagnostics.Expected_at_least_0_arguments_but_got_1 :
                    ts.Diagnostics.Expected_0_arguments_but_got_1_or_more : ts.Diagnostics.Expected_0_arguments_but_got_1;
            if (closestSignature && getMinArgumentCount(closestSignature) > argCount && closestSignature.declaration) {
                var paramDecl = closestSignature.declaration.parameters[closestSignature.thisParameter ? argCount + 1 : argCount];
                if (paramDecl) {
                    related = ts.createDiagnosticForNode(paramDecl, ts.isBindingPattern(paramDecl.name) ? ts.Diagnostics.An_argument_matching_this_binding_pattern_was_not_provided : ts.Diagnostics.An_argument_for_0_was_not_provided, !paramDecl.name ? argCount : !ts.isBindingPattern(paramDecl.name) ? ts.idText(getFirstIdentifier(paramDecl.name)) : undefined);
                }
            }
            if (min < argCount && argCount < max) {
                return ts.createDiagnosticForNode(node, ts.Diagnostics.No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments, argCount, belowArgCount, aboveArgCount);
            }
            if (!hasSpreadArgument && argCount < min) {
                var diagnostic_1 = ts.createDiagnosticForNode(node, error, paramRange, argCount);
                return related ? ts.addRelatedInfo(diagnostic_1, related) : diagnostic_1;
            }
            if (hasRestParameter || hasSpreadArgument) {
                spanArray = ts.createNodeArray(args);
                if (hasSpreadArgument && argCount) {
                    var nextArg = ts.elementAt(args, getSpreadArgumentIndex(args) + 1) || undefined;
                    spanArray = ts.createNodeArray(args.slice(max > argCount && nextArg ? args.indexOf(nextArg) : Math.min(max, args.length - 1)));
                }
            }
            else {
                spanArray = ts.createNodeArray(args.slice(max));
            }
            spanArray.pos = ts.first(spanArray).pos;
            spanArray.end = ts.last(spanArray).end;
            if (spanArray.end === spanArray.pos) {
                spanArray.end++;
            }
            var diagnostic = ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), spanArray, error, paramRange, argCount);
            return related ? ts.addRelatedInfo(diagnostic, related) : diagnostic;
        }
        function getTypeArgumentArityError(node, signatures, typeArguments) {
            var argCount = typeArguments.length;
            // No overloads exist
            if (signatures.length === 1) {
                var sig = signatures[0];
                var min_1 = getMinTypeArgumentCount(sig.typeParameters);
                var max = ts.length(sig.typeParameters);
                return ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), typeArguments, ts.Diagnostics.Expected_0_type_arguments_but_got_1, min_1 < max ? min_1 + "-" + max : min_1, argCount);
            }
            // Overloads exist
            var belowArgCount = -Infinity;
            var aboveArgCount = Infinity;
            for (var _i = 0, signatures_5 = signatures; _i < signatures_5.length; _i++) {
                var sig = signatures_5[_i];
                var min_2 = getMinTypeArgumentCount(sig.typeParameters);
                var max = ts.length(sig.typeParameters);
                if (min_2 > argCount) {
                    aboveArgCount = Math.min(aboveArgCount, min_2);
                }
                else if (max < argCount) {
                    belowArgCount = Math.max(belowArgCount, max);
                }
            }
            if (belowArgCount !== -Infinity && aboveArgCount !== Infinity) {
                return ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), typeArguments, ts.Diagnostics.No_overload_expects_0_type_arguments_but_overloads_do_exist_that_expect_either_1_or_2_type_arguments, argCount, belowArgCount, aboveArgCount);
            }
            return ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), typeArguments, ts.Diagnostics.Expected_0_type_arguments_but_got_1, belowArgCount === -Infinity ? aboveArgCount : belowArgCount, argCount);
        }
        function resolveCall(node, signatures, candidatesOutArray, checkMode, fallbackError) {
            var isTaggedTemplate = node.kind === 194 /* TaggedTemplateExpression */;
            var isDecorator = node.kind === 153 /* Decorator */;
            var isJsxOpeningOrSelfClosingElement = ts.isJsxOpeningLikeElement(node);
            var reportErrors = !candidatesOutArray;
            var typeArguments;
            if (!isDecorator) {
                typeArguments = node.typeArguments;
                // We already perform checking on the type arguments on the class declaration itself.
                if (isTaggedTemplate || isJsxOpeningOrSelfClosingElement || node.expression.kind !== 99 /* SuperKeyword */) {
                    ts.forEach(typeArguments, checkSourceElement);
                }
            }
            var candidates = candidatesOutArray || [];
            // reorderCandidates fills up the candidates array directly
            reorderCandidates(signatures, candidates);
            if (!candidates.length) {
                if (reportErrors) {
                    diagnostics.add(ts.createDiagnosticForNode(node, ts.Diagnostics.Call_target_does_not_contain_any_signatures));
                }
                return resolveErrorCall(node);
            }
            var args = getEffectiveCallArguments(node);
            // The excludeArgument array contains true for each context sensitive argument (an argument
            // is context sensitive it is susceptible to a one-time permanent contextual typing).
            //
            // The idea is that we will perform type argument inference & assignability checking once
            // without using the susceptible parameters that are functions, and once more for those
            // parameters, contextually typing each as we go along.
            //
            // For a tagged template, then the first argument be 'undefined' if necessary because it
            // represents a TemplateStringsArray.
            //
            // For a decorator, no arguments are susceptible to contextual typing due to the fact
            // decorators are applied to a declaration by the emitter, and not to an expression.
            var isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters;
            var argCheckMode = !isDecorator && !isSingleNonGenericCandidate && ts.some(args, isContextSensitive) ? 4 /* SkipContextSensitive */ : 0 /* Normal */;
            // The following variables are captured and modified by calls to chooseOverload.
            // If overload resolution or type argument inference fails, we want to report the
            // best error possible. The best error is one which says that an argument was not
            // assignable to a parameter. This implies that everything else about the overload
            // was fine. So if there is any overload that is only incorrect because of an
            // argument, we will report an error on that one.
            //
            //     function foo(s: string): void;
            //     function foo(n: number): void; // Report argument error on this overload
            //     function foo(): void;
            //     foo(true);
            //
            // If none of the overloads even made it that far, there are two possibilities.
            // There was a problem with type arguments for some overload, in which case
            // report an error on that. Or none of the overloads even had correct arity,
            // in which case give an arity error.
            //
            //     function foo<T extends string>(x: T): void; // Report type argument error
            //     function foo(): void;
            //     foo<number>(0);
            //
            var candidateForArgumentError;
            var candidateForArgumentArityError;
            var candidateForTypeArgumentError;
            var result;
            // If we are in signature help, a trailing comma indicates that we intend to provide another argument,
            // so we will only accept overloads with arity at least 1 higher than the current number of provided arguments.
            var signatureHelpTrailingComma = !!(checkMode & 16 /* IsForSignatureHelp */) && node.kind === 192 /* CallExpression */ && node.arguments.hasTrailingComma;
            // Section 4.12.1:
            // if the candidate list contains one or more signatures for which the type of each argument
            // expression is a subtype of each corresponding parameter type, the return type of the first
            // of those signatures becomes the return type of the function call.
            // Otherwise, the return type of the first signature in the candidate list becomes the return
            // type of the function call.
            //
            // Whether the call is an error is determined by assignability of the arguments. The subtype pass
            // is just important for choosing the best signature. So in the case where there is only one
            // signature, the subtype pass is useless. So skipping it is an optimization.
            if (candidates.length > 1) {
                result = chooseOverload(candidates, subtypeRelation, signatureHelpTrailingComma);
            }
            if (!result) {
                result = chooseOverload(candidates, assignableRelation, signatureHelpTrailingComma);
            }
            if (result) {
                return result;
            }
            // No signatures were applicable. Now report errors based on the last applicable signature with
            // no arguments excluded from assignability checks.
            // If candidate is undefined, it means that no candidates had a suitable arity. In that case,
            // skip the checkApplicableSignature check.
            if (reportErrors) {
                if (candidateForArgumentError) {
                    checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, 0 /* Normal */, /*reportErrors*/ true);
                }
                else if (candidateForArgumentArityError) {
                    diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args));
                }
                else if (candidateForTypeArgumentError) {
                    checkTypeArguments(candidateForTypeArgumentError, node.typeArguments, /*reportErrors*/ true, fallbackError);
                }
                else {
                    var signaturesWithCorrectTypeArgumentArity = ts.filter(signatures, function (s) { return hasCorrectTypeArgumentArity(s, typeArguments); });
                    if (signaturesWithCorrectTypeArgumentArity.length === 0) {
                        diagnostics.add(getTypeArgumentArityError(node, signatures, typeArguments));
                    }
                    else if (!isDecorator) {
                        diagnostics.add(getArgumentArityError(node, signaturesWithCorrectTypeArgumentArity, args));
                    }
                    else if (fallbackError) {
                        diagnostics.add(ts.createDiagnosticForNode(node, fallbackError));
                    }
                }
            }
            return produceDiagnostics || !args ? resolveErrorCall(node) : getCandidateForOverloadFailure(node, candidates, args, !!candidatesOutArray);
            function chooseOverload(candidates, relation, signatureHelpTrailingComma) {
                if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; }
                candidateForArgumentError = undefined;
                candidateForArgumentArityError = undefined;
                candidateForTypeArgumentError = undefined;
                if (isSingleNonGenericCandidate) {
                    var candidate = candidates[0];
                    if (typeArguments || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
                        return undefined;
                    }
                    if (!checkApplicableSignature(node, args, candidate, relation, 0 /* Normal */, /*reportErrors*/ false)) {
                        candidateForArgumentError = candidate;
                        return undefined;
                    }
                    return candidate;
                }
                for (var candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) {
                    var candidate = candidates[candidateIndex];
                    if (!hasCorrectTypeArgumentArity(candidate, typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
                        continue;
                    }
                    var checkCandidate = void 0;
                    var inferenceContext = void 0;
                    if (candidate.typeParameters) {
                        var typeArgumentTypes = void 0;
                        if (typeArguments) {
                            typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false);
                            if (!typeArgumentTypes) {
                                candidateForTypeArgumentError = candidate;
                                continue;
                            }
                        }
                        else {
                            inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ ts.isInJSFile(node) ? 2 /* AnyDefault */ : 0 /* None */);
                            typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | 8 /* SkipGenericFunctions */, inferenceContext);
                            argCheckMode |= inferenceContext.flags & 4 /* SkippedGenericFunction */ ? 8 /* SkipGenericFunctions */ : 0 /* Normal */;
                        }
                        checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, ts.isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
                        // If the original signature has a generic rest type, instantiation may produce a
                        // signature with different arity and we need to perform another arity check.
                        if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
                            candidateForArgumentArityError = checkCandidate;
                            continue;
                        }
                    }
                    else {
                        checkCandidate = candidate;
                    }
                    if (!checkApplicableSignature(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false)) {
                        // Give preference to error candidates that have no rest parameters (as they are more specific)
                        if (!candidateForArgumentError || getEffectiveRestType(candidateForArgumentError) || !getEffectiveRestType(checkCandidate)) {
                            candidateForArgumentError = checkCandidate;
                        }
                        continue;
                    }
                    if (argCheckMode) {
                        // If one or more context sensitive arguments were excluded, we start including
                        // them now (and keeping do so for any subsequent candidates) and perform a second
                        // round of type inference and applicability checking for this particular candidate.
                        argCheckMode = 0 /* Normal */;
                        if (inferenceContext) {
                            var typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext);
                            checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, ts.isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
                            // If the original signature has a generic rest type, instantiation may produce a
                            // signature with different arity and we need to perform another arity check.
                            if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
                                candidateForArgumentArityError = checkCandidate;
                                continue;
                            }
                        }
                        if (!checkApplicableSignature(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false)) {
                            // Give preference to error candidates that have no rest parameters (as they are more specific)
                            if (!candidateForArgumentError || getEffectiveRestType(candidateForArgumentError) || !getEffectiveRestType(checkCandidate)) {
                                candidateForArgumentError = checkCandidate;
                            }
                            continue;
                        }
                    }
                    candidates[candidateIndex] = checkCandidate;
                    return checkCandidate;
                }
                return undefined;
            }
        }
        // No signature was applicable. We have already reported the errors for the invalid signature.
        // If this is a type resolution session, e.g. Language Service, try to get better information than anySignature.
        function getCandidateForOverloadFailure(node, candidates, args, hasCandidatesOutArray) {
            ts.Debug.assert(candidates.length > 0); // Else should not have called this.
            // Normally we will combine overloads. Skip this if they have type parameters since that's hard to combine.
            // Don't do this if there is a `candidatesOutArray`,
            // because then we want the chosen best candidate to be one of the overloads, not a combination.
            return hasCandidatesOutArray || candidates.length === 1 || candidates.some(function (c) { return !!c.typeParameters; })
                ? pickLongestCandidateSignature(node, candidates, args)
                : createUnionOfSignaturesForOverloadFailure(candidates);
        }
        function createUnionOfSignaturesForOverloadFailure(candidates) {
            var thisParameters = ts.mapDefined(candidates, function (c) { return c.thisParameter; });
            var thisParameter;
            if (thisParameters.length) {
                thisParameter = createCombinedSymbolFromTypes(thisParameters, thisParameters.map(getTypeOfParameter));
            }
            var _a = ts.minAndMax(candidates, getNumNonRestParameters), minArgumentCount = _a.min, maxNonRestParam = _a.max;
            var parameters = [];
            var _loop_11 = function (i) {
                var symbols = ts.mapDefined(candidates, function (_a) {
                    var parameters = _a.parameters, hasRestParameter = _a.hasRestParameter;
                    return hasRestParameter ?
                        i < parameters.length - 1 ? parameters[i] : ts.last(parameters) :
                        i < parameters.length ? parameters[i] : undefined;
                });
                ts.Debug.assert(symbols.length !== 0);
                parameters.push(createCombinedSymbolFromTypes(symbols, ts.mapDefined(candidates, function (candidate) { return tryGetTypeAtPosition(candidate, i); })));
            };
            for (var i = 0; i < maxNonRestParam; i++) {
                _loop_11(i);
            }
            var restParameterSymbols = ts.mapDefined(candidates, function (c) { return c.hasRestParameter ? ts.last(c.parameters) : undefined; });
            var hasRestParameter = restParameterSymbols.length !== 0;
            if (hasRestParameter) {
                var type = createArrayType(getUnionType(ts.mapDefined(candidates, tryGetRestTypeOfSignature), 2 /* Subtype */));
                parameters.push(createCombinedSymbolForOverloadFailure(restParameterSymbols, type));
            }
            return createSignature(candidates[0].declaration, 
            /*typeParameters*/ undefined, // Before calling this we tested for `!candidates.some(c => !!c.typeParameters)`.
            thisParameter, parameters, 
            /*resolvedReturnType*/ getIntersectionType(candidates.map(getReturnTypeOfSignature)), 
            /*typePredicate*/ undefined, minArgumentCount, hasRestParameter, 
            /*hasLiteralTypes*/ candidates.some(function (c) { return c.hasLiteralTypes; }));
        }
        function getNumNonRestParameters(signature) {
            var numParams = signature.parameters.length;
            return signature.hasRestParameter ? numParams - 1 : numParams;
        }
        function createCombinedSymbolFromTypes(sources, types) {
            return createCombinedSymbolForOverloadFailure(sources, getUnionType(types, 2 /* Subtype */));
        }
        function createCombinedSymbolForOverloadFailure(sources, type) {
            // This function is currently only used for erroneous overloads, so it's good enough to just use the first source.
            return createSymbolWithType(ts.first(sources), type);
        }
        function pickLongestCandidateSignature(node, candidates, args) {
            // Pick the longest signature. This way we can get a contextual type for cases like:
            //     declare function f(a: { xa: number; xb: number; }, b: number);
            //     f({ |
            // Also, use explicitly-supplied type arguments if they are provided, so we can get a contextual signature in cases like:
            //     declare function f<T>(k: keyof T);
            //     f<Foo>("
            var bestIndex = getLongestCandidateIndex(candidates, apparentArgumentCount === undefined ? args.length : apparentArgumentCount);
            var candidate = candidates[bestIndex];
            var typeParameters = candidate.typeParameters;
            if (!typeParameters) {
                return candidate;
            }
            var typeArgumentNodes = callLikeExpressionMayHaveTypeArguments(node) ? node.typeArguments : undefined;
            var instantiated = typeArgumentNodes
                ? createSignatureInstantiation(candidate, getTypeArgumentsFromNodes(typeArgumentNodes, typeParameters, ts.isInJSFile(node)))
                : inferSignatureInstantiationForOverloadFailure(node, typeParameters, candidate, args);
            candidates[bestIndex] = instantiated;
            return instantiated;
        }
        function getTypeArgumentsFromNodes(typeArgumentNodes, typeParameters, isJs) {
            var typeArguments = typeArgumentNodes.map(getTypeOfNode);
            while (typeArguments.length > typeParameters.length) {
                typeArguments.pop();
            }
            while (typeArguments.length < typeParameters.length) {
                typeArguments.push(getConstraintOfTypeParameter(typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isJs));
            }
            return typeArguments;
        }
        function inferSignatureInstantiationForOverloadFailure(node, typeParameters, candidate, args) {
            var inferenceContext = createInferenceContext(typeParameters, candidate, /*flags*/ ts.isInJSFile(node) ? 2 /* AnyDefault */ : 0 /* None */);
            var typeArgumentTypes = inferTypeArguments(node, candidate, args, 4 /* SkipContextSensitive */ | 8 /* SkipGenericFunctions */, inferenceContext);
            return createSignatureInstantiation(candidate, typeArgumentTypes);
        }
        function getLongestCandidateIndex(candidates, argsCount) {
            var maxParamsIndex = -1;
            var maxParams = -1;
            for (var i = 0; i < candidates.length; i++) {
                var candidate = candidates[i];
                var paramCount = getParameterCount(candidate);
                if (hasEffectiveRestParameter(candidate) || paramCount >= argsCount) {
                    return i;
                }
                if (paramCount > maxParams) {
                    maxParams = paramCount;
                    maxParamsIndex = i;
                }
            }
            return maxParamsIndex;
        }
        function resolveCallExpression(node, candidatesOutArray, checkMode) {
            if (node.expression.kind === 99 /* SuperKeyword */) {
                var superType = checkSuperExpression(node.expression);
                if (isTypeAny(superType)) {
                    for (var _i = 0, _a = node.arguments; _i < _a.length; _i++) {
                        var arg = _a[_i];
                        checkExpression(arg); // Still visit arguments so they get marked for visibility, etc
                    }
                    return anySignature;
                }
                if (superType !== errorType) {
                    // In super call, the candidate signatures are the matching arity signatures of the base constructor function instantiated
                    // with the type arguments specified in the extends clause.
                    var baseTypeNode = ts.getEffectiveBaseTypeNode(ts.getContainingClass(node));
                    if (baseTypeNode) {
                        var baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments, baseTypeNode);
                        return resolveCall(node, baseConstructors, candidatesOutArray, checkMode);
                    }
                }
                return resolveUntypedCall(node);
            }
            var funcType = checkNonNullExpression(node.expression, ts.Diagnostics.Cannot_invoke_an_object_which_is_possibly_null, ts.Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined, ts.Diagnostics.Cannot_invoke_an_object_which_is_possibly_null_or_undefined);
            if (funcType === silentNeverType) {
                return silentNeverSignature;
            }
            var apparentType = getApparentType(funcType);
            if (apparentType === errorType) {
                // Another error has already been reported
                return resolveErrorCall(node);
            }
            // Technically, this signatures list may be incomplete. We are taking the apparent type,
            // but we are not including call signatures that may have been added to the Object or
            // Function interface, since they have none by default. This is a bit of a leap of faith
            // that the user will not add any.
            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
            var numConstructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */).length;
            // TS 1.0 Spec: 4.12
            // In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
            // types are provided for the argument expressions, and the result is always of type Any.
            if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, numConstructSignatures)) {
                // The unknownType indicates that an error already occurred (and was reported).  No
                // need to report another error in this case.
                if (funcType !== errorType && node.typeArguments) {
                    error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
                }
                return resolveUntypedCall(node);
            }
            // If FuncExpr's apparent type(section 3.8.1) is a function type, the call is a typed function call.
            // TypeScript employs overload resolution in typed function calls in order to support functions
            // with multiple call signatures.
            if (!callSignatures.length) {
                if (numConstructSignatures) {
                    error(node, ts.Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
                }
                else {
                    var relatedInformation = void 0;
                    if (node.arguments.length === 1) {
                        var text = ts.getSourceFileOfNode(node).text;
                        if (ts.isLineBreak(text.charCodeAt(ts.skipTrivia(text, node.expression.end, /* stopAfterLineBreak */ true) - 1))) {
                            relatedInformation = ts.createDiagnosticForNode(node.expression, ts.Diagnostics.It_is_highly_likely_that_you_are_missing_a_semicolon);
                        }
                    }
                    invocationError(node, apparentType, 0 /* Call */, relatedInformation);
                }
                return resolveErrorCall(node);
            }
            // When a call to a generic function is an argument to an outer call to a generic function for which
            // inference is in process, we have a choice to make. If the inner call relies on inferences made from
            // its contextual type to its return type, deferring the inner call processing allows the best possible
            // contextual type to accumulate. But if the outer call relies on inferences made from the return type of
            // the inner call, the inner call should be processed early. There's no sure way to know which choice is
            // right (only a full unification algorithm can determine that), so we resort to the following heuristic:
            // If no type arguments are specified in the inner call and at least one call signature is generic and
            // returns a function type, we choose to defer processing. This narrowly permits function composition
            // operators to flow inferences through return types, but otherwise processes calls right away. We
            // use the resolvingSignature singleton to indicate that we deferred processing. This result will be
            // propagated out and eventually turned into nonInferrableType (a type that is assignable to anything and
            // from which we never make inferences).
            if (checkMode & 8 /* SkipGenericFunctions */ && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) {
                skippedGenericFunction(node, checkMode);
                return resolvingSignature;
            }
            // If the function is explicitly marked with `@class`, then it must be constructed.
            if (callSignatures.some(function (sig) { return ts.isInJSFile(sig.declaration) && !!ts.getJSDocClassTag(sig.declaration); })) {
                error(node, ts.Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
                return resolveErrorCall(node);
            }
            return resolveCall(node, callSignatures, candidatesOutArray, checkMode);
        }
        function isGenericFunctionReturningFunction(signature) {
            return !!(signature.typeParameters && isFunctionType(getReturnTypeOfSignature(signature)));
        }
        /**
         * TS 1.0 spec: 4.12
         * If FuncExpr is of type Any, or of an object type that has no call or construct signatures
         * but is a subtype of the Function interface, the call is an untyped function call.
         */
        function isUntypedFunctionCall(funcType, apparentFuncType, numCallSignatures, numConstructSignatures) {
            // We exclude union types because we may have a union of function types that happen to have no common signatures.
            return isTypeAny(funcType) || isTypeAny(apparentFuncType) && !!(funcType.flags & 262144 /* TypeParameter */) ||
                !numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & (1048576 /* Union */ | 131072 /* Never */)) && isTypeAssignableTo(funcType, globalFunctionType);
        }
        function resolveNewExpression(node, candidatesOutArray, checkMode) {
            if (node.arguments && languageVersion < 1 /* ES5 */) {
                var spreadIndex = getSpreadArgumentIndex(node.arguments);
                if (spreadIndex >= 0) {
                    error(node.arguments[spreadIndex], ts.Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher);
                }
            }
            var expressionType = checkNonNullExpression(node.expression);
            if (expressionType === silentNeverType) {
                return silentNeverSignature;
            }
            // If expressionType's apparent type(section 3.8.1) is an object type with one or
            // more construct signatures, the expression is processed in the same manner as a
            // function call, but using the construct signatures as the initial set of candidate
            // signatures for overload resolution. The result type of the function call becomes
            // the result type of the operation.
            expressionType = getApparentType(expressionType);
            if (expressionType === errorType) {
                // Another error has already been reported
                return resolveErrorCall(node);
            }
            // TS 1.0 spec: 4.11
            // If expressionType is of type Any, Args can be any argument
            // list and the result of the operation is of type Any.
            if (isTypeAny(expressionType)) {
                if (node.typeArguments) {
                    error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
                }
                return resolveUntypedCall(node);
            }
            // Technically, this signatures list may be incomplete. We are taking the apparent type,
            // but we are not including construct signatures that may have been added to the Object or
            // Function interface, since they have none by default. This is a bit of a leap of faith
            // that the user will not add any.
            var constructSignatures = getSignaturesOfType(expressionType, 1 /* Construct */);
            if (constructSignatures.length) {
                if (!isConstructorAccessible(node, constructSignatures[0])) {
                    return resolveErrorCall(node);
                }
                // If the expression is a class of abstract type, then it cannot be instantiated.
                // Note, only class declarations can be declared abstract.
                // In the case of a merged class-module or class-interface declaration,
                // only the class declaration node will have the Abstract flag set.
                var valueDecl = expressionType.symbol && ts.getClassLikeDeclarationOfSymbol(expressionType.symbol);
                if (valueDecl && ts.hasModifier(valueDecl, 128 /* Abstract */)) {
                    error(node, ts.Diagnostics.Cannot_create_an_instance_of_an_abstract_class);
                    return resolveErrorCall(node);
                }
                return resolveCall(node, constructSignatures, candidatesOutArray, checkMode);
            }
            // If expressionType's apparent type is an object type with no construct signatures but
            // one or more call signatures, the expression is processed as a function call. A compile-time
            // error occurs if the result of the function call is not Void. The type of the result of the
            // operation is Any. It is an error to have a Void this type.
            var callSignatures = getSignaturesOfType(expressionType, 0 /* Call */);
            if (callSignatures.length) {
                var signature = resolveCall(node, callSignatures, candidatesOutArray, checkMode);
                if (!noImplicitAny) {
                    if (signature.declaration && !isJSConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) {
                        error(node, ts.Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword);
                    }
                    if (getThisTypeOfSignature(signature) === voidType) {
                        error(node, ts.Diagnostics.A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void);
                    }
                }
                return signature;
            }
            invocationError(node, expressionType, 1 /* Construct */);
            return resolveErrorCall(node);
        }
        function typeHasProtectedAccessibleBase(target, type) {
            var baseTypes = getBaseTypes(type);
            if (!ts.length(baseTypes)) {
                return false;
            }
            var firstBase = baseTypes[0];
            if (firstBase.flags & 2097152 /* Intersection */) {
                var types = firstBase.types;
                var mixinFlags = findMixins(types);
                var i = 0;
                for (var _i = 0, _a = firstBase.types; _i < _a.length; _i++) {
                    var intersectionMember = _a[_i];
                    // We want to ignore mixin ctors
                    if (!mixinFlags[i]) {
                        if (ts.getObjectFlags(intersectionMember) & (1 /* Class */ | 2 /* Interface */)) {
                            if (intersectionMember.symbol === target) {
                                return true;
                            }
                            if (typeHasProtectedAccessibleBase(target, intersectionMember)) {
                                return true;
                            }
                        }
                    }
                    i++;
                }
                return false;
            }
            if (firstBase.symbol === target) {
                return true;
            }
            return typeHasProtectedAccessibleBase(target, firstBase);
        }
        function isConstructorAccessible(node, signature) {
            if (!signature || !signature.declaration) {
                return true;
            }
            var declaration = signature.declaration;
            var modifiers = ts.getSelectedModifierFlags(declaration, 24 /* NonPublicAccessibilityModifier */);
            // Public constructor is accessible.
            if (!modifiers) {
                return true;
            }
            var declaringClassDeclaration = ts.getClassLikeDeclarationOfSymbol(declaration.parent.symbol);
            var declaringClass = getDeclaredTypeOfSymbol(declaration.parent.symbol);
            // A private or protected constructor can only be instantiated within its own class (or a subclass, for protected)
            if (!isNodeWithinClass(node, declaringClassDeclaration)) {
                var containingClass = ts.getContainingClass(node);
                if (containingClass && modifiers & 16 /* Protected */) {
                    var containingType = getTypeOfNode(containingClass);
                    if (typeHasProtectedAccessibleBase(declaration.parent.symbol, containingType)) {
                        return true;
                    }
                }
                if (modifiers & 8 /* Private */) {
                    error(node, ts.Diagnostics.Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration, typeToString(declaringClass));
                }
                if (modifiers & 16 /* Protected */) {
                    error(node, ts.Diagnostics.Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration, typeToString(declaringClass));
                }
                return false;
            }
            return true;
        }
        function invocationError(node, apparentType, kind, relatedInformation) {
            var diagnostic = error(node, (kind === 0 /* Call */ ?
                ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures :
                ts.Diagnostics.Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature), typeToString(apparentType));
            invocationErrorRecovery(apparentType, kind, relatedInformation ? ts.addRelatedInfo(diagnostic, relatedInformation) : diagnostic);
        }
        function invocationErrorRecovery(apparentType, kind, diagnostic) {
            if (!apparentType.symbol) {
                return;
            }
            var importNode = getSymbolLinks(apparentType.symbol).originatingImport;
            // Create a diagnostic on the originating import if possible onto which we can attach a quickfix
            //  An import call expression cannot be rewritten into another form to correct the error - the only solution is to use `.default` at the use-site
            if (importNode && !ts.isImportCall(importNode)) {
                var sigs = getSignaturesOfType(getTypeOfSymbol(getSymbolLinks(apparentType.symbol).target), kind);
                if (!sigs || !sigs.length)
                    return;
                ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(importNode, ts.Diagnostics.Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead));
            }
        }
        function resolveTaggedTemplateExpression(node, candidatesOutArray, checkMode) {
            var tagType = checkExpression(node.tag);
            var apparentType = getApparentType(tagType);
            if (apparentType === errorType) {
                // Another error has already been reported
                return resolveErrorCall(node);
            }
            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
            var numConstructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */).length;
            if (isUntypedFunctionCall(tagType, apparentType, callSignatures.length, numConstructSignatures)) {
                return resolveUntypedCall(node);
            }
            if (!callSignatures.length) {
                invocationError(node, apparentType, 0 /* Call */);
                return resolveErrorCall(node);
            }
            return resolveCall(node, callSignatures, candidatesOutArray, checkMode);
        }
        /**
         * Gets the localized diagnostic head message to use for errors when resolving a decorator as a call expression.
         */
        function getDiagnosticHeadMessageForDecoratorResolution(node) {
            switch (node.parent.kind) {
                case 241 /* ClassDeclaration */:
                case 210 /* ClassExpression */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression;
                case 152 /* Parameter */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression;
                case 155 /* PropertyDeclaration */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression;
                case 157 /* MethodDeclaration */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression;
                default:
                    return ts.Debug.fail();
            }
        }
        /**
         * Resolves a decorator as if it were a call expression.
         */
        function resolveDecorator(node, candidatesOutArray, checkMode) {
            var funcType = checkExpression(node.expression);
            var apparentType = getApparentType(funcType);
            if (apparentType === errorType) {
                return resolveErrorCall(node);
            }
            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
            var numConstructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */).length;
            if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, numConstructSignatures)) {
                return resolveUntypedCall(node);
            }
            if (isPotentiallyUncalledDecorator(node, callSignatures)) {
                var nodeStr = ts.getTextOfNode(node.expression, /*includeTrivia*/ false);
                error(node, ts.Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0, nodeStr);
                return resolveErrorCall(node);
            }
            var headMessage = getDiagnosticHeadMessageForDecoratorResolution(node);
            if (!callSignatures.length) {
                var errorInfo = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType));
                errorInfo = ts.chainDiagnosticMessages(errorInfo, headMessage);
                var diag = ts.createDiagnosticForNodeFromMessageChain(node, errorInfo);
                diagnostics.add(diag);
                invocationErrorRecovery(apparentType, 0 /* Call */, diag);
                return resolveErrorCall(node);
            }
            return resolveCall(node, callSignatures, candidatesOutArray, checkMode, headMessage);
        }
        function createSignatureForJSXIntrinsic(node, result) {
            var namespace = getJsxNamespaceAt(node);
            var exports = namespace && getExportsOfSymbol(namespace);
            // We fake up a SFC signature for each intrinsic, however a more specific per-element signature drawn from the JSX declaration
            // file would probably be preferable.
            var typeSymbol = exports && getSymbol(exports, JsxNames.Element, 67897832 /* Type */);
            var returnNode = typeSymbol && nodeBuilder.symbolToEntityName(typeSymbol, 67897832 /* Type */, node);
            var declaration = ts.createFunctionTypeNode(/*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotdotdot*/ undefined, "props", /*questionMark*/ undefined, nodeBuilder.typeToTypeNode(result, node))], returnNode ? ts.createTypeReferenceNode(returnNode, /*typeArguments*/ undefined) : ts.createKeywordTypeNode(121 /* AnyKeyword */));
            var parameterSymbol = createSymbol(1 /* FunctionScopedVariable */, "props");
            parameterSymbol.type = result;
            return createSignature(declaration, 
            /*typeParameters*/ undefined, 
            /*thisParameter*/ undefined, [parameterSymbol], typeSymbol ? getDeclaredTypeOfSymbol(typeSymbol) : errorType, 
            /*returnTypePredicate*/ undefined, 1, 
            /*hasRestparameter*/ false, 
            /*hasLiteralTypes*/ false);
        }
        function resolveJsxOpeningLikeElement(node, candidatesOutArray, checkMode) {
            if (isJsxIntrinsicIdentifier(node.tagName)) {
                var result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
                var fakeSignature = createSignatureForJSXIntrinsic(node, result);
                checkTypeAssignableToAndOptionallyElaborate(checkExpressionWithContextualType(node.attributes, getEffectiveFirstArgumentForJsxSignature(fakeSignature, node), /*mapper*/ undefined, 0 /* Normal */), result, node.tagName, node.attributes);
                return fakeSignature;
            }
            var exprTypes = checkExpression(node.tagName);
            var apparentType = getApparentType(exprTypes);
            if (apparentType === errorType) {
                return resolveErrorCall(node);
            }
            var signatures = getUninstantiatedJsxSignaturesOfType(exprTypes, node);
            if (isUntypedFunctionCall(exprTypes, apparentType, signatures.length, /*constructSignatures*/ 0)) {
                return resolveUntypedCall(node);
            }
            if (signatures.length === 0) {
                // We found no signatures at all, which is an error
                error(node.tagName, ts.Diagnostics.JSX_element_type_0_does_not_have_any_construct_or_call_signatures, ts.getTextOfNode(node.tagName));
                return resolveErrorCall(node);
            }
            return resolveCall(node, signatures, candidatesOutArray, checkMode);
        }
        /**
         * Sometimes, we have a decorator that could accept zero arguments,
         * but is receiving too many arguments as part of the decorator invocation.
         * In those cases, a user may have meant to *call* the expression before using it as a decorator.
         */
        function isPotentiallyUncalledDecorator(decorator, signatures) {
            return signatures.length && ts.every(signatures, function (signature) {
                return signature.minArgumentCount === 0 &&
                    !signature.hasRestParameter &&
                    signature.parameters.length < getDecoratorArgumentCount(decorator, signature);
            });
        }
        function resolveSignature(node, candidatesOutArray, checkMode) {
            switch (node.kind) {
                case 192 /* CallExpression */:
                    return resolveCallExpression(node, candidatesOutArray, checkMode);
                case 193 /* NewExpression */:
                    return resolveNewExpression(node, candidatesOutArray, checkMode);
                case 194 /* TaggedTemplateExpression */:
                    return resolveTaggedTemplateExpression(node, candidatesOutArray, checkMode);
                case 153 /* Decorator */:
                    return resolveDecorator(node, candidatesOutArray, checkMode);
                case 263 /* JsxOpeningElement */:
                case 262 /* JsxSelfClosingElement */:
                    return resolveJsxOpeningLikeElement(node, candidatesOutArray, checkMode);
            }
            throw ts.Debug.assertNever(node, "Branch in 'resolveSignature' should be unreachable.");
        }
        /**
         * Resolve a signature of a given call-like expression.
         * @param node a call-like expression to try resolve a signature for
         * @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service;
         *                           the function will fill it up with appropriate candidate signatures
         * @return a signature of the call-like expression or undefined if one can't be found
         */
        function getResolvedSignature(node, candidatesOutArray, checkMode) {
            var links = getNodeLinks(node);
            // If getResolvedSignature has already been called, we will have cached the resolvedSignature.
            // However, it is possible that either candidatesOutArray was not passed in the first time,
            // or that a different candidatesOutArray was passed in. Therefore, we need to redo the work
            // to correctly fill the candidatesOutArray.
            var cached = links.resolvedSignature;
            if (cached && cached !== resolvingSignature && !candidatesOutArray) {
                return cached;
            }
            links.resolvedSignature = resolvingSignature;
            var result = resolveSignature(node, candidatesOutArray, checkMode || 0 /* Normal */);
            // When CheckMode.SkipGenericFunctions is set we use resolvingSignature to indicate that call
            // resolution should be deferred.
            if (result !== resolvingSignature) {
                // If signature resolution originated in control flow type analysis (for example to compute the
                // assigned type in a flow assignment) we don't cache the result as it may be based on temporary
                // types from the control flow analysis.
                links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached;
            }
            return result;
        }
        /**
         * Indicates whether a declaration can be treated as a constructor in a JavaScript
         * file.
         */
        function isJSConstructor(node) {
            if (!node || !ts.isInJSFile(node)) {
                return false;
            }
            var func = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) ? node :
                ts.isVariableDeclaration(node) && node.initializer && ts.isFunctionExpression(node.initializer) ? node.initializer :
                    undefined;
            if (func) {
                // If the node has a @class tag, treat it like a constructor.
                if (ts.getJSDocClassTag(node))
                    return true;
                // If the symbol of the node has members, treat it like a constructor.
                var symbol = getSymbolOfNode(func);
                return !!symbol && (symbol.members !== undefined || symbol.exports !== undefined && symbol.exports.get("prototype") !== undefined);
            }
            return false;
        }
        function isJSConstructorType(type) {
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                return resolved.callSignatures.length === 1 && isJSConstructor(resolved.callSignatures[0].declaration);
            }
            return false;
        }
        function getJSClassType(symbol) {
            var inferred;
            if (isJSConstructor(symbol.valueDeclaration)) {
                inferred = getInferredClassType(symbol);
            }
            var assigned = getAssignedClassType(symbol);
            return assigned && inferred ?
                getIntersectionType([inferred, assigned]) :
                assigned || inferred;
        }
        function getAssignedClassType(symbol) {
            var decl = symbol.valueDeclaration;
            var assignmentSymbol = decl && decl.parent &&
                (ts.isFunctionDeclaration(decl) && getSymbolOfNode(decl) ||
                    ts.isBinaryExpression(decl.parent) && getSymbolOfNode(decl.parent.left) ||
                    ts.isVariableDeclaration(decl.parent) && getSymbolOfNode(decl.parent));
            var prototype = assignmentSymbol && assignmentSymbol.exports && assignmentSymbol.exports.get("prototype");
            var init = prototype && prototype.valueDeclaration && getAssignedJSPrototype(prototype.valueDeclaration);
            return init ? checkExpression(init) : undefined;
        }
        function getAssignedJSPrototype(node) {
            if (!node.parent) {
                return false;
            }
            var parent = node.parent;
            while (parent && parent.kind === 190 /* PropertyAccessExpression */) {
                parent = parent.parent;
            }
            if (parent && ts.isBinaryExpression(parent) && ts.isPrototypeAccess(parent.left) && parent.operatorToken.kind === 60 /* EqualsToken */) {
                var right = ts.getInitializerOfBinaryExpression(parent);
                return ts.isObjectLiteralExpression(right) && right;
            }
        }
        function getInferredClassType(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.inferredClassType) {
                links.inferredClassType = createAnonymousType(symbol, getMembersOfSymbol(symbol) || emptySymbols, ts.emptyArray, ts.emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined);
            }
            return links.inferredClassType;
        }
        /**
         * Syntactically and semantically checks a call or new expression.
         * @param node The call/new expression to be checked.
         * @returns On success, the expression's signature's return type. On failure, anyType.
         */
        function checkCallExpression(node, checkMode) {
            if (!checkGrammarTypeArguments(node, node.typeArguments))
                checkGrammarArguments(node.arguments);
            var signature = getResolvedSignature(node, /*candidatesOutArray*/ undefined, checkMode);
            if (signature === resolvingSignature) {
                // CheckMode.SkipGenericFunctions is enabled and this is a call to a generic function that
                // returns a function type. We defer checking and return nonInferrableType.
                return nonInferrableType;
            }
            if (node.expression.kind === 99 /* SuperKeyword */) {
                return voidType;
            }
            if (node.kind === 193 /* NewExpression */) {
                var declaration = signature.declaration;
                if (declaration &&
                    declaration.kind !== 158 /* Constructor */ &&
                    declaration.kind !== 162 /* ConstructSignature */ &&
                    declaration.kind !== 167 /* ConstructorType */ &&
                    !ts.isJSDocConstructSignature(declaration) &&
                    !isJSConstructor(declaration)) {
                    // When resolved signature is a call signature (and not a construct signature) the result type is any
                    if (noImplicitAny) {
                        error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
                    }
                    return anyType;
                }
            }
            // In JavaScript files, calls to any identifier 'require' are treated as external module imports
            if (ts.isInJSFile(node) && isCommonJsRequire(node)) {
                return resolveExternalModuleTypeByLiteral(node.arguments[0]);
            }
            var returnType = getReturnTypeOfSignature(signature);
            // Treat any call to the global 'Symbol' function that is part of a const variable or readonly property
            // as a fresh unique symbol literal type.
            if (returnType.flags & 12288 /* ESSymbolLike */ && isSymbolOrSymbolForCall(node)) {
                return getESSymbolLikeTypeForNode(ts.walkUpParenthesizedExpressions(node.parent));
            }
            var jsAssignmentType;
            if (ts.isInJSFile(node)) {
                var decl = ts.getDeclarationOfExpando(node);
                if (decl) {
                    var jsSymbol = getSymbolOfNode(decl);
                    if (jsSymbol && ts.hasEntries(jsSymbol.exports)) {
                        jsAssignmentType = createAnonymousType(jsSymbol, jsSymbol.exports, ts.emptyArray, ts.emptyArray, undefined, undefined);
                        jsAssignmentType.objectFlags |= 16384 /* JSLiteral */;
                    }
                }
            }
            return jsAssignmentType ? getIntersectionType([returnType, jsAssignmentType]) : returnType;
        }
        function isSymbolOrSymbolForCall(node) {
            if (!ts.isCallExpression(node))
                return false;
            var left = node.expression;
            if (ts.isPropertyAccessExpression(left) && left.name.escapedText === "for") {
                left = left.expression;
            }
            if (!ts.isIdentifier(left) || left.escapedText !== "Symbol") {
                return false;
            }
            // make sure `Symbol` is the global symbol
            var globalESSymbol = getGlobalESSymbolConstructorSymbol(/*reportErrors*/ false);
            if (!globalESSymbol) {
                return false;
            }
            return globalESSymbol === resolveName(left, "Symbol", 67220415 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
        }
        function checkImportCallExpression(node) {
            // Check grammar of dynamic import
            if (!checkGrammarArguments(node.arguments))
                checkGrammarImportCallExpression(node);
            if (node.arguments.length === 0) {
                return createPromiseReturnType(node, anyType);
            }
            var specifier = node.arguments[0];
            var specifierType = checkExpressionCached(specifier);
            // Even though multiple arguments is grammatically incorrect, type-check extra arguments for completion
            for (var i = 1; i < node.arguments.length; ++i) {
                checkExpressionCached(node.arguments[i]);
            }
            if (specifierType.flags & 32768 /* Undefined */ || specifierType.flags & 65536 /* Null */ || !isTypeAssignableTo(specifierType, stringType)) {
                error(specifier, ts.Diagnostics.Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0, typeToString(specifierType));
            }
            // resolveExternalModuleName will return undefined if the moduleReferenceExpression is not a string literal
            var moduleSymbol = resolveExternalModuleName(node, specifier);
            if (moduleSymbol) {
                var esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true);
                if (esModuleSymbol) {
                    return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol));
                }
            }
            return createPromiseReturnType(node, anyType);
        }
        function getTypeWithSyntheticDefaultImportType(type, symbol, originalSymbol) {
            if (allowSyntheticDefaultImports && type && type !== errorType) {
                var synthType = type;
                if (!synthType.syntheticType) {
                    var file = ts.find(originalSymbol.declarations, ts.isSourceFile);
                    var hasSyntheticDefault = canHaveSyntheticDefault(file, originalSymbol, /*dontResolveAlias*/ false);
                    if (hasSyntheticDefault) {
                        var memberTable = ts.createSymbolTable();
                        var newSymbol = createSymbol(2097152 /* Alias */, "default" /* Default */);
                        newSymbol.nameType = getLiteralType("default");
                        newSymbol.target = resolveSymbol(symbol);
                        memberTable.set("default" /* Default */, newSymbol);
                        var anonymousSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */);
                        var defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
                        anonymousSymbol.type = defaultContainingObject;
                        synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*objectFlags*/ 0, /*readonly*/ false) : defaultContainingObject;
                    }
                    else {
                        synthType.syntheticType = type;
                    }
                }
                return synthType.syntheticType;
            }
            return type;
        }
        function isCommonJsRequire(node) {
            if (!ts.isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) {
                return false;
            }
            // Make sure require is not a local function
            if (!ts.isIdentifier(node.expression))
                return ts.Debug.fail();
            var resolvedRequire = resolveName(node.expression, node.expression.escapedText, 67220415 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); // TODO: GH#18217
            if (resolvedRequire === requireSymbol) {
                return true;
            }
            // project includes symbol named 'require' - make sure that it is ambient and local non-alias
            if (resolvedRequire.flags & 2097152 /* Alias */) {
                return false;
            }
            var targetDeclarationKind = resolvedRequire.flags & 16 /* Function */
                ? 240 /* FunctionDeclaration */
                : resolvedRequire.flags & 3 /* Variable */
                    ? 238 /* VariableDeclaration */
                    : 0 /* Unknown */;
            if (targetDeclarationKind !== 0 /* Unknown */) {
                var decl = ts.getDeclarationOfKind(resolvedRequire, targetDeclarationKind);
                // function/variable declaration should be ambient
                return !!decl && !!(decl.flags & 4194304 /* Ambient */);
            }
            return false;
        }
        function checkTaggedTemplateExpression(node) {
            checkGrammarTypeArguments(node, node.typeArguments);
            if (languageVersion < 2 /* ES2015 */) {
                checkExternalEmitHelpers(node, 65536 /* MakeTemplateObject */);
            }
            return getReturnTypeOfSignature(getResolvedSignature(node));
        }
        function checkAssertion(node) {
            return checkAssertionWorker(node, node.type, node.expression);
        }
        function isValidConstAssertionArgument(node) {
            switch (node.kind) {
                case 10 /* StringLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 103 /* TrueKeyword */:
                case 88 /* FalseKeyword */:
                case 188 /* ArrayLiteralExpression */:
                case 189 /* ObjectLiteralExpression */:
                    return true;
                case 196 /* ParenthesizedExpression */:
                    return isValidConstAssertionArgument(node.expression);
                case 203 /* PrefixUnaryExpression */:
                    var op = node.operator;
                    var arg = node.operand;
                    return op === 39 /* MinusToken */ && (arg.kind === 8 /* NumericLiteral */ || arg.kind === 9 /* BigIntLiteral */) ||
                        op === 38 /* PlusToken */ && arg.kind === 8 /* NumericLiteral */;
                case 190 /* PropertyAccessExpression */:
                case 191 /* ElementAccessExpression */:
                    var expr = node.expression;
                    if (ts.isIdentifier(expr)) {
                        var symbol = getSymbolAtLocation(expr);
                        return !!(symbol && (symbol.flags & 384 /* Enum */) && getEnumKind(symbol) === 1 /* Literal */);
                    }
            }
            return false;
        }
        function checkAssertionWorker(errNode, type, expression, checkMode) {
            var exprType = checkExpression(expression, checkMode);
            if (ts.isConstTypeReference(type)) {
                if (!isValidConstAssertionArgument(expression)) {
                    error(expression, ts.Diagnostics.A_const_assertions_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array_or_object_literals);
                }
                return getRegularTypeOfLiteralType(exprType);
            }
            checkSourceElement(type);
            exprType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(exprType));
            var targetType = getTypeFromTypeNode(type);
            if (produceDiagnostics && targetType !== errorType) {
                var widenedType = getWidenedType(exprType);
                if (!isTypeComparableTo(targetType, widenedType)) {
                    checkTypeComparableTo(exprType, targetType, errNode, ts.Diagnostics.Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the_other_If_this_was_intentional_convert_the_expression_to_unknown_first);
                }
            }
            return targetType;
        }
        function checkNonNullAssertion(node) {
            return getNonNullableType(checkExpression(node.expression));
        }
        function checkMetaProperty(node) {
            checkGrammarMetaProperty(node);
            if (node.keywordToken === 96 /* NewKeyword */) {
                return checkNewTargetMetaProperty(node);
            }
            if (node.keywordToken === 93 /* ImportKeyword */) {
                return checkImportMetaProperty(node);
            }
            return ts.Debug.assertNever(node.keywordToken);
        }
        function checkNewTargetMetaProperty(node) {
            var container = ts.getNewTargetContainer(node);
            if (!container) {
                error(node, ts.Diagnostics.Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor, "new.target");
                return errorType;
            }
            else if (container.kind === 158 /* Constructor */) {
                var symbol = getSymbolOfNode(container.parent);
                return getTypeOfSymbol(symbol);
            }
            else {
                var symbol = getSymbolOfNode(container);
                return getTypeOfSymbol(symbol);
            }
        }
        function checkImportMetaProperty(node) {
            if (languageVersion < 8 /* ESNext */ || moduleKind < ts.ModuleKind.ESNext) {
                error(node, ts.Diagnostics.The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_options);
            }
            var file = ts.getSourceFileOfNode(node);
            ts.Debug.assert(!!(file.flags & 1048576 /* PossiblyContainsImportMeta */), "Containing file is missing import meta node flag.");
            ts.Debug.assert(!!file.externalModuleIndicator, "Containing file should be a module.");
            return node.name.escapedText === "meta" ? getGlobalImportMetaType() : errorType;
        }
        function getTypeOfParameter(symbol) {
            var type = getTypeOfSymbol(symbol);
            if (strictNullChecks) {
                var declaration = symbol.valueDeclaration;
                if (declaration && ts.hasInitializer(declaration)) {
                    return getOptionalType(type);
                }
            }
            return type;
        }
        function getParameterNameAtPosition(signature, pos) {
            var paramCount = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
            if (pos < paramCount) {
                return signature.parameters[pos].escapedName;
            }
            var restParameter = signature.parameters[paramCount] || unknownSymbol;
            var restType = getTypeOfSymbol(restParameter);
            if (isTupleType(restType)) {
                var associatedNames = restType.target.associatedNames;
                var index = pos - paramCount;
                return associatedNames && associatedNames[index] || restParameter.escapedName + "_" + index;
            }
            return restParameter.escapedName;
        }
        function getTypeAtPosition(signature, pos) {
            return tryGetTypeAtPosition(signature, pos) || anyType;
        }
        function tryGetTypeAtPosition(signature, pos) {
            var paramCount = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
            if (pos < paramCount) {
                return getTypeOfParameter(signature.parameters[pos]);
            }
            if (signature.hasRestParameter) {
                // We want to return the value undefined for an out of bounds parameter position,
                // so we need to check bounds here before calling getIndexedAccessType (which
                // otherwise would return the type 'undefined').
                var restType = getTypeOfSymbol(signature.parameters[paramCount]);
                var index = pos - paramCount;
                if (!isTupleType(restType) || restType.target.hasRestElement || index < (restType.typeArguments || ts.emptyArray).length) {
                    return getIndexedAccessType(restType, getLiteralType(index));
                }
            }
            return undefined;
        }
        function getRestTypeAtPosition(source, pos) {
            var paramCount = getParameterCount(source);
            var restType = getEffectiveRestType(source);
            var nonRestCount = paramCount - (restType ? 1 : 0);
            if (restType && pos === nonRestCount) {
                return restType;
            }
            var types = [];
            var names = [];
            for (var i = pos; i < nonRestCount; i++) {
                types.push(getTypeAtPosition(source, i));
                names.push(getParameterNameAtPosition(source, i));
            }
            if (restType) {
                types.push(getIndexedAccessType(restType, numberType));
                names.push(getParameterNameAtPosition(source, nonRestCount));
            }
            var minArgumentCount = getMinArgumentCount(source);
            var minLength = minArgumentCount < pos ? 0 : minArgumentCount - pos;
            return createTupleType(types, minLength, !!restType, /*readonly*/ false, names);
        }
        function getParameterCount(signature) {
            var length = signature.parameters.length;
            if (signature.hasRestParameter) {
                var restType = getTypeOfSymbol(signature.parameters[length - 1]);
                if (isTupleType(restType)) {
                    return length + (restType.typeArguments || ts.emptyArray).length - 1;
                }
            }
            return length;
        }
        function getMinArgumentCount(signature) {
            if (signature.hasRestParameter) {
                var restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
                if (isTupleType(restType)) {
                    var minLength = restType.target.minLength;
                    if (minLength > 0) {
                        return signature.parameters.length - 1 + minLength;
                    }
                }
            }
            return signature.minArgumentCount;
        }
        function hasEffectiveRestParameter(signature) {
            if (signature.hasRestParameter) {
                var restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
                return !isTupleType(restType) || restType.target.hasRestElement;
            }
            return false;
        }
        function getEffectiveRestType(signature) {
            if (signature.hasRestParameter) {
                var restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
                return isTupleType(restType) ? getRestArrayTypeOfTupleType(restType) : restType;
            }
            return undefined;
        }
        function getNonArrayRestType(signature) {
            var restType = getEffectiveRestType(signature);
            return restType && !isArrayType(restType) && !isTypeAny(restType) ? restType : undefined;
        }
        function getTypeOfFirstParameterOfSignature(signature) {
            return getTypeOfFirstParameterOfSignatureWithFallback(signature, neverType);
        }
        function getTypeOfFirstParameterOfSignatureWithFallback(signature, fallbackType) {
            return signature.parameters.length > 0 ? getTypeAtPosition(signature, 0) : fallbackType;
        }
        function inferFromAnnotatedParameters(signature, context, inferenceContext) {
            var len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
            for (var i = 0; i < len; i++) {
                var declaration = signature.parameters[i].valueDeclaration;
                if (declaration.type) {
                    var typeNode = ts.getEffectiveTypeAnnotationNode(declaration);
                    if (typeNode) {
                        inferTypes(inferenceContext.inferences, getTypeFromTypeNode(typeNode), getTypeAtPosition(context, i));
                    }
                }
            }
            var restType = getEffectiveRestType(context);
            if (restType && restType.flags & 262144 /* TypeParameter */) {
                // The contextual signature has a generic rest parameter. We first instantiate the contextual
                // signature (without fixing type parameters) and assign types to contextually typed parameters.
                var instantiatedContext = instantiateSignature(context, inferenceContext.nonFixingMapper);
                assignContextualParameterTypes(signature, instantiatedContext);
                // We then infer from a tuple type representing the parameters that correspond to the contextual
                // rest parameter.
                var restPos = getParameterCount(context) - 1;
                inferTypes(inferenceContext.inferences, getRestTypeAtPosition(signature, restPos), restType);
            }
        }
        function assignContextualParameterTypes(signature, context) {
            signature.typeParameters = context.typeParameters;
            if (context.thisParameter) {
                var parameter = signature.thisParameter;
                if (!parameter || parameter.valueDeclaration && !parameter.valueDeclaration.type) {
                    if (!parameter) {
                        signature.thisParameter = createSymbolWithType(context.thisParameter, /*type*/ undefined);
                    }
                    assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter));
                }
            }
            var len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
            for (var i = 0; i < len; i++) {
                var parameter = signature.parameters[i];
                if (!ts.getEffectiveTypeAnnotationNode(parameter.valueDeclaration)) {
                    var contextualParameterType = getTypeAtPosition(context, i);
                    assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
                }
            }
            if (signature.hasRestParameter) {
                // parameter might be a transient symbol generated by use of `arguments` in the function body.
                var parameter = ts.last(signature.parameters);
                if (isTransientSymbol(parameter) || !ts.getEffectiveTypeAnnotationNode(parameter.valueDeclaration)) {
                    var contextualParameterType = getRestTypeAtPosition(context, len);
                    assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
                }
            }
        }
        // When contextual typing assigns a type to a parameter that contains a binding pattern, we also need to push
        // the destructured type into the contained binding elements.
        function assignBindingElementTypes(pattern) {
            for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                var element = _a[_i];
                if (!ts.isOmittedExpression(element)) {
                    if (element.name.kind === 73 /* Identifier */) {
                        getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element);
                    }
                    else {
                        assignBindingElementTypes(element.name);
                    }
                }
            }
        }
        function assignTypeToParameterAndFixTypeParameters(parameter, contextualType) {
            var links = getSymbolLinks(parameter);
            if (!links.type) {
                links.type = contextualType;
                var decl = parameter.valueDeclaration;
                if (decl.name.kind !== 73 /* Identifier */) {
                    // if inference didn't come up with anything but {}, fall back to the binding pattern if present.
                    if (links.type === unknownType) {
                        links.type = getTypeFromBindingPattern(decl.name);
                    }
                    assignBindingElementTypes(decl.name);
                }
            }
        }
        function createPromiseType(promisedType) {
            // creates a `Promise<T>` type where `T` is the promisedType argument
            var globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
            if (globalPromiseType !== emptyGenericType) {
                // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
                promisedType = getAwaitedType(promisedType) || unknownType;
                return createTypeReference(globalPromiseType, [promisedType]);
            }
            return unknownType;
        }
        function createPromiseLikeType(promisedType) {
            // creates a `PromiseLike<T>` type where `T` is the promisedType argument
            var globalPromiseLikeType = getGlobalPromiseLikeType(/*reportErrors*/ true);
            if (globalPromiseLikeType !== emptyGenericType) {
                // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
                promisedType = getAwaitedType(promisedType) || unknownType;
                return createTypeReference(globalPromiseLikeType, [promisedType]);
            }
            return unknownType;
        }
        function createPromiseReturnType(func, promisedType) {
            var promiseType = createPromiseType(promisedType);
            if (promiseType === unknownType) {
                error(func, ts.isImportCall(func) ?
                    ts.Diagnostics.A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option :
                    ts.Diagnostics.An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option);
                return errorType;
            }
            else if (!getGlobalPromiseConstructorSymbol(/*reportErrors*/ true)) {
                error(func, ts.isImportCall(func) ?
                    ts.Diagnostics.A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option :
                    ts.Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
            }
            return promiseType;
        }
        function getReturnTypeFromBody(func, checkMode) {
            if (!func.body) {
                return errorType;
            }
            var functionFlags = ts.getFunctionFlags(func);
            var type;
            if (func.body.kind !== 219 /* Block */) {
                type = checkExpressionCached(func.body, checkMode && checkMode & ~8 /* SkipGenericFunctions */);
                if (functionFlags & 2 /* Async */) {
                    // From within an async function you can return either a non-promise value or a promise. Any
                    // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
                    // return type of the body should be unwrapped to its awaited type, which we will wrap in
                    // the native Promise<T> type later in this function.
                    type = checkAwaitedType(type, /*errorNode*/ func, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
                }
            }
            else {
                var types = checkAndAggregateReturnExpressionTypes(func, checkMode);
                if (functionFlags & 1 /* Generator */) { // Generator or AsyncGenerator function
                    types = ts.concatenate(checkAndAggregateYieldOperandTypes(func, checkMode), types);
                    if (!types || types.length === 0) {
                        var iterableIteratorAny = functionFlags & 2 /* Async */
                            ? createAsyncIterableIteratorType(anyType) // AsyncGenerator function
                            : createIterableIteratorType(anyType); // Generator function
                        if (noImplicitAny) {
                            error(func.asteriskToken, ts.Diagnostics.Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type, typeToString(iterableIteratorAny));
                        }
                        return iterableIteratorAny;
                    }
                }
                else {
                    if (!types) {
                        // For an async function, the return type will not be never, but rather a Promise for never.
                        return functionFlags & 2 /* Async */
                            ? createPromiseReturnType(func, neverType) // Async function
                            : neverType; // Normal function
                    }
                    if (types.length === 0) {
                        // For an async function, the return type will not be void, but rather a Promise for void.
                        return functionFlags & 2 /* Async */
                            ? createPromiseReturnType(func, voidType) // Async function
                            : voidType; // Normal function
                    }
                }
                // Return a union of the return expression types.
                type = getUnionType(types, 2 /* Subtype */);
            }
            var contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func);
            if (!contextualSignature) {
                reportErrorsFromWidening(func, type);
            }
            if (isUnitType(type)) {
                var contextualType = !contextualSignature ? undefined :
                    contextualSignature === getSignatureFromDeclaration(func) ? type :
                        getReturnTypeOfSignature(contextualSignature);
                if (contextualType) {
                    switch (functionFlags & 3 /* AsyncGenerator */) {
                        case 3 /* AsyncGenerator */:
                            contextualType = getIteratedTypeOfGenerator(contextualType, /*isAsyncGenerator*/ true);
                            break;
                        case 1 /* Generator */:
                            contextualType = getIteratedTypeOfGenerator(contextualType, /*isAsyncGenerator*/ false);
                            break;
                        case 2 /* Async */:
                            contextualType = getPromisedTypeOfPromise(contextualType);
                            break;
                    }
                }
                type = getWidenedLiteralLikeTypeForContextualType(type, contextualType);
            }
            var widenedType = getWidenedType(type);
            switch (functionFlags & 3 /* AsyncGenerator */) {
                case 3 /* AsyncGenerator */:
                    return createAsyncIterableIteratorType(widenedType);
                case 1 /* Generator */:
                    return createIterableIteratorType(widenedType);
                case 2 /* Async */:
                    // From within an async function you can return either a non-promise value or a promise. Any
                    // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
                    // return type of the body is awaited type of the body, wrapped in a native Promise<T> type.
                    return createPromiseType(widenedType);
                default:
                    return widenedType;
            }
        }
        function checkAndAggregateYieldOperandTypes(func, checkMode) {
            var aggregatedTypes = [];
            var isAsync = (ts.getFunctionFlags(func) & 2 /* Async */) !== 0;
            ts.forEachYieldExpression(func.body, function (yieldExpression) {
                ts.pushIfUnique(aggregatedTypes, getYieldedTypeOfYieldExpression(yieldExpression, isAsync, checkMode));
            });
            return aggregatedTypes;
        }
        function getYieldedTypeOfYieldExpression(node, isAsync, checkMode) {
            var errorNode = node.expression || node;
            var expressionType = node.expression ? checkExpression(node.expression, checkMode) : undefinedWideningType;
            // A `yield*` expression effectively yields everything that its operand yields
            var yieldedType = node.asteriskToken ? checkIteratedTypeOrElementType(expressionType, errorNode, /*allowStringInput*/ false, isAsync) : expressionType;
            return !isAsync ? yieldedType : getAwaitedType(yieldedType, errorNode, node.asteriskToken
                ? ts.Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member
                : ts.Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
        }
        /**
         * Collect the TypeFacts learned from a typeof switch with
         * total clauses `witnesses`, and the active clause ranging
         * from `start` to `end`. Parameter `hasDefault` denotes
         * whether the active clause contains a default clause.
         */
        function getFactsFromTypeofSwitch(start, end, witnesses, hasDefault) {
            var facts = 0 /* None */;
            // When in the default we only collect inequality facts
            // because default is 'in theory' a set of infinite
            // equalities.
            if (hasDefault) {
                // Value is not equal to any types after the active clause.
                for (var i = end; i < witnesses.length; i++) {
                    facts |= typeofNEFacts.get(witnesses[i]) || 32768 /* TypeofNEHostObject */;
                }
                // Remove inequalities for types that appear in the
                // active clause because they appear before other
                // types collected so far.
                for (var i = start; i < end; i++) {
                    facts &= ~(typeofNEFacts.get(witnesses[i]) || 0);
                }
                // Add inequalities for types before the active clause unconditionally.
                for (var i = 0; i < start; i++) {
                    facts |= typeofNEFacts.get(witnesses[i]) || 32768 /* TypeofNEHostObject */;
                }
            }
            // When in an active clause without default the set of
            // equalities is finite.
            else {
                // Add equalities for all types in the active clause.
                for (var i = start; i < end; i++) {
                    facts |= typeofEQFacts.get(witnesses[i]) || 128 /* TypeofEQHostObject */;
                }
                // Remove equalities for types that appear before the
                // active clause.
                for (var i = 0; i < start; i++) {
                    facts &= ~(typeofEQFacts.get(witnesses[i]) || 0);
                }
            }
            return facts;
        }
        function isExhaustiveSwitchStatement(node) {
            if (!node.possiblyExhaustive) {
                return false;
            }
            if (node.expression.kind === 200 /* TypeOfExpression */) {
                var operandType = getTypeOfExpression(node.expression.expression);
                // This cast is safe because the switch is possibly exhaustive and does not contain a default case, so there can be no undefined.
                var witnesses = getSwitchClauseTypeOfWitnesses(node);
                // notEqualFacts states that the type of the switched value is not equal to every type in the switch.
                var notEqualFacts_1 = getFactsFromTypeofSwitch(0, 0, witnesses, /*hasDefault*/ true);
                var type_5 = getBaseConstraintOfType(operandType) || operandType;
                return !!(filterType(type_5, function (t) { return (getTypeFacts(t) & notEqualFacts_1) === notEqualFacts_1; }).flags & 131072 /* Never */);
            }
            var type = getTypeOfExpression(node.expression);
            if (!isLiteralType(type)) {
                return false;
            }
            var switchTypes = getSwitchClauseTypes(node);
            if (!switchTypes.length || ts.some(switchTypes, isNeitherUnitTypeNorNever)) {
                return false;
            }
            return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes);
        }
        function functionHasImplicitReturn(func) {
            if (!(func.flags & 128 /* HasImplicitReturn */)) {
                return false;
            }
            if (ts.some(func.body.statements, function (statement) { return statement.kind === 233 /* SwitchStatement */ && isExhaustiveSwitchStatement(statement); })) {
                return false;
            }
            return true;
        }
        /** NOTE: Return value of `[]` means a different thing than `undefined`. `[]` means func returns `void`, `undefined` means it returns `never`. */
        function checkAndAggregateReturnExpressionTypes(func, checkMode) {
            var functionFlags = ts.getFunctionFlags(func);
            var aggregatedTypes = [];
            var hasReturnWithNoExpression = functionHasImplicitReturn(func);
            var hasReturnOfTypeNever = false;
            ts.forEachReturnStatement(func.body, function (returnStatement) {
                var expr = returnStatement.expression;
                if (expr) {
                    var type = checkExpressionCached(expr, checkMode && checkMode & ~8 /* SkipGenericFunctions */);
                    if (functionFlags & 2 /* Async */) {
                        // From within an async function you can return either a non-promise value or a promise. Any
                        // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
                        // return type of the body should be unwrapped to its awaited type, which should be wrapped in
                        // the native Promise<T> type by the caller.
                        type = checkAwaitedType(type, func, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
                    }
                    if (type.flags & 131072 /* Never */) {
                        hasReturnOfTypeNever = true;
                    }
                    ts.pushIfUnique(aggregatedTypes, type);
                }
                else {
                    hasReturnWithNoExpression = true;
                }
            });
            if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever || mayReturnNever(func))) {
                return undefined;
            }
            if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression &&
                !(isJSConstructor(func) && aggregatedTypes.some(function (t) { return t.symbol === func.symbol; }))) {
                // Javascript "callable constructors", containing eg `if (!(this instanceof A)) return new A()` should not add undefined
                ts.pushIfUnique(aggregatedTypes, undefinedType);
            }
            return aggregatedTypes;
        }
        function mayReturnNever(func) {
            switch (func.kind) {
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */:
                    return true;
                case 157 /* MethodDeclaration */:
                    return func.parent.kind === 189 /* ObjectLiteralExpression */;
                default:
                    return false;
            }
        }
        /**
         * TypeScript Specification 1.0 (6.3) - July 2014
         *   An explicitly typed function whose return type isn't the Void type,
         *   the Any type, or a union type containing the Void or Any type as a constituent
         *   must have at least one return statement somewhere in its body.
         *   An exception to this rule is if the function implementation consists of a single 'throw' statement.
         *
         * @param returnType - return type of the function, can be undefined if return type is not explicitly specified
         */
        function checkAllCodePathsInNonVoidFunctionReturnOrThrow(func, returnType) {
            if (!produceDiagnostics) {
                return;
            }
            // Functions with with an explicitly specified 'void' or 'any' return type don't need any return expressions.
            if (returnType && maybeTypeOfKind(returnType, 1 /* Any */ | 16384 /* Void */)) {
                return;
            }
            // If all we have is a function signature, or an arrow function with an expression body, then there is nothing to check.
            // also if HasImplicitReturn flag is not set this means that all codepaths in function body end with return or throw
            if (func.kind === 156 /* MethodSignature */ || ts.nodeIsMissing(func.body) || func.body.kind !== 219 /* Block */ || !functionHasImplicitReturn(func)) {
                return;
            }
            var hasExplicitReturn = func.flags & 256 /* HasExplicitReturn */;
            if (returnType && returnType.flags & 131072 /* Never */) {
                error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point);
            }
            else if (returnType && !hasExplicitReturn) {
                // minimal check: function has syntactic return type annotation and no explicit return statements in the body
                // this function does not conform to the specification.
                // NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
                error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
            }
            else if (returnType && strictNullChecks && !isTypeAssignableTo(undefinedType, returnType)) {
                error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined);
            }
            else if (compilerOptions.noImplicitReturns) {
                if (!returnType) {
                    // If return type annotation is omitted check if function has any explicit return statements.
                    // If it does not have any - its inferred return type is void - don't do any checks.
                    // Otherwise get inferred return type from function body and report error only if it is not void / anytype
                    if (!hasExplicitReturn) {
                        return;
                    }
                    var inferredReturnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func));
                    if (isUnwrappedReturnTypeVoidOrAny(func, inferredReturnType)) {
                        return;
                    }
                }
                error(ts.getEffectiveReturnTypeNode(func) || func, ts.Diagnostics.Not_all_code_paths_return_a_value);
            }
        }
        function checkFunctionExpressionOrObjectLiteralMethod(node, checkMode) {
            ts.Debug.assert(node.kind !== 157 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            checkNodeDeferred(node);
            // The identityMapper object is used to indicate that function expressions are wildcards
            if (checkMode && checkMode & 4 /* SkipContextSensitive */ && isContextSensitive(node)) {
                // Skip parameters, return signature with return type that retains noncontextual parts so inferences can still be drawn in an early stage
                if (!ts.getEffectiveReturnTypeNode(node) && hasContextSensitiveReturnExpression(node)) {
                    var links_1 = getNodeLinks(node);
                    if (links_1.contextFreeType) {
                        return links_1.contextFreeType;
                    }
                    var returnType = getReturnTypeFromBody(node, checkMode);
                    var returnOnlySignature = createSignature(undefined, undefined, undefined, ts.emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
                    var returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], ts.emptyArray, undefined, undefined);
                    returnOnlyType.objectFlags |= 524288 /* NonInferrableType */;
                    return links_1.contextFreeType = returnOnlyType;
                }
                return anyFunctionType;
            }
            // Grammar checking
            var hasGrammarError = checkGrammarFunctionLikeDeclaration(node);
            if (!hasGrammarError && node.kind === 197 /* FunctionExpression */) {
                checkGrammarForGenerator(node);
            }
            var links = getNodeLinks(node);
            var type = getTypeOfSymbol(getMergedSymbol(node.symbol));
            if (isTypeAny(type)) {
                return type;
            }
            // Check if function expression is contextually typed and assign parameter types if so.
            if (!(links.flags & 1024 /* ContextChecked */)) {
                var contextualSignature = getContextualSignature(node);
                // If a type check is started at a function expression that is an argument of a function call, obtaining the
                // contextual type may recursively get back to here during overload resolution of the call. If so, we will have
                // already assigned contextual types.
                if (!(links.flags & 1024 /* ContextChecked */)) {
                    links.flags |= 1024 /* ContextChecked */;
                    if (contextualSignature) {
                        var signature = getSignaturesOfType(type, 0 /* Call */)[0];
                        if (isContextSensitive(node)) {
                            var inferenceContext = getInferenceContext(node);
                            if (checkMode && checkMode & 2 /* Inferential */) {
                                inferFromAnnotatedParameters(signature, contextualSignature, inferenceContext);
                            }
                            var instantiatedContextualSignature = inferenceContext ?
                                instantiateSignature(contextualSignature, inferenceContext.mapper) : contextualSignature;
                            assignContextualParameterTypes(signature, instantiatedContextualSignature);
                        }
                        if (!getReturnTypeFromAnnotation(node) && !signature.resolvedReturnType) {
                            var returnType = getReturnTypeFromBody(node, checkMode);
                            if (!signature.resolvedReturnType) {
                                signature.resolvedReturnType = returnType;
                            }
                        }
                    }
                    checkSignatureDeclaration(node);
                }
            }
            return type;
        }
        function getReturnOrPromisedType(node, functionFlags) {
            var type = getReturnTypeFromAnnotation(node);
            return type && ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */) ?
                getAwaitedType(type) || errorType : type;
        }
        function checkFunctionExpressionOrObjectLiteralMethodDeferred(node) {
            ts.Debug.assert(node.kind !== 157 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            var functionFlags = ts.getFunctionFlags(node);
            var returnOrPromisedType = getReturnOrPromisedType(node, functionFlags);
            if ((functionFlags & 1 /* Generator */) === 0) { // Async function or normal function
                // return is not necessary in the body of generators
                checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
            }
            if (node.body) {
                if (!ts.getEffectiveReturnTypeNode(node)) {
                    // There are some checks that are only performed in getReturnTypeFromBody, that may produce errors
                    // we need. An example is the noImplicitAny errors resulting from widening the return expression
                    // of a function. Because checking of function expression bodies is deferred, there was never an
                    // appropriate time to do this during the main walk of the file (see the comment at the top of
                    // checkFunctionExpressionBodies). So it must be done now.
                    getReturnTypeOfSignature(getSignatureFromDeclaration(node));
                }
                if (node.body.kind === 219 /* Block */) {
                    checkSourceElement(node.body);
                }
                else {
                    // From within an async function you can return either a non-promise value or a promise. Any
                    // Promise/A+ compatible implementation will always assimilate any foreign promise, so we
                    // should not be checking assignability of a promise to the return type. Instead, we need to
                    // check assignability of the awaited type of the expression body against the promised type of
                    // its return type annotation.
                    var exprType = checkExpression(node.body);
                    if (returnOrPromisedType) {
                        if ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */) { // Async function
                            var awaitedType = checkAwaitedType(exprType, node.body, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
                            checkTypeAssignableToAndOptionallyElaborate(awaitedType, returnOrPromisedType, node.body, node.body);
                        }
                        else { // Normal function
                            checkTypeAssignableToAndOptionallyElaborate(exprType, returnOrPromisedType, node.body, node.body);
                        }
                    }
                }
            }
        }
        function checkArithmeticOperandType(operand, type, diagnostic) {
            if (!isTypeAssignableTo(type, numberOrBigIntType)) {
                error(operand, diagnostic);
                return false;
            }
            return true;
        }
        function isReadonlyAssignmentDeclaration(d) {
            if (!ts.isCallExpression(d)) {
                return false;
            }
            if (!ts.isBindableObjectDefinePropertyCall(d)) {
                return false;
            }
            var objectLitType = checkExpressionCached(d.arguments[2]);
            var valueType = getTypeOfPropertyOfType(objectLitType, "value");
            if (valueType) {
                var writableProp = getPropertyOfType(objectLitType, "writable");
                var writableType = writableProp && getTypeOfSymbol(writableProp);
                if (!writableType || writableType === falseType || writableType === regularFalseType) {
                    return true;
                }
                // We include this definition whereupon we walk back and check the type at the declaration because
                // The usual definition of `Object.defineProperty` will _not_ cause literal types to be preserved in the
                // argument types, should the type be contextualized by the call itself.
                if (writableProp && writableProp.valueDeclaration && ts.isPropertyAssignment(writableProp.valueDeclaration)) {
                    var initializer = writableProp.valueDeclaration.initializer;
                    var rawOriginalType = checkExpression(initializer);
                    if (rawOriginalType === falseType || rawOriginalType === regularFalseType) {
                        return true;
                    }
                }
                return false;
            }
            var setProp = getPropertyOfType(objectLitType, "set");
            return !setProp;
        }
        function isReadonlySymbol(symbol) {
            // The following symbols are considered read-only:
            // Properties with a 'readonly' modifier
            // Variables declared with 'const'
            // Get accessors without matching set accessors
            // Enum members
            // Object.defineProperty assignments with writable false or no setter
            // Unions and intersections of the above (unions and intersections eagerly set isReadonly on creation)
            return !!(ts.getCheckFlags(symbol) & 8 /* Readonly */ ||
                symbol.flags & 4 /* Property */ && ts.getDeclarationModifierFlagsFromSymbol(symbol) & 64 /* Readonly */ ||
                symbol.flags & 3 /* Variable */ && getDeclarationNodeFlagsFromSymbol(symbol) & 2 /* Const */ ||
                symbol.flags & 98304 /* Accessor */ && !(symbol.flags & 65536 /* SetAccessor */) ||
                symbol.flags & 8 /* EnumMember */ ||
                ts.some(symbol.declarations, isReadonlyAssignmentDeclaration));
        }
        function isReferenceToReadonlyEntity(expr, symbol) {
            if (isReadonlySymbol(symbol)) {
                // Allow assignments to readonly properties within constructors of the same class declaration.
                if (symbol.flags & 4 /* Property */ &&
                    (expr.kind === 190 /* PropertyAccessExpression */ || expr.kind === 191 /* ElementAccessExpression */) &&
                    expr.expression.kind === 101 /* ThisKeyword */) {
                    // Look for if this is the constructor for the class that `symbol` is a property of.
                    var func = ts.getContainingFunction(expr);
                    if (!(func && func.kind === 158 /* Constructor */)) {
                        return true;
                    }
                    // If func.parent is a class and symbol is a (readonly) property of that class, or
                    // if func is a constructor and symbol is a (readonly) parameter property declared in it,
                    // then symbol is writeable here.
                    return !symbol.valueDeclaration || !(func.parent === symbol.valueDeclaration.parent || func === symbol.valueDeclaration.parent);
                }
                return true;
            }
            return false;
        }
        function isReferenceThroughNamespaceImport(expr) {
            if (expr.kind === 190 /* PropertyAccessExpression */ || expr.kind === 191 /* ElementAccessExpression */) {
                var node = ts.skipParentheses(expr.expression);
                if (node.kind === 73 /* Identifier */) {
                    var symbol = getNodeLinks(node).resolvedSymbol;
                    if (symbol.flags & 2097152 /* Alias */) {
                        var declaration = getDeclarationOfAliasSymbol(symbol);
                        return !!declaration && declaration.kind === 252 /* NamespaceImport */;
                    }
                }
            }
            return false;
        }
        function checkReferenceExpression(expr, invalidReferenceMessage) {
            // References are combinations of identifiers, parentheses, and property accesses.
            var node = ts.skipOuterExpressions(expr, 2 /* Assertions */ | 1 /* Parentheses */);
            if (node.kind !== 73 /* Identifier */ && node.kind !== 190 /* PropertyAccessExpression */ && node.kind !== 191 /* ElementAccessExpression */) {
                error(expr, invalidReferenceMessage);
                return false;
            }
            return true;
        }
        function checkDeleteExpression(node) {
            checkExpression(node.expression);
            var expr = ts.skipParentheses(node.expression);
            if (expr.kind !== 190 /* PropertyAccessExpression */ && expr.kind !== 191 /* ElementAccessExpression */) {
                error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_must_be_a_property_reference);
                return booleanType;
            }
            var links = getNodeLinks(expr);
            var symbol = getExportSymbolOfValueSymbolIfExported(links.resolvedSymbol);
            if (symbol && isReadonlySymbol(symbol)) {
                error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_cannot_be_a_read_only_property);
            }
            return booleanType;
        }
        function checkTypeOfExpression(node) {
            checkExpression(node.expression);
            return typeofType;
        }
        function checkVoidExpression(node) {
            checkExpression(node.expression);
            return undefinedWideningType;
        }
        function checkAwaitExpression(node) {
            // Grammar checking
            if (produceDiagnostics) {
                if (!(node.flags & 16384 /* AwaitContext */)) {
                    // use of 'await' in non-async function
                    var sourceFile = ts.getSourceFileOfNode(node);
                    if (!hasParseDiagnostics(sourceFile)) {
                        var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                        var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expression_is_only_allowed_within_an_async_function);
                        var func = ts.getContainingFunction(node);
                        if (func && func.kind !== 158 /* Constructor */) {
                            ts.Debug.assert((ts.getFunctionFlags(func) & 2 /* Async */) === 0, "Enclosing function should never be an async function.");
                            var relatedInfo = ts.createDiagnosticForNode(func, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async);
                            ts.addRelatedInfo(diagnostic, relatedInfo);
                        }
                        diagnostics.add(diagnostic);
                    }
                }
                if (isInParameterInitializerBeforeContainingFunction(node)) {
                    error(node, ts.Diagnostics.await_expressions_cannot_be_used_in_a_parameter_initializer);
                }
            }
            var operandType = checkExpression(node.expression);
            return checkAwaitedType(operandType, node, ts.Diagnostics.Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
        }
        function checkPrefixUnaryExpression(node) {
            var operandType = checkExpression(node.operand);
            if (operandType === silentNeverType) {
                return silentNeverType;
            }
            switch (node.operand.kind) {
                case 8 /* NumericLiteral */:
                    switch (node.operator) {
                        case 39 /* MinusToken */:
                            return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text));
                        case 38 /* PlusToken */:
                            return getFreshTypeOfLiteralType(getLiteralType(+node.operand.text));
                    }
                    break;
                case 9 /* BigIntLiteral */:
                    if (node.operator === 39 /* MinusToken */) {
                        return getFreshTypeOfLiteralType(getLiteralType({
                            negative: true,
                            base10Value: ts.parsePseudoBigInt(node.operand.text)
                        }));
                    }
            }
            switch (node.operator) {
                case 38 /* PlusToken */:
                case 39 /* MinusToken */:
                case 53 /* TildeToken */:
                    checkNonNullType(operandType, node.operand);
                    if (maybeTypeOfKind(operandType, 12288 /* ESSymbolLike */)) {
                        error(node.operand, ts.Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, ts.tokenToString(node.operator));
                    }
                    if (node.operator === 38 /* PlusToken */) {
                        if (maybeTypeOfKind(operandType, 2112 /* BigIntLike */)) {
                            error(node.operand, ts.Diagnostics.Operator_0_cannot_be_applied_to_type_1, ts.tokenToString(node.operator), typeToString(operandType));
                        }
                        return numberType;
                    }
                    return getUnaryResultType(operandType);
                case 52 /* ExclamationToken */:
                    checkTruthinessExpression(node.operand);
                    var facts = getTypeFacts(operandType) & (4194304 /* Truthy */ | 8388608 /* Falsy */);
                    return facts === 4194304 /* Truthy */ ? falseType :
                        facts === 8388608 /* Falsy */ ? trueType :
                            booleanType;
                case 44 /* PlusPlusToken */:
                case 45 /* MinusMinusToken */:
                    var ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type);
                    if (ok) {
                        // run check only if former checks succeeded to avoid reporting cascading errors
                        checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access);
                    }
                    return getUnaryResultType(operandType);
            }
            return errorType;
        }
        function checkPostfixUnaryExpression(node) {
            var operandType = checkExpression(node.operand);
            if (operandType === silentNeverType) {
                return silentNeverType;
            }
            var ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type);
            if (ok) {
                // run check only if former checks succeeded to avoid reporting cascading errors
                checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access);
            }
            return getUnaryResultType(operandType);
        }
        function getUnaryResultType(operandType) {
            if (maybeTypeOfKind(operandType, 2112 /* BigIntLike */)) {
                return isTypeAssignableToKind(operandType, 3 /* AnyOrUnknown */) || maybeTypeOfKind(operandType, 296 /* NumberLike */)
                    ? numberOrBigIntType
                    : bigintType;
            }
            // If it's not a bigint type, implicit coercion will result in a number
            return numberType;
        }
        // Return true if type might be of the given kind. A union or intersection type might be of a given
        // kind if at least one constituent type is of the given kind.
        function maybeTypeOfKind(type, kind) {
            if (type.flags & kind & ~131072 /* GenericMappedType */ || kind & 131072 /* GenericMappedType */ && isGenericMappedType(type)) {
                return true;
            }
            if (type.flags & 3145728 /* UnionOrIntersection */) {
                var types = type.types;
                for (var _i = 0, types_15 = types; _i < types_15.length; _i++) {
                    var t = types_15[_i];
                    if (maybeTypeOfKind(t, kind)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function isTypeAssignableToKind(source, kind, strict) {
            if (source.flags & kind) {
                return true;
            }
            if (strict && source.flags & (3 /* AnyOrUnknown */ | 16384 /* Void */ | 32768 /* Undefined */ | 65536 /* Null */)) {
                return false;
            }
            return !!(kind & 296 /* NumberLike */) && isTypeAssignableTo(source, numberType) ||
                !!(kind & 2112 /* BigIntLike */) && isTypeAssignableTo(source, bigintType) ||
                !!(kind & 132 /* StringLike */) && isTypeAssignableTo(source, stringType) ||
                !!(kind & 528 /* BooleanLike */) && isTypeAssignableTo(source, booleanType) ||
                !!(kind & 16384 /* Void */) && isTypeAssignableTo(source, voidType) ||
                !!(kind & 131072 /* Never */) && isTypeAssignableTo(source, neverType) ||
                !!(kind & 65536 /* Null */) && isTypeAssignableTo(source, nullType) ||
                !!(kind & 32768 /* Undefined */) && isTypeAssignableTo(source, undefinedType) ||
                !!(kind & 4096 /* ESSymbol */) && isTypeAssignableTo(source, esSymbolType) ||
                !!(kind & 67108864 /* NonPrimitive */) && isTypeAssignableTo(source, nonPrimitiveType);
        }
        function allTypesAssignableToKind(source, kind, strict) {
            return source.flags & 1048576 /* Union */ ?
                ts.every(source.types, function (subType) { return allTypesAssignableToKind(subType, kind, strict); }) :
                isTypeAssignableToKind(source, kind, strict);
        }
        function isConstEnumObjectType(type) {
            return !!(ts.getObjectFlags(type) & 16 /* Anonymous */) && !!type.symbol && isConstEnumSymbol(type.symbol);
        }
        function isConstEnumSymbol(symbol) {
            return (symbol.flags & 128 /* ConstEnum */) !== 0;
        }
        function checkInstanceOfExpression(left, right, leftType, rightType) {
            if (leftType === silentNeverType || rightType === silentNeverType) {
                return silentNeverType;
            }
            // TypeScript 1.0 spec (April 2014): 4.15.4
            // The instanceof operator requires the left operand to be of type Any, an object type, or a type parameter type,
            // and the right operand to be of type Any, a subtype of the 'Function' interface type, or have a call or construct signature.
            // The result is always of the Boolean primitive type.
            // NOTE: do not raise error if leftType is unknown as related error was already reported
            if (!isTypeAny(leftType) &&
                allTypesAssignableToKind(leftType, 131068 /* Primitive */)) {
                error(left, ts.Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
            }
            // NOTE: do not raise error if right is unknown as related error was already reported
            if (!(isTypeAny(rightType) || typeHasCallOrConstructSignatures(rightType) || isTypeSubtypeOf(rightType, globalFunctionType))) {
                error(right, ts.Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type);
            }
            return booleanType;
        }
        function checkInExpression(left, right, leftType, rightType) {
            if (leftType === silentNeverType || rightType === silentNeverType) {
                return silentNeverType;
            }
            leftType = checkNonNullType(leftType, left);
            rightType = checkNonNullType(rightType, right);
            // TypeScript 1.0 spec (April 2014): 4.15.5
            // The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
            // and the right operand to be of type Any, an object type, or a type parameter type.
            // The result is always of the Boolean primitive type.
            if (!(isTypeComparableTo(leftType, stringType) || isTypeAssignableToKind(leftType, 296 /* NumberLike */ | 12288 /* ESSymbolLike */))) {
                error(left, ts.Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
            }
            if (!allTypesAssignableToKind(rightType, 67108864 /* NonPrimitive */ | 58982400 /* InstantiableNonPrimitive */)) {
                error(right, ts.Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
            }
            return booleanType;
        }
        function checkObjectLiteralAssignment(node, sourceType, rightIsThis) {
            var properties = node.properties;
            if (strictNullChecks && properties.length === 0) {
                return checkNonNullType(sourceType, node);
            }
            for (var i = 0; i < properties.length; i++) {
                checkObjectLiteralDestructuringPropertyAssignment(node, sourceType, i, properties, rightIsThis);
            }
            return sourceType;
        }
        /** Note: If property cannot be a SpreadAssignment, then allProperties does not need to be provided */
        function checkObjectLiteralDestructuringPropertyAssignment(node, objectLiteralType, propertyIndex, allProperties, rightIsThis) {
            if (rightIsThis === void 0) { rightIsThis = false; }
            var properties = node.properties;
            var property = properties[propertyIndex];
            if (property.kind === 276 /* PropertyAssignment */ || property.kind === 277 /* ShorthandPropertyAssignment */) {
                var name = property.name;
                var exprType = getLiteralTypeFromPropertyName(name);
                if (isTypeUsableAsPropertyName(exprType)) {
                    var text = getPropertyNameFromType(exprType);
                    var prop = getPropertyOfType(objectLiteralType, text);
                    if (prop) {
                        markPropertyAsReferenced(prop, property, rightIsThis);
                        checkPropertyAccessibility(property, /*isSuper*/ false, objectLiteralType, prop);
                    }
                }
                var elementType = getIndexedAccessType(objectLiteralType, exprType, name);
                var type = getFlowTypeOfDestructuring(property, elementType);
                return checkDestructuringAssignment(property.kind === 277 /* ShorthandPropertyAssignment */ ? property : property.initializer, type);
            }
            else if (property.kind === 278 /* SpreadAssignment */) {
                if (propertyIndex < properties.length - 1) {
                    error(property, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
                }
                else {
                    if (languageVersion < 8 /* ESNext */) {
                        checkExternalEmitHelpers(property, 4 /* Rest */);
                    }
                    var nonRestNames = [];
                    if (allProperties) {
                        for (var _i = 0, allProperties_1 = allProperties; _i < allProperties_1.length; _i++) {
                            var otherProperty = allProperties_1[_i];
                            if (!ts.isSpreadAssignment(otherProperty)) {
                                nonRestNames.push(otherProperty.name);
                            }
                        }
                    }
                    var type = getRestType(objectLiteralType, nonRestNames, objectLiteralType.symbol);
                    checkGrammarForDisallowedTrailingComma(allProperties, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
                    return checkDestructuringAssignment(property.expression, type);
                }
            }
            else {
                error(property, ts.Diagnostics.Property_assignment_expected);
            }
        }
        function checkArrayLiteralAssignment(node, sourceType, checkMode) {
            var elements = node.elements;
            if (languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
                checkExternalEmitHelpers(node, 512 /* Read */);
            }
            // This elementType will be used if the specific property corresponding to this index is not
            // present (aka the tuple element property). This call also checks that the parentType is in
            // fact an iterable or array (depending on target language).
            var elementType = checkIteratedTypeOrElementType(sourceType, node, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || errorType;
            for (var i = 0; i < elements.length; i++) {
                checkArrayLiteralDestructuringElementAssignment(node, sourceType, i, elementType, checkMode);
            }
            return sourceType;
        }
        function checkArrayLiteralDestructuringElementAssignment(node, sourceType, elementIndex, elementType, checkMode) {
            var elements = node.elements;
            var element = elements[elementIndex];
            if (element.kind !== 211 /* OmittedExpression */) {
                if (element.kind !== 209 /* SpreadElement */) {
                    var indexType = getLiteralType(elementIndex);
                    if (isArrayLikeType(sourceType)) {
                        // We create a synthetic expression so that getIndexedAccessType doesn't get confused
                        // when the element is a SyntaxKind.ElementAccessExpression.
                        var elementType_2 = getIndexedAccessType(sourceType, indexType, createSyntheticExpression(element, indexType));
                        var type = getFlowTypeOfDestructuring(element, elementType_2);
                        return checkDestructuringAssignment(element, type, checkMode);
                    }
                    return checkDestructuringAssignment(element, elementType, checkMode);
                }
                if (elementIndex < elements.length - 1) {
                    error(element, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
                }
                else {
                    var restExpression = element.expression;
                    if (restExpression.kind === 205 /* BinaryExpression */ && restExpression.operatorToken.kind === 60 /* EqualsToken */) {
                        error(restExpression.operatorToken, ts.Diagnostics.A_rest_element_cannot_have_an_initializer);
                    }
                    else {
                        checkGrammarForDisallowedTrailingComma(node.elements, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
                        var type = everyType(sourceType, isTupleType) ?
                            mapType(sourceType, function (t) { return sliceTupleType(t, elementIndex); }) :
                            createArrayType(elementType);
                        return checkDestructuringAssignment(restExpression, type, checkMode);
                    }
                }
            }
            return undefined;
        }
        function checkDestructuringAssignment(exprOrAssignment, sourceType, checkMode, rightIsThis) {
            var target;
            if (exprOrAssignment.kind === 277 /* ShorthandPropertyAssignment */) {
                var prop = exprOrAssignment;
                if (prop.objectAssignmentInitializer) {
                    // In strict null checking mode, if a default value of a non-undefined type is specified, remove
                    // undefined from the final type.
                    if (strictNullChecks &&
                        !(getFalsyFlags(checkExpression(prop.objectAssignmentInitializer)) & 32768 /* Undefined */)) {
                        sourceType = getTypeWithFacts(sourceType, 524288 /* NEUndefined */);
                    }
                    checkBinaryLikeExpression(prop.name, prop.equalsToken, prop.objectAssignmentInitializer, checkMode);
                }
                target = exprOrAssignment.name;
            }
            else {
                target = exprOrAssignment;
            }
            if (target.kind === 205 /* BinaryExpression */ && target.operatorToken.kind === 60 /* EqualsToken */) {
                checkBinaryExpression(target, checkMode);
                target = target.left;
            }
            if (target.kind === 189 /* ObjectLiteralExpression */) {
                return checkObjectLiteralAssignment(target, sourceType, rightIsThis);
            }
            if (target.kind === 188 /* ArrayLiteralExpression */) {
                return checkArrayLiteralAssignment(target, sourceType, checkMode);
            }
            return checkReferenceAssignment(target, sourceType, checkMode);
        }
        function checkReferenceAssignment(target, sourceType, checkMode) {
            var targetType = checkExpression(target, checkMode);
            var error = target.parent.kind === 278 /* SpreadAssignment */ ?
                ts.Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access :
                ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access;
            if (checkReferenceExpression(target, error)) {
                checkTypeAssignableToAndOptionallyElaborate(sourceType, targetType, target, target);
            }
            return sourceType;
        }
        /**
         * This is a *shallow* check: An expression is side-effect-free if the
         * evaluation of the expression *itself* cannot produce side effects.
         * For example, x++ / 3 is side-effect free because the / operator
         * does not have side effects.
         * The intent is to "smell test" an expression for correctness in positions where
         * its value is discarded (e.g. the left side of the comma operator).
         */
        function isSideEffectFree(node) {
            node = ts.skipParentheses(node);
            switch (node.kind) {
                case 73 /* Identifier */:
                case 10 /* StringLiteral */:
                case 13 /* RegularExpressionLiteral */:
                case 194 /* TaggedTemplateExpression */:
                case 207 /* TemplateExpression */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 103 /* TrueKeyword */:
                case 88 /* FalseKeyword */:
                case 97 /* NullKeyword */:
                case 142 /* UndefinedKeyword */:
                case 197 /* FunctionExpression */:
                case 210 /* ClassExpression */:
                case 198 /* ArrowFunction */:
                case 188 /* ArrayLiteralExpression */:
                case 189 /* ObjectLiteralExpression */:
                case 200 /* TypeOfExpression */:
                case 214 /* NonNullExpression */:
                case 262 /* JsxSelfClosingElement */:
                case 261 /* JsxElement */:
                    return true;
                case 206 /* ConditionalExpression */:
                    return isSideEffectFree(node.whenTrue) &&
                        isSideEffectFree(node.whenFalse);
                case 205 /* BinaryExpression */:
                    if (ts.isAssignmentOperator(node.operatorToken.kind)) {
                        return false;
                    }
                    return isSideEffectFree(node.left) &&
                        isSideEffectFree(node.right);
                case 203 /* PrefixUnaryExpression */:
                case 204 /* PostfixUnaryExpression */:
                    // Unary operators ~, !, +, and - have no side effects.
                    // The rest do.
                    switch (node.operator) {
                        case 52 /* ExclamationToken */:
                        case 38 /* PlusToken */:
                        case 39 /* MinusToken */:
                        case 53 /* TildeToken */:
                            return true;
                    }
                    return false;
                // Some forms listed here for clarity
                case 201 /* VoidExpression */: // Explicit opt-out
                case 195 /* TypeAssertionExpression */: // Not SEF, but can produce useful type warnings
                case 213 /* AsExpression */: // Not SEF, but can produce useful type warnings
                default:
                    return false;
            }
        }
        function isTypeEqualityComparableTo(source, target) {
            return (target.flags & 98304 /* Nullable */) !== 0 || isTypeComparableTo(source, target);
        }
        function checkBinaryExpression(node, checkMode) {
            if (ts.isInJSFile(node) && ts.getAssignedExpandoInitializer(node)) {
                return checkExpression(node.right, checkMode);
            }
            return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, checkMode, node);
        }
        function checkBinaryLikeExpression(left, operatorToken, right, checkMode, errorNode) {
            var operator = operatorToken.kind;
            if (operator === 60 /* EqualsToken */ && (left.kind === 189 /* ObjectLiteralExpression */ || left.kind === 188 /* ArrayLiteralExpression */)) {
                return checkDestructuringAssignment(left, checkExpression(right, checkMode), checkMode, right.kind === 101 /* ThisKeyword */);
            }
            var leftType;
            if (operator === 54 /* AmpersandAmpersandToken */ || operator === 55 /* BarBarToken */) {
                leftType = checkTruthinessExpression(left, checkMode);
            }
            else {
                leftType = checkExpression(left, checkMode);
            }
            var rightType = checkExpression(right, checkMode);
            switch (operator) {
                case 40 /* AsteriskToken */:
                case 41 /* AsteriskAsteriskToken */:
                case 63 /* AsteriskEqualsToken */:
                case 64 /* AsteriskAsteriskEqualsToken */:
                case 42 /* SlashToken */:
                case 65 /* SlashEqualsToken */:
                case 43 /* PercentToken */:
                case 66 /* PercentEqualsToken */:
                case 39 /* MinusToken */:
                case 62 /* MinusEqualsToken */:
                case 46 /* LessThanLessThanToken */:
                case 67 /* LessThanLessThanEqualsToken */:
                case 47 /* GreaterThanGreaterThanToken */:
                case 68 /* GreaterThanGreaterThanEqualsToken */:
                case 48 /* GreaterThanGreaterThanGreaterThanToken */:
                case 69 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                case 50 /* BarToken */:
                case 71 /* BarEqualsToken */:
                case 51 /* CaretToken */:
                case 72 /* CaretEqualsToken */:
                case 49 /* AmpersandToken */:
                case 70 /* AmpersandEqualsToken */:
                    if (leftType === silentNeverType || rightType === silentNeverType) {
                        return silentNeverType;
                    }
                    leftType = checkNonNullType(leftType, left);
                    rightType = checkNonNullType(rightType, right);
                    var suggestedOperator = void 0;
                    // if a user tries to apply a bitwise operator to 2 boolean operands
                    // try and return them a helpful suggestion
                    if ((leftType.flags & 528 /* BooleanLike */) &&
                        (rightType.flags & 528 /* BooleanLike */) &&
                        (suggestedOperator = getSuggestedBooleanOperator(operatorToken.kind)) !== undefined) {
                        error(errorNode || operatorToken, ts.Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, ts.tokenToString(operatorToken.kind), ts.tokenToString(suggestedOperator));
                        return numberType;
                    }
                    else {
                        // otherwise just check each operand separately and report errors as normal
                        var leftOk = checkArithmeticOperandType(left, leftType, ts.Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type);
                        var rightOk = checkArithmeticOperandType(right, rightType, ts.Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type);
                        var resultType_1;
                        // If both are any or unknown, allow operation; assume it will resolve to number
                        if ((isTypeAssignableToKind(leftType, 3 /* AnyOrUnknown */) && isTypeAssignableToKind(rightType, 3 /* AnyOrUnknown */)) ||
                            // Or, if neither could be bigint, implicit coercion results in a number result
                            !(maybeTypeOfKind(leftType, 2112 /* BigIntLike */) || maybeTypeOfKind(rightType, 2112 /* BigIntLike */))) {
                            resultType_1 = numberType;
                        }
                        // At least one is assignable to bigint, so both should be only assignable to bigint
                        else if (isTypeAssignableToKind(leftType, 2112 /* BigIntLike */) && isTypeAssignableToKind(rightType, 2112 /* BigIntLike */)) {
                            switch (operator) {
                                case 48 /* GreaterThanGreaterThanGreaterThanToken */:
                                case 69 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                                    reportOperatorError();
                            }
                            resultType_1 = bigintType;
                        }
                        else {
                            reportOperatorError();
                            resultType_1 = errorType;
                        }
                        if (leftOk && rightOk) {
                            checkAssignmentOperator(resultType_1);
                        }
                        return resultType_1;
                    }
                case 38 /* PlusToken */:
                case 61 /* PlusEqualsToken */:
                    if (leftType === silentNeverType || rightType === silentNeverType) {
                        return silentNeverType;
                    }
                    if (!isTypeAssignableToKind(leftType, 132 /* StringLike */) && !isTypeAssignableToKind(rightType, 132 /* StringLike */)) {
                        leftType = checkNonNullType(leftType, left);
                        rightType = checkNonNullType(rightType, right);
                    }
                    var resultType = void 0;
                    if (isTypeAssignableToKind(leftType, 296 /* NumberLike */, /*strict*/ true) && isTypeAssignableToKind(rightType, 296 /* NumberLike */, /*strict*/ true)) {
                        // Operands of an enum type are treated as having the primitive type Number.
                        // If both operands are of the Number primitive type, the result is of the Number primitive type.
                        resultType = numberType;
                    }
                    else if (isTypeAssignableToKind(leftType, 2112 /* BigIntLike */, /*strict*/ true) && isTypeAssignableToKind(rightType, 2112 /* BigIntLike */, /*strict*/ true)) {
                        // If both operands are of the BigInt primitive type, the result is of the BigInt primitive type.
                        resultType = bigintType;
                    }
                    else if (isTypeAssignableToKind(leftType, 132 /* StringLike */, /*strict*/ true) || isTypeAssignableToKind(rightType, 132 /* StringLike */, /*strict*/ true)) {
                        // If one or both operands are of the String primitive type, the result is of the String primitive type.
                        resultType = stringType;
                    }
                    else if (isTypeAny(leftType) || isTypeAny(rightType)) {
                        // Otherwise, the result is of type Any.
                        // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we.
                        resultType = leftType === errorType || rightType === errorType ? errorType : anyType;
                    }
                    // Symbols are not allowed at all in arithmetic expressions
                    if (resultType && !checkForDisallowedESSymbolOperand(operator)) {
                        return resultType;
                    }
                    if (!resultType) {
                        reportOperatorError();
                        return anyType;
                    }
                    if (operator === 61 /* PlusEqualsToken */) {
                        checkAssignmentOperator(resultType);
                    }
                    return resultType;
                case 28 /* LessThanToken */:
                case 30 /* GreaterThanToken */:
                case 31 /* LessThanEqualsToken */:
                case 32 /* GreaterThanEqualsToken */:
                    if (checkForDisallowedESSymbolOperand(operator)) {
                        leftType = getBaseTypeOfLiteralType(checkNonNullType(leftType, left));
                        rightType = getBaseTypeOfLiteralType(checkNonNullType(rightType, right));
                        if (!(isTypeComparableTo(leftType, rightType) || isTypeComparableTo(rightType, leftType) ||
                            (isTypeAssignableTo(leftType, numberOrBigIntType) && isTypeAssignableTo(rightType, numberOrBigIntType)))) {
                            reportOperatorError();
                        }
                    }
                    return booleanType;
                case 33 /* EqualsEqualsToken */:
                case 34 /* ExclamationEqualsToken */:
                case 35 /* EqualsEqualsEqualsToken */:
                case 36 /* ExclamationEqualsEqualsToken */:
                    if (!isTypeEqualityComparableTo(leftType, rightType) && !isTypeEqualityComparableTo(rightType, leftType)) {
                        reportOperatorError();
                    }
                    return booleanType;
                case 95 /* InstanceOfKeyword */:
                    return checkInstanceOfExpression(left, right, leftType, rightType);
                case 94 /* InKeyword */:
                    return checkInExpression(left, right, leftType, rightType);
                case 54 /* AmpersandAmpersandToken */:
                    return getTypeFacts(leftType) & 4194304 /* Truthy */ ?
                        getUnionType([extractDefinitelyFalsyTypes(strictNullChecks ? leftType : getBaseTypeOfLiteralType(rightType)), rightType]) :
                        leftType;
                case 55 /* BarBarToken */:
                    return getTypeFacts(leftType) & 8388608 /* Falsy */ ?
                        getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], 2 /* Subtype */) :
                        leftType;
                case 60 /* EqualsToken */:
                    var declKind = ts.isBinaryExpression(left.parent) ? ts.getAssignmentDeclarationKind(left.parent) : 0 /* None */;
                    checkAssignmentDeclaration(declKind, rightType);
                    if (isAssignmentDeclaration(declKind)) {
                        if (!(rightType.flags & 524288 /* Object */) ||
                            declKind !== 2 /* ModuleExports */ &&
                                declKind !== 6 /* Prototype */ &&
                                !isEmptyObjectType(rightType) &&
                                !isFunctionObjectType(rightType) &&
                                !(ts.getObjectFlags(rightType) & 1 /* Class */)) {
                            // don't check assignability of module.exports=, C.prototype=, or expando types because they will necessarily be incomplete
                            checkAssignmentOperator(rightType);
                        }
                        return leftType;
                    }
                    else {
                        checkAssignmentOperator(rightType);
                        return getRegularTypeOfObjectLiteral(rightType);
                    }
                case 27 /* CommaToken */:
                    if (!compilerOptions.allowUnreachableCode && isSideEffectFree(left) && !isEvalNode(right)) {
                        error(left, ts.Diagnostics.Left_side_of_comma_operator_is_unused_and_has_no_side_effects);
                    }
                    return rightType;
                default:
                    return ts.Debug.fail();
            }
            function checkAssignmentDeclaration(kind, rightType) {
                if (kind === 2 /* ModuleExports */) {
                    for (var _i = 0, _a = getPropertiesOfObjectType(rightType); _i < _a.length; _i++) {
                        var prop = _a[_i];
                        var propType = getTypeOfSymbol(prop);
                        if (propType.symbol && propType.symbol.flags & 32 /* Class */) {
                            var name = prop.escapedName;
                            var symbol = resolveName(prop.valueDeclaration, name, 67897832 /* Type */, undefined, name, /*isUse*/ false);
                            if (symbol && symbol.declarations.some(ts.isJSDocTypedefTag)) {
                                grammarErrorOnNode(symbol.declarations[0], ts.Diagnostics.Duplicate_identifier_0, ts.unescapeLeadingUnderscores(name));
                                return grammarErrorOnNode(prop.valueDeclaration, ts.Diagnostics.Duplicate_identifier_0, ts.unescapeLeadingUnderscores(name));
                            }
                        }
                    }
                }
            }
            function isEvalNode(node) {
                return node.kind === 73 /* Identifier */ && node.escapedText === "eval";
            }
            // Return true if there was no error, false if there was an error.
            function checkForDisallowedESSymbolOperand(operator) {
                var offendingSymbolOperand = maybeTypeOfKind(leftType, 12288 /* ESSymbolLike */) ? left :
                    maybeTypeOfKind(rightType, 12288 /* ESSymbolLike */) ? right :
                        undefined;
                if (offendingSymbolOperand) {
                    error(offendingSymbolOperand, ts.Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, ts.tokenToString(operator));
                    return false;
                }
                return true;
            }
            function getSuggestedBooleanOperator(operator) {
                switch (operator) {
                    case 50 /* BarToken */:
                    case 71 /* BarEqualsToken */:
                        return 55 /* BarBarToken */;
                    case 51 /* CaretToken */:
                    case 72 /* CaretEqualsToken */:
                        return 36 /* ExclamationEqualsEqualsToken */;
                    case 49 /* AmpersandToken */:
                    case 70 /* AmpersandEqualsToken */:
                        return 54 /* AmpersandAmpersandToken */;
                    default:
                        return undefined;
                }
            }
            function checkAssignmentOperator(valueType) {
                if (produceDiagnostics && ts.isAssignmentOperator(operator)) {
                    // TypeScript 1.0 spec (April 2014): 4.17
                    // An assignment of the form
                    //    VarExpr = ValueExpr
                    // requires VarExpr to be classified as a reference
                    // A compound assignment furthermore requires VarExpr to be classified as a reference (section 4.1)
                    // and the type of the non-compound operation to be assignable to the type of VarExpr.
                    if (checkReferenceExpression(left, ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access)
                        && (!ts.isIdentifier(left) || ts.unescapeLeadingUnderscores(left.escapedText) !== "exports")) {
                        // to avoid cascading errors check assignability only if 'isReference' check succeeded and no errors were reported
                        checkTypeAssignableToAndOptionallyElaborate(valueType, leftType, left, right);
                    }
                }
            }
            function isAssignmentDeclaration(kind) {
                switch (kind) {
                    case 2 /* ModuleExports */:
                        return true;
                    case 1 /* ExportsProperty */:
                    case 5 /* Property */:
                    case 6 /* Prototype */:
                    case 3 /* PrototypeProperty */:
                    case 4 /* ThisProperty */:
                        var symbol = getSymbolOfNode(left);
                        var init = ts.getAssignedExpandoInitializer(right);
                        return init && ts.isObjectLiteralExpression(init) &&
                            symbol && ts.hasEntries(symbol.exports);
                    default:
                        return false;
                }
            }
            function reportOperatorError() {
                var _a = getTypeNamesForErrorDisplay(leftType, rightType), leftStr = _a[0], rightStr = _a[1];
                var errNode = errorNode || operatorToken;
                if (!tryGiveBetterPrimaryError(errNode, leftStr, rightStr)) {
                    error(errNode, ts.Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, ts.tokenToString(operatorToken.kind), leftStr, rightStr);
                }
            }
            function tryGiveBetterPrimaryError(errNode, leftStr, rightStr) {
                switch (operatorToken.kind) {
                    case 35 /* EqualsEqualsEqualsToken */:
                    case 33 /* EqualsEqualsToken */:
                        return error(errNode, ts.Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, "false", leftStr, rightStr);
                    case 36 /* ExclamationEqualsEqualsToken */:
                    case 34 /* ExclamationEqualsToken */:
                        return error(errNode, ts.Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, "true", leftStr, rightStr);
                }
                return undefined;
            }
        }
        function isYieldExpressionInClass(node) {
            var current = node;
            var parent = node.parent;
            while (parent) {
                if (ts.isFunctionLike(parent) && current === parent.body) {
                    return false;
                }
                else if (ts.isClassLike(current)) {
                    return true;
                }
                current = parent;
                parent = parent.parent;
            }
            return false;
        }
        function checkYieldExpression(node) {
            // Grammar checking
            if (produceDiagnostics) {
                if (!(node.flags & 4096 /* YieldContext */) || isYieldExpressionInClass(node)) {
                    grammarErrorOnFirstToken(node, ts.Diagnostics.A_yield_expression_is_only_allowed_in_a_generator_body);
                }
                if (isInParameterInitializerBeforeContainingFunction(node)) {
                    error(node, ts.Diagnostics.yield_expressions_cannot_be_used_in_a_parameter_initializer);
                }
            }
            var func = ts.getContainingFunction(node);
            if (!func)
                return anyType;
            var functionFlags = ts.getFunctionFlags(func);
            if (!(functionFlags & 1 /* Generator */)) {
                // If the user's code is syntactically correct, the func should always have a star. After all, we are in a yield context.
                return anyType;
            }
            if (node.asteriskToken) {
                // Async generator functions prior to ESNext require the __await, __asyncDelegator,
                // and __asyncValues helpers
                if ((functionFlags & 3 /* AsyncGenerator */) === 3 /* AsyncGenerator */ &&
                    languageVersion < 8 /* ESNext */) {
                    checkExternalEmitHelpers(node, 26624 /* AsyncDelegatorIncludes */);
                }
                // Generator functions prior to ES2015 require the __values helper
                if ((functionFlags & 3 /* AsyncGenerator */) === 1 /* Generator */ &&
                    languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
                    checkExternalEmitHelpers(node, 256 /* Values */);
                }
            }
            var isAsync = (functionFlags & 2 /* Async */) !== 0;
            var yieldedType = getYieldedTypeOfYieldExpression(node, isAsync); // TODO: GH#18217
            // There is no point in doing an assignability check if the function
            // has no explicit return type because the return type is directly computed
            // from the yield expressions.
            var returnType = getReturnTypeFromAnnotation(func);
            if (returnType) {
                var signatureElementType = getIteratedTypeOfGenerator(returnType, isAsync) || anyType;
                checkTypeAssignableToAndOptionallyElaborate(yieldedType, signatureElementType, node.expression || node, node.expression);
            }
            // Both yield and yield* expressions have type 'any'
            return anyType;
        }
        function checkConditionalExpression(node, checkMode) {
            checkTruthinessExpression(node.condition);
            var type1 = checkExpression(node.whenTrue, checkMode);
            var type2 = checkExpression(node.whenFalse, checkMode);
            return getUnionType([type1, type2], 2 /* Subtype */);
        }
        function checkTemplateExpression(node) {
            // We just want to check each expressions, but we are unconcerned with
            // the type of each expression, as any value may be coerced into a string.
            // It is worth asking whether this is what we really want though.
            // A place where we actually *are* concerned with the expressions' types are
            // in tagged templates.
            ts.forEach(node.templateSpans, function (templateSpan) {
                if (maybeTypeOfKind(checkExpression(templateSpan.expression), 12288 /* ESSymbolLike */)) {
                    error(templateSpan.expression, ts.Diagnostics.Implicit_conversion_of_a_symbol_to_a_string_will_fail_at_runtime_Consider_wrapping_this_expression_in_String);
                }
            });
            return stringType;
        }
        function getContextNode(node) {
            if (node.kind === 269 /* JsxAttributes */ && !ts.isJsxSelfClosingElement(node.parent)) {
                return node.parent.parent; // Needs to be the root JsxElement, so it encompasses the attributes _and_ the children (which are essentially part of the attributes)
            }
            return node;
        }
        function checkExpressionWithContextualType(node, contextualType, inferenceContext, checkMode) {
            var context = getContextNode(node);
            var saveContextualType = context.contextualType;
            var saveInferenceContext = context.inferenceContext;
            context.contextualType = contextualType;
            context.inferenceContext = inferenceContext;
            var type = checkExpression(node, checkMode | 1 /* Contextual */ | (inferenceContext ? 2 /* Inferential */ : 0));
            // We strip literal freshness when an appropriate contextual type is present such that contextually typed
            // literals always preserve their literal types (otherwise they might widen during type inference). An alternative
            // here would be to not mark contextually typed literals as fresh in the first place.
            var result = maybeTypeOfKind(type, 2944 /* Literal */) && isLiteralOfContextualType(type, instantiateContextualType(contextualType, node)) ?
                getRegularTypeOfLiteralType(type) : type;
            context.contextualType = saveContextualType;
            context.inferenceContext = saveInferenceContext;
            return result;
        }
        function checkExpressionCached(node, checkMode) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                if (checkMode && checkMode !== 0 /* Normal */) {
                    return checkExpression(node, checkMode);
                }
                // When computing a type that we're going to cache, we need to ignore any ongoing control flow
                // analysis because variables may have transient types in indeterminable states. Moving flowLoopStart
                // to the top of the stack ensures all transient types are computed from a known point.
                var saveFlowLoopStart = flowLoopStart;
                flowLoopStart = flowLoopCount;
                links.resolvedType = checkExpression(node, checkMode);
                flowLoopStart = saveFlowLoopStart;
            }
            return links.resolvedType;
        }
        function isTypeAssertion(node) {
            node = ts.skipParentheses(node);
            return node.kind === 195 /* TypeAssertionExpression */ || node.kind === 213 /* AsExpression */;
        }
        function checkDeclarationInitializer(declaration) {
            var initializer = ts.getEffectiveInitializer(declaration);
            var type = getTypeOfExpression(initializer, /*cache*/ true);
            var widened = ts.getCombinedNodeFlags(declaration) & 2 /* Const */ ||
                ts.isDeclarationReadonly(declaration) ||
                isTypeAssertion(initializer) ||
                isLiteralOfContextualType(type, getContextualType(initializer)) ? type : getWidenedLiteralType(type);
            if (ts.isInJSFile(declaration)) {
                if (widened.flags & 98304 /* Nullable */) {
                    reportImplicitAny(declaration, anyType);
                    return anyType;
                }
                else if (isEmptyArrayLiteralType(widened)) {
                    reportImplicitAny(declaration, anyArrayType);
                    return anyArrayType;
                }
            }
            return widened;
        }
        function isLiteralOfContextualType(candidateType, contextualType) {
            if (contextualType) {
                if (contextualType.flags & 3145728 /* UnionOrIntersection */) {
                    var types = contextualType.types;
                    return ts.some(types, function (t) { return isLiteralOfContextualType(candidateType, t); });
                }
                if (contextualType.flags & 58982400 /* InstantiableNonPrimitive */) {
                    // If the contextual type is a type variable constrained to a primitive type, consider
                    // this a literal context for literals of that primitive type. For example, given a
                    // type parameter 'T extends string', infer string literal types for T.
                    var constraint = getBaseConstraintOfType(contextualType) || unknownType;
                    return maybeTypeOfKind(constraint, 4 /* String */) && maybeTypeOfKind(candidateType, 128 /* StringLiteral */) ||
                        maybeTypeOfKind(constraint, 8 /* Number */) && maybeTypeOfKind(candidateType, 256 /* NumberLiteral */) ||
                        maybeTypeOfKind(constraint, 64 /* BigInt */) && maybeTypeOfKind(candidateType, 2048 /* BigIntLiteral */) ||
                        maybeTypeOfKind(constraint, 4096 /* ESSymbol */) && maybeTypeOfKind(candidateType, 8192 /* UniqueESSymbol */) ||
                        isLiteralOfContextualType(candidateType, constraint);
                }
                // If the contextual type is a literal of a particular primitive type, we consider this a
                // literal context for all literals of that primitive type.
                return !!(contextualType.flags & (128 /* StringLiteral */ | 4194304 /* Index */) && maybeTypeOfKind(candidateType, 128 /* StringLiteral */) ||
                    contextualType.flags & 256 /* NumberLiteral */ && maybeTypeOfKind(candidateType, 256 /* NumberLiteral */) ||
                    contextualType.flags & 2048 /* BigIntLiteral */ && maybeTypeOfKind(candidateType, 2048 /* BigIntLiteral */) ||
                    contextualType.flags & 512 /* BooleanLiteral */ && maybeTypeOfKind(candidateType, 512 /* BooleanLiteral */) ||
                    contextualType.flags & 8192 /* UniqueESSymbol */ && maybeTypeOfKind(candidateType, 8192 /* UniqueESSymbol */));
            }
            return false;
        }
        function isConstContext(node) {
            var parent = node.parent;
            return ts.isAssertionExpression(parent) && ts.isConstTypeReference(parent.type) ||
                (ts.isParenthesizedExpression(parent) || ts.isArrayLiteralExpression(parent) || ts.isSpreadElement(parent)) && isConstContext(parent) ||
                (ts.isPropertyAssignment(parent) || ts.isShorthandPropertyAssignment(parent)) && isConstContext(parent.parent);
        }
        function checkExpressionForMutableLocation(node, checkMode, contextualType, forceTuple) {
            var type = checkExpression(node, checkMode, forceTuple);
            return isConstContext(node) ? getRegularTypeOfLiteralType(type) :
                isTypeAssertion(node) ? type :
                    getWidenedLiteralLikeTypeForContextualType(type, instantiateContextualType(arguments.length === 2 ? getContextualType(node) : contextualType, node));
        }
        function checkPropertyAssignment(node, checkMode) {
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name.kind === 150 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
            }
            return checkExpressionForMutableLocation(node.initializer, checkMode);
        }
        function checkObjectLiteralMethod(node, checkMode) {
            // Grammar checking
            checkGrammarMethod(node);
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name.kind === 150 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
            }
            var uninstantiatedType = checkFunctionExpressionOrObjectLiteralMethod(node, checkMode);
            return instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
        }
        function instantiateTypeWithSingleGenericCallSignature(node, type, checkMode) {
            if (checkMode && checkMode & (2 /* Inferential */ | 8 /* SkipGenericFunctions */)) {
                var callSignature = getSingleSignature(type, 0 /* Call */, /*allowMembers*/ true);
                var constructSignature = getSingleSignature(type, 1 /* Construct */, /*allowMembers*/ true);
                var signature = callSignature || constructSignature;
                if (signature && signature.typeParameters) {
                    var contextualType = getApparentTypeOfContextualType(node);
                    if (contextualType && !isMixinConstructorType(contextualType)) {
                        var contextualSignature = getSingleSignature(getNonNullableType(contextualType), callSignature ? 0 /* Call */ : 1 /* Construct */, /*allowMembers*/ false);
                        if (contextualSignature && !contextualSignature.typeParameters) {
                            if (checkMode & 8 /* SkipGenericFunctions */) {
                                skippedGenericFunction(node, checkMode);
                                return anyFunctionType;
                            }
                            var context = getInferenceContext(node);
                            // We have an expression that is an argument of a generic function for which we are performing
                            // type argument inference. The expression is of a function type with a single generic call
                            // signature and a contextual function type with a single non-generic call signature. Now check
                            // if the outer function returns a function type with a single non-generic call signature and
                            // if some of the outer function type parameters have no inferences so far. If so, we can
                            // potentially add inferred type parameters to the outer function return type.
                            var returnType = context.signature && getReturnTypeOfSignature(context.signature);
                            var returnSignature = returnType && getSingleCallOrConstructSignature(returnType);
                            if (returnSignature && !returnSignature.typeParameters && !ts.every(context.inferences, hasInferenceCandidates)) {
                                // Instantiate the signature with its own type parameters as type arguments, possibly
                                // renaming the type parameters to ensure they have unique names.
                                var uniqueTypeParameters = getUniqueTypeParameters(context, signature.typeParameters);
                                var instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, uniqueTypeParameters);
                                // Infer from the parameters of the instantiated signature to the parameters of the
                                // contextual signature starting with an empty set of inference candidates.
                                var inferences_2 = ts.map(context.inferences, function (info) { return createInferenceInfo(info.typeParameter); });
                                applyToParameterTypes(instantiatedSignature, contextualSignature, function (source, target) {
                                    inferTypes(inferences_2, source, target, /*priority*/ 0, /*contravariant*/ true);
                                });
                                if (ts.some(inferences_2, hasInferenceCandidates)) {
                                    // We have inference candidates, indicating that one or more type parameters are referenced
                                    // in the parameter types of the contextual signature. Now also infer from the return type.
                                    applyToReturnTypes(instantiatedSignature, contextualSignature, function (source, target) {
                                        inferTypes(inferences_2, source, target);
                                    });
                                    // If the type parameters for which we produced candidates do not have any inferences yet,
                                    // we adopt the new inference candidates and add the type parameters of the expression type
                                    // to the set of inferred type parameters for the outer function return type.
                                    if (!hasOverlappingInferences(context.inferences, inferences_2)) {
                                        mergeInferences(context.inferences, inferences_2);
                                        context.inferredTypeParameters = ts.concatenate(context.inferredTypeParameters, uniqueTypeParameters);
                                        return getOrCreateTypeFromSignature(instantiatedSignature);
                                    }
                                }
                            }
                            return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, context));
                        }
                    }
                }
            }
            return type;
        }
        function skippedGenericFunction(node, checkMode) {
            if (checkMode & 2 /* Inferential */) {
                // We have skipped a generic function during inferential typing. Obtain the inference context and
                // indicate this has occurred such that we know a second pass of inference is be needed.
                var context = getInferenceContext(node);
                context.flags |= 4 /* SkippedGenericFunction */;
            }
        }
        function hasInferenceCandidates(info) {
            return !!(info.candidates || info.contraCandidates);
        }
        function hasOverlappingInferences(a, b) {
            for (var i = 0; i < a.length; i++) {
                if (hasInferenceCandidates(a[i]) && hasInferenceCandidates(b[i])) {
                    return true;
                }
            }
            return false;
        }
        function mergeInferences(target, source) {
            for (var i = 0; i < target.length; i++) {
                if (!hasInferenceCandidates(target[i]) && hasInferenceCandidates(source[i])) {
                    target[i] = source[i];
                }
            }
        }
        function getUniqueTypeParameters(context, typeParameters) {
            var result = [];
            var oldTypeParameters;
            var newTypeParameters;
            for (var _i = 0, typeParameters_2 = typeParameters; _i < typeParameters_2.length; _i++) {
                var tp = typeParameters_2[_i];
                var name = tp.symbol.escapedName;
                if (hasTypeParameterByName(context.inferredTypeParameters, name) || hasTypeParameterByName(result, name)) {
                    var newName = getUniqueTypeParameterName(ts.concatenate(context.inferredTypeParameters, result), name);
                    var symbol = createSymbol(262144 /* TypeParameter */, newName);
                    var newTypeParameter = createTypeParameter(symbol);
                    newTypeParameter.target = tp;
                    oldTypeParameters = ts.append(oldTypeParameters, tp);
                    newTypeParameters = ts.append(newTypeParameters, newTypeParameter);
                    result.push(newTypeParameter);
                }
                else {
                    result.push(tp);
                }
            }
            if (newTypeParameters) {
                var mapper = createTypeMapper(oldTypeParameters, newTypeParameters);
                for (var _a = 0, newTypeParameters_1 = newTypeParameters; _a < newTypeParameters_1.length; _a++) {
                    var tp = newTypeParameters_1[_a];
                    tp.mapper = mapper;
                }
            }
            return result;
        }
        function hasTypeParameterByName(typeParameters, name) {
            return ts.some(typeParameters, function (tp) { return tp.symbol.escapedName === name; });
        }
        function getUniqueTypeParameterName(typeParameters, baseName) {
            var len = baseName.length;
            while (len > 1 && baseName.charCodeAt(len - 1) >= 48 /* _0 */ && baseName.charCodeAt(len - 1) <= 57 /* _9 */)
                len--;
            var s = baseName.slice(0, len);
            for (var index = 1; true; index++) {
                var augmentedName = (s + index);
                if (!hasTypeParameterByName(typeParameters, augmentedName)) {
                    return augmentedName;
                }
            }
        }
        /**
         * Returns the type of an expression. Unlike checkExpression, this function is simply concerned
         * with computing the type and may not fully check all contained sub-expressions for errors.
         * A cache argument of true indicates that if the function performs a full type check, it is ok
         * to cache the result.
         */
        function getTypeOfExpression(node, cache) {
            var expr = ts.skipParentheses(node);
            // Optimize for the common case of a call to a function with a single non-generic call
            // signature where we can just fetch the return type without checking the arguments.
            if (expr.kind === 192 /* CallExpression */ && expr.expression.kind !== 99 /* SuperKeyword */ && !ts.isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) {
                var funcType = checkNonNullExpression(expr.expression);
                var signature = getSingleCallSignature(funcType);
                if (signature && !signature.typeParameters) {
                    return getReturnTypeOfSignature(signature);
                }
            }
            else if (ts.isAssertionExpression(expr) && !ts.isConstTypeReference(expr.type)) {
                return getTypeFromTypeNode(expr.type);
            }
            // Otherwise simply call checkExpression. Ideally, the entire family of checkXXX functions
            // should have a parameter that indicates whether full error checking is required such that
            // we can perform the optimizations locally.
            return cache ? checkExpressionCached(node) : checkExpression(node);
        }
        /**
         * Returns the type of an expression. Unlike checkExpression, this function is simply concerned
         * with computing the type and may not fully check all contained sub-expressions for errors.
         * It is intended for uses where you know there is no contextual type,
         * and requesting the contextual type might cause a circularity or other bad behaviour.
         * It sets the contextual type of the node to any before calling getTypeOfExpression.
         */
        function getContextFreeTypeOfExpression(node) {
            var links = getNodeLinks(node);
            if (links.contextFreeType) {
                return links.contextFreeType;
            }
            var saveContextualType = node.contextualType;
            node.contextualType = anyType;
            var type = links.contextFreeType = checkExpression(node, 4 /* SkipContextSensitive */);
            node.contextualType = saveContextualType;
            return type;
        }
        function checkExpression(node, checkMode, forceTuple) {
            var saveCurrentNode = currentNode;
            currentNode = node;
            var uninstantiatedType = checkExpressionWorker(node, checkMode, forceTuple);
            var type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
            if (isConstEnumObjectType(type)) {
                checkConstEnumAccess(node, type);
            }
            currentNode = saveCurrentNode;
            return type;
        }
        function checkConstEnumAccess(node, type) {
            // enum object type for const enums are only permitted in:
            // - 'left' in property access
            // - 'object' in indexed access
            // - target in rhs of import statement
            var ok = (node.parent.kind === 190 /* PropertyAccessExpression */ && node.parent.expression === node) ||
                (node.parent.kind === 191 /* ElementAccessExpression */ && node.parent.expression === node) ||
                ((node.kind === 73 /* Identifier */ || node.kind === 149 /* QualifiedName */) && isInRightSideOfImportOrExportAssignment(node) ||
                    (node.parent.kind === 168 /* TypeQuery */ && node.parent.exprName === node));
            if (!ok) {
                error(node, ts.Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query);
            }
            if (compilerOptions.isolatedModules) {
                ts.Debug.assert(!!(type.symbol.flags & 128 /* ConstEnum */));
                var constEnumDeclaration = type.symbol.valueDeclaration;
                if (constEnumDeclaration.flags & 4194304 /* Ambient */) {
                    error(node, ts.Diagnostics.Cannot_access_ambient_const_enums_when_the_isolatedModules_flag_is_provided);
                }
            }
        }
        function checkParenthesizedExpression(node, checkMode) {
            var tag = ts.isInJSFile(node) ? ts.getJSDocTypeTag(node) : undefined;
            if (tag) {
                return checkAssertionWorker(tag, tag.typeExpression.type, node.expression, checkMode);
            }
            return checkExpression(node.expression, checkMode);
        }
        function checkExpressionWorker(node, checkMode, forceTuple) {
            switch (node.kind) {
                case 73 /* Identifier */:
                    return checkIdentifier(node);
                case 101 /* ThisKeyword */:
                    return checkThisExpression(node);
                case 99 /* SuperKeyword */:
                    return checkSuperExpression(node);
                case 97 /* NullKeyword */:
                    return nullWideningType;
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 10 /* StringLiteral */:
                    return getFreshTypeOfLiteralType(getLiteralType(node.text));
                case 8 /* NumericLiteral */:
                    checkGrammarNumericLiteral(node);
                    return getFreshTypeOfLiteralType(getLiteralType(+node.text));
                case 9 /* BigIntLiteral */:
                    checkGrammarBigIntLiteral(node);
                    return getFreshTypeOfLiteralType(getBigIntLiteralType(node));
                case 103 /* TrueKeyword */:
                    return trueType;
                case 88 /* FalseKeyword */:
                    return falseType;
                case 207 /* TemplateExpression */:
                    return checkTemplateExpression(node);
                case 13 /* RegularExpressionLiteral */:
                    return globalRegExpType;
                case 188 /* ArrayLiteralExpression */:
                    return checkArrayLiteral(node, checkMode, forceTuple);
                case 189 /* ObjectLiteralExpression */:
                    return checkObjectLiteral(node, checkMode);
                case 190 /* PropertyAccessExpression */:
                    return checkPropertyAccessExpression(node);
                case 149 /* QualifiedName */:
                    return checkQualifiedName(node);
                case 191 /* ElementAccessExpression */:
                    return checkIndexedAccess(node);
                case 192 /* CallExpression */:
                    if (node.expression.kind === 93 /* ImportKeyword */) {
                        return checkImportCallExpression(node);
                    }
                /* falls through */
                case 193 /* NewExpression */:
                    return checkCallExpression(node, checkMode);
                case 194 /* TaggedTemplateExpression */:
                    return checkTaggedTemplateExpression(node);
                case 196 /* ParenthesizedExpression */:
                    return checkParenthesizedExpression(node, checkMode);
                case 210 /* ClassExpression */:
                    return checkClassExpression(node);
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */:
                    return checkFunctionExpressionOrObjectLiteralMethod(node, checkMode);
                case 200 /* TypeOfExpression */:
                    return checkTypeOfExpression(node);
                case 195 /* TypeAssertionExpression */:
                case 213 /* AsExpression */:
                    return checkAssertion(node);
                case 214 /* NonNullExpression */:
                    return checkNonNullAssertion(node);
                case 215 /* MetaProperty */:
                    return checkMetaProperty(node);
                case 199 /* DeleteExpression */:
                    return checkDeleteExpression(node);
                case 201 /* VoidExpression */:
                    return checkVoidExpression(node);
                case 202 /* AwaitExpression */:
                    return checkAwaitExpression(node);
                case 203 /* PrefixUnaryExpression */:
                    return checkPrefixUnaryExpression(node);
                case 204 /* PostfixUnaryExpression */:
                    return checkPostfixUnaryExpression(node);
                case 205 /* BinaryExpression */:
                    return checkBinaryExpression(node, checkMode);
                case 206 /* ConditionalExpression */:
                    return checkConditionalExpression(node, checkMode);
                case 209 /* SpreadElement */:
                    return checkSpreadExpression(node, checkMode);
                case 211 /* OmittedExpression */:
                    return undefinedWideningType;
                case 208 /* YieldExpression */:
                    return checkYieldExpression(node);
                case 216 /* SyntheticExpression */:
                    return node.type;
                case 271 /* JsxExpression */:
                    return checkJsxExpression(node, checkMode);
                case 261 /* JsxElement */:
                    return checkJsxElement(node, checkMode);
                case 262 /* JsxSelfClosingElement */:
                    return checkJsxSelfClosingElement(node, checkMode);
                case 265 /* JsxFragment */:
                    return checkJsxFragment(node);
                case 269 /* JsxAttributes */:
                    return checkJsxAttributes(node, checkMode);
                case 263 /* JsxOpeningElement */:
                    ts.Debug.fail("Shouldn't ever directly check a JsxOpeningElement");
            }
            return errorType;
        }
        // DECLARATION AND STATEMENT TYPE CHECKING
        function checkTypeParameter(node) {
            // Grammar Checking
            if (node.expression) {
                grammarErrorOnFirstToken(node.expression, ts.Diagnostics.Type_expected);
            }
            checkSourceElement(node.constraint);
            checkSourceElement(node.default);
            var typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node));
            // Resolve base constraint to reveal circularity errors
            getBaseConstraintOfType(typeParameter);
            if (!hasNonCircularTypeParameterDefault(typeParameter)) {
                error(node.default, ts.Diagnostics.Type_parameter_0_has_a_circular_default, typeToString(typeParameter));
            }
            var constraintType = getConstraintOfTypeParameter(typeParameter);
            var defaultType = getDefaultFromTypeParameter(typeParameter);
            if (constraintType && defaultType) {
                checkTypeAssignableTo(defaultType, getTypeWithThisArgument(instantiateType(constraintType, makeUnaryTypeMapper(typeParameter, defaultType)), defaultType), node.default, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
            }
            if (produceDiagnostics) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_parameter_name_cannot_be_0);
            }
        }
        function checkParameter(node) {
            // Grammar checking
            // It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the
            // Identifier in a PropertySetParameterList of a PropertyAssignment that is contained in strict code
            // or if its FunctionBody is strict code(11.1.5).
            checkGrammarDecoratorsAndModifiers(node);
            checkVariableLikeDeclaration(node);
            var func = ts.getContainingFunction(node);
            if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) {
                if (!(func.kind === 158 /* Constructor */ && ts.nodeIsPresent(func.body))) {
                    error(node, ts.Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation);
                }
            }
            if (node.questionToken && ts.isBindingPattern(node.name) && func.body) {
                error(node, ts.Diagnostics.A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature);
            }
            if (node.name && ts.isIdentifier(node.name) && (node.name.escapedText === "this" || node.name.escapedText === "new")) {
                if (func.parameters.indexOf(node) !== 0) {
                    error(node, ts.Diagnostics.A_0_parameter_must_be_the_first_parameter, node.name.escapedText);
                }
                if (func.kind === 158 /* Constructor */ || func.kind === 162 /* ConstructSignature */ || func.kind === 167 /* ConstructorType */) {
                    error(node, ts.Diagnostics.A_constructor_cannot_have_a_this_parameter);
                }
                if (func.kind === 198 /* ArrowFunction */) {
                    error(node, ts.Diagnostics.An_arrow_function_cannot_have_a_this_parameter);
                }
            }
            // Only check rest parameter type if it's not a binding pattern. Since binding patterns are
            // not allowed in a rest parameter, we already have an error from checkGrammarParameterList.
            if (node.dotDotDotToken && !ts.isBindingPattern(node.name) && !isTypeAssignableTo(getTypeOfSymbol(node.symbol), anyReadonlyArrayType)) {
                error(node, ts.Diagnostics.A_rest_parameter_must_be_of_an_array_type);
            }
        }
        function checkTypePredicate(node) {
            var parent = getTypePredicateParent(node);
            if (!parent) {
                // The parent must not be valid.
                error(node, ts.Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods);
                return;
            }
            var signature = getSignatureFromDeclaration(parent);
            var typePredicate = getTypePredicateOfSignature(signature);
            if (!typePredicate) {
                return;
            }
            checkSourceElement(node.type);
            var parameterName = node.parameterName;
            if (ts.isThisTypePredicate(typePredicate)) {
                getTypeFromThisTypeNode(parameterName);
            }
            else {
                if (typePredicate.parameterIndex >= 0) {
                    if (signature.hasRestParameter && typePredicate.parameterIndex === signature.parameters.length - 1) {
                        error(parameterName, ts.Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
                    }
                    else {
                        var leadingError = function () { return ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type); };
                        checkTypeAssignableTo(typePredicate.type, getTypeOfSymbol(signature.parameters[typePredicate.parameterIndex]), node.type, 
                        /*headMessage*/ undefined, leadingError);
                    }
                }
                else if (parameterName) {
                    var hasReportedError = false;
                    for (var _i = 0, _a = parent.parameters; _i < _a.length; _i++) {
                        var name = _a[_i].name;
                        if (ts.isBindingPattern(name) &&
                            checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, parameterName, typePredicate.parameterName)) {
                            hasReportedError = true;
                            break;
                        }
                    }
                    if (!hasReportedError) {
                        error(node.parameterName, ts.Diagnostics.Cannot_find_parameter_0, typePredicate.parameterName);
                    }
                }
            }
        }
        function getTypePredicateParent(node) {
            switch (node.parent.kind) {
                case 198 /* ArrowFunction */:
                case 161 /* CallSignature */:
                case 240 /* FunctionDeclaration */:
                case 197 /* FunctionExpression */:
                case 166 /* FunctionType */:
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                    var parent = node.parent;
                    if (node === parent.type) {
                        return parent;
                    }
            }
        }
        function checkIfTypePredicateVariableIsDeclaredInBindingPattern(pattern, predicateVariableNode, predicateVariableName) {
            for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                var element = _a[_i];
                if (ts.isOmittedExpression(element)) {
                    continue;
                }
                var name = element.name;
                if (name.kind === 73 /* Identifier */ && name.escapedText === predicateVariableName) {
                    error(predicateVariableNode, ts.Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern, predicateVariableName);
                    return true;
                }
                else if (name.kind === 186 /* ArrayBindingPattern */ || name.kind === 185 /* ObjectBindingPattern */) {
                    if (checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, predicateVariableNode, predicateVariableName)) {
                        return true;
                    }
                }
            }
        }
        function checkSignatureDeclaration(node) {
            // Grammar checking
            if (node.kind === 163 /* IndexSignature */) {
                checkGrammarIndexSignature(node);
            }
            // TODO (yuisu): Remove this check in else-if when SyntaxKind.Construct is moved and ambient context is handled
            else if (node.kind === 166 /* FunctionType */ || node.kind === 240 /* FunctionDeclaration */ || node.kind === 167 /* ConstructorType */ ||
                node.kind === 161 /* CallSignature */ || node.kind === 158 /* Constructor */ ||
                node.kind === 162 /* ConstructSignature */) {
                checkGrammarFunctionLikeDeclaration(node);
            }
            var functionFlags = ts.getFunctionFlags(node);
            if (!(functionFlags & 4 /* Invalid */)) {
                // Async generators prior to ESNext require the __await and __asyncGenerator helpers
                if ((functionFlags & 3 /* AsyncGenerator */) === 3 /* AsyncGenerator */ && languageVersion < 8 /* ESNext */) {
                    checkExternalEmitHelpers(node, 6144 /* AsyncGeneratorIncludes */);
                }
                // Async functions prior to ES2017 require the __awaiter helper
                if ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */ && languageVersion < 4 /* ES2017 */) {
                    checkExternalEmitHelpers(node, 64 /* Awaiter */);
                }
                // Generator functions, Async functions, and Async Generator functions prior to
                // ES2015 require the __generator helper
                if ((functionFlags & 3 /* AsyncGenerator */) !== 0 /* Normal */ && languageVersion < 2 /* ES2015 */) {
                    checkExternalEmitHelpers(node, 128 /* Generator */);
                }
            }
            checkTypeParameters(node.typeParameters);
            ts.forEach(node.parameters, checkParameter);
            // TODO(rbuckton): Should we start checking JSDoc types?
            if (node.type) {
                checkSourceElement(node.type);
            }
            if (produceDiagnostics) {
                checkCollisionWithArgumentsInGeneratedCode(node);
                var returnTypeNode = ts.getEffectiveReturnTypeNode(node);
                if (noImplicitAny && !returnTypeNode) {
                    switch (node.kind) {
                        case 162 /* ConstructSignature */:
                            error(node, ts.Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
                            break;
                        case 161 /* CallSignature */:
                            error(node, ts.Diagnostics.Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
                            break;
                    }
                }
                if (returnTypeNode) {
                    var functionFlags_1 = ts.getFunctionFlags(node);
                    if ((functionFlags_1 & (4 /* Invalid */ | 1 /* Generator */)) === 1 /* Generator */) {
                        var returnType = getTypeFromTypeNode(returnTypeNode);
                        if (returnType === voidType) {
                            error(returnTypeNode, ts.Diagnostics.A_generator_cannot_have_a_void_type_annotation);
                        }
                        else {
                            var generatorElementType = getIteratedTypeOfGenerator(returnType, (functionFlags_1 & 2 /* Async */) !== 0) || anyType;
                            var iterableIteratorInstantiation = functionFlags_1 & 2 /* Async */
                                ? createAsyncIterableIteratorType(generatorElementType) // AsyncGenerator function
                                : createIterableIteratorType(generatorElementType); // Generator function
                            // Naively, one could check that IterableIterator<any> is assignable to the return type annotation.
                            // However, that would not catch the error in the following case.
                            //
                            //    interface BadGenerator extends Iterable<number>, Iterator<string> { }
                            //    function* g(): BadGenerator { } // Iterable and Iterator have different types!
                            //
                            checkTypeAssignableTo(iterableIteratorInstantiation, returnType, returnTypeNode);
                        }
                    }
                    else if ((functionFlags_1 & 3 /* AsyncGenerator */) === 2 /* Async */) {
                        checkAsyncFunctionReturnType(node, returnTypeNode);
                    }
                }
                if (node.kind !== 163 /* IndexSignature */ && node.kind !== 295 /* JSDocFunctionType */) {
                    registerForUnusedIdentifiersCheck(node);
                }
            }
        }
        function checkClassForDuplicateDeclarations(node) {
            var Declaration;
            (function (Declaration) {
                Declaration[Declaration["Getter"] = 1] = "Getter";
                Declaration[Declaration["Setter"] = 2] = "Setter";
                Declaration[Declaration["Method"] = 4] = "Method";
                Declaration[Declaration["Property"] = 3] = "Property";
            })(Declaration || (Declaration = {}));
            var instanceNames = ts.createUnderscoreEscapedMap();
            var staticNames = ts.createUnderscoreEscapedMap();
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                if (member.kind === 158 /* Constructor */) {
                    for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) {
                        var param = _c[_b];
                        if (ts.isParameterPropertyDeclaration(param) && !ts.isBindingPattern(param.name)) {
                            addName(instanceNames, param.name, param.name.escapedText, 3 /* Property */);
                        }
                    }
                }
                else {
                    var isStatic = ts.hasModifier(member, 32 /* Static */);
                    var names = isStatic ? staticNames : instanceNames;
                    var name = member.name;
                    var memberName = name && ts.getPropertyNameForPropertyNameNode(name);
                    if (name && memberName) {
                        switch (member.kind) {
                            case 159 /* GetAccessor */:
                                addName(names, name, memberName, 1 /* Getter */);
                                break;
                            case 160 /* SetAccessor */:
                                addName(names, name, memberName, 2 /* Setter */);
                                break;
                            case 155 /* PropertyDeclaration */:
                                addName(names, name, memberName, 3 /* Property */);
                                break;
                            case 157 /* MethodDeclaration */:
                                addName(names, name, memberName, 4 /* Method */);
                                break;
                        }
                    }
                }
            }
            function addName(names, location, name, meaning) {
                var prev = names.get(name);
                if (prev) {
                    if (prev & 4 /* Method */) {
                        if (meaning !== 4 /* Method */) {
                            error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location));
                        }
                    }
                    else if (prev & meaning) {
                        error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location));
                    }
                    else {
                        names.set(name, prev | meaning);
                    }
                }
                else {
                    names.set(name, meaning);
                }
            }
        }
        /**
         * Static members being set on a constructor function may conflict with built-in properties
         * of Function. Esp. in ECMAScript 5 there are non-configurable and non-writable
         * built-in properties. This check issues a transpile error when a class has a static
         * member with the same name as a non-writable built-in property.
         *
         * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.3
         * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5
         * @see http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-function-constructor
         * @see http://www.ecma-international.org/ecma-262/6.0/#sec-function-instances
         */
        function checkClassForStaticPropertyNameConflicts(node) {
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                var memberNameNode = member.name;
                var isStatic = ts.hasModifier(member, 32 /* Static */);
                if (isStatic && memberNameNode) {
                    var memberName = ts.getPropertyNameForPropertyNameNode(memberNameNode);
                    switch (memberName) {
                        case "name":
                        case "length":
                        case "caller":
                        case "arguments":
                        case "prototype":
                            var message = ts.Diagnostics.Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1;
                            var className = getNameOfSymbolAsWritten(getSymbolOfNode(node));
                            error(memberNameNode, message, memberName, className);
                            break;
                    }
                }
            }
        }
        function checkObjectTypeForDuplicateDeclarations(node) {
            var names = ts.createMap();
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                if (member.kind === 154 /* PropertySignature */) {
                    var memberName = void 0;
                    var name = member.name;
                    switch (name.kind) {
                        case 10 /* StringLiteral */:
                        case 8 /* NumericLiteral */:
                            memberName = name.text;
                            break;
                        case 73 /* Identifier */:
                            memberName = ts.idText(name);
                            break;
                        default:
                            continue;
                    }
                    if (names.get(memberName)) {
                        error(ts.getNameOfDeclaration(member.symbol.valueDeclaration), ts.Diagnostics.Duplicate_identifier_0, memberName);
                        error(member.name, ts.Diagnostics.Duplicate_identifier_0, memberName);
                    }
                    else {
                        names.set(memberName, true);
                    }
                }
            }
        }
        function checkTypeForDuplicateIndexSignatures(node) {
            if (node.kind === 242 /* InterfaceDeclaration */) {
                var nodeSymbol = getSymbolOfNode(node);
                // in case of merging interface declaration it is possible that we'll enter this check procedure several times for every declaration
                // to prevent this run check only for the first declaration of a given kind
                if (nodeSymbol.declarations.length > 0 && nodeSymbol.declarations[0] !== node) {
                    return;
                }
            }
            // TypeScript 1.0 spec (April 2014)
            // 3.7.4: An object type can contain at most one string index signature and one numeric index signature.
            // 8.5: A class declaration can have at most one string index member declaration and one numeric index member declaration
            var indexSymbol = getIndexSymbol(getSymbolOfNode(node));
            if (indexSymbol) {
                var seenNumericIndexer = false;
                var seenStringIndexer = false;
                for (var _i = 0, _a = indexSymbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var declaration = decl;
                    if (declaration.parameters.length === 1 && declaration.parameters[0].type) {
                        switch (declaration.parameters[0].type.kind) {
                            case 139 /* StringKeyword */:
                                if (!seenStringIndexer) {
                                    seenStringIndexer = true;
                                }
                                else {
                                    error(declaration, ts.Diagnostics.Duplicate_string_index_signature);
                                }
                                break;
                            case 136 /* NumberKeyword */:
                                if (!seenNumericIndexer) {
                                    seenNumericIndexer = true;
                                }
                                else {
                                    error(declaration, ts.Diagnostics.Duplicate_number_index_signature);
                                }
                                break;
                        }
                    }
                }
            }
        }
        function checkPropertyDeclaration(node) {
            // Grammar checking
            if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarProperty(node))
                checkGrammarComputedPropertyName(node.name);
            checkVariableLikeDeclaration(node);
        }
        function checkMethodDeclaration(node) {
            // Grammar checking
            if (!checkGrammarMethod(node))
                checkGrammarComputedPropertyName(node.name);
            // Grammar checking for modifiers is done inside the function checkGrammarFunctionLikeDeclaration
            checkFunctionOrMethodDeclaration(node);
            // Abstract methods cannot have an implementation.
            // Extra checks are to avoid reporting multiple errors relating to the "abstractness" of the node.
            if (ts.hasModifier(node, 128 /* Abstract */) && node.kind === 157 /* MethodDeclaration */ && node.body) {
                error(node, ts.Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, ts.declarationNameToString(node.name));
            }
        }
        function checkConstructorDeclaration(node) {
            // Grammar check on signature of constructor and modifier of the constructor is done in checkSignatureDeclaration function.
            checkSignatureDeclaration(node);
            // Grammar check for checking only related to constructorDeclaration
            if (!checkGrammarConstructorTypeParameters(node))
                checkGrammarConstructorTypeAnnotation(node);
            checkSourceElement(node.body);
            var symbol = getSymbolOfNode(node);
            var firstDeclaration = ts.getDeclarationOfKind(symbol, node.kind);
            // Only type check the symbol once
            if (node === firstDeclaration) {
                checkFunctionOrConstructorSymbol(symbol);
            }
            // exit early in the case of signature - super checks are not relevant to them
            if (ts.nodeIsMissing(node.body)) {
                return;
            }
            if (!produceDiagnostics) {
                return;
            }
            function isInstancePropertyWithInitializer(n) {
                return n.kind === 155 /* PropertyDeclaration */ &&
                    !ts.hasModifier(n, 32 /* Static */) &&
                    !!n.initializer;
            }
            // TS 1.0 spec (April 2014): 8.3.2
            // Constructors of classes with no extends clause may not contain super calls, whereas
            // constructors of derived classes must contain at least one super call somewhere in their function body.
            var containingClassDecl = node.parent;
            if (ts.getClassExtendsHeritageElement(containingClassDecl)) {
                captureLexicalThis(node.parent, containingClassDecl);
                var classExtendsNull = classDeclarationExtendsNull(containingClassDecl);
                var superCall = getSuperCallInConstructor(node);
                if (superCall) {
                    if (classExtendsNull) {
                        error(superCall, ts.Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null);
                    }
                    // The first statement in the body of a constructor (excluding prologue directives) must be a super call
                    // if both of the following are true:
                    // - The containing class is a derived class.
                    // - The constructor declares parameter properties
                    //   or the containing class declares instance member variables with initializers.
                    var superCallShouldBeFirst = ts.some(node.parent.members, isInstancePropertyWithInitializer) ||
                        ts.some(node.parameters, function (p) { return ts.hasModifier(p, 92 /* ParameterPropertyModifier */); });
                    // Skip past any prologue directives to find the first statement
                    // to ensure that it was a super call.
                    if (superCallShouldBeFirst) {
                        var statements = node.body.statements;
                        var superCallStatement = void 0;
                        for (var _i = 0, statements_2 = statements; _i < statements_2.length; _i++) {
                            var statement = statements_2[_i];
                            if (statement.kind === 222 /* ExpressionStatement */ && ts.isSuperCall(statement.expression)) {
                                superCallStatement = statement;
                                break;
                            }
                            if (!ts.isPrologueDirective(statement)) {
                                break;
                            }
                        }
                        if (!superCallStatement) {
                            error(node, ts.Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties);
                        }
                    }
                }
                else if (!classExtendsNull) {
                    error(node, ts.Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call);
                }
            }
        }
        function checkAccessorDeclaration(node) {
            if (produceDiagnostics) {
                // Grammar checking accessors
                if (!checkGrammarFunctionLikeDeclaration(node) && !checkGrammarAccessor(node))
                    checkGrammarComputedPropertyName(node.name);
                checkDecorators(node);
                checkSignatureDeclaration(node);
                if (node.kind === 159 /* GetAccessor */) {
                    if (!(node.flags & 4194304 /* Ambient */) && ts.nodeIsPresent(node.body) && (node.flags & 128 /* HasImplicitReturn */)) {
                        if (!(node.flags & 256 /* HasExplicitReturn */)) {
                            error(node.name, ts.Diagnostics.A_get_accessor_must_return_a_value);
                        }
                    }
                }
                // Do not use hasDynamicName here, because that returns false for well known symbols.
                // We want to perform checkComputedPropertyName for all computed properties, including
                // well known symbols.
                if (node.name.kind === 150 /* ComputedPropertyName */) {
                    checkComputedPropertyName(node.name);
                }
                if (!hasNonBindableDynamicName(node)) {
                    // TypeScript 1.0 spec (April 2014): 8.4.3
                    // Accessors for the same member name must specify the same accessibility.
                    var otherKind = node.kind === 159 /* GetAccessor */ ? 160 /* SetAccessor */ : 159 /* GetAccessor */;
                    var otherAccessor = ts.getDeclarationOfKind(getSymbolOfNode(node), otherKind);
                    if (otherAccessor) {
                        var nodeFlags = ts.getModifierFlags(node);
                        var otherFlags = ts.getModifierFlags(otherAccessor);
                        if ((nodeFlags & 28 /* AccessibilityModifier */) !== (otherFlags & 28 /* AccessibilityModifier */)) {
                            error(node.name, ts.Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility);
                        }
                        if ((nodeFlags & 128 /* Abstract */) !== (otherFlags & 128 /* Abstract */)) {
                            error(node.name, ts.Diagnostics.Accessors_must_both_be_abstract_or_non_abstract);
                        }
                        // TypeScript 1.0 spec (April 2014): 4.5
                        // If both accessors include type annotations, the specified types must be identical.
                        checkAccessorDeclarationTypesIdentical(node, otherAccessor, getAnnotatedAccessorType, ts.Diagnostics.get_and_set_accessor_must_have_the_same_type);
                        checkAccessorDeclarationTypesIdentical(node, otherAccessor, getThisTypeOfDeclaration, ts.Diagnostics.get_and_set_accessor_must_have_the_same_this_type);
                    }
                }
                var returnType = getTypeOfAccessors(getSymbolOfNode(node));
                if (node.kind === 159 /* GetAccessor */) {
                    checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType);
                }
            }
            checkSourceElement(node.body);
        }
        function checkAccessorDeclarationTypesIdentical(first, second, getAnnotatedType, message) {
            var firstType = getAnnotatedType(first);
            var secondType = getAnnotatedType(second);
            if (firstType && secondType && !isTypeIdenticalTo(firstType, secondType)) {
                error(first, message);
            }
        }
        function checkMissingDeclaration(node) {
            checkDecorators(node);
        }
        function getEffectiveTypeArguments(node, typeParameters) {
            return fillMissingTypeArguments(ts.map(node.typeArguments, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), ts.isInJSFile(node));
        }
        function checkTypeArgumentConstraints(node, typeParameters) {
            var typeArguments;
            var mapper;
            var result = true;
            for (var i = 0; i < typeParameters.length; i++) {
                var constraint = getConstraintOfTypeParameter(typeParameters[i]);
                if (constraint) {
                    if (!typeArguments) {
                        typeArguments = getEffectiveTypeArguments(node, typeParameters);
                        mapper = createTypeMapper(typeParameters, typeArguments);
                    }
                    result = result && checkTypeAssignableTo(typeArguments[i], instantiateType(constraint, mapper), node.typeArguments[i], ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
                }
            }
            return result;
        }
        function getTypeParametersForTypeReference(node) {
            var type = getTypeFromTypeReference(node);
            if (type !== errorType) {
                var symbol = getNodeLinks(node).resolvedSymbol;
                if (symbol) {
                    return symbol.flags & 524288 /* TypeAlias */ && getSymbolLinks(symbol).typeParameters ||
                        (ts.getObjectFlags(type) & 4 /* Reference */ ? type.target.localTypeParameters : undefined);
                }
            }
            return undefined;
        }
        function checkTypeReferenceNode(node) {
            checkGrammarTypeArguments(node, node.typeArguments);
            if (node.kind === 165 /* TypeReference */ && node.typeName.jsdocDotPos !== undefined && !ts.isInJSFile(node) && !ts.isInJSDoc(node)) {
                grammarErrorAtPos(node, node.typeName.jsdocDotPos, 1, ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments);
            }
            var type = getTypeFromTypeReference(node);
            if (type !== errorType) {
                if (node.typeArguments) {
                    // Do type argument local checks only if referenced type is successfully resolved
                    ts.forEach(node.typeArguments, checkSourceElement);
                    if (produceDiagnostics) {
                        var typeParameters = getTypeParametersForTypeReference(node);
                        if (typeParameters) {
                            checkTypeArgumentConstraints(node, typeParameters);
                        }
                    }
                }
                if (type.flags & 32 /* Enum */ && getNodeLinks(node).resolvedSymbol.flags & 8 /* EnumMember */) {
                    error(node, ts.Diagnostics.Enum_type_0_has_members_with_initializers_that_are_not_literals, typeToString(type));
                }
            }
        }
        function getTypeArgumentConstraint(node) {
            var typeReferenceNode = ts.tryCast(node.parent, ts.isTypeReferenceType);
            if (!typeReferenceNode)
                return undefined;
            var typeParameters = getTypeParametersForTypeReference(typeReferenceNode); // TODO: GH#18217
            var constraint = getConstraintOfTypeParameter(typeParameters[typeReferenceNode.typeArguments.indexOf(node)]);
            return constraint && instantiateType(constraint, createTypeMapper(typeParameters, getEffectiveTypeArguments(typeReferenceNode, typeParameters)));
        }
        function checkTypeQuery(node) {
            getTypeFromTypeQueryNode(node);
        }
        function checkTypeLiteral(node) {
            ts.forEach(node.members, checkSourceElement);
            if (produceDiagnostics) {
                var type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
                checkIndexConstraints(type);
                checkTypeForDuplicateIndexSignatures(node);
                checkObjectTypeForDuplicateDeclarations(node);
            }
        }
        function checkArrayType(node) {
            checkSourceElement(node.elementType);
        }
        function checkTupleType(node) {
            var elementTypes = node.elementTypes;
            var seenOptionalElement = false;
            for (var i = 0; i < elementTypes.length; i++) {
                var e = elementTypes[i];
                if (e.kind === 173 /* RestType */) {
                    if (i !== elementTypes.length - 1) {
                        grammarErrorOnNode(e, ts.Diagnostics.A_rest_element_must_be_last_in_a_tuple_type);
                        break;
                    }
                    if (!isArrayType(getTypeFromTypeNode(e))) {
                        error(e, ts.Diagnostics.A_rest_element_type_must_be_an_array_type);
                    }
                }
                else if (e.kind === 172 /* OptionalType */) {
                    seenOptionalElement = true;
                }
                else if (seenOptionalElement) {
                    grammarErrorOnNode(e, ts.Diagnostics.A_required_element_cannot_follow_an_optional_element);
                    break;
                }
            }
            ts.forEach(node.elementTypes, checkSourceElement);
        }
        function checkUnionOrIntersectionType(node) {
            ts.forEach(node.types, checkSourceElement);
        }
        function checkIndexedAccessIndexType(type, accessNode) {
            if (!(type.flags & 8388608 /* IndexedAccess */)) {
                return type;
            }
            // Check if the index type is assignable to 'keyof T' for the object type.
            var objectType = type.objectType;
            var indexType = type.indexType;
            if (isTypeAssignableTo(indexType, getIndexType(objectType, /*stringsOnly*/ false))) {
                if (accessNode.kind === 191 /* ElementAccessExpression */ && ts.isAssignmentTarget(accessNode) &&
                    ts.getObjectFlags(objectType) & 32 /* Mapped */ && getMappedTypeModifiers(objectType) & 1 /* IncludeReadonly */) {
                    error(accessNode, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
                }
                return type;
            }
            // Check if we're indexing with a numeric type and if either object or index types
            // is a generic type with a constraint that has a numeric index signature.
            if (getIndexInfoOfType(getApparentType(objectType), 1 /* Number */) && isTypeAssignableToKind(indexType, 296 /* NumberLike */)) {
                return type;
            }
            error(accessNode, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
            return errorType;
        }
        function checkIndexedAccessType(node) {
            checkSourceElement(node.objectType);
            checkSourceElement(node.indexType);
            checkIndexedAccessIndexType(getTypeFromIndexedAccessTypeNode(node), node);
        }
        function checkMappedType(node) {
            checkSourceElement(node.typeParameter);
            checkSourceElement(node.type);
            if (!node.type) {
                reportImplicitAny(node, anyType);
            }
            var type = getTypeFromMappedTypeNode(node);
            var constraintType = getConstraintTypeFromMappedType(type);
            checkTypeAssignableTo(constraintType, keyofConstraintType, ts.getEffectiveConstraintOfTypeParameter(node.typeParameter));
        }
        function checkThisType(node) {
            getTypeFromThisTypeNode(node);
        }
        function checkTypeOperator(node) {
            checkGrammarTypeOperatorNode(node);
            checkSourceElement(node.type);
        }
        function checkConditionalType(node) {
            ts.forEachChild(node, checkSourceElement);
        }
        function checkInferType(node) {
            if (!ts.findAncestor(node, function (n) { return n.parent && n.parent.kind === 176 /* ConditionalType */ && n.parent.extendsType === n; })) {
                grammarErrorOnNode(node, ts.Diagnostics.infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type);
            }
            checkSourceElement(node.typeParameter);
            registerForUnusedIdentifiersCheck(node);
        }
        function checkImportType(node) {
            checkSourceElement(node.argument);
            getTypeFromTypeNode(node);
        }
        function isPrivateWithinAmbient(node) {
            return ts.hasModifier(node, 8 /* Private */) && !!(node.flags & 4194304 /* Ambient */);
        }
        function getEffectiveDeclarationFlags(n, flagsToCheck) {
            var flags = ts.getCombinedModifierFlags(n);
            // children of classes (even ambient classes) should not be marked as ambient or export
            // because those flags have no useful semantics there.
            if (n.parent.kind !== 242 /* InterfaceDeclaration */ &&
                n.parent.kind !== 241 /* ClassDeclaration */ &&
                n.parent.kind !== 210 /* ClassExpression */ &&
                n.flags & 4194304 /* Ambient */) {
                if (!(flags & 2 /* Ambient */) && !(ts.isModuleBlock(n.parent) && ts.isModuleDeclaration(n.parent.parent) && ts.isGlobalScopeAugmentation(n.parent.parent))) {
                    // It is nested in an ambient context, which means it is automatically exported
                    flags |= 1 /* Export */;
                }
                flags |= 2 /* Ambient */;
            }
            return flags & flagsToCheck;
        }
        function checkFunctionOrConstructorSymbol(symbol) {
            if (!produceDiagnostics) {
                return;
            }
            function getCanonicalOverload(overloads, implementation) {
                // Consider the canonical set of flags to be the flags of the bodyDeclaration or the first declaration
                // Error on all deviations from this canonical set of flags
                // The caveat is that if some overloads are defined in lib.d.ts, we don't want to
                // report the errors on those. To achieve this, we will say that the implementation is
                // the canonical signature only if it is in the same container as the first overload
                var implementationSharesContainerWithFirstOverload = implementation !== undefined && implementation.parent === overloads[0].parent;
                return implementationSharesContainerWithFirstOverload ? implementation : overloads[0];
            }
            function checkFlagAgreementBetweenOverloads(overloads, implementation, flagsToCheck, someOverloadFlags, allOverloadFlags) {
                // Error if some overloads have a flag that is not shared by all overloads. To find the
                // deviations, we XOR someOverloadFlags with allOverloadFlags
                var someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags;
                if (someButNotAllOverloadFlags !== 0) {
                    var canonicalFlags_1 = getEffectiveDeclarationFlags(getCanonicalOverload(overloads, implementation), flagsToCheck);
                    ts.forEach(overloads, function (o) {
                        var deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags_1;
                        if (deviation & 1 /* Export */) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported);
                        }
                        else if (deviation & 2 /* Ambient */) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient);
                        }
                        else if (deviation & (8 /* Private */ | 16 /* Protected */)) {
                            error(ts.getNameOfDeclaration(o) || o, ts.Diagnostics.Overload_signatures_must_all_be_public_private_or_protected);
                        }
                        else if (deviation & 128 /* Abstract */) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_abstract_or_non_abstract);
                        }
                    });
                }
            }
            function checkQuestionTokenAgreementBetweenOverloads(overloads, implementation, someHaveQuestionToken, allHaveQuestionToken) {
                if (someHaveQuestionToken !== allHaveQuestionToken) {
                    var canonicalHasQuestionToken_1 = ts.hasQuestionToken(getCanonicalOverload(overloads, implementation));
                    ts.forEach(overloads, function (o) {
                        var deviation = ts.hasQuestionToken(o) !== canonicalHasQuestionToken_1;
                        if (deviation) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_optional_or_required);
                        }
                    });
                }
            }
            var flagsToCheck = 1 /* Export */ | 2 /* Ambient */ | 8 /* Private */ | 16 /* Protected */ | 128 /* Abstract */;
            var someNodeFlags = 0 /* None */;
            var allNodeFlags = flagsToCheck;
            var someHaveQuestionToken = false;
            var allHaveQuestionToken = true;
            var hasOverloads = false;
            var bodyDeclaration;
            var lastSeenNonAmbientDeclaration;
            var previousDeclaration;
            var declarations = symbol.declarations;
            var isConstructor = (symbol.flags & 16384 /* Constructor */) !== 0;
            function reportImplementationExpectedError(node) {
                if (node.name && ts.nodeIsMissing(node.name)) {
                    return;
                }
                var seen = false;
                var subsequentNode = ts.forEachChild(node.parent, function (c) {
                    if (seen) {
                        return c;
                    }
                    else {
                        seen = c === node;
                    }
                });
                // We may be here because of some extra nodes between overloads that could not be parsed into a valid node.
                // In this case the subsequent node is not really consecutive (.pos !== node.end), and we must ignore it here.
                if (subsequentNode && subsequentNode.pos === node.end) {
                    if (subsequentNode.kind === node.kind) {
                        var errorNode_1 = subsequentNode.name || subsequentNode;
                        // TODO: GH#17345: These are methods, so handle computed name case. (`Always allowing computed property names is *not* the correct behavior!)
                        var subsequentName = subsequentNode.name;
                        if (node.name && subsequentName &&
                            (ts.isComputedPropertyName(node.name) && ts.isComputedPropertyName(subsequentName) ||
                                !ts.isComputedPropertyName(node.name) && !ts.isComputedPropertyName(subsequentName) && ts.getEscapedTextOfIdentifierOrLiteral(node.name) === ts.getEscapedTextOfIdentifierOrLiteral(subsequentName))) {
                            var reportError = (node.kind === 157 /* MethodDeclaration */ || node.kind === 156 /* MethodSignature */) &&
                                ts.hasModifier(node, 32 /* Static */) !== ts.hasModifier(subsequentNode, 32 /* Static */);
                            // we can get here in two cases
                            // 1. mixed static and instance class members
                            // 2. something with the same name was defined before the set of overloads that prevents them from merging
                            // here we'll report error only for the first case since for second we should already report error in binder
                            if (reportError) {
                                var diagnostic = ts.hasModifier(node, 32 /* Static */) ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static;
                                error(errorNode_1, diagnostic);
                            }
                            return;
                        }
                        else if (ts.nodeIsPresent(subsequentNode.body)) {
                            error(errorNode_1, ts.Diagnostics.Function_implementation_name_must_be_0, ts.declarationNameToString(node.name));
                            return;
                        }
                    }
                }
                var errorNode = node.name || node;
                if (isConstructor) {
                    error(errorNode, ts.Diagnostics.Constructor_implementation_is_missing);
                }
                else {
                    // Report different errors regarding non-consecutive blocks of declarations depending on whether
                    // the node in question is abstract.
                    if (ts.hasModifier(node, 128 /* Abstract */)) {
                        error(errorNode, ts.Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive);
                    }
                    else {
                        error(errorNode, ts.Diagnostics.Function_implementation_is_missing_or_not_immediately_following_the_declaration);
                    }
                }
            }
            var duplicateFunctionDeclaration = false;
            var multipleConstructorImplementation = false;
            for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) {
                var current = declarations_4[_i];
                var node = current;
                var inAmbientContext = node.flags & 4194304 /* Ambient */;
                var inAmbientContextOrInterface = node.parent.kind === 242 /* InterfaceDeclaration */ || node.parent.kind === 169 /* TypeLiteral */ || inAmbientContext;
                if (inAmbientContextOrInterface) {
                    // check if declarations are consecutive only if they are non-ambient
                    // 1. ambient declarations can be interleaved
                    // i.e. this is legal
                    //     declare function foo();
                    //     declare function bar();
                    //     declare function foo();
                    // 2. mixing ambient and non-ambient declarations is a separate error that will be reported - do not want to report an extra one
                    previousDeclaration = undefined;
                }
                if (node.kind === 240 /* FunctionDeclaration */ || node.kind === 157 /* MethodDeclaration */ || node.kind === 156 /* MethodSignature */ || node.kind === 158 /* Constructor */) {
                    var currentNodeFlags = getEffectiveDeclarationFlags(node, flagsToCheck);
                    someNodeFlags |= currentNodeFlags;
                    allNodeFlags &= currentNodeFlags;
                    someHaveQuestionToken = someHaveQuestionToken || ts.hasQuestionToken(node);
                    allHaveQuestionToken = allHaveQuestionToken && ts.hasQuestionToken(node);
                    if (ts.nodeIsPresent(node.body) && bodyDeclaration) {
                        if (isConstructor) {
                            multipleConstructorImplementation = true;
                        }
                        else {
                            duplicateFunctionDeclaration = true;
                        }
                    }
                    else if (previousDeclaration && previousDeclaration.parent === node.parent && previousDeclaration.end !== node.pos) {
                        reportImplementationExpectedError(previousDeclaration);
                    }
                    if (ts.nodeIsPresent(node.body)) {
                        if (!bodyDeclaration) {
                            bodyDeclaration = node;
                        }
                    }
                    else {
                        hasOverloads = true;
                    }
                    previousDeclaration = node;
                    if (!inAmbientContextOrInterface) {
                        lastSeenNonAmbientDeclaration = node;
                    }
                }
            }
            if (multipleConstructorImplementation) {
                ts.forEach(declarations, function (declaration) {
                    error(declaration, ts.Diagnostics.Multiple_constructor_implementations_are_not_allowed);
                });
            }
            if (duplicateFunctionDeclaration) {
                ts.forEach(declarations, function (declaration) {
                    error(ts.getNameOfDeclaration(declaration), ts.Diagnostics.Duplicate_function_implementation);
                });
            }
            // Abstract methods can't have an implementation -- in particular, they don't need one.
            if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
                !ts.hasModifier(lastSeenNonAmbientDeclaration, 128 /* Abstract */) && !lastSeenNonAmbientDeclaration.questionToken) {
                reportImplementationExpectedError(lastSeenNonAmbientDeclaration);
            }
            if (hasOverloads) {
                checkFlagAgreementBetweenOverloads(declarations, bodyDeclaration, flagsToCheck, someNodeFlags, allNodeFlags);
                checkQuestionTokenAgreementBetweenOverloads(declarations, bodyDeclaration, someHaveQuestionToken, allHaveQuestionToken);
                if (bodyDeclaration) {
                    var signatures = getSignaturesOfSymbol(symbol);
                    var bodySignature = getSignatureFromDeclaration(bodyDeclaration);
                    for (var _a = 0, signatures_6 = signatures; _a < signatures_6.length; _a++) {
                        var signature = signatures_6[_a];
                        if (!isImplementationCompatibleWithOverload(bodySignature, signature)) {
                            ts.addRelatedInfo(error(signature.declaration, ts.Diagnostics.This_overload_signature_is_not_compatible_with_its_implementation_signature), ts.createDiagnosticForNode(bodyDeclaration, ts.Diagnostics.The_implementation_signature_is_declared_here));
                            break;
                        }
                    }
                }
            }
        }
        var DeclarationSpaces;
        (function (DeclarationSpaces) {
            DeclarationSpaces[DeclarationSpaces["None"] = 0] = "None";
            DeclarationSpaces[DeclarationSpaces["ExportValue"] = 1] = "ExportValue";
            DeclarationSpaces[DeclarationSpaces["ExportType"] = 2] = "ExportType";
            DeclarationSpaces[DeclarationSpaces["ExportNamespace"] = 4] = "ExportNamespace";
        })(DeclarationSpaces || (DeclarationSpaces = {}));
        function checkExportsOnMergedDeclarations(node) {
            if (!produceDiagnostics) {
                return;
            }
            // if localSymbol is defined on node then node itself is exported - check is required
            var symbol = node.localSymbol;
            if (!symbol) {
                // local symbol is undefined => this declaration is non-exported.
                // however symbol might contain other declarations that are exported
                symbol = getSymbolOfNode(node);
                if (!symbol.exportSymbol) {
                    // this is a pure local symbol (all declarations are non-exported) - no need to check anything
                    return;
                }
            }
            // run the check only for the first declaration in the list
            if (ts.getDeclarationOfKind(symbol, node.kind) !== node) {
                return;
            }
            var exportedDeclarationSpaces = 0 /* None */;
            var nonExportedDeclarationSpaces = 0 /* None */;
            var defaultExportedDeclarationSpaces = 0 /* None */;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var d = _a[_i];
                var declarationSpaces = getDeclarationSpaces(d);
                var effectiveDeclarationFlags = getEffectiveDeclarationFlags(d, 1 /* Export */ | 512 /* Default */);
                if (effectiveDeclarationFlags & 1 /* Export */) {
                    if (effectiveDeclarationFlags & 512 /* Default */) {
                        defaultExportedDeclarationSpaces |= declarationSpaces;
                    }
                    else {
                        exportedDeclarationSpaces |= declarationSpaces;
                    }
                }
                else {
                    nonExportedDeclarationSpaces |= declarationSpaces;
                }
            }
            // Spaces for anything not declared a 'default export'.
            var nonDefaultExportedDeclarationSpaces = exportedDeclarationSpaces | nonExportedDeclarationSpaces;
            var commonDeclarationSpacesForExportsAndLocals = exportedDeclarationSpaces & nonExportedDeclarationSpaces;
            var commonDeclarationSpacesForDefaultAndNonDefault = defaultExportedDeclarationSpaces & nonDefaultExportedDeclarationSpaces;
            if (commonDeclarationSpacesForExportsAndLocals || commonDeclarationSpacesForDefaultAndNonDefault) {
                // declaration spaces for exported and non-exported declarations intersect
                for (var _b = 0, _c = symbol.declarations; _b < _c.length; _b++) {
                    var d = _c[_b];
                    var declarationSpaces = getDeclarationSpaces(d);
                    var name = ts.getNameOfDeclaration(d);
                    // Only error on the declarations that contributed to the intersecting spaces.
                    if (declarationSpaces & commonDeclarationSpacesForDefaultAndNonDefault) {
                        error(name, ts.Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead, ts.declarationNameToString(name));
                    }
                    else if (declarationSpaces & commonDeclarationSpacesForExportsAndLocals) {
                        error(name, ts.Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, ts.declarationNameToString(name));
                    }
                }
            }
            function getDeclarationSpaces(decl) {
                var d = decl;
                switch (d.kind) {
                    case 242 /* InterfaceDeclaration */:
                    case 243 /* TypeAliasDeclaration */:
                    // A jsdoc typedef and callback are, by definition, type aliases
                    case 310 /* JSDocTypedefTag */:
                    case 303 /* JSDocCallbackTag */:
                        return 2 /* ExportType */;
                    case 245 /* ModuleDeclaration */:
                        return ts.isAmbientModule(d) || ts.getModuleInstanceState(d) !== 0 /* NonInstantiated */
                            ? 4 /* ExportNamespace */ | 1 /* ExportValue */
                            : 4 /* ExportNamespace */;
                    case 241 /* ClassDeclaration */:
                    case 244 /* EnumDeclaration */:
                        return 2 /* ExportType */ | 1 /* ExportValue */;
                    case 285 /* SourceFile */:
                        return 2 /* ExportType */ | 1 /* ExportValue */ | 4 /* ExportNamespace */;
                    case 255 /* ExportAssignment */:
                        // Export assigned entity name expressions act as aliases and should fall through, otherwise they export values
                        if (!ts.isEntityNameExpression(d.expression)) {
                            return 1 /* ExportValue */;
                        }
                        d = d.expression;
                    /* falls through */
                    // The below options all declare an Alias, which is allowed to merge with other values within the importing module
                    case 249 /* ImportEqualsDeclaration */:
                    case 252 /* NamespaceImport */:
                    case 251 /* ImportClause */:
                        var result_7 = 0 /* None */;
                        var target = resolveAlias(getSymbolOfNode(d));
                        ts.forEach(target.declarations, function (d) { result_7 |= getDeclarationSpaces(d); });
                        return result_7;
                    case 238 /* VariableDeclaration */:
                    case 187 /* BindingElement */:
                    case 240 /* FunctionDeclaration */:
                    case 254 /* ImportSpecifier */: // https://github.com/Microsoft/TypeScript/pull/7591
                        return 1 /* ExportValue */;
                    default:
                        return ts.Debug.failBadSyntaxKind(d);
                }
            }
        }
        function getAwaitedTypeOfPromise(type, errorNode, diagnosticMessage) {
            var promisedType = getPromisedTypeOfPromise(type, errorNode);
            return promisedType && getAwaitedType(promisedType, errorNode, diagnosticMessage);
        }
        /**
         * Gets the "promised type" of a promise.
         * @param type The type of the promise.
         * @remarks The "promised type" of a type is the type of the "value" parameter of the "onfulfilled" callback.
         */
        function getPromisedTypeOfPromise(promise, errorNode) {
            //
            //  { // promise
            //      then( // thenFunction
            //          onfulfilled: ( // onfulfilledParameterType
            //              value: T // valueParameterType
            //          ) => any
            //      ): any;
            //  }
            //
            if (isTypeAny(promise)) {
                return undefined;
            }
            var typeAsPromise = promise;
            if (typeAsPromise.promisedTypeOfPromise) {
                return typeAsPromise.promisedTypeOfPromise;
            }
            if (isReferenceToType(promise, getGlobalPromiseType(/*reportErrors*/ false))) {
                return typeAsPromise.promisedTypeOfPromise = promise.typeArguments[0];
            }
            var thenFunction = getTypeOfPropertyOfType(promise, "then"); // TODO: GH#18217
            if (isTypeAny(thenFunction)) {
                return undefined;
            }
            var thenSignatures = thenFunction ? getSignaturesOfType(thenFunction, 0 /* Call */) : ts.emptyArray;
            if (thenSignatures.length === 0) {
                if (errorNode) {
                    error(errorNode, ts.Diagnostics.A_promise_must_have_a_then_method);
                }
                return undefined;
            }
            var onfulfilledParameterType = getTypeWithFacts(getUnionType(ts.map(thenSignatures, getTypeOfFirstParameterOfSignature)), 2097152 /* NEUndefinedOrNull */);
            if (isTypeAny(onfulfilledParameterType)) {
                return undefined;
            }
            var onfulfilledParameterSignatures = getSignaturesOfType(onfulfilledParameterType, 0 /* Call */);
            if (onfulfilledParameterSignatures.length === 0) {
                if (errorNode) {
                    error(errorNode, ts.Diagnostics.The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback);
                }
                return undefined;
            }
            return typeAsPromise.promisedTypeOfPromise = getUnionType(ts.map(onfulfilledParameterSignatures, getTypeOfFirstParameterOfSignature), 2 /* Subtype */);
        }
        /**
         * Gets the "awaited type" of a type.
         * @param type The type to await.
         * @remarks The "awaited type" of an expression is its "promised type" if the expression is a
         * Promise-like type; otherwise, it is the type of the expression. This is used to reflect
         * The runtime behavior of the `await` keyword.
         */
        function checkAwaitedType(type, errorNode, diagnosticMessage) {
            return getAwaitedType(type, errorNode, diagnosticMessage) || errorType;
        }
        function getAwaitedType(type, errorNode, diagnosticMessage) {
            var typeAsAwaitable = type;
            if (typeAsAwaitable.awaitedTypeOfType) {
                return typeAsAwaitable.awaitedTypeOfType;
            }
            if (isTypeAny(type)) {
                return typeAsAwaitable.awaitedTypeOfType = type;
            }
            if (type.flags & 1048576 /* Union */) {
                var types = void 0;
                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                    var constituentType = _a[_i];
                    types = ts.append(types, getAwaitedType(constituentType, errorNode, diagnosticMessage));
                }
                if (!types) {
                    return undefined;
                }
                return typeAsAwaitable.awaitedTypeOfType = getUnionType(types);
            }
            var promisedType = getPromisedTypeOfPromise(type);
            if (promisedType) {
                if (type.id === promisedType.id || awaitedTypeStack.indexOf(promisedType.id) >= 0) {
                    // Verify that we don't have a bad actor in the form of a promise whose
                    // promised type is the same as the promise type, or a mutually recursive
                    // promise. If so, we return undefined as we cannot guess the shape. If this
                    // were the actual case in the JavaScript, this Promise would never resolve.
                    //
                    // An example of a bad actor with a singly-recursive promise type might
                    // be:
                    //
                    //  interface BadPromise {
                    //      then(
                    //          onfulfilled: (value: BadPromise) => any,
                    //          onrejected: (error: any) => any): BadPromise;
                    //  }
                    // The above interface will pass the PromiseLike check, and return a
                    // promised type of `BadPromise`. Since this is a self reference, we
                    // don't want to keep recursing ad infinitum.
                    //
                    // An example of a bad actor in the form of a mutually-recursive
                    // promise type might be:
                    //
                    //  interface BadPromiseA {
                    //      then(
                    //          onfulfilled: (value: BadPromiseB) => any,
                    //          onrejected: (error: any) => any): BadPromiseB;
                    //  }
                    //
                    //  interface BadPromiseB {
                    //      then(
                    //          onfulfilled: (value: BadPromiseA) => any,
                    //          onrejected: (error: any) => any): BadPromiseA;
                    //  }
                    //
                    if (errorNode) {
                        error(errorNode, ts.Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method);
                    }
                    return undefined;
                }
                // Keep track of the type we're about to unwrap to avoid bad recursive promise types.
                // See the comments above for more information.
                awaitedTypeStack.push(type.id);
                var awaitedType = getAwaitedType(promisedType, errorNode, diagnosticMessage);
                awaitedTypeStack.pop();
                if (!awaitedType) {
                    return undefined;
                }
                return typeAsAwaitable.awaitedTypeOfType = awaitedType;
            }
            // The type was not a promise, so it could not be unwrapped any further.
            // As long as the type does not have a callable "then" property, it is
            // safe to return the type; otherwise, an error will be reported in
            // the call to getNonThenableType and we will return undefined.
            //
            // An example of a non-promise "thenable" might be:
            //
            //  await { then(): void {} }
            //
            // The "thenable" does not match the minimal definition for a promise. When
            // a Promise/A+-compatible or ES6 promise tries to adopt this value, the promise
            // will never settle. We treat this as an error to help flag an early indicator
            // of a runtime problem. If the user wants to return this value from an async
            // function, they would need to wrap it in some other value. If they want it to
            // be treated as a promise, they can cast to <any>.
            var thenFunction = getTypeOfPropertyOfType(type, "then");
            if (thenFunction && getSignaturesOfType(thenFunction, 0 /* Call */).length > 0) {
                if (errorNode) {
                    if (!diagnosticMessage)
                        return ts.Debug.fail();
                    error(errorNode, diagnosticMessage);
                }
                return undefined;
            }
            return typeAsAwaitable.awaitedTypeOfType = type;
        }
        /**
         * Checks the return type of an async function to ensure it is a compatible
         * Promise implementation.
         *
         * This checks that an async function has a valid Promise-compatible return type.
         * An async function has a valid Promise-compatible return type if the resolved value
         * of the return type has a construct signature that takes in an `initializer` function
         * that in turn supplies a `resolve` function as one of its arguments and results in an
         * object with a callable `then` signature.
         *
         * @param node The signature to check
         */
        function checkAsyncFunctionReturnType(node, returnTypeNode) {
            // As part of our emit for an async function, we will need to emit the entity name of
            // the return type annotation as an expression. To meet the necessary runtime semantics
            // for __awaiter, we must also check that the type of the declaration (e.g. the static
            // side or "constructor" of the promise type) is compatible `PromiseConstructorLike`.
            //
            // An example might be (from lib.es6.d.ts):
            //
            //  interface Promise<T> { ... }
            //  interface PromiseConstructor {
            //      new <T>(...): Promise<T>;
            //  }
            //  declare var Promise: PromiseConstructor;
            //
            // When an async function declares a return type annotation of `Promise<T>`, we
            // need to get the type of the `Promise` variable declaration above, which would
            // be `PromiseConstructor`.
            //
            // The same case applies to a class:
            //
            //  declare class Promise<T> {
            //      constructor(...);
            //      then<U>(...): Promise<U>;
            //  }
            //
            var returnType = getTypeFromTypeNode(returnTypeNode);
            if (languageVersion >= 2 /* ES2015 */) {
                if (returnType === errorType) {
                    return;
                }
                var globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
                if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) {
                    // The promise type was not a valid type reference to the global promise type, so we
                    // report an error and return the unknown type.
                    error(returnTypeNode, ts.Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type);
                    return;
                }
            }
            else {
                // Always mark the type node as referenced if it points to a value
                markTypeNodeAsReferenced(returnTypeNode);
                if (returnType === errorType) {
                    return;
                }
                var promiseConstructorName = ts.getEntityNameFromTypeNode(returnTypeNode);
                if (promiseConstructorName === undefined) {
                    error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType));
                    return;
                }
                var promiseConstructorSymbol = resolveEntityName(promiseConstructorName, 67220415 /* Value */, /*ignoreErrors*/ true);
                var promiseConstructorType = promiseConstructorSymbol ? getTypeOfSymbol(promiseConstructorSymbol) : errorType;
                if (promiseConstructorType === errorType) {
                    if (promiseConstructorName.kind === 73 /* Identifier */ && promiseConstructorName.escapedText === "Promise" && getTargetType(returnType) === getGlobalPromiseType(/*reportErrors*/ false)) {
                        error(returnTypeNode, ts.Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
                    }
                    else {
                        error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, ts.entityNameToString(promiseConstructorName));
                    }
                    return;
                }
                var globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType(/*reportErrors*/ true);
                if (globalPromiseConstructorLikeType === emptyObjectType) {
                    // If we couldn't resolve the global PromiseConstructorLike type we cannot verify
                    // compatibility with __awaiter.
                    error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, ts.entityNameToString(promiseConstructorName));
                    return;
                }
                if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value)) {
                    return;
                }
                // Verify there is no local declaration that could collide with the promise constructor.
                var rootName = promiseConstructorName && getFirstIdentifier(promiseConstructorName);
                var collidingSymbol = getSymbol(node.locals, rootName.escapedText, 67220415 /* Value */);
                if (collidingSymbol) {
                    error(collidingSymbol.valueDeclaration, ts.Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, ts.idText(rootName), ts.entityNameToString(promiseConstructorName));
                    return;
                }
            }
            checkAwaitedType(returnType, node, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
        }
        /** Check a decorator */
        function checkDecorator(node) {
            var signature = getResolvedSignature(node);
            var returnType = getReturnTypeOfSignature(signature);
            if (returnType.flags & 1 /* Any */) {
                return;
            }
            var expectedReturnType;
            var headMessage = getDiagnosticHeadMessageForDecoratorResolution(node);
            var errorInfo;
            switch (node.parent.kind) {
                case 241 /* ClassDeclaration */:
                    var classSymbol = getSymbolOfNode(node.parent);
                    var classConstructorType = getTypeOfSymbol(classSymbol);
                    expectedReturnType = getUnionType([classConstructorType, voidType]);
                    break;
                case 152 /* Parameter */:
                    expectedReturnType = voidType;
                    errorInfo = ts.chainDiagnosticMessages(
                    /*details*/ undefined, ts.Diagnostics.The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any);
                    break;
                case 155 /* PropertyDeclaration */:
                    expectedReturnType = voidType;
                    errorInfo = ts.chainDiagnosticMessages(
                    /*details*/ undefined, ts.Diagnostics.The_return_type_of_a_property_decorator_function_must_be_either_void_or_any);
                    break;
                case 157 /* MethodDeclaration */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    var methodType = getTypeOfNode(node.parent);
                    var descriptorType = createTypedPropertyDescriptorType(methodType);
                    expectedReturnType = getUnionType([descriptorType, voidType]);
                    break;
                default:
                    return ts.Debug.fail();
            }
            checkTypeAssignableTo(returnType, expectedReturnType, node, headMessage, function () { return errorInfo; });
        }
        /**
         * If a TypeNode can be resolved to a value symbol imported from an external module, it is
         * marked as referenced to prevent import elision.
         */
        function markTypeNodeAsReferenced(node) {
            markEntityNameOrEntityExpressionAsReference(node && ts.getEntityNameFromTypeNode(node));
        }
        function markEntityNameOrEntityExpressionAsReference(typeName) {
            if (!typeName)
                return;
            var rootName = getFirstIdentifier(typeName);
            var meaning = (typeName.kind === 73 /* Identifier */ ? 67897832 /* Type */ : 1920 /* Namespace */) | 2097152 /* Alias */;
            var rootSymbol = resolveName(rootName, rootName.escapedText, meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isRefernce*/ true);
            if (rootSymbol
                && rootSymbol.flags & 2097152 /* Alias */
                && symbolIsValue(rootSymbol)
                && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) {
                markAliasSymbolAsReferenced(rootSymbol);
            }
        }
        /**
         * This function marks the type used for metadata decorator as referenced if it is import
         * from external module.
         * This is different from markTypeNodeAsReferenced because it tries to simplify type nodes in
         * union and intersection type
         * @param node
         */
        function markDecoratorMedataDataTypeNodeAsReferenced(node) {
            var entityName = getEntityNameForDecoratorMetadata(node);
            if (entityName && ts.isEntityName(entityName)) {
                markEntityNameOrEntityExpressionAsReference(entityName);
            }
        }
        function getEntityNameForDecoratorMetadata(node) {
            if (node) {
                switch (node.kind) {
                    case 175 /* IntersectionType */:
                    case 174 /* UnionType */:
                        return getEntityNameForDecoratorMetadataFromTypeList(node.types);
                    case 176 /* ConditionalType */:
                        return getEntityNameForDecoratorMetadataFromTypeList([node.trueType, node.falseType]);
                    case 178 /* ParenthesizedType */:
                        return getEntityNameForDecoratorMetadata(node.type);
                    case 165 /* TypeReference */:
                        return node.typeName;
                }
            }
        }
        function getEntityNameForDecoratorMetadataFromTypeList(types) {
            var commonEntityName;
            for (var _i = 0, types_16 = types; _i < types_16.length; _i++) {
                var typeNode = types_16[_i];
                while (typeNode.kind === 178 /* ParenthesizedType */) {
                    typeNode = typeNode.type; // Skip parens if need be
                }
                if (typeNode.kind === 133 /* NeverKeyword */) {
                    continue; // Always elide `never` from the union/intersection if possible
                }
                if (!strictNullChecks && (typeNode.kind === 97 /* NullKeyword */ || typeNode.kind === 142 /* UndefinedKeyword */)) {
                    continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks
                }
                var individualEntityName = getEntityNameForDecoratorMetadata(typeNode);
                if (!individualEntityName) {
                    // Individual is something like string number
                    // So it would be serialized to either that type or object
                    // Safe to return here
                    return undefined;
                }
                if (commonEntityName) {
                    // Note this is in sync with the transformation that happens for type node.
                    // Keep this in sync with serializeUnionOrIntersectionType
                    // Verify if they refer to same entity and is identifier
                    // return undefined if they dont match because we would emit object
                    if (!ts.isIdentifier(commonEntityName) ||
                        !ts.isIdentifier(individualEntityName) ||
                        commonEntityName.escapedText !== individualEntityName.escapedText) {
                        return undefined;
                    }
                }
                else {
                    commonEntityName = individualEntityName;
                }
            }
            return commonEntityName;
        }
        function getParameterTypeNodeForDecoratorCheck(node) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(node);
            return ts.isRestParameter(node) ? ts.getRestParameterElementType(typeNode) : typeNode;
        }
        /** Check the decorators of a node */
        function checkDecorators(node) {
            if (!node.decorators) {
                return;
            }
            // skip this check for nodes that cannot have decorators. These should have already had an error reported by
            // checkGrammarDecorators.
            if (!ts.nodeCanBeDecorated(node, node.parent, node.parent.parent)) {
                return;
            }
            if (!compilerOptions.experimentalDecorators) {
                error(node, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning);
            }
            var firstDecorator = node.decorators[0];
            checkExternalEmitHelpers(firstDecorator, 8 /* Decorate */);
            if (node.kind === 152 /* Parameter */) {
                checkExternalEmitHelpers(firstDecorator, 32 /* Param */);
            }
            if (compilerOptions.emitDecoratorMetadata) {
                checkExternalEmitHelpers(firstDecorator, 16 /* Metadata */);
                // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator.
                switch (node.kind) {
                    case 241 /* ClassDeclaration */:
                        var constructor = ts.getFirstConstructorWithBody(node);
                        if (constructor) {
                            for (var _i = 0, _a = constructor.parameters; _i < _a.length; _i++) {
                                var parameter = _a[_i];
                                markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
                            }
                        }
                        break;
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                        var otherKind = node.kind === 159 /* GetAccessor */ ? 160 /* SetAccessor */ : 159 /* GetAccessor */;
                        var otherAccessor = ts.getDeclarationOfKind(getSymbolOfNode(node), otherKind);
                        markDecoratorMedataDataTypeNodeAsReferenced(getAnnotatedAccessorTypeNode(node) || otherAccessor && getAnnotatedAccessorTypeNode(otherAccessor));
                        break;
                    case 157 /* MethodDeclaration */:
                        for (var _b = 0, _c = node.parameters; _b < _c.length; _b++) {
                            var parameter = _c[_b];
                            markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
                        }
                        markDecoratorMedataDataTypeNodeAsReferenced(ts.getEffectiveReturnTypeNode(node));
                        break;
                    case 155 /* PropertyDeclaration */:
                        markDecoratorMedataDataTypeNodeAsReferenced(ts.getEffectiveTypeAnnotationNode(node));
                        break;
                    case 152 /* Parameter */:
                        markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(node));
                        var containingSignature = node.parent;
                        for (var _d = 0, _e = containingSignature.parameters; _d < _e.length; _d++) {
                            var parameter = _e[_d];
                            markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
                        }
                        break;
                }
            }
            ts.forEach(node.decorators, checkDecorator);
        }
        function checkFunctionDeclaration(node) {
            if (produceDiagnostics) {
                checkFunctionOrMethodDeclaration(node);
                checkGrammarForGenerator(node);
                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            }
        }
        function checkJSDocTypeAliasTag(node) {
            if (!node.typeExpression) {
                // If the node had `@property` tags, `typeExpression` would have been set to the first property tag.
                error(node.name, ts.Diagnostics.JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags);
            }
            if (node.name) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_alias_name_cannot_be_0);
            }
            checkSourceElement(node.typeExpression);
        }
        function checkJSDocTemplateTag(node) {
            checkSourceElement(node.constraint);
            for (var _i = 0, _a = node.typeParameters; _i < _a.length; _i++) {
                var tp = _a[_i];
                checkSourceElement(tp);
            }
        }
        function checkJSDocTypeTag(node) {
            checkSourceElement(node.typeExpression);
        }
        function checkJSDocParameterTag(node) {
            checkSourceElement(node.typeExpression);
            if (!ts.getParameterSymbolFromJSDoc(node)) {
                var decl = ts.getHostSignatureFromJSDoc(node);
                // don't issue an error for invalid hosts -- just functions --
                // and give a better error message when the host function mentions `arguments`
                // but the tag doesn't have an array type
                if (decl) {
                    var i = ts.getJSDocTags(decl).filter(ts.isJSDocParameterTag).indexOf(node);
                    if (i > -1 && i < decl.parameters.length && ts.isBindingPattern(decl.parameters[i].name)) {
                        return;
                    }
                    if (!containsArgumentsReference(decl)) {
                        if (ts.isQualifiedName(node.name)) {
                            error(node.name, ts.Diagnostics.Qualified_name_0_is_not_allowed_without_a_leading_param_object_1, ts.entityNameToString(node.name), ts.entityNameToString(node.name.left));
                        }
                        else {
                            error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name));
                        }
                    }
                    else if (ts.findLast(ts.getJSDocTags(decl), ts.isJSDocParameterTag) === node &&
                        node.typeExpression && node.typeExpression.type &&
                        !isArrayType(getTypeFromTypeNode(node.typeExpression.type))) {
                        error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, ts.idText(node.name.kind === 149 /* QualifiedName */ ? node.name.right : node.name));
                    }
                }
            }
        }
        function checkJSDocFunctionType(node) {
            if (produceDiagnostics && !node.type && !ts.isJSDocConstructSignature(node)) {
                reportImplicitAny(node, anyType);
            }
            checkSignatureDeclaration(node);
        }
        function checkJSDocAugmentsTag(node) {
            var classLike = ts.getJSDocHost(node);
            if (!ts.isClassDeclaration(classLike) && !ts.isClassExpression(classLike)) {
                error(classLike, ts.Diagnostics.JSDoc_0_is_not_attached_to_a_class, ts.idText(node.tagName));
                return;
            }
            var augmentsTags = ts.getJSDocTags(classLike).filter(ts.isJSDocAugmentsTag);
            ts.Debug.assert(augmentsTags.length > 0);
            if (augmentsTags.length > 1) {
                error(augmentsTags[1], ts.Diagnostics.Class_declarations_cannot_have_more_than_one_augments_or_extends_tag);
            }
            var name = getIdentifierFromEntityNameExpression(node.class.expression);
            var extend = ts.getClassExtendsHeritageElement(classLike);
            if (extend) {
                var className = getIdentifierFromEntityNameExpression(extend.expression);
                if (className && name.escapedText !== className.escapedText) {
                    error(name, ts.Diagnostics.JSDoc_0_1_does_not_match_the_extends_2_clause, ts.idText(node.tagName), ts.idText(name), ts.idText(className));
                }
            }
        }
        function getIdentifierFromEntityNameExpression(node) {
            switch (node.kind) {
                case 73 /* Identifier */:
                    return node;
                case 190 /* PropertyAccessExpression */:
                    return node.name;
                default:
                    return undefined;
            }
        }
        function checkFunctionOrMethodDeclaration(node) {
            checkDecorators(node);
            checkSignatureDeclaration(node);
            var functionFlags = ts.getFunctionFlags(node);
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name && node.name.kind === 150 /* ComputedPropertyName */) {
                // This check will account for methods in class/interface declarations,
                // as well as accessors in classes/object literals
                checkComputedPropertyName(node.name);
            }
            if (!hasNonBindableDynamicName(node)) {
                // first we want to check the local symbol that contain this declaration
                // - if node.localSymbol !== undefined - this is current declaration is exported and localSymbol points to the local symbol
                // - if node.localSymbol === undefined - this node is non-exported so we can just pick the result of getSymbolOfNode
                var symbol = getSymbolOfNode(node);
                var localSymbol = node.localSymbol || symbol;
                // Since the javascript won't do semantic analysis like typescript,
                // if the javascript file comes before the typescript file and both contain same name functions,
                // checkFunctionOrConstructorSymbol wouldn't be called if we didnt ignore javascript function.
                var firstDeclaration = ts.find(localSymbol.declarations, 
                // Get first non javascript function declaration
                function (declaration) { return declaration.kind === node.kind && !(declaration.flags & 65536 /* JavaScriptFile */); });
                // Only type check the symbol once
                if (node === firstDeclaration) {
                    checkFunctionOrConstructorSymbol(localSymbol);
                }
                if (symbol.parent) {
                    // run check once for the first declaration
                    if (ts.getDeclarationOfKind(symbol, node.kind) === node) {
                        // run check on export symbol to check that modifiers agree across all exported declarations
                        checkFunctionOrConstructorSymbol(symbol);
                    }
                }
            }
            var body = node.kind === 156 /* MethodSignature */ ? undefined : node.body;
            checkSourceElement(body);
            if ((functionFlags & 1 /* Generator */) === 0) { // Async function or normal function
                var returnOrPromisedType = getReturnOrPromisedType(node, functionFlags);
                checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
            }
            if (produceDiagnostics && !ts.getEffectiveReturnTypeNode(node)) {
                // Report an implicit any error if there is no body, no explicit return type, and node is not a private method
                // in an ambient context
                if (ts.nodeIsMissing(body) && !isPrivateWithinAmbient(node)) {
                    reportImplicitAny(node, anyType);
                }
                if (functionFlags & 1 /* Generator */ && ts.nodeIsPresent(body)) {
                    // A generator with a body and no type annotation can still cause errors. It can error if the
                    // yielded values have no common supertype, or it can give an implicit any error if it has no
                    // yielded values. The only way to trigger these errors is to try checking its return type.
                    getReturnTypeOfSignature(getSignatureFromDeclaration(node));
                }
            }
            // A js function declaration can have a @type tag instead of a return type node, but that type must have a call signature
            if (ts.isInJSFile(node)) {
                var typeTag = ts.getJSDocTypeTag(node);
                if (typeTag && typeTag.typeExpression && !getContextualCallSignature(getTypeFromTypeNode(typeTag.typeExpression), node)) {
                    error(typeTag, ts.Diagnostics.The_type_of_a_function_declaration_must_match_the_function_s_signature);
                }
            }
        }
        function registerForUnusedIdentifiersCheck(node) {
            // May be in a call such as getTypeOfNode that happened to call this. But potentiallyUnusedIdentifiers is only defined in the scope of `checkSourceFile`.
            if (produceDiagnostics && !(node.flags & 4194304 /* Ambient */)) {
                var sourceFile = ts.getSourceFileOfNode(node);
                var potentiallyUnusedIdentifiers = allPotentiallyUnusedIdentifiers.get(sourceFile.path);
                if (!potentiallyUnusedIdentifiers) {
                    potentiallyUnusedIdentifiers = [];
                    allPotentiallyUnusedIdentifiers.set(sourceFile.path, potentiallyUnusedIdentifiers);
                }
                // TODO: GH#22580
                // Debug.assert(addToSeen(seenPotentiallyUnusedIdentifiers, getNodeId(node)), "Adding potentially-unused identifier twice");
                potentiallyUnusedIdentifiers.push(node);
            }
        }
        function checkUnusedIdentifiers(potentiallyUnusedIdentifiers, addDiagnostic) {
            for (var _i = 0, potentiallyUnusedIdentifiers_1 = potentiallyUnusedIdentifiers; _i < potentiallyUnusedIdentifiers_1.length; _i++) {
                var node = potentiallyUnusedIdentifiers_1[_i];
                switch (node.kind) {
                    case 241 /* ClassDeclaration */:
                    case 210 /* ClassExpression */:
                        checkUnusedClassMembers(node, addDiagnostic);
                        checkUnusedTypeParameters(node, addDiagnostic);
                        break;
                    case 285 /* SourceFile */:
                    case 245 /* ModuleDeclaration */:
                    case 219 /* Block */:
                    case 247 /* CaseBlock */:
                    case 226 /* ForStatement */:
                    case 227 /* ForInStatement */:
                    case 228 /* ForOfStatement */:
                        checkUnusedLocalsAndParameters(node, addDiagnostic);
                        break;
                    case 158 /* Constructor */:
                    case 197 /* FunctionExpression */:
                    case 240 /* FunctionDeclaration */:
                    case 198 /* ArrowFunction */:
                    case 157 /* MethodDeclaration */:
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                        if (node.body) { // Don't report unused parameters in overloads
                            checkUnusedLocalsAndParameters(node, addDiagnostic);
                        }
                        checkUnusedTypeParameters(node, addDiagnostic);
                        break;
                    case 156 /* MethodSignature */:
                    case 161 /* CallSignature */:
                    case 162 /* ConstructSignature */:
                    case 166 /* FunctionType */:
                    case 167 /* ConstructorType */:
                    case 243 /* TypeAliasDeclaration */:
                    case 242 /* InterfaceDeclaration */:
                        checkUnusedTypeParameters(node, addDiagnostic);
                        break;
                    case 177 /* InferType */:
                        checkUnusedInferTypeParameter(node, addDiagnostic);
                        break;
                    default:
                        ts.Debug.assertNever(node, "Node should not have been registered for unused identifiers check");
                }
            }
        }
        function errorUnusedLocal(declaration, name, addDiagnostic) {
            var node = ts.getNameOfDeclaration(declaration) || declaration;
            var message = isTypeDeclaration(declaration) ? ts.Diagnostics._0_is_declared_but_never_used : ts.Diagnostics._0_is_declared_but_its_value_is_never_read;
            addDiagnostic(declaration, 0 /* Local */, ts.createDiagnosticForNode(node, message, name));
        }
        function isIdentifierThatStartsWithUnderscore(node) {
            return ts.isIdentifier(node) && ts.idText(node).charCodeAt(0) === 95 /* _ */;
        }
        function checkUnusedClassMembers(node, addDiagnostic) {
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                switch (member.kind) {
                    case 157 /* MethodDeclaration */:
                    case 155 /* PropertyDeclaration */:
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                        if (member.kind === 160 /* SetAccessor */ && member.symbol.flags & 32768 /* GetAccessor */) {
                            // Already would have reported an error on the getter.
                            break;
                        }
                        var symbol = getSymbolOfNode(member);
                        if (!symbol.isReferenced && ts.hasModifier(member, 8 /* Private */)) {
                            addDiagnostic(member, 0 /* Local */, ts.createDiagnosticForNode(member.name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol)));
                        }
                        break;
                    case 158 /* Constructor */:
                        for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) {
                            var parameter = _c[_b];
                            if (!parameter.symbol.isReferenced && ts.hasModifier(parameter, 8 /* Private */)) {
                                addDiagnostic(parameter, 0 /* Local */, ts.createDiagnosticForNode(parameter.name, ts.Diagnostics.Property_0_is_declared_but_its_value_is_never_read, ts.symbolName(parameter.symbol)));
                            }
                        }
                        break;
                    case 163 /* IndexSignature */:
                    case 218 /* SemicolonClassElement */:
                        // Can't be private
                        break;
                    default:
                        ts.Debug.fail();
                }
            }
        }
        function checkUnusedInferTypeParameter(node, addDiagnostic) {
            var typeParameter = node.typeParameter;
            if (isTypeParameterUnused(typeParameter)) {
                addDiagnostic(node, 1 /* Parameter */, ts.createDiagnosticForNode(node, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.idText(typeParameter.name)));
            }
        }
        function checkUnusedTypeParameters(node, addDiagnostic) {
            // Only report errors on the last declaration for the type parameter container;
            // this ensures that all uses have been accounted for.
            if (ts.last(getSymbolOfNode(node).declarations) !== node)
                return;
            var typeParameters = ts.getEffectiveTypeParameterDeclarations(node);
            var seenParentsWithEveryUnused = new ts.NodeSet();
            for (var _i = 0, typeParameters_3 = typeParameters; _i < typeParameters_3.length; _i++) {
                var typeParameter = typeParameters_3[_i];
                if (!isTypeParameterUnused(typeParameter))
                    continue;
                var name = ts.idText(typeParameter.name);
                var parent = typeParameter.parent;
                if (parent.kind !== 177 /* InferType */ && parent.typeParameters.every(isTypeParameterUnused)) {
                    if (seenParentsWithEveryUnused.tryAdd(parent)) {
                        var range = ts.isJSDocTemplateTag(parent)
                            // Whole @template tag
                            ? ts.rangeOfNode(parent)
                            // Include the `<>` in the error message
                            : ts.rangeOfTypeParameters(parent.typeParameters);
                        var only = typeParameters.length === 1;
                        var message = only ? ts.Diagnostics._0_is_declared_but_its_value_is_never_read : ts.Diagnostics.All_type_parameters_are_unused;
                        var arg0 = only ? name : undefined;
                        addDiagnostic(typeParameter, 1 /* Parameter */, ts.createFileDiagnostic(ts.getSourceFileOfNode(parent), range.pos, range.end - range.pos, message, arg0));
                    }
                }
                else {
                    addDiagnostic(typeParameter, 1 /* Parameter */, ts.createDiagnosticForNode(typeParameter, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, name));
                }
            }
        }
        function isTypeParameterUnused(typeParameter) {
            return !(getMergedSymbol(typeParameter.symbol).isReferenced & 262144 /* TypeParameter */) && !isIdentifierThatStartsWithUnderscore(typeParameter.name);
        }
        function addToGroup(map, key, value, getKey) {
            var keyString = String(getKey(key));
            var group = map.get(keyString);
            if (group) {
                group[1].push(value);
            }
            else {
                map.set(keyString, [key, [value]]);
            }
        }
        function tryGetRootParameterDeclaration(node) {
            return ts.tryCast(ts.getRootDeclaration(node), ts.isParameter);
        }
        function checkUnusedLocalsAndParameters(nodeWithLocals, addDiagnostic) {
            if (nodeWithLocals.flags & 4194304 /* Ambient */)
                return;
            // Ideally we could use the ImportClause directly as a key, but must wait until we have full ES6 maps. So must store key along with value.
            var unusedImports = ts.createMap();
            var unusedDestructures = ts.createMap();
            var unusedVariables = ts.createMap();
            nodeWithLocals.locals.forEach(function (local) {
                // If it's purely a type parameter, ignore, will be checked in `checkUnusedTypeParameters`.
                // If it's a type parameter merged with a parameter, check if the parameter-side is used.
                if (local.flags & 262144 /* TypeParameter */ ? !(local.flags & 3 /* Variable */ && !(local.isReferenced & 3 /* Variable */)) : local.isReferenced || local.exportSymbol) {
                    return;
                }
                for (var _i = 0, _a = local.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    if (ts.isAmbientModule(declaration) ||
                        (ts.isVariableDeclaration(declaration) && ts.isForInOrOfStatement(declaration.parent.parent) || isImportedDeclaration(declaration)) && isIdentifierThatStartsWithUnderscore(declaration.name)) {
                        continue;
                    }
                    if (isImportedDeclaration(declaration)) {
                        addToGroup(unusedImports, importClauseFromImported(declaration), declaration, getNodeId);
                    }
                    else if (ts.isBindingElement(declaration) && ts.isObjectBindingPattern(declaration.parent)) {
                        // In `{ a, ...b }, `a` is considered used since it removes a property from `b`. `b` may still be unused though.
                        var lastElement = ts.last(declaration.parent.elements);
                        if (declaration === lastElement || !ts.last(declaration.parent.elements).dotDotDotToken) {
                            addToGroup(unusedDestructures, declaration.parent, declaration, getNodeId);
                        }
                    }
                    else if (ts.isVariableDeclaration(declaration)) {
                        addToGroup(unusedVariables, declaration.parent, declaration, getNodeId);
                    }
                    else {
                        var parameter = local.valueDeclaration && tryGetRootParameterDeclaration(local.valueDeclaration);
                        var name = local.valueDeclaration && ts.getNameOfDeclaration(local.valueDeclaration);
                        if (parameter && name) {
                            if (!ts.isParameterPropertyDeclaration(parameter) && !ts.parameterIsThisKeyword(parameter) && !isIdentifierThatStartsWithUnderscore(name)) {
                                addDiagnostic(parameter, 1 /* Parameter */, ts.createDiagnosticForNode(name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.symbolName(local)));
                            }
                        }
                        else {
                            errorUnusedLocal(declaration, ts.symbolName(local), addDiagnostic);
                        }
                    }
                }
            });
            unusedImports.forEach(function (_a) {
                var importClause = _a[0], unuseds = _a[1];
                var importDecl = importClause.parent;
                var nDeclarations = (importClause.name ? 1 : 0) +
                    (importClause.namedBindings ?
                        (importClause.namedBindings.kind === 252 /* NamespaceImport */ ? 1 : importClause.namedBindings.elements.length)
                        : 0);
                if (nDeclarations === unuseds.length) {
                    addDiagnostic(importDecl, 0 /* Local */, unuseds.length === 1
                        ? ts.createDiagnosticForNode(importDecl, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.idText(ts.first(unuseds).name))
                        : ts.createDiagnosticForNode(importDecl, ts.Diagnostics.All_imports_in_import_declaration_are_unused));
                }
                else {
                    for (var _i = 0, unuseds_1 = unuseds; _i < unuseds_1.length; _i++) {
                        var unused = unuseds_1[_i];
                        errorUnusedLocal(unused, ts.idText(unused.name), addDiagnostic);
                    }
                }
            });
            unusedDestructures.forEach(function (_a) {
                var bindingPattern = _a[0], bindingElements = _a[1];
                var kind = tryGetRootParameterDeclaration(bindingPattern.parent) ? 1 /* Parameter */ : 0 /* Local */;
                if (bindingPattern.elements.length === bindingElements.length) {
                    if (bindingElements.length === 1 && bindingPattern.parent.kind === 238 /* VariableDeclaration */ && bindingPattern.parent.parent.kind === 239 /* VariableDeclarationList */) {
                        addToGroup(unusedVariables, bindingPattern.parent.parent, bindingPattern.parent, getNodeId);
                    }
                    else {
                        addDiagnostic(bindingPattern, kind, bindingElements.length === 1
                            ? ts.createDiagnosticForNode(bindingPattern, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(ts.first(bindingElements).name))
                            : ts.createDiagnosticForNode(bindingPattern, ts.Diagnostics.All_destructured_elements_are_unused));
                    }
                }
                else {
                    for (var _i = 0, bindingElements_1 = bindingElements; _i < bindingElements_1.length; _i++) {
                        var e = bindingElements_1[_i];
                        addDiagnostic(e, kind, ts.createDiagnosticForNode(e, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(e.name)));
                    }
                }
            });
            unusedVariables.forEach(function (_a) {
                var declarationList = _a[0], declarations = _a[1];
                if (declarationList.declarations.length === declarations.length) {
                    addDiagnostic(declarationList, 0 /* Local */, declarations.length === 1
                        ? ts.createDiagnosticForNode(ts.first(declarations).name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(ts.first(declarations).name))
                        : ts.createDiagnosticForNode(declarationList.parent.kind === 220 /* VariableStatement */ ? declarationList.parent : declarationList, ts.Diagnostics.All_variables_are_unused));
                }
                else {
                    for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) {
                        var decl = declarations_5[_i];
                        addDiagnostic(decl, 0 /* Local */, ts.createDiagnosticForNode(decl, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(decl.name)));
                    }
                }
            });
        }
        function bindingNameText(name) {
            switch (name.kind) {
                case 73 /* Identifier */:
                    return ts.idText(name);
                case 186 /* ArrayBindingPattern */:
                case 185 /* ObjectBindingPattern */:
                    return bindingNameText(ts.cast(ts.first(name.elements), ts.isBindingElement).name);
                default:
                    return ts.Debug.assertNever(name);
            }
        }
        function isImportedDeclaration(node) {
            return node.kind === 251 /* ImportClause */ || node.kind === 254 /* ImportSpecifier */ || node.kind === 252 /* NamespaceImport */;
        }
        function importClauseFromImported(decl) {
            return decl.kind === 251 /* ImportClause */ ? decl : decl.kind === 252 /* NamespaceImport */ ? decl.parent : decl.parent.parent;
        }
        function checkBlock(node) {
            // Grammar checking for SyntaxKind.Block
            if (node.kind === 219 /* Block */) {
                checkGrammarStatementInAmbientContext(node);
            }
            if (ts.isFunctionOrModuleBlock(node)) {
                var saveFlowAnalysisDisabled = flowAnalysisDisabled;
                ts.forEach(node.statements, checkSourceElement);
                flowAnalysisDisabled = saveFlowAnalysisDisabled;
            }
            else {
                ts.forEach(node.statements, checkSourceElement);
            }
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkCollisionWithArgumentsInGeneratedCode(node) {
            // no rest parameters \ declaration context \ overload - no codegen impact
            if (languageVersion >= 2 /* ES2015 */ || compilerOptions.noEmit || !ts.hasRestParameter(node) || node.flags & 4194304 /* Ambient */ || ts.nodeIsMissing(node.body)) {
                return;
            }
            ts.forEach(node.parameters, function (p) {
                if (p.name && !ts.isBindingPattern(p.name) && p.name.escapedText === argumentsSymbol.escapedName) {
                    error(p, ts.Diagnostics.Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters);
                }
            });
        }
        function needCollisionCheckForIdentifier(node, identifier, name) {
            if (!(identifier && identifier.escapedText === name)) {
                return false;
            }
            if (node.kind === 155 /* PropertyDeclaration */ ||
                node.kind === 154 /* PropertySignature */ ||
                node.kind === 157 /* MethodDeclaration */ ||
                node.kind === 156 /* MethodSignature */ ||
                node.kind === 159 /* GetAccessor */ ||
                node.kind === 160 /* SetAccessor */) {
                // it is ok to have member named '_super' or '_this' - member access is always qualified
                return false;
            }
            if (node.flags & 4194304 /* Ambient */) {
                // ambient context - no codegen impact
                return false;
            }
            var root = ts.getRootDeclaration(node);
            if (root.kind === 152 /* Parameter */ && ts.nodeIsMissing(root.parent.body)) {
                // just an overload - no codegen impact
                return false;
            }
            return true;
        }
        // this function will run after checking the source file so 'CaptureThis' is correct for all nodes
        function checkIfThisIsCapturedInEnclosingScope(node) {
            ts.findAncestor(node, function (current) {
                if (getNodeCheckFlags(current) & 4 /* CaptureThis */) {
                    var isDeclaration_1 = node.kind !== 73 /* Identifier */;
                    if (isDeclaration_1) {
                        error(ts.getNameOfDeclaration(node), ts.Diagnostics.Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference);
                    }
                    else {
                        error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference);
                    }
                    return true;
                }
                return false;
            });
        }
        function checkIfNewTargetIsCapturedInEnclosingScope(node) {
            ts.findAncestor(node, function (current) {
                if (getNodeCheckFlags(current) & 8 /* CaptureNewTarget */) {
                    var isDeclaration_2 = node.kind !== 73 /* Identifier */;
                    if (isDeclaration_2) {
                        error(ts.getNameOfDeclaration(node), ts.Diagnostics.Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference);
                    }
                    else {
                        error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference);
                    }
                    return true;
                }
                return false;
            });
        }
        function checkCollisionWithRequireExportsInGeneratedCode(node, name) {
            // No need to check for require or exports for ES6 modules and later
            if (moduleKind >= ts.ModuleKind.ES2015 || compilerOptions.noEmit) {
                return;
            }
            if (!needCollisionCheckForIdentifier(node, name, "require") && !needCollisionCheckForIdentifier(node, name, "exports")) {
                return;
            }
            // Uninstantiated modules shouldnt do this check
            if (ts.isModuleDeclaration(node) && ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
                return;
            }
            // In case of variable declaration, node.parent is variable statement so look at the variable statement's parent
            var parent = getDeclarationContainer(node);
            if (parent.kind === 285 /* SourceFile */ && ts.isExternalOrCommonJsModule(parent)) {
                // If the declaration happens to be in external module, report error that require and exports are reserved keywords
                error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module, ts.declarationNameToString(name), ts.declarationNameToString(name));
            }
        }
        function checkCollisionWithGlobalPromiseInGeneratedCode(node, name) {
            if (languageVersion >= 4 /* ES2017 */ || compilerOptions.noEmit || !needCollisionCheckForIdentifier(node, name, "Promise")) {
                return;
            }
            // Uninstantiated modules shouldnt do this check
            if (ts.isModuleDeclaration(node) && ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
                return;
            }
            // In case of variable declaration, node.parent is variable statement so look at the variable statement's parent
            var parent = getDeclarationContainer(node);
            if (parent.kind === 285 /* SourceFile */ && ts.isExternalOrCommonJsModule(parent) && parent.flags & 1024 /* HasAsyncFunctions */) {
                // If the declaration happens to be in external module, report error that Promise is a reserved identifier.
                error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions, ts.declarationNameToString(name), ts.declarationNameToString(name));
            }
        }
        function checkVarDeclaredNamesNotShadowed(node) {
            // - ScriptBody : StatementList
            // It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList
            // also occurs in the VarDeclaredNames of StatementList.
            // - Block : { StatementList }
            // It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList
            // also occurs in the VarDeclaredNames of StatementList.
            // Variable declarations are hoisted to the top of their function scope. They can shadow
            // block scoped declarations, which bind tighter. this will not be flagged as duplicate definition
            // by the binder as the declaration scope is different.
            // A non-initialized declaration is a no-op as the block declaration will resolve before the var
            // declaration. the problem is if the declaration has an initializer. this will act as a write to the
            // block declared value. this is fine for let, but not const.
            // Only consider declarations with initializers, uninitialized const declarations will not
            // step on a let/const variable.
            // Do not consider const and const declarations, as duplicate block-scoped declarations
            // are handled by the binder.
            // We are only looking for const declarations that step on let\const declarations from a
            // different scope. e.g.:
            //      {
            //          const x = 0; // localDeclarationSymbol obtained after name resolution will correspond to this declaration
            //          const x = 0; // symbol for this declaration will be 'symbol'
            //      }
            // skip block-scoped variables and parameters
            if ((ts.getCombinedNodeFlags(node) & 3 /* BlockScoped */) !== 0 || ts.isParameterDeclaration(node)) {
                return;
            }
            // skip variable declarations that don't have initializers
            // NOTE: in ES6 spec initializer is required in variable declarations where name is binding pattern
            // so we'll always treat binding elements as initialized
            if (node.kind === 238 /* VariableDeclaration */ && !node.initializer) {
                return;
            }
            var symbol = getSymbolOfNode(node);
            if (symbol.flags & 1 /* FunctionScopedVariable */) {
                if (!ts.isIdentifier(node.name))
                    return ts.Debug.fail();
                var localDeclarationSymbol = resolveName(node, node.name.escapedText, 3 /* Variable */, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
                if (localDeclarationSymbol &&
                    localDeclarationSymbol !== symbol &&
                    localDeclarationSymbol.flags & 2 /* BlockScopedVariable */) {
                    if (getDeclarationNodeFlagsFromSymbol(localDeclarationSymbol) & 3 /* BlockScoped */) {
                        var varDeclList = ts.getAncestor(localDeclarationSymbol.valueDeclaration, 239 /* VariableDeclarationList */);
                        var container = varDeclList.parent.kind === 220 /* VariableStatement */ && varDeclList.parent.parent
                            ? varDeclList.parent.parent
                            : undefined;
                        // names of block-scoped and function scoped variables can collide only
                        // if block scoped variable is defined in the function\module\source file scope (because of variable hoisting)
                        var namesShareScope = container &&
                            (container.kind === 219 /* Block */ && ts.isFunctionLike(container.parent) ||
                                container.kind === 246 /* ModuleBlock */ ||
                                container.kind === 245 /* ModuleDeclaration */ ||
                                container.kind === 285 /* SourceFile */);
                        // here we know that function scoped variable is shadowed by block scoped one
                        // if they are defined in the same scope - binder has already reported redeclaration error
                        // otherwise if variable has an initializer - show error that initialization will fail
                        // since LHS will be block scoped name instead of function scoped
                        if (!namesShareScope) {
                            var name = symbolToString(localDeclarationSymbol);
                            error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name, name);
                        }
                    }
                }
            }
        }
        function convertAutoToAny(type) {
            return type === autoType ? anyType : type === autoArrayType ? anyArrayType : type;
        }
        // Check variable, parameter, or property declaration
        function checkVariableLikeDeclaration(node) {
            checkDecorators(node);
            if (!ts.isBindingElement(node)) {
                checkSourceElement(node.type);
            }
            // JSDoc `function(string, string): string` syntax results in parameters with no name
            if (!node.name) {
                return;
            }
            // For a computed property, just check the initializer and exit
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name.kind === 150 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
                if (node.initializer) {
                    checkExpressionCached(node.initializer);
                }
            }
            if (node.kind === 187 /* BindingElement */) {
                if (node.parent.kind === 185 /* ObjectBindingPattern */ && languageVersion < 8 /* ESNext */) {
                    checkExternalEmitHelpers(node, 4 /* Rest */);
                }
                // check computed properties inside property names of binding elements
                if (node.propertyName && node.propertyName.kind === 150 /* ComputedPropertyName */) {
                    checkComputedPropertyName(node.propertyName);
                }
                // check private/protected variable access
                var parent = node.parent.parent;
                var parentType = getTypeForBindingElementParent(parent);
                var name = node.propertyName || node.name;
                if (parentType && !ts.isBindingPattern(name)) {
                    var exprType = getLiteralTypeFromPropertyName(name);
                    if (isTypeUsableAsPropertyName(exprType)) {
                        var nameText = getPropertyNameFromType(exprType);
                        var property = getPropertyOfType(parentType, nameText);
                        if (property) {
                            markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference.
                            checkPropertyAccessibility(parent, !!parent.initializer && parent.initializer.kind === 99 /* SuperKeyword */, parentType, property);
                        }
                    }
                }
            }
            // For a binding pattern, check contained binding elements
            if (ts.isBindingPattern(node.name)) {
                if (node.name.kind === 186 /* ArrayBindingPattern */ && languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
                    checkExternalEmitHelpers(node, 512 /* Read */);
                }
                ts.forEach(node.name.elements, checkSourceElement);
            }
            // For a parameter declaration with an initializer, error and exit if the containing function doesn't have a body
            if (node.initializer && ts.getRootDeclaration(node).kind === 152 /* Parameter */ && ts.nodeIsMissing(ts.getContainingFunction(node).body)) {
                error(node, ts.Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation);
                return;
            }
            // For a binding pattern, validate the initializer and exit
            if (ts.isBindingPattern(node.name)) {
                var needCheckInitializer = node.initializer && node.parent.parent.kind !== 227 /* ForInStatement */;
                var needCheckWidenedType = node.name.elements.length === 0;
                if (needCheckInitializer || needCheckWidenedType) {
                    // Don't validate for-in initializer as it is already an error
                    var widenedType = getWidenedTypeForVariableLikeDeclaration(node);
                    if (needCheckInitializer) {
                        var initializerType = checkExpressionCached(node.initializer);
                        if (strictNullChecks && needCheckWidenedType) {
                            checkNonNullNonVoidType(initializerType, node);
                        }
                        else {
                            checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
                        }
                    }
                    // check the binding pattern with empty elements
                    if (needCheckWidenedType) {
                        if (ts.isArrayBindingPattern(node.name)) {
                            checkIteratedTypeOrElementType(widenedType, node, /* allowStringInput */ false, /* allowAsyncIterables */ false);
                        }
                        else if (strictNullChecks) {
                            checkNonNullNonVoidType(widenedType, node);
                        }
                    }
                }
                return;
            }
            var symbol = getSymbolOfNode(node);
            var type = convertAutoToAny(getTypeOfSymbol(symbol));
            if (node === symbol.valueDeclaration) {
                // Node is the primary declaration of the symbol, just validate the initializer
                // Don't validate for-in initializer as it is already an error
                var initializer = ts.getEffectiveInitializer(node);
                if (initializer) {
                    var isJSObjectLiteralInitializer = ts.isInJSFile(node) &&
                        ts.isObjectLiteralExpression(initializer) &&
                        (initializer.properties.length === 0 || ts.isPrototypeAccess(node.name)) &&
                        ts.hasEntries(symbol.exports);
                    if (!isJSObjectLiteralInitializer && node.parent.parent.kind !== 227 /* ForInStatement */) {
                        checkTypeAssignableToAndOptionallyElaborate(checkExpressionCached(initializer), type, node, initializer, /*headMessage*/ undefined);
                    }
                }
                if (symbol.declarations.length > 1) {
                    if (ts.some(symbol.declarations, function (d) { return d !== node && ts.isVariableLike(d) && !areDeclarationFlagsIdentical(d, node); })) {
                        error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name));
                    }
                }
            }
            else {
                // Node is a secondary declaration, check that type is identical to primary declaration and check that
                // initializer is consistent with type associated with the node
                var declarationType = convertAutoToAny(getWidenedTypeForVariableLikeDeclaration(node));
                if (type !== errorType && declarationType !== errorType &&
                    !isTypeIdenticalTo(type, declarationType) &&
                    !(symbol.flags & 67108864 /* Assignment */)) {
                    errorNextVariableOrPropertyDeclarationMustHaveSameType(symbol.valueDeclaration, type, node, declarationType);
                }
                if (node.initializer) {
                    checkTypeAssignableToAndOptionallyElaborate(checkExpressionCached(node.initializer), declarationType, node, node.initializer, /*headMessage*/ undefined);
                }
                if (!areDeclarationFlagsIdentical(node, symbol.valueDeclaration)) {
                    error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name));
                }
            }
            if (node.kind !== 155 /* PropertyDeclaration */ && node.kind !== 154 /* PropertySignature */) {
                // We know we don't have a binding pattern or computed name here
                checkExportsOnMergedDeclarations(node);
                if (node.kind === 238 /* VariableDeclaration */ || node.kind === 187 /* BindingElement */) {
                    checkVarDeclaredNamesNotShadowed(node);
                }
                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            }
        }
        function errorNextVariableOrPropertyDeclarationMustHaveSameType(firstDeclaration, firstType, nextDeclaration, nextType) {
            var nextDeclarationName = ts.getNameOfDeclaration(nextDeclaration);
            var message = nextDeclaration.kind === 155 /* PropertyDeclaration */ || nextDeclaration.kind === 154 /* PropertySignature */
                ? ts.Diagnostics.Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_type_2
                : ts.Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2;
            var declName = ts.declarationNameToString(nextDeclarationName);
            var err = error(nextDeclarationName, message, declName, typeToString(firstType), typeToString(nextType));
            if (firstDeclaration) {
                ts.addRelatedInfo(err, ts.createDiagnosticForNode(firstDeclaration, ts.Diagnostics._0_was_also_declared_here, declName));
            }
        }
        function areDeclarationFlagsIdentical(left, right) {
            if ((left.kind === 152 /* Parameter */ && right.kind === 238 /* VariableDeclaration */) ||
                (left.kind === 238 /* VariableDeclaration */ && right.kind === 152 /* Parameter */)) {
                // Differences in optionality between parameters and variables are allowed.
                return true;
            }
            if (ts.hasQuestionToken(left) !== ts.hasQuestionToken(right)) {
                return false;
            }
            var interestingFlags = 8 /* Private */ |
                16 /* Protected */ |
                256 /* Async */ |
                128 /* Abstract */ |
                64 /* Readonly */ |
                32 /* Static */;
            return ts.getSelectedModifierFlags(left, interestingFlags) === ts.getSelectedModifierFlags(right, interestingFlags);
        }
        function checkVariableDeclaration(node) {
            checkGrammarVariableDeclaration(node);
            return checkVariableLikeDeclaration(node);
        }
        function checkBindingElement(node) {
            checkGrammarBindingElement(node);
            return checkVariableLikeDeclaration(node);
        }
        function checkVariableStatement(node) {
            // Grammar checking
            if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarVariableDeclarationList(node.declarationList))
                checkGrammarForDisallowedLetOrConstStatement(node);
            ts.forEach(node.declarationList.declarations, checkSourceElement);
        }
        function checkExpressionStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkExpression(node.expression);
        }
        function checkIfStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkTruthinessExpression(node.expression);
            checkSourceElement(node.thenStatement);
            if (node.thenStatement.kind === 221 /* EmptyStatement */) {
                error(node.thenStatement, ts.Diagnostics.The_body_of_an_if_statement_cannot_be_the_empty_statement);
            }
            checkSourceElement(node.elseStatement);
        }
        function checkDoStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkSourceElement(node.statement);
            checkTruthinessExpression(node.expression);
        }
        function checkWhileStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkTruthinessExpression(node.expression);
            checkSourceElement(node.statement);
        }
        function checkTruthinessExpression(node, checkMode) {
            var type = checkExpression(node, checkMode);
            if (type.flags & 16384 /* Void */) {
                error(node, ts.Diagnostics.An_expression_of_type_void_cannot_be_tested_for_truthiness);
            }
            return type;
        }
        function checkForStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node)) {
                if (node.initializer && node.initializer.kind === 239 /* VariableDeclarationList */) {
                    checkGrammarVariableDeclarationList(node.initializer);
                }
            }
            if (node.initializer) {
                if (node.initializer.kind === 239 /* VariableDeclarationList */) {
                    ts.forEach(node.initializer.declarations, checkVariableDeclaration);
                }
                else {
                    checkExpression(node.initializer);
                }
            }
            if (node.condition)
                checkTruthinessExpression(node.condition);
            if (node.incrementor)
                checkExpression(node.incrementor);
            checkSourceElement(node.statement);
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkForOfStatement(node) {
            checkGrammarForInOrForOfStatement(node);
            if (node.awaitModifier) {
                var functionFlags = ts.getFunctionFlags(ts.getContainingFunction(node));
                if ((functionFlags & (4 /* Invalid */ | 2 /* Async */)) === 2 /* Async */ && languageVersion < 8 /* ESNext */) {
                    // for..await..of in an async function or async generator function prior to ESNext requires the __asyncValues helper
                    checkExternalEmitHelpers(node, 16384 /* ForAwaitOfIncludes */);
                }
            }
            else if (compilerOptions.downlevelIteration && languageVersion < 2 /* ES2015 */) {
                // for..of prior to ES2015 requires the __values helper when downlevelIteration is enabled
                checkExternalEmitHelpers(node, 256 /* ForOfIncludes */);
            }
            // Check the LHS and RHS
            // If the LHS is a declaration, just check it as a variable declaration, which will in turn check the RHS
            // via checkRightHandSideOfForOf.
            // If the LHS is an expression, check the LHS, as a destructuring assignment or as a reference.
            // Then check that the RHS is assignable to it.
            if (node.initializer.kind === 239 /* VariableDeclarationList */) {
                checkForInOrForOfVariableDeclaration(node);
            }
            else {
                var varExpr = node.initializer;
                var iteratedType = checkRightHandSideOfForOf(node.expression, node.awaitModifier);
                // There may be a destructuring assignment on the left side
                if (varExpr.kind === 188 /* ArrayLiteralExpression */ || varExpr.kind === 189 /* ObjectLiteralExpression */) {
                    // iteratedType may be undefined. In this case, we still want to check the structure of
                    // varExpr, in particular making sure it's a valid LeftHandSideExpression. But we'd like
                    // to short circuit the type relation checking as much as possible, so we pass the unknownType.
                    checkDestructuringAssignment(varExpr, iteratedType || errorType);
                }
                else {
                    var leftType = checkExpression(varExpr);
                    checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access);
                    // iteratedType will be undefined if the rightType was missing properties/signatures
                    // required to get its iteratedType (like [Symbol.iterator] or next). This may be
                    // because we accessed properties from anyType, or it may have led to an error inside
                    // getElementTypeOfIterable.
                    if (iteratedType) {
                        checkTypeAssignableToAndOptionallyElaborate(iteratedType, leftType, varExpr, node.expression);
                    }
                }
            }
            checkSourceElement(node.statement);
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkForInStatement(node) {
            // Grammar checking
            checkGrammarForInOrForOfStatement(node);
            var rightType = getNonNullableTypeIfNeeded(checkExpression(node.expression));
            // TypeScript 1.0 spec (April 2014): 5.4
            // In a 'for-in' statement of the form
            // for (let VarDecl in Expr) Statement
            //   VarDecl must be a variable declaration without a type annotation that declares a variable of type Any,
            //   and Expr must be an expression of type Any, an object type, or a type parameter type.
            if (node.initializer.kind === 239 /* VariableDeclarationList */) {
                var variable = node.initializer.declarations[0];
                if (variable && ts.isBindingPattern(variable.name)) {
                    error(variable.name, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
                }
                checkForInOrForOfVariableDeclaration(node);
            }
            else {
                // In a 'for-in' statement of the form
                // for (Var in Expr) Statement
                //   Var must be an expression classified as a reference of type Any or the String primitive type,
                //   and Expr must be an expression of type Any, an object type, or a type parameter type.
                var varExpr = node.initializer;
                var leftType = checkExpression(varExpr);
                if (varExpr.kind === 188 /* ArrayLiteralExpression */ || varExpr.kind === 189 /* ObjectLiteralExpression */) {
                    error(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
                }
                else if (!isTypeAssignableTo(getIndexTypeOrString(rightType), leftType)) {
                    error(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any);
                }
                else {
                    // run check only former check succeeded to avoid cascading errors
                    checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access);
                }
            }
            // unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
            // in this case error about missing name is already reported - do not report extra one
            if (rightType === neverType || !isTypeAssignableToKind(rightType, 67108864 /* NonPrimitive */ | 58982400 /* InstantiableNonPrimitive */)) {
                error(node.expression, ts.Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_but_here_has_type_0, typeToString(rightType));
            }
            checkSourceElement(node.statement);
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkForInOrForOfVariableDeclaration(iterationStatement) {
            var variableDeclarationList = iterationStatement.initializer;
            // checkGrammarForInOrForOfStatement will check that there is exactly one declaration.
            if (variableDeclarationList.declarations.length >= 1) {
                var decl = variableDeclarationList.declarations[0];
                checkVariableDeclaration(decl);
            }
        }
        function checkRightHandSideOfForOf(rhsExpression, awaitModifier) {
            var expressionType = checkNonNullExpression(rhsExpression);
            return checkIteratedTypeOrElementType(expressionType, rhsExpression, /*allowStringInput*/ true, awaitModifier !== undefined);
        }
        function checkIteratedTypeOrElementType(inputType, errorNode, allowStringInput, allowAsyncIterables) {
            if (isTypeAny(inputType)) {
                return inputType;
            }
            return getIteratedTypeOrElementType(inputType, errorNode, allowStringInput, allowAsyncIterables, /*checkAssignability*/ true) || anyType;
        }
        /**
         * When consuming an iterable type in a for..of, spread, or iterator destructuring assignment
         * we want to get the iterated type of an iterable for ES2015 or later, or the iterated type
         * of a iterable (if defined globally) or element type of an array like for ES2015 or earlier.
         */
        function getIteratedTypeOrElementType(inputType, errorNode, allowStringInput, allowAsyncIterables, checkAssignability) {
            if (inputType === neverType) {
                reportTypeNotIterableError(errorNode, inputType, allowAsyncIterables); // TODO: GH#18217
                return undefined;
            }
            var uplevelIteration = languageVersion >= 2 /* ES2015 */;
            var downlevelIteration = !uplevelIteration && compilerOptions.downlevelIteration;
            // Get the iterated type of an `Iterable<T>` or `IterableIterator<T>` only in ES2015
            // or higher, when inside of an async generator or for-await-if, or when
            // downlevelIteration is requested.
            if (uplevelIteration || downlevelIteration || allowAsyncIterables) {
                // We only report errors for an invalid iterable type in ES2015 or higher.
                var iteratedType = getIteratedTypeOfIterable(inputType, uplevelIteration ? errorNode : undefined, allowAsyncIterables, /*allowSyncIterables*/ true, checkAssignability);
                if (iteratedType || uplevelIteration) {
                    return iteratedType;
                }
            }
            var arrayType = inputType;
            var reportedError = false;
            var hasStringConstituent = false;
            // If strings are permitted, remove any string-like constituents from the array type.
            // This allows us to find other non-string element types from an array unioned with
            // a string.
            if (allowStringInput) {
                if (arrayType.flags & 1048576 /* Union */) {
                    // After we remove all types that are StringLike, we will know if there was a string constituent
                    // based on whether the result of filter is a new array.
                    var arrayTypes = inputType.types;
                    var filteredTypes = ts.filter(arrayTypes, function (t) { return !(t.flags & 132 /* StringLike */); });
                    if (filteredTypes !== arrayTypes) {
                        arrayType = getUnionType(filteredTypes, 2 /* Subtype */);
                    }
                }
                else if (arrayType.flags & 132 /* StringLike */) {
                    arrayType = neverType;
                }
                hasStringConstituent = arrayType !== inputType;
                if (hasStringConstituent) {
                    if (languageVersion < 1 /* ES5 */) {
                        if (errorNode) {
                            error(errorNode, ts.Diagnostics.Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher);
                            reportedError = true;
                        }
                    }
                    // Now that we've removed all the StringLike types, if no constituents remain, then the entire
                    // arrayOrStringType was a string.
                    if (arrayType.flags & 131072 /* Never */) {
                        return stringType;
                    }
                }
            }
            if (!isArrayLikeType(arrayType)) {
                if (errorNode && !reportedError) {
                    // Which error we report depends on whether we allow strings or if there was a
                    // string constituent. For example, if the input type is number | string, we
                    // want to say that number is not an array type. But if the input was just
                    // number and string input is allowed, we want to say that number is not an
                    // array type or a string type.
                    var isIterable = !!getIteratedTypeOfIterable(inputType, /* errorNode */ undefined, allowAsyncIterables, /*allowSyncIterables*/ true, checkAssignability);
                    var diagnostic = !allowStringInput || hasStringConstituent
                        ? downlevelIteration
                            ? ts.Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator
                            : isIterable
                                ? ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators
                                : ts.Diagnostics.Type_0_is_not_an_array_type
                        : downlevelIteration
                            ? ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator
                            : isIterable
                                ? ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators
                                : ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type;
                    error(errorNode, diagnostic, typeToString(arrayType));
                }
                return hasStringConstituent ? stringType : undefined;
            }
            var arrayElementType = getIndexTypeOfType(arrayType, 1 /* Number */);
            if (hasStringConstituent && arrayElementType) {
                // This is just an optimization for the case where arrayOrStringType is string | string[]
                if (arrayElementType.flags & 132 /* StringLike */) {
                    return stringType;
                }
                return getUnionType([arrayElementType, stringType], 2 /* Subtype */);
            }
            return arrayElementType;
        }
        /**
         * We want to treat type as an iterable, and get the type it is an iterable of. The iterable
         * must have the following structure (annotated with the names of the variables below):
         *
         *     { // iterable
         *         [Symbol.iterator]: { // iteratorMethod
         *             (): Iterator<T>
         *         }
         *     }
         *
         * For an async iterable, we expect the following structure:
         *
         *     { // iterable
         *         [Symbol.asyncIterator]: { // iteratorMethod
         *             (): AsyncIterator<T>
         *         }
         *     }
         *
         * T is the type we are after. At every level that involves analyzing return types
         * of signatures, we union the return types of all the signatures.
         *
         * Another thing to note is that at any step of this process, we could run into a dead end,
         * meaning either the property is missing, or we run into the anyType. If either of these things
         * happens, we return undefined to signal that we could not find the iterated type. If a property
         * is missing, and the previous step did not result in 'any', then we also give an error if the
         * caller requested it. Then the caller can decide what to do in the case where there is no iterated
         * type. This is different from returning anyType, because that would signify that we have matched the
         * whole pattern and that T (above) is 'any'.
         *
         * For a **for-of** statement, `yield*` (in a normal generator), spread, array
         * destructuring, or normal generator we will only ever look for a `[Symbol.iterator]()`
         * method.
         *
         * For an async generator we will only ever look at the `[Symbol.asyncIterator]()` method.
         *
         * For a **for-await-of** statement or a `yield*` in an async generator we will look for
         * the `[Symbol.asyncIterator]()` method first, and then the `[Symbol.iterator]()` method.
         */
        function getIteratedTypeOfIterable(type, errorNode, allowAsyncIterables, allowSyncIterables, checkAssignability) {
            if (isTypeAny(type)) {
                return undefined;
            }
            return mapType(type, getIteratedType);
            function getIteratedType(type) {
                var typeAsIterable = type;
                if (allowAsyncIterables) {
                    if (typeAsIterable.iteratedTypeOfAsyncIterable) {
                        return typeAsIterable.iteratedTypeOfAsyncIterable;
                    }
                    // As an optimization, if the type is an instantiation of the global `AsyncIterable<T>`
                    // or the global `AsyncIterableIterator<T>` then just grab its type argument.
                    if (isReferenceToType(type, getGlobalAsyncIterableType(/*reportErrors*/ false)) ||
                        isReferenceToType(type, getGlobalAsyncIterableIteratorType(/*reportErrors*/ false))) {
                        return typeAsIterable.iteratedTypeOfAsyncIterable = type.typeArguments[0];
                    }
                }
                if (allowSyncIterables) {
                    if (typeAsIterable.iteratedTypeOfIterable) {
                        return allowAsyncIterables
                            ? typeAsIterable.iteratedTypeOfAsyncIterable = getAwaitedType(typeAsIterable.iteratedTypeOfIterable)
                            : typeAsIterable.iteratedTypeOfIterable;
                    }
                    // As an optimization, if the type is an instantiation of the global `Iterable<T>` or
                    // `IterableIterator<T>` then just grab its type argument.
                    if (isReferenceToType(type, getGlobalIterableType(/*reportErrors*/ false)) ||
                        isReferenceToType(type, getGlobalIterableIteratorType(/*reportErrors*/ false))) {
                        return allowAsyncIterables
                            ? typeAsIterable.iteratedTypeOfAsyncIterable = getAwaitedType(type.typeArguments[0])
                            : typeAsIterable.iteratedTypeOfIterable = type.typeArguments[0];
                    }
                }
                var asyncMethodType = allowAsyncIterables && getTypeOfPropertyOfType(type, ts.getPropertyNameForKnownSymbolName("asyncIterator"));
                var methodType = asyncMethodType || (allowSyncIterables ? getTypeOfPropertyOfType(type, ts.getPropertyNameForKnownSymbolName("iterator")) : undefined);
                if (isTypeAny(methodType)) {
                    return undefined;
                }
                var signatures = methodType ? getSignaturesOfType(methodType, 0 /* Call */) : undefined;
                if (!ts.some(signatures)) {
                    if (errorNode) {
                        // only report on the first error
                        reportTypeNotIterableError(errorNode, type, allowAsyncIterables);
                        errorNode = undefined;
                    }
                    return undefined;
                }
                var returnType = getUnionType(ts.map(signatures, getReturnTypeOfSignature), 2 /* Subtype */);
                var iteratedType = getIteratedTypeOfIterator(returnType, errorNode, /*isAsyncIterator*/ !!asyncMethodType);
                if (checkAssignability && errorNode && iteratedType) {
                    // If `checkAssignability` was specified, we were called from
                    // `checkIteratedTypeOrElementType`. As such, we need to validate that
                    // the type passed in is actually an Iterable.
                    checkTypeAssignableTo(type, asyncMethodType
                        ? createAsyncIterableType(iteratedType)
                        : createIterableType(iteratedType), errorNode);
                }
                if (iteratedType) {
                    return allowAsyncIterables
                        ? typeAsIterable.iteratedTypeOfAsyncIterable = asyncMethodType ? iteratedType : getAwaitedType(iteratedType)
                        : typeAsIterable.iteratedTypeOfIterable = iteratedType;
                }
            }
        }
        function reportTypeNotIterableError(errorNode, type, allowAsyncIterables) {
            error(errorNode, allowAsyncIterables
                ? ts.Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator
                : ts.Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator, typeToString(type));
        }
        /**
         * This function has very similar logic as getIteratedTypeOfIterable, except that it operates on
         * Iterators instead of Iterables. Here is the structure:
         *
         *  { // iterator
         *      next: { // nextMethod
         *          (): { // nextResult
         *              value: T // nextValue
         *          }
         *      }
         *  }
         *
         * For an async iterator, we expect the following structure:
         *
         *  { // iterator
         *      next: { // nextMethod
         *          (): PromiseLike<{ // nextResult
         *              value: T // nextValue
         *          }>
         *      }
         *  }
         */
        function getIteratedTypeOfIterator(type, errorNode, isAsyncIterator) {
            if (isTypeAny(type)) {
                return undefined;
            }
            var typeAsIterator = type;
            if (isAsyncIterator ? typeAsIterator.iteratedTypeOfAsyncIterator : typeAsIterator.iteratedTypeOfIterator) {
                return isAsyncIterator ? typeAsIterator.iteratedTypeOfAsyncIterator : typeAsIterator.iteratedTypeOfIterator;
            }
            // As an optimization, if the type is an instantiation of the global `Iterator<T>` (for
            // a non-async iterator) or the global `AsyncIterator<T>` (for an async-iterator) then
            // just grab its type argument.
            var getIteratorType = isAsyncIterator ? getGlobalAsyncIteratorType : getGlobalIteratorType;
            if (isReferenceToType(type, getIteratorType(/*reportErrors*/ false))) {
                return isAsyncIterator
                    ? typeAsIterator.iteratedTypeOfAsyncIterator = type.typeArguments[0]
                    : typeAsIterator.iteratedTypeOfIterator = type.typeArguments[0];
            }
            // Both async and non-async iterators must have a `next` method.
            var nextMethod = getTypeOfPropertyOfType(type, "next");
            if (isTypeAny(nextMethod)) {
                return undefined;
            }
            var nextMethodSignatures = nextMethod ? getSignaturesOfType(nextMethod, 0 /* Call */) : ts.emptyArray;
            if (nextMethodSignatures.length === 0) {
                if (errorNode) {
                    error(errorNode, isAsyncIterator
                        ? ts.Diagnostics.An_async_iterator_must_have_a_next_method
                        : ts.Diagnostics.An_iterator_must_have_a_next_method);
                }
                return undefined;
            }
            var nextResult = getUnionType(ts.map(nextMethodSignatures, getReturnTypeOfSignature), 2 /* Subtype */);
            if (isTypeAny(nextResult)) {
                return undefined;
            }
            // For an async iterator, we must get the awaited type of the return type.
            if (isAsyncIterator) {
                nextResult = getAwaitedTypeOfPromise(nextResult, errorNode, ts.Diagnostics.The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property);
                if (isTypeAny(nextResult)) {
                    return undefined;
                }
            }
            var nextValue = nextResult && getTypeOfPropertyOfType(nextResult, "value");
            if (!nextValue) {
                if (errorNode) {
                    error(errorNode, isAsyncIterator
                        ? ts.Diagnostics.The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property
                        : ts.Diagnostics.The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property);
                }
                return undefined;
            }
            return isAsyncIterator
                ? typeAsIterator.iteratedTypeOfAsyncIterator = nextValue
                : typeAsIterator.iteratedTypeOfIterator = nextValue;
        }
        /**
         * A generator may have a return type of `Iterator<T>`, `Iterable<T>`, or
         * `IterableIterator<T>`. An async generator may have a return type of `AsyncIterator<T>`,
         * `AsyncIterable<T>`, or `AsyncIterableIterator<T>`. This function can be used to extract
         * the iterated type from this return type for contextual typing and verifying signatures.
         */
        function getIteratedTypeOfGenerator(returnType, isAsyncGenerator) {
            if (isTypeAny(returnType)) {
                return undefined;
            }
            return getIteratedTypeOfIterable(returnType, /*errorNode*/ undefined, /*allowAsyncIterables*/ isAsyncGenerator, /*allowSyncIterables*/ !isAsyncGenerator, /*checkAssignability*/ false)
                || getIteratedTypeOfIterator(returnType, /*errorNode*/ undefined, isAsyncGenerator);
        }
        function checkBreakOrContinueStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node))
                checkGrammarBreakOrContinueStatement(node);
            // TODO: Check that target label is valid
        }
        function isUnwrappedReturnTypeVoidOrAny(func, returnType) {
            var unwrappedReturnType = (ts.getFunctionFlags(func) & 3 /* AsyncGenerator */) === 2 /* Async */
                ? getPromisedTypeOfPromise(returnType) // Async function
                : returnType; // AsyncGenerator function, Generator function, or normal function
            return !!unwrappedReturnType && maybeTypeOfKind(unwrappedReturnType, 16384 /* Void */ | 3 /* AnyOrUnknown */);
        }
        function checkReturnStatement(node) {
            // Grammar checking
            if (checkGrammarStatementInAmbientContext(node)) {
                return;
            }
            var func = ts.getContainingFunction(node);
            if (!func) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.A_return_statement_can_only_be_used_within_a_function_body);
                return;
            }
            var signature = getSignatureFromDeclaration(func);
            var returnType = getReturnTypeOfSignature(signature);
            var functionFlags = ts.getFunctionFlags(func);
            var isGenerator = functionFlags & 1 /* Generator */;
            if (strictNullChecks || node.expression || returnType.flags & 131072 /* Never */) {
                var exprType = node.expression ? checkExpressionCached(node.expression) : undefinedType;
                if (isGenerator) { // AsyncGenerator function or Generator function
                    // A generator does not need its return expressions checked against its return type.
                    // Instead, the yield expressions are checked against the element type.
                    // TODO: Check return types of generators when return type tracking is added
                    // for generators.
                    return;
                }
                else if (func.kind === 160 /* SetAccessor */) {
                    if (node.expression) {
                        error(node, ts.Diagnostics.Setters_cannot_return_a_value);
                    }
                }
                else if (func.kind === 158 /* Constructor */) {
                    if (node.expression && !checkTypeAssignableToAndOptionallyElaborate(exprType, returnType, node, node.expression)) {
                        error(node, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class);
                    }
                }
                else if (getReturnTypeFromAnnotation(func)) {
                    if (functionFlags & 2 /* Async */) { // Async function
                        var promisedType = getPromisedTypeOfPromise(returnType);
                        var awaitedType = checkAwaitedType(exprType, node, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
                        if (promisedType) {
                            // If the function has a return type, but promisedType is
                            // undefined, an error will be reported in checkAsyncFunctionReturnType
                            // so we don't need to report one here.
                            checkTypeAssignableToAndOptionallyElaborate(awaitedType, promisedType, node, node.expression);
                        }
                    }
                    else {
                        checkTypeAssignableToAndOptionallyElaborate(exprType, returnType, node, node.expression);
                    }
                }
            }
            else if (func.kind !== 158 /* Constructor */ && compilerOptions.noImplicitReturns && !isUnwrappedReturnTypeVoidOrAny(func, returnType) && !isGenerator) {
                // The function has a return type, but the return statement doesn't have an expression.
                error(node, ts.Diagnostics.Not_all_code_paths_return_a_value);
            }
        }
        function checkWithStatement(node) {
            // Grammar checking for withStatement
            if (!checkGrammarStatementInAmbientContext(node)) {
                if (node.flags & 16384 /* AwaitContext */) {
                    grammarErrorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_an_async_function_block);
                }
            }
            checkExpression(node.expression);
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                var start = ts.getSpanOfTokenAtPosition(sourceFile, node.pos).start;
                var end = node.statement.pos;
                grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any);
            }
        }
        function checkSwitchStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            var firstDefaultClause;
            var hasDuplicateDefaultClause = false;
            var expressionType = checkExpression(node.expression);
            var expressionIsLiteral = isLiteralType(expressionType);
            ts.forEach(node.caseBlock.clauses, function (clause) {
                // Grammar check for duplicate default clauses, skip if we already report duplicate default clause
                if (clause.kind === 273 /* DefaultClause */ && !hasDuplicateDefaultClause) {
                    if (firstDefaultClause === undefined) {
                        firstDefaultClause = clause;
                    }
                    else {
                        var sourceFile = ts.getSourceFileOfNode(node);
                        var start = ts.skipTrivia(sourceFile.text, clause.pos);
                        var end = clause.statements.length > 0 ? clause.statements[0].pos : clause.end;
                        grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.A_default_clause_cannot_appear_more_than_once_in_a_switch_statement);
                        hasDuplicateDefaultClause = true;
                    }
                }
                if (produceDiagnostics && clause.kind === 272 /* CaseClause */) {
                    // TypeScript 1.0 spec (April 2014): 5.9
                    // In a 'switch' statement, each 'case' expression must be of a type that is comparable
                    // to or from the type of the 'switch' expression.
                    var caseType = checkExpression(clause.expression);
                    var caseIsLiteral = isLiteralType(caseType);
                    var comparedExpressionType = expressionType;
                    if (!caseIsLiteral || !expressionIsLiteral) {
                        caseType = caseIsLiteral ? getBaseTypeOfLiteralType(caseType) : caseType;
                        comparedExpressionType = getBaseTypeOfLiteralType(expressionType);
                    }
                    if (!isTypeEqualityComparableTo(comparedExpressionType, caseType)) {
                        // expressionType is not comparable to caseType, try the reversed check and report errors if it fails
                        checkTypeComparableTo(caseType, comparedExpressionType, clause.expression, /*headMessage*/ undefined);
                    }
                }
                ts.forEach(clause.statements, checkSourceElement);
            });
            if (node.caseBlock.locals) {
                registerForUnusedIdentifiersCheck(node.caseBlock);
            }
        }
        function checkLabeledStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node)) {
                ts.findAncestor(node.parent, function (current) {
                    if (ts.isFunctionLike(current)) {
                        return "quit";
                    }
                    if (current.kind === 234 /* LabeledStatement */ && current.label.escapedText === node.label.escapedText) {
                        grammarErrorOnNode(node.label, ts.Diagnostics.Duplicate_label_0, ts.getTextOfNode(node.label));
                        return true;
                    }
                    return false;
                });
            }
            // ensure that label is unique
            checkSourceElement(node.statement);
        }
        function checkThrowStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node)) {
                if (node.expression === undefined) {
                    grammarErrorAfterFirstToken(node, ts.Diagnostics.Line_break_not_permitted_here);
                }
            }
            if (node.expression) {
                checkExpression(node.expression);
            }
        }
        function checkTryStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkBlock(node.tryBlock);
            var catchClause = node.catchClause;
            if (catchClause) {
                // Grammar checking
                if (catchClause.variableDeclaration) {
                    if (catchClause.variableDeclaration.type) {
                        grammarErrorOnFirstToken(catchClause.variableDeclaration.type, ts.Diagnostics.Catch_clause_variable_cannot_have_a_type_annotation);
                    }
                    else if (catchClause.variableDeclaration.initializer) {
                        grammarErrorOnFirstToken(catchClause.variableDeclaration.initializer, ts.Diagnostics.Catch_clause_variable_cannot_have_an_initializer);
                    }
                    else {
                        var blockLocals_1 = catchClause.block.locals;
                        if (blockLocals_1) {
                            ts.forEachKey(catchClause.locals, function (caughtName) {
                                var blockLocal = blockLocals_1.get(caughtName);
                                if (blockLocal && (blockLocal.flags & 2 /* BlockScopedVariable */) !== 0) {
                                    grammarErrorOnNode(blockLocal.valueDeclaration, ts.Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, caughtName);
                                }
                            });
                        }
                    }
                }
                checkBlock(catchClause.block);
            }
            if (node.finallyBlock) {
                checkBlock(node.finallyBlock);
            }
        }
        function checkIndexConstraints(type) {
            var declaredNumberIndexer = getIndexDeclarationOfSymbol(type.symbol, 1 /* Number */);
            var declaredStringIndexer = getIndexDeclarationOfSymbol(type.symbol, 0 /* String */);
            var stringIndexType = getIndexTypeOfType(type, 0 /* String */);
            var numberIndexType = getIndexTypeOfType(type, 1 /* Number */);
            if (stringIndexType || numberIndexType) {
                ts.forEach(getPropertiesOfObjectType(type), function (prop) {
                    var propType = getTypeOfSymbol(prop);
                    checkIndexConstraintForProperty(prop, propType, type, declaredStringIndexer, stringIndexType, 0 /* String */);
                    checkIndexConstraintForProperty(prop, propType, type, declaredNumberIndexer, numberIndexType, 1 /* Number */);
                });
                var classDeclaration = type.symbol.valueDeclaration;
                if (ts.getObjectFlags(type) & 1 /* Class */ && ts.isClassLike(classDeclaration)) {
                    for (var _i = 0, _a = classDeclaration.members; _i < _a.length; _i++) {
                        var member = _a[_i];
                        // Only process instance properties with computed names here.
                        // Static properties cannot be in conflict with indexers,
                        // and properties with literal names were already checked.
                        if (!ts.hasModifier(member, 32 /* Static */) && hasNonBindableDynamicName(member)) {
                            var symbol = getSymbolOfNode(member);
                            var propType = getTypeOfSymbol(symbol);
                            checkIndexConstraintForProperty(symbol, propType, type, declaredStringIndexer, stringIndexType, 0 /* String */);
                            checkIndexConstraintForProperty(symbol, propType, type, declaredNumberIndexer, numberIndexType, 1 /* Number */);
                        }
                    }
                }
            }
            var errorNode;
            if (stringIndexType && numberIndexType) {
                errorNode = declaredNumberIndexer || declaredStringIndexer;
                // condition 'errorNode === undefined' may appear if types does not declare nor string neither number indexer
                if (!errorNode && (ts.getObjectFlags(type) & 2 /* Interface */)) {
                    var someBaseTypeHasBothIndexers = ts.forEach(getBaseTypes(type), function (base) { return getIndexTypeOfType(base, 0 /* String */) && getIndexTypeOfType(base, 1 /* Number */); });
                    errorNode = someBaseTypeHasBothIndexers ? undefined : type.symbol.declarations[0];
                }
            }
            if (errorNode && !isTypeAssignableTo(numberIndexType, stringIndexType)) { // TODO: GH#18217
                error(errorNode, ts.Diagnostics.Numeric_index_type_0_is_not_assignable_to_string_index_type_1, typeToString(numberIndexType), typeToString(stringIndexType));
            }
            function checkIndexConstraintForProperty(prop, propertyType, containingType, indexDeclaration, indexType, indexKind) {
                // ESSymbol properties apply to neither string nor numeric indexers.
                if (!indexType || ts.isKnownSymbol(prop)) {
                    return;
                }
                var propDeclaration = prop.valueDeclaration;
                var name = propDeclaration && ts.getNameOfDeclaration(propDeclaration);
                // index is numeric and property name is not valid numeric literal
                if (indexKind === 1 /* Number */ && !(name ? isNumericName(name) : isNumericLiteralName(prop.escapedName))) {
                    return;
                }
                // perform property check if property or indexer is declared in 'type'
                // this allows us to rule out cases when both property and indexer are inherited from the base class
                var errorNode;
                if (propDeclaration && name &&
                    (propDeclaration.kind === 205 /* BinaryExpression */ ||
                        name.kind === 150 /* ComputedPropertyName */ ||
                        prop.parent === containingType.symbol)) {
                    errorNode = propDeclaration;
                }
                else if (indexDeclaration) {
                    errorNode = indexDeclaration;
                }
                else if (ts.getObjectFlags(containingType) & 2 /* Interface */) {
                    // for interfaces property and indexer might be inherited from different bases
                    // check if any base class already has both property and indexer.
                    // check should be performed only if 'type' is the first type that brings property\indexer together
                    var someBaseClassHasBothPropertyAndIndexer = ts.forEach(getBaseTypes(containingType), function (base) { return getPropertyOfObjectType(base, prop.escapedName) && getIndexTypeOfType(base, indexKind); });
                    errorNode = someBaseClassHasBothPropertyAndIndexer ? undefined : containingType.symbol.declarations[0];
                }
                if (errorNode && !isTypeAssignableTo(propertyType, indexType)) {
                    var errorMessage = indexKind === 0 /* String */
                        ? ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_string_index_type_2
                        : ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2;
                    error(errorNode, errorMessage, symbolToString(prop), typeToString(propertyType), typeToString(indexType));
                }
            }
        }
        function checkTypeNameIsReserved(name, message) {
            // TS 1.0 spec (April 2014): 3.6.1
            // The predefined type keywords are reserved and cannot be used as names of user defined types.
            switch (name.escapedText) {
                case "any":
                case "unknown":
                case "number":
                case "bigint":
                case "boolean":
                case "string":
                case "symbol":
                case "void":
                case "object":
                    error(name, message, name.escapedText);
            }
        }
        /**
         * The name cannot be used as 'Object' of user defined types with special target.
         */
        function checkClassNameCollisionWithObject(name) {
            if (languageVersion === 1 /* ES5 */ && name.escapedText === "Object"
                && moduleKind !== ts.ModuleKind.ES2015 && moduleKind !== ts.ModuleKind.ESNext) {
                error(name, ts.Diagnostics.Class_name_cannot_be_Object_when_targeting_ES5_with_module_0, ts.ModuleKind[moduleKind]); // https://github.com/Microsoft/TypeScript/issues/17494
            }
        }
        /**
         * Check each type parameter and check that type parameters have no duplicate type parameter declarations
         */
        function checkTypeParameters(typeParameterDeclarations) {
            if (typeParameterDeclarations) {
                var seenDefault = false;
                for (var i = 0; i < typeParameterDeclarations.length; i++) {
                    var node = typeParameterDeclarations[i];
                    checkTypeParameter(node);
                    if (produceDiagnostics) {
                        if (node.default) {
                            seenDefault = true;
                            checkTypeParametersNotReferenced(node.default, typeParameterDeclarations, i);
                        }
                        else if (seenDefault) {
                            error(node, ts.Diagnostics.Required_type_parameters_may_not_follow_optional_type_parameters);
                        }
                        for (var j = 0; j < i; j++) {
                            if (typeParameterDeclarations[j].symbol === node.symbol) {
                                error(node.name, ts.Diagnostics.Duplicate_identifier_0, ts.declarationNameToString(node.name));
                            }
                        }
                    }
                }
            }
        }
        /** Check that type parameter defaults only reference previously declared type parameters */
        function checkTypeParametersNotReferenced(root, typeParameters, index) {
            visit(root);
            function visit(node) {
                if (node.kind === 165 /* TypeReference */) {
                    var type = getTypeFromTypeReference(node);
                    if (type.flags & 262144 /* TypeParameter */) {
                        for (var i = index; i < typeParameters.length; i++) {
                            if (type.symbol === getSymbolOfNode(typeParameters[i])) {
                                error(node, ts.Diagnostics.Type_parameter_defaults_can_only_reference_previously_declared_type_parameters);
                            }
                        }
                    }
                }
                ts.forEachChild(node, visit);
            }
        }
        /** Check that type parameter lists are identical across multiple declarations */
        function checkTypeParameterListsIdentical(symbol) {
            if (symbol.declarations.length === 1) {
                return;
            }
            var links = getSymbolLinks(symbol);
            if (!links.typeParametersChecked) {
                links.typeParametersChecked = true;
                var declarations = getClassOrInterfaceDeclarationsOfSymbol(symbol);
                if (declarations.length <= 1) {
                    return;
                }
                var type = getDeclaredTypeOfSymbol(symbol);
                if (!areTypeParametersIdentical(declarations, type.localTypeParameters)) {
                    // Report an error on every conflicting declaration.
                    var name = symbolToString(symbol);
                    for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) {
                        var declaration = declarations_6[_i];
                        error(declaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, name);
                    }
                }
            }
        }
        function areTypeParametersIdentical(declarations, targetParameters) {
            var maxTypeArgumentCount = ts.length(targetParameters);
            var minTypeArgumentCount = getMinTypeArgumentCount(targetParameters);
            for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) {
                var declaration = declarations_7[_i];
                // If this declaration has too few or too many type parameters, we report an error
                var sourceParameters = ts.getEffectiveTypeParameterDeclarations(declaration);
                var numTypeParameters = sourceParameters.length;
                if (numTypeParameters < minTypeArgumentCount || numTypeParameters > maxTypeArgumentCount) {
                    return false;
                }
                for (var i = 0; i < numTypeParameters; i++) {
                    var source = sourceParameters[i];
                    var target = targetParameters[i];
                    // If the type parameter node does not have the same as the resolved type
                    // parameter at this position, we report an error.
                    if (source.name.escapedText !== target.symbol.escapedName) {
                        return false;
                    }
                    // If the type parameter node does not have an identical constraint as the resolved
                    // type parameter at this position, we report an error.
                    var constraint = ts.getEffectiveConstraintOfTypeParameter(source);
                    var sourceConstraint = constraint && getTypeFromTypeNode(constraint);
                    var targetConstraint = getConstraintOfTypeParameter(target);
                    if (sourceConstraint) {
                        // relax check if later interface augmentation has no constraint
                        if (!targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint)) {
                            return false;
                        }
                    }
                    // If the type parameter node has a default and it is not identical to the default
                    // for the type parameter at this position, we report an error.
                    var sourceDefault = source.default && getTypeFromTypeNode(source.default);
                    var targetDefault = getDefaultFromTypeParameter(target);
                    if (sourceDefault && targetDefault && !isTypeIdenticalTo(sourceDefault, targetDefault)) {
                        return false;
                    }
                }
            }
            return true;
        }
        function checkClassExpression(node) {
            checkClassLikeDeclaration(node);
            checkNodeDeferred(node);
            return getTypeOfSymbol(getSymbolOfNode(node));
        }
        function checkClassExpressionDeferred(node) {
            ts.forEach(node.members, checkSourceElement);
            registerForUnusedIdentifiersCheck(node);
        }
        function checkClassDeclaration(node) {
            if (!node.name && !ts.hasModifier(node, 512 /* Default */)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name);
            }
            checkClassLikeDeclaration(node);
            ts.forEach(node.members, checkSourceElement);
            registerForUnusedIdentifiersCheck(node);
        }
        function checkClassLikeDeclaration(node) {
            checkGrammarClassLikeDeclaration(node);
            checkDecorators(node);
            if (node.name) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Class_name_cannot_be_0);
                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
                if (!(node.flags & 4194304 /* Ambient */)) {
                    checkClassNameCollisionWithObject(node.name);
                }
            }
            checkTypeParameters(ts.getEffectiveTypeParameterDeclarations(node));
            checkExportsOnMergedDeclarations(node);
            var symbol = getSymbolOfNode(node);
            var type = getDeclaredTypeOfSymbol(symbol);
            var typeWithThis = getTypeWithThisArgument(type);
            var staticType = getTypeOfSymbol(symbol);
            checkTypeParameterListsIdentical(symbol);
            checkClassForDuplicateDeclarations(node);
            // Only check for reserved static identifiers on non-ambient context.
            if (!(node.flags & 4194304 /* Ambient */)) {
                checkClassForStaticPropertyNameConflicts(node);
            }
            var baseTypeNode = ts.getEffectiveBaseTypeNode(node);
            if (baseTypeNode) {
                if (languageVersion < 2 /* ES2015 */) {
                    checkExternalEmitHelpers(baseTypeNode.parent, 1 /* Extends */);
                }
                // check both @extends and extends if both are specified.
                var extendsNode = ts.getClassExtendsHeritageElement(node);
                if (extendsNode && extendsNode !== baseTypeNode) {
                    checkExpression(extendsNode.expression);
                }
                var baseTypes = getBaseTypes(type);
                if (baseTypes.length && produceDiagnostics) {
                    var baseType_1 = baseTypes[0];
                    var baseConstructorType = getBaseConstructorTypeOfClass(type);
                    var staticBaseType = getApparentType(baseConstructorType);
                    checkBaseTypeAccessibility(staticBaseType, baseTypeNode);
                    checkSourceElement(baseTypeNode.expression);
                    if (ts.some(baseTypeNode.typeArguments)) {
                        ts.forEach(baseTypeNode.typeArguments, checkSourceElement);
                        for (var _i = 0, _a = getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode); _i < _a.length; _i++) {
                            var constructor = _a[_i];
                            if (!checkTypeArgumentConstraints(baseTypeNode, constructor.typeParameters)) {
                                break;
                            }
                        }
                    }
                    var baseWithThis = getTypeWithThisArgument(baseType_1, type.thisType);
                    if (!checkTypeAssignableTo(typeWithThis, baseWithThis, /*errorNode*/ undefined)) {
                        issueMemberSpecificError(node, typeWithThis, baseWithThis, ts.Diagnostics.Class_0_incorrectly_extends_base_class_1);
                    }
                    else {
                        // Report static side error only when instance type is assignable
                        checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, ts.Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1);
                    }
                    if (baseConstructorType.flags & 8650752 /* TypeVariable */ && !isMixinConstructorType(staticType)) {
                        error(node.name || node, ts.Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any);
                    }
                    if (!(staticBaseType.symbol && staticBaseType.symbol.flags & 32 /* Class */) && !(baseConstructorType.flags & 8650752 /* TypeVariable */)) {
                        // When the static base type is a "class-like" constructor function (but not actually a class), we verify
                        // that all instantiated base constructor signatures return the same type. We can simply compare the type
                        // references (as opposed to checking the structure of the types) because elsewhere we have already checked
                        // that the base type is a class or interface type (and not, for example, an anonymous object type).
                        // (Javascript constructor functions have this property trivially true since their return type is ignored.)
                        var constructors = getInstantiatedConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode);
                        if (ts.forEach(constructors, function (sig) { return !isJSConstructor(sig.declaration) && getReturnTypeOfSignature(sig) !== baseType_1; })) {
                            error(baseTypeNode.expression, ts.Diagnostics.Base_constructors_must_all_have_the_same_return_type);
                        }
                    }
                    checkKindsOfPropertyMemberOverrides(type, baseType_1);
                }
            }
            var implementedTypeNodes = ts.getClassImplementsHeritageClauseElements(node);
            if (implementedTypeNodes) {
                for (var _b = 0, implementedTypeNodes_1 = implementedTypeNodes; _b < implementedTypeNodes_1.length; _b++) {
                    var typeRefNode = implementedTypeNodes_1[_b];
                    if (!ts.isEntityNameExpression(typeRefNode.expression)) {
                        error(typeRefNode.expression, ts.Diagnostics.A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments);
                    }
                    checkTypeReferenceNode(typeRefNode);
                    if (produceDiagnostics) {
                        var t = getTypeFromTypeNode(typeRefNode);
                        if (t !== errorType) {
                            if (isValidBaseType(t)) {
                                var genericDiag = t.symbol && t.symbol.flags & 32 /* Class */ ?
                                    ts.Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass :
                                    ts.Diagnostics.Class_0_incorrectly_implements_interface_1;
                                var baseWithThis = getTypeWithThisArgument(t, type.thisType);
                                if (!checkTypeAssignableTo(typeWithThis, baseWithThis, /*errorNode*/ undefined)) {
                                    issueMemberSpecificError(node, typeWithThis, baseWithThis, genericDiag);
                                }
                            }
                            else {
                                error(typeRefNode, ts.Diagnostics.A_class_can_only_implement_an_object_type_or_intersection_of_object_types_with_statically_known_members);
                            }
                        }
                    }
                }
            }
            if (produceDiagnostics) {
                checkIndexConstraints(type);
                checkTypeForDuplicateIndexSignatures(node);
                checkPropertyInitialization(node);
            }
        }
        function issueMemberSpecificError(node, typeWithThis, baseWithThis, broadDiag) {
            // iterate over all implemented properties and issue errors on each one which isn't compatible, rather than the class as a whole, if possible
            var issuedMemberError = false;
            var _loop_12 = function (member) {
                if (ts.hasStaticModifier(member)) {
                    return "continue";
                }
                var declaredProp = member.name && getSymbolAtLocation(member.name) || getSymbolAtLocation(member);
                if (declaredProp) {
                    var prop = getPropertyOfType(typeWithThis, declaredProp.escapedName);
                    var baseProp = getPropertyOfType(baseWithThis, declaredProp.escapedName);
                    if (prop && baseProp) {
                        var rootChain = function () { return ts.chainDiagnosticMessages(
                        /*details*/ undefined, ts.Diagnostics.Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2, symbolToString(declaredProp), typeToString(typeWithThis), typeToString(baseWithThis)); };
                        if (!checkTypeAssignableTo(getTypeOfSymbol(prop), getTypeOfSymbol(baseProp), member.name || member, /*message*/ undefined, rootChain)) {
                            issuedMemberError = true;
                        }
                    }
                }
            };
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                _loop_12(member);
            }
            if (!issuedMemberError) {
                // check again with diagnostics to generate a less-specific error
                checkTypeAssignableTo(typeWithThis, baseWithThis, node.name || node, broadDiag);
            }
        }
        function checkBaseTypeAccessibility(type, node) {
            var signatures = getSignaturesOfType(type, 1 /* Construct */);
            if (signatures.length) {
                var declaration = signatures[0].declaration;
                if (declaration && ts.hasModifier(declaration, 8 /* Private */)) {
                    var typeClassDeclaration = ts.getClassLikeDeclarationOfSymbol(type.symbol);
                    if (!isNodeWithinClass(node, typeClassDeclaration)) {
                        error(node, ts.Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol));
                    }
                }
            }
        }
        function getTargetSymbol(s) {
            // if symbol is instantiated its flags are not copied from the 'target'
            // so we'll need to get back original 'target' symbol to work with correct set of flags
            return ts.getCheckFlags(s) & 1 /* Instantiated */ ? s.target : s;
        }
        function getClassOrInterfaceDeclarationsOfSymbol(symbol) {
            return ts.filter(symbol.declarations, function (d) {
                return d.kind === 241 /* ClassDeclaration */ || d.kind === 242 /* InterfaceDeclaration */;
            });
        }
        function checkKindsOfPropertyMemberOverrides(type, baseType) {
            // TypeScript 1.0 spec (April 2014): 8.2.3
            // A derived class inherits all members from its base class it doesn't override.
            // Inheritance means that a derived class implicitly contains all non - overridden members of the base class.
            // Both public and private property members are inherited, but only public property members can be overridden.
            // A property member in a derived class is said to override a property member in a base class
            // when the derived class property member has the same name and kind(instance or static)
            // as the base class property member.
            // The type of an overriding property member must be assignable(section 3.8.4)
            // to the type of the overridden property member, or otherwise a compile - time error occurs.
            // Base class instance member functions can be overridden by derived class instance member functions,
            // but not by other kinds of members.
            // Base class instance member variables and accessors can be overridden by
            // derived class instance member variables and accessors, but not by other kinds of members.
            // NOTE: assignability is checked in checkClassDeclaration
            var baseProperties = getPropertiesOfType(baseType);
            for (var _i = 0, baseProperties_1 = baseProperties; _i < baseProperties_1.length; _i++) {
                var baseProperty = baseProperties_1[_i];
                var base = getTargetSymbol(baseProperty);
                if (base.flags & 4194304 /* Prototype */) {
                    continue;
                }
                var derived = getTargetSymbol(getPropertyOfObjectType(type, base.escapedName)); // TODO: GH#18217
                var baseDeclarationFlags = ts.getDeclarationModifierFlagsFromSymbol(base);
                ts.Debug.assert(!!derived, "derived should point to something, even if it is the base class' declaration.");
                if (derived) {
                    // In order to resolve whether the inherited method was overridden in the base class or not,
                    // we compare the Symbols obtained. Since getTargetSymbol returns the symbol on the *uninstantiated*
                    // type declaration, derived and base resolve to the same symbol even in the case of generic classes.
                    if (derived === base) {
                        // derived class inherits base without override/redeclaration
                        var derivedClassDecl = ts.getClassLikeDeclarationOfSymbol(type.symbol);
                        // It is an error to inherit an abstract member without implementing it or being declared abstract.
                        // If there is no declaration for the derived class (as in the case of class expressions),
                        // then the class cannot be declared abstract.
                        if (baseDeclarationFlags & 128 /* Abstract */ && (!derivedClassDecl || !ts.hasModifier(derivedClassDecl, 128 /* Abstract */))) {
                            if (derivedClassDecl.kind === 210 /* ClassExpression */) {
                                error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, symbolToString(baseProperty), typeToString(baseType));
                            }
                            else {
                                error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2, typeToString(type), symbolToString(baseProperty), typeToString(baseType));
                            }
                        }
                    }
                    else {
                        // derived overrides base.
                        var derivedDeclarationFlags = ts.getDeclarationModifierFlagsFromSymbol(derived);
                        if (baseDeclarationFlags & 8 /* Private */ || derivedDeclarationFlags & 8 /* Private */) {
                            // either base or derived property is private - not override, skip it
                            continue;
                        }
                        if (isPrototypeProperty(base) || base.flags & 98308 /* PropertyOrAccessor */ && derived.flags & 98308 /* PropertyOrAccessor */) {
                            // method is overridden with method or property/accessor is overridden with property/accessor - correct case
                            continue;
                        }
                        var errorMessage = void 0;
                        if (isPrototypeProperty(base)) {
                            if (derived.flags & 98304 /* Accessor */) {
                                errorMessage = ts.Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor;
                            }
                            else {
                                errorMessage = ts.Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property;
                            }
                        }
                        else if (base.flags & 98304 /* Accessor */) {
                            errorMessage = ts.Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function;
                        }
                        else {
                            errorMessage = ts.Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function;
                        }
                        error(ts.getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type));
                    }
                }
            }
        }
        function checkInheritedPropertiesAreIdentical(type, typeNode) {
            var baseTypes = getBaseTypes(type);
            if (baseTypes.length < 2) {
                return true;
            }
            var seen = ts.createUnderscoreEscapedMap();
            ts.forEach(resolveDeclaredMembers(type).declaredProperties, function (p) { seen.set(p.escapedName, { prop: p, containingType: type }); });
            var ok = true;
            for (var _i = 0, baseTypes_2 = baseTypes; _i < baseTypes_2.length; _i++) {
                var base = baseTypes_2[_i];
                var properties = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType));
                for (var _a = 0, properties_4 = properties; _a < properties_4.length; _a++) {
                    var prop = properties_4[_a];
                    var existing = seen.get(prop.escapedName);
                    if (!existing) {
                        seen.set(prop.escapedName, { prop: prop, containingType: base });
                    }
                    else {
                        var isInheritedProperty = existing.containingType !== type;
                        if (isInheritedProperty && !isPropertyIdenticalTo(existing.prop, prop)) {
                            ok = false;
                            var typeName1 = typeToString(existing.containingType);
                            var typeName2 = typeToString(base);
                            var errorInfo = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Named_property_0_of_types_1_and_2_are_not_identical, symbolToString(prop), typeName1, typeName2);
                            errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Interface_0_cannot_simultaneously_extend_types_1_and_2, typeToString(type), typeName1, typeName2);
                            diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(typeNode, errorInfo));
                        }
                    }
                }
            }
            return ok;
        }
        function checkPropertyInitialization(node) {
            if (!strictNullChecks || !strictPropertyInitialization || node.flags & 4194304 /* Ambient */) {
                return;
            }
            var constructor = findConstructorDeclaration(node);
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                if (isInstancePropertyWithoutInitializer(member)) {
                    var propName = member.name;
                    if (ts.isIdentifier(propName)) {
                        var type = getTypeOfSymbol(getSymbolOfNode(member));
                        if (!(type.flags & 3 /* AnyOrUnknown */ || getFalsyFlags(type) & 32768 /* Undefined */)) {
                            if (!constructor || !isPropertyInitializedInConstructor(propName, type, constructor)) {
                                error(member.name, ts.Diagnostics.Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor, ts.declarationNameToString(propName));
                            }
                        }
                    }
                }
            }
        }
        function isInstancePropertyWithoutInitializer(node) {
            return node.kind === 155 /* PropertyDeclaration */ &&
                !ts.hasModifier(node, 32 /* Static */ | 128 /* Abstract */) &&
                !node.exclamationToken &&
                !node.initializer;
        }
        function isPropertyInitializedInConstructor(propName, propType, constructor) {
            var reference = ts.createPropertyAccess(ts.createThis(), propName);
            reference.expression.parent = reference;
            reference.parent = constructor;
            reference.flowNode = constructor.returnFlowNode;
            var flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType));
            return !(getFalsyFlags(flowType) & 32768 /* Undefined */);
        }
        function checkInterfaceDeclaration(node) {
            // Grammar checking
            if (!checkGrammarDecoratorsAndModifiers(node))
                checkGrammarInterfaceDeclaration(node);
            checkTypeParameters(node.typeParameters);
            if (produceDiagnostics) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Interface_name_cannot_be_0);
                checkExportsOnMergedDeclarations(node);
                var symbol = getSymbolOfNode(node);
                checkTypeParameterListsIdentical(symbol);
                // Only check this symbol once
                var firstInterfaceDecl = ts.getDeclarationOfKind(symbol, 242 /* InterfaceDeclaration */);
                if (node === firstInterfaceDecl) {
                    var type = getDeclaredTypeOfSymbol(symbol);
                    var typeWithThis = getTypeWithThisArgument(type);
                    // run subsequent checks only if first set succeeded
                    if (checkInheritedPropertiesAreIdentical(type, node.name)) {
                        for (var _i = 0, _a = getBaseTypes(type); _i < _a.length; _i++) {
                            var baseType = _a[_i];
                            checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType, type.thisType), node.name, ts.Diagnostics.Interface_0_incorrectly_extends_interface_1);
                        }
                        checkIndexConstraints(type);
                    }
                }
                checkObjectTypeForDuplicateDeclarations(node);
            }
            ts.forEach(ts.getInterfaceBaseTypeNodes(node), function (heritageElement) {
                if (!ts.isEntityNameExpression(heritageElement.expression)) {
                    error(heritageElement.expression, ts.Diagnostics.An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments);
                }
                checkTypeReferenceNode(heritageElement);
            });
            ts.forEach(node.members, checkSourceElement);
            if (produceDiagnostics) {
                checkTypeForDuplicateIndexSignatures(node);
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkTypeAliasDeclaration(node) {
            // Grammar checking
            checkGrammarDecoratorsAndModifiers(node);
            checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_alias_name_cannot_be_0);
            checkTypeParameters(node.typeParameters);
            checkSourceElement(node.type);
            registerForUnusedIdentifiersCheck(node);
        }
        function computeEnumMemberValues(node) {
            var nodeLinks = getNodeLinks(node);
            if (!(nodeLinks.flags & 16384 /* EnumValuesComputed */)) {
                nodeLinks.flags |= 16384 /* EnumValuesComputed */;
                var autoValue = 0;
                for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                    var member = _a[_i];
                    var value = computeMemberValue(member, autoValue);
                    getNodeLinks(member).enumMemberValue = value;
                    autoValue = typeof value === "number" ? value + 1 : undefined;
                }
            }
        }
        function computeMemberValue(member, autoValue) {
            if (isComputedNonLiteralName(member.name)) {
                error(member.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_enums);
            }
            else {
                var text = ts.getTextOfPropertyName(member.name);
                if (isNumericLiteralName(text) && !isInfinityOrNaNString(text)) {
                    error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name);
                }
            }
            if (member.initializer) {
                return computeConstantValue(member);
            }
            // In ambient enum declarations that specify no const modifier, enum member declarations that omit
            // a value are considered computed members (as opposed to having auto-incremented values).
            if (member.parent.flags & 4194304 /* Ambient */ && !ts.isEnumConst(member.parent)) {
                return undefined;
            }
            // If the member declaration specifies no value, the member is considered a constant enum member.
            // If the member is the first member in the enum declaration, it is assigned the value zero.
            // Otherwise, it is assigned the value of the immediately preceding member plus one, and an error
            // occurs if the immediately preceding member is not a constant enum member.
            if (autoValue !== undefined) {
                return autoValue;
            }
            error(member.name, ts.Diagnostics.Enum_member_must_have_initializer);
            return undefined;
        }
        function computeConstantValue(member) {
            var enumKind = getEnumKind(getSymbolOfNode(member.parent));
            var isConstEnum = ts.isEnumConst(member.parent);
            var initializer = member.initializer;
            var value = enumKind === 1 /* Literal */ && !isLiteralEnumMember(member) ? undefined : evaluate(initializer);
            if (value !== undefined) {
                if (isConstEnum && typeof value === "number" && !isFinite(value)) {
                    error(initializer, isNaN(value) ?
                        ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN :
                        ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value);
                }
            }
            else if (enumKind === 1 /* Literal */) {
                error(initializer, ts.Diagnostics.Computed_values_are_not_permitted_in_an_enum_with_string_valued_members);
                return 0;
            }
            else if (isConstEnum) {
                error(initializer, ts.Diagnostics.const_enum_member_initializers_can_only_contain_literal_values_and_other_computed_enum_values);
            }
            else if (member.parent.flags & 4194304 /* Ambient */) {
                error(initializer, ts.Diagnostics.In_ambient_enum_declarations_member_initializer_must_be_constant_expression);
            }
            else {
                // Only here do we need to check that the initializer is assignable to the enum type.
                checkTypeAssignableTo(checkExpression(initializer), getDeclaredTypeOfSymbol(getSymbolOfNode(member.parent)), initializer, /*headMessage*/ undefined);
            }
            return value;
            function evaluate(expr) {
                switch (expr.kind) {
                    case 203 /* PrefixUnaryExpression */:
                        var value_2 = evaluate(expr.operand);
                        if (typeof value_2 === "number") {
                            switch (expr.operator) {
                                case 38 /* PlusToken */: return value_2;
                                case 39 /* MinusToken */: return -value_2;
                                case 53 /* TildeToken */: return ~value_2;
                            }
                        }
                        break;
                    case 205 /* BinaryExpression */:
                        var left = evaluate(expr.left);
                        var right = evaluate(expr.right);
                        if (typeof left === "number" && typeof right === "number") {
                            switch (expr.operatorToken.kind) {
                                case 50 /* BarToken */: return left | right;
                                case 49 /* AmpersandToken */: return left & right;
                                case 47 /* GreaterThanGreaterThanToken */: return left >> right;
                                case 48 /* GreaterThanGreaterThanGreaterThanToken */: return left >>> right;
                                case 46 /* LessThanLessThanToken */: return left << right;
                                case 51 /* CaretToken */: return left ^ right;
                                case 40 /* AsteriskToken */: return left * right;
                                case 42 /* SlashToken */: return left / right;
                                case 38 /* PlusToken */: return left + right;
                                case 39 /* MinusToken */: return left - right;
                                case 43 /* PercentToken */: return left % right;
                                case 41 /* AsteriskAsteriskToken */: return Math.pow(left, right);
                            }
                        }
                        else if (typeof left === "string" && typeof right === "string" && expr.operatorToken.kind === 38 /* PlusToken */) {
                            return left + right;
                        }
                        break;
                    case 10 /* StringLiteral */:
                        return expr.text;
                    case 8 /* NumericLiteral */:
                        checkGrammarNumericLiteral(expr);
                        return +expr.text;
                    case 196 /* ParenthesizedExpression */:
                        return evaluate(expr.expression);
                    case 73 /* Identifier */:
                        var identifier = expr;
                        if (isInfinityOrNaNString(identifier.escapedText)) {
                            return +(identifier.escapedText);
                        }
                        return ts.nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), identifier.escapedText);
                    case 191 /* ElementAccessExpression */:
                    case 190 /* PropertyAccessExpression */:
                        var ex = expr;
                        if (isConstantMemberAccess(ex)) {
                            var type = getTypeOfExpression(ex.expression);
                            if (type.symbol && type.symbol.flags & 384 /* Enum */) {
                                var name = void 0;
                                if (ex.kind === 190 /* PropertyAccessExpression */) {
                                    name = ex.name.escapedText;
                                }
                                else {
                                    var argument = ex.argumentExpression;
                                    ts.Debug.assert(ts.isLiteralExpression(argument));
                                    name = ts.escapeLeadingUnderscores(argument.text);
                                }
                                return evaluateEnumMember(expr, type.symbol, name);
                            }
                        }
                        break;
                }
                return undefined;
            }
            function evaluateEnumMember(expr, enumSymbol, name) {
                var memberSymbol = enumSymbol.exports.get(name);
                if (memberSymbol) {
                    var declaration = memberSymbol.valueDeclaration;
                    if (declaration !== member) {
                        if (isBlockScopedNameDeclaredBeforeUse(declaration, member)) {
                            return getEnumMemberValue(declaration);
                        }
                        error(expr, ts.Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums);
                        return 0;
                    }
                }
                return undefined;
            }
        }
        function isConstantMemberAccess(node) {
            return node.kind === 73 /* Identifier */ ||
                node.kind === 190 /* PropertyAccessExpression */ && isConstantMemberAccess(node.expression) ||
                node.kind === 191 /* ElementAccessExpression */ && isConstantMemberAccess(node.expression) &&
                    node.argumentExpression.kind === 10 /* StringLiteral */;
        }
        function checkEnumDeclaration(node) {
            if (!produceDiagnostics) {
                return;
            }
            // Grammar checking
            checkGrammarDecoratorsAndModifiers(node);
            checkTypeNameIsReserved(node.name, ts.Diagnostics.Enum_name_cannot_be_0);
            checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
            checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            checkExportsOnMergedDeclarations(node);
            computeEnumMemberValues(node);
            // Spec 2014 - Section 9.3:
            // It isn't possible for one enum declaration to continue the automatic numbering sequence of another,
            // and when an enum type has multiple declarations, only one declaration is permitted to omit a value
            // for the first member.
            //
            // Only perform this check once per symbol
            var enumSymbol = getSymbolOfNode(node);
            var firstDeclaration = ts.getDeclarationOfKind(enumSymbol, node.kind);
            if (node === firstDeclaration) {
                if (enumSymbol.declarations.length > 1) {
                    var enumIsConst_1 = ts.isEnumConst(node);
                    // check that const is placed\omitted on all enum declarations
                    ts.forEach(enumSymbol.declarations, function (decl) {
                        if (ts.isEnumDeclaration(decl) && ts.isEnumConst(decl) !== enumIsConst_1) {
                            error(ts.getNameOfDeclaration(decl), ts.Diagnostics.Enum_declarations_must_all_be_const_or_non_const);
                        }
                    });
                }
                var seenEnumMissingInitialInitializer_1 = false;
                ts.forEach(enumSymbol.declarations, function (declaration) {
                    // return true if we hit a violation of the rule, false otherwise
                    if (declaration.kind !== 244 /* EnumDeclaration */) {
                        return false;
                    }
                    var enumDeclaration = declaration;
                    if (!enumDeclaration.members.length) {
                        return false;
                    }
                    var firstEnumMember = enumDeclaration.members[0];
                    if (!firstEnumMember.initializer) {
                        if (seenEnumMissingInitialInitializer_1) {
                            error(firstEnumMember.name, ts.Diagnostics.In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element);
                        }
                        else {
                            seenEnumMissingInitialInitializer_1 = true;
                        }
                    }
                });
            }
        }
        function getFirstNonAmbientClassOrFunctionDeclaration(symbol) {
            var declarations = symbol.declarations;
            for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) {
                var declaration = declarations_8[_i];
                if ((declaration.kind === 241 /* ClassDeclaration */ ||
                    (declaration.kind === 240 /* FunctionDeclaration */ && ts.nodeIsPresent(declaration.body))) &&
                    !(declaration.flags & 4194304 /* Ambient */)) {
                    return declaration;
                }
            }
            return undefined;
        }
        function inSameLexicalScope(node1, node2) {
            var container1 = ts.getEnclosingBlockScopeContainer(node1);
            var container2 = ts.getEnclosingBlockScopeContainer(node2);
            if (isGlobalSourceFile(container1)) {
                return isGlobalSourceFile(container2);
            }
            else if (isGlobalSourceFile(container2)) {
                return false;
            }
            else {
                return container1 === container2;
            }
        }
        function checkModuleDeclaration(node) {
            if (produceDiagnostics) {
                // Grammar checking
                var isGlobalAugmentation = ts.isGlobalScopeAugmentation(node);
                var inAmbientContext = node.flags & 4194304 /* Ambient */;
                if (isGlobalAugmentation && !inAmbientContext) {
                    error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context);
                }
                var isAmbientExternalModule = ts.isAmbientModule(node);
                var contextErrorMessage = isAmbientExternalModule
                    ? ts.Diagnostics.An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file
                    : ts.Diagnostics.A_namespace_declaration_is_only_allowed_in_a_namespace_or_module;
                if (checkGrammarModuleElementContext(node, contextErrorMessage)) {
                    // If we hit a module declaration in an illegal context, just bail out to avoid cascading errors.
                    return;
                }
                if (!checkGrammarDecoratorsAndModifiers(node)) {
                    if (!inAmbientContext && node.name.kind === 10 /* StringLiteral */) {
                        grammarErrorOnNode(node.name, ts.Diagnostics.Only_ambient_modules_can_use_quoted_names);
                    }
                }
                if (ts.isIdentifier(node.name)) {
                    checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                    checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
                }
                checkExportsOnMergedDeclarations(node);
                var symbol = getSymbolOfNode(node);
                // The following checks only apply on a non-ambient instantiated module declaration.
                if (symbol.flags & 512 /* ValueModule */
                    && !inAmbientContext
                    && symbol.declarations.length > 1
                    && isInstantiatedModule(node, !!compilerOptions.preserveConstEnums || !!compilerOptions.isolatedModules)) {
                    var firstNonAmbientClassOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol);
                    if (firstNonAmbientClassOrFunc) {
                        if (ts.getSourceFileOfNode(node) !== ts.getSourceFileOfNode(firstNonAmbientClassOrFunc)) {
                            error(node.name, ts.Diagnostics.A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged);
                        }
                        else if (node.pos < firstNonAmbientClassOrFunc.pos) {
                            error(node.name, ts.Diagnostics.A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged);
                        }
                    }
                    // if the module merges with a class declaration in the same lexical scope,
                    // we need to track this to ensure the correct emit.
                    var mergedClass = ts.getDeclarationOfKind(symbol, 241 /* ClassDeclaration */);
                    if (mergedClass &&
                        inSameLexicalScope(node, mergedClass)) {
                        getNodeLinks(node).flags |= 32768 /* LexicalModuleMergesWithClass */;
                    }
                }
                if (isAmbientExternalModule) {
                    if (ts.isExternalModuleAugmentation(node)) {
                        // body of the augmentation should be checked for consistency only if augmentation was applied to its target (either global scope or module)
                        // otherwise we'll be swamped in cascading errors.
                        // We can detect if augmentation was applied using following rules:
                        // - augmentation for a global scope is always applied
                        // - augmentation for some external module is applied if symbol for augmentation is merged (it was combined with target module).
                        var checkBody = isGlobalAugmentation || (getSymbolOfNode(node).flags & 33554432 /* Transient */);
                        if (checkBody && node.body) {
                            for (var _i = 0, _a = node.body.statements; _i < _a.length; _i++) {
                                var statement = _a[_i];
                                checkModuleAugmentationElement(statement, isGlobalAugmentation);
                            }
                        }
                    }
                    else if (isGlobalSourceFile(node.parent)) {
                        if (isGlobalAugmentation) {
                            error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations);
                        }
                        else if (ts.isExternalModuleNameRelative(ts.getTextOfIdentifierOrLiteral(node.name))) {
                            error(node.name, ts.Diagnostics.Ambient_module_declaration_cannot_specify_relative_module_name);
                        }
                    }
                    else {
                        if (isGlobalAugmentation) {
                            error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations);
                        }
                        else {
                            // Node is not an augmentation and is not located on the script level.
                            // This means that this is declaration of ambient module that is located in other module or namespace which is prohibited.
                            error(node.name, ts.Diagnostics.Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces);
                        }
                    }
                }
            }
            if (node.body) {
                checkSourceElement(node.body);
                if (!ts.isGlobalScopeAugmentation(node)) {
                    registerForUnusedIdentifiersCheck(node);
                }
            }
        }
        function checkModuleAugmentationElement(node, isGlobalAugmentation) {
            switch (node.kind) {
                case 220 /* VariableStatement */:
                    // error each individual name in variable statement instead of marking the entire variable statement
                    for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                        var decl = _a[_i];
                        checkModuleAugmentationElement(decl, isGlobalAugmentation);
                    }
                    break;
                case 255 /* ExportAssignment */:
                case 256 /* ExportDeclaration */:
                    grammarErrorOnFirstToken(node, ts.Diagnostics.Exports_and_export_assignments_are_not_permitted_in_module_augmentations);
                    break;
                case 249 /* ImportEqualsDeclaration */:
                case 250 /* ImportDeclaration */:
                    grammarErrorOnFirstToken(node, ts.Diagnostics.Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module);
                    break;
                case 187 /* BindingElement */:
                case 238 /* VariableDeclaration */:
                    var name = node.name;
                    if (ts.isBindingPattern(name)) {
                        for (var _b = 0, _c = name.elements; _b < _c.length; _b++) {
                            var el = _c[_b];
                            // mark individual names in binding pattern
                            checkModuleAugmentationElement(el, isGlobalAugmentation);
                        }
                        break;
                    }
                // falls through
                case 241 /* ClassDeclaration */:
                case 244 /* EnumDeclaration */:
                case 240 /* FunctionDeclaration */:
                case 242 /* InterfaceDeclaration */:
                case 245 /* ModuleDeclaration */:
                case 243 /* TypeAliasDeclaration */:
                    if (isGlobalAugmentation) {
                        return;
                    }
                    var symbol = getSymbolOfNode(node);
                    if (symbol) {
                        // module augmentations cannot introduce new names on the top level scope of the module
                        // this is done it two steps
                        // 1. quick check - if symbol for node is not merged - this is local symbol to this augmentation - report error
                        // 2. main check - report error if value declaration of the parent symbol is module augmentation)
                        var reportError = !(symbol.flags & 33554432 /* Transient */);
                        if (!reportError) {
                            // symbol should not originate in augmentation
                            reportError = !!symbol.parent && ts.isExternalModuleAugmentation(symbol.parent.declarations[0]);
                        }
                    }
                    break;
            }
        }
        function getFirstIdentifier(node) {
            switch (node.kind) {
                case 73 /* Identifier */:
                    return node;
                case 149 /* QualifiedName */:
                    do {
                        node = node.left;
                    } while (node.kind !== 73 /* Identifier */);
                    return node;
                case 190 /* PropertyAccessExpression */:
                    do {
                        node = node.expression;
                    } while (node.kind !== 73 /* Identifier */);
                    return node;
            }
        }
        function checkExternalImportOrExportDeclaration(node) {
            var moduleName = ts.getExternalModuleName(node);
            if (!moduleName || ts.nodeIsMissing(moduleName)) {
                // Should be a parse error.
                return false;
            }
            if (!ts.isStringLiteral(moduleName)) {
                error(moduleName, ts.Diagnostics.String_literal_expected);
                return false;
            }
            var inAmbientExternalModule = node.parent.kind === 246 /* ModuleBlock */ && ts.isAmbientModule(node.parent.parent);
            if (node.parent.kind !== 285 /* SourceFile */ && !inAmbientExternalModule) {
                error(moduleName, node.kind === 256 /* ExportDeclaration */ ?
                    ts.Diagnostics.Export_declarations_are_not_permitted_in_a_namespace :
                    ts.Diagnostics.Import_declarations_in_a_namespace_cannot_reference_a_module);
                return false;
            }
            if (inAmbientExternalModule && ts.isExternalModuleNameRelative(moduleName.text)) {
                // we have already reported errors on top level imports\exports in external module augmentations in checkModuleDeclaration
                // no need to do this again.
                if (!isTopLevelInExternalModuleAugmentation(node)) {
                    // TypeScript 1.0 spec (April 2013): 12.1.6
                    // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference
                    // other external modules only through top - level external module names.
                    // Relative external module names are not permitted.
                    error(node, ts.Diagnostics.Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name);
                    return false;
                }
            }
            return true;
        }
        function checkAliasSymbol(node) {
            var symbol = getSymbolOfNode(node);
            var target = resolveAlias(symbol);
            if (target !== unknownSymbol) {
                // For external modules symbol represent local symbol for an alias.
                // This local symbol will merge any other local declarations (excluding other aliases)
                // and symbol.flags will contains combined representation for all merged declaration.
                // Based on symbol.flags we can compute a set of excluded meanings (meaning that resolved alias should not have,
                // otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export*
                // in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names).
                var excludedMeanings = (symbol.flags & (67220415 /* Value */ | 1048576 /* ExportValue */) ? 67220415 /* Value */ : 0) |
                    (symbol.flags & 67897832 /* Type */ ? 67897832 /* Type */ : 0) |
                    (symbol.flags & 1920 /* Namespace */ ? 1920 /* Namespace */ : 0);
                if (target.flags & excludedMeanings) {
                    var message = node.kind === 258 /* ExportSpecifier */ ?
                        ts.Diagnostics.Export_declaration_conflicts_with_exported_declaration_of_0 :
                        ts.Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0;
                    error(node, message, symbolToString(symbol));
                }
                // Don't allow to re-export something with no value side when `--isolatedModules` is set.
                if (compilerOptions.isolatedModules
                    && node.kind === 258 /* ExportSpecifier */
                    && !(target.flags & 67220415 /* Value */)
                    && !(node.flags & 4194304 /* Ambient */)) {
                    error(node, ts.Diagnostics.Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided);
                }
            }
        }
        function checkImportBinding(node) {
            checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
            checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            checkAliasSymbol(node);
        }
        function checkImportDeclaration(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) {
                // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            if (!checkGrammarDecoratorsAndModifiers(node) && ts.hasModifiers(node)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.An_import_declaration_cannot_have_modifiers);
            }
            if (checkExternalImportOrExportDeclaration(node)) {
                var importClause = node.importClause;
                if (importClause) {
                    if (importClause.name) {
                        checkImportBinding(importClause);
                    }
                    if (importClause.namedBindings) {
                        if (importClause.namedBindings.kind === 252 /* NamespaceImport */) {
                            checkImportBinding(importClause.namedBindings);
                        }
                        else {
                            var moduleExisted = resolveExternalModuleName(node, node.moduleSpecifier);
                            if (moduleExisted) {
                                ts.forEach(importClause.namedBindings.elements, checkImportBinding);
                            }
                        }
                    }
                }
            }
        }
        function checkImportEqualsDeclaration(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) {
                // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            checkGrammarDecoratorsAndModifiers(node);
            if (ts.isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) {
                checkImportBinding(node);
                if (ts.hasModifier(node, 1 /* Export */)) {
                    markExportAsReferenced(node);
                }
                if (node.moduleReference.kind !== 260 /* ExternalModuleReference */) {
                    var target = resolveAlias(getSymbolOfNode(node));
                    if (target !== unknownSymbol) {
                        if (target.flags & 67220415 /* Value */) {
                            // Target is a value symbol, check that it is not hidden by a local declaration with the same name
                            var moduleName = getFirstIdentifier(node.moduleReference);
                            if (!(resolveEntityName(moduleName, 67220415 /* Value */ | 1920 /* Namespace */).flags & 1920 /* Namespace */)) {
                                error(moduleName, ts.Diagnostics.Module_0_is_hidden_by_a_local_declaration_with_the_same_name, ts.declarationNameToString(moduleName));
                            }
                        }
                        if (target.flags & 67897832 /* Type */) {
                            checkTypeNameIsReserved(node.name, ts.Diagnostics.Import_name_cannot_be_0);
                        }
                    }
                }
                else {
                    if (moduleKind >= ts.ModuleKind.ES2015 && !(node.flags & 4194304 /* Ambient */)) {
                        // Import equals declaration is deprecated in es6 or above
                        grammarErrorOnNode(node, ts.Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead);
                    }
                }
            }
        }
        function checkExportDeclaration(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_export_declaration_can_only_be_used_in_a_module)) {
                // If we hit an export in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            if (!checkGrammarDecoratorsAndModifiers(node) && ts.hasModifiers(node)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_declaration_cannot_have_modifiers);
            }
            if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) {
                if (node.exportClause) {
                    // export { x, y }
                    // export { x, y } from "foo"
                    ts.forEach(node.exportClause.elements, checkExportSpecifier);
                    var inAmbientExternalModule = node.parent.kind === 246 /* ModuleBlock */ && ts.isAmbientModule(node.parent.parent);
                    var inAmbientNamespaceDeclaration = !inAmbientExternalModule && node.parent.kind === 246 /* ModuleBlock */ &&
                        !node.moduleSpecifier && node.flags & 4194304 /* Ambient */;
                    if (node.parent.kind !== 285 /* SourceFile */ && !inAmbientExternalModule && !inAmbientNamespaceDeclaration) {
                        error(node, ts.Diagnostics.Export_declarations_are_not_permitted_in_a_namespace);
                    }
                }
                else {
                    // export * from "foo"
                    var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier);
                    if (moduleSymbol && hasExportAssignmentSymbol(moduleSymbol)) {
                        error(node.moduleSpecifier, ts.Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol));
                    }
                    if (moduleKind !== ts.ModuleKind.System && moduleKind !== ts.ModuleKind.ES2015 && moduleKind !== ts.ModuleKind.ESNext) {
                        checkExternalEmitHelpers(node, 32768 /* ExportStar */);
                    }
                }
            }
        }
        function checkGrammarModuleElementContext(node, errorMessage) {
            var isInAppropriateContext = node.parent.kind === 285 /* SourceFile */ || node.parent.kind === 246 /* ModuleBlock */ || node.parent.kind === 245 /* ModuleDeclaration */;
            if (!isInAppropriateContext) {
                grammarErrorOnFirstToken(node, errorMessage);
            }
            return !isInAppropriateContext;
        }
        function checkExportSpecifier(node) {
            checkAliasSymbol(node);
            if (ts.getEmitDeclarations(compilerOptions)) {
                collectLinkedAliases(node.propertyName || node.name, /*setVisibility*/ true);
            }
            if (!node.parent.parent.moduleSpecifier) {
                var exportedName = node.propertyName || node.name;
                // find immediate value referenced by exported name (SymbolFlags.Alias is set so we don't chase down aliases)
                var symbol = resolveName(exportedName, exportedName.escapedText, 67220415 /* Value */ | 67897832 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */, 
                /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
                if (symbol && (symbol === undefinedSymbol || isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) {
                    error(exportedName, ts.Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, ts.idText(exportedName));
                }
                else {
                    markExportAsReferenced(node);
                }
            }
        }
        function checkExportAssignment(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_export_assignment_can_only_be_used_in_a_module)) {
                // If we hit an export assignment in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            var container = node.parent.kind === 285 /* SourceFile */ ? node.parent : node.parent.parent;
            if (container.kind === 245 /* ModuleDeclaration */ && !ts.isAmbientModule(container)) {
                if (node.isExportEquals) {
                    error(node, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_namespace);
                }
                else {
                    error(node, ts.Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module);
                }
                return;
            }
            // Grammar checking
            if (!checkGrammarDecoratorsAndModifiers(node) && ts.hasModifiers(node)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_assignment_cannot_have_modifiers);
            }
            if (node.expression.kind === 73 /* Identifier */) {
                markExportAsReferenced(node);
                if (ts.getEmitDeclarations(compilerOptions)) {
                    collectLinkedAliases(node.expression, /*setVisibility*/ true);
                }
            }
            else {
                checkExpressionCached(node.expression);
            }
            checkExternalModuleExports(container);
            if ((node.flags & 4194304 /* Ambient */) && !ts.isEntityNameExpression(node.expression)) {
                grammarErrorOnNode(node.expression, ts.Diagnostics.The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context);
            }
            if (node.isExportEquals && !(node.flags & 4194304 /* Ambient */)) {
                if (moduleKind >= ts.ModuleKind.ES2015) {
                    // export assignment is not supported in es6 modules
                    grammarErrorOnNode(node, ts.Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead);
                }
                else if (moduleKind === ts.ModuleKind.System) {
                    // system modules does not support export assignment
                    grammarErrorOnNode(node, ts.Diagnostics.Export_assignment_is_not_supported_when_module_flag_is_system);
                }
            }
        }
        function hasExportedMembers(moduleSymbol) {
            return ts.forEachEntry(moduleSymbol.exports, function (_, id) { return id !== "export="; });
        }
        function checkExternalModuleExports(node) {
            var moduleSymbol = getSymbolOfNode(node);
            var links = getSymbolLinks(moduleSymbol);
            if (!links.exportsChecked) {
                var exportEqualsSymbol = moduleSymbol.exports.get("export=");
                if (exportEqualsSymbol && hasExportedMembers(moduleSymbol)) {
                    var declaration = getDeclarationOfAliasSymbol(exportEqualsSymbol) || exportEqualsSymbol.valueDeclaration;
                    if (!isTopLevelInExternalModuleAugmentation(declaration) && !ts.isInJSFile(declaration)) {
                        error(declaration, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements);
                    }
                }
                // Checks for export * conflicts
                var exports_1 = getExportsOfModule(moduleSymbol);
                if (exports_1) {
                    exports_1.forEach(function (_a, id) {
                        var declarations = _a.declarations, flags = _a.flags;
                        if (id === "__export") {
                            return;
                        }
                        // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries.
                        // (TS Exceptions: namespaces, function overloads, enums, and interfaces)
                        if (flags & (1920 /* Namespace */ | 64 /* Interface */ | 384 /* Enum */)) {
                            return;
                        }
                        var exportedDeclarationsCount = ts.countWhere(declarations, isNotOverloadAndNotAccessor);
                        if (flags & 524288 /* TypeAlias */ && exportedDeclarationsCount <= 2) {
                            // it is legal to merge type alias with other values
                            // so count should be either 1 (just type alias) or 2 (type alias + merged value)
                            return;
                        }
                        if (exportedDeclarationsCount > 1) {
                            for (var _i = 0, declarations_9 = declarations; _i < declarations_9.length; _i++) {
                                var declaration = declarations_9[_i];
                                if (isNotOverload(declaration)) {
                                    diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Cannot_redeclare_exported_variable_0, ts.unescapeLeadingUnderscores(id)));
                                }
                            }
                        }
                    });
                }
                links.exportsChecked = true;
            }
        }
        function isNotAccessor(declaration) {
            // Accessors check for their own matching duplicates, and in contexts where they are valid, there are already duplicate identifier checks
            return !ts.isAccessor(declaration);
        }
        function isNotOverload(declaration) {
            return (declaration.kind !== 240 /* FunctionDeclaration */ && declaration.kind !== 157 /* MethodDeclaration */) ||
                !!declaration.body;
        }
        function checkSourceElement(node) {
            if (node) {
                var saveCurrentNode = currentNode;
                currentNode = node;
                checkSourceElementWorker(node);
                currentNode = saveCurrentNode;
            }
        }
        function checkSourceElementWorker(node) {
            if (ts.isInJSFile(node)) {
                ts.forEach(node.jsDoc, function (_a) {
                    var tags = _a.tags;
                    return ts.forEach(tags, checkSourceElement);
                });
            }
            var kind = node.kind;
            if (cancellationToken) {
                // Only bother checking on a few construct kinds.  We don't want to be excessively
                // hitting the cancellation token on every node we check.
                switch (kind) {
                    case 245 /* ModuleDeclaration */:
                    case 241 /* ClassDeclaration */:
                    case 242 /* InterfaceDeclaration */:
                    case 240 /* FunctionDeclaration */:
                        cancellationToken.throwIfCancellationRequested();
                }
            }
            switch (kind) {
                case 151 /* TypeParameter */:
                    return checkTypeParameter(node);
                case 152 /* Parameter */:
                    return checkParameter(node);
                case 155 /* PropertyDeclaration */:
                case 154 /* PropertySignature */:
                    return checkPropertyDeclaration(node);
                case 166 /* FunctionType */:
                case 167 /* ConstructorType */:
                case 161 /* CallSignature */:
                case 162 /* ConstructSignature */:
                case 163 /* IndexSignature */:
                    return checkSignatureDeclaration(node);
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                    return checkMethodDeclaration(node);
                case 158 /* Constructor */:
                    return checkConstructorDeclaration(node);
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    return checkAccessorDeclaration(node);
                case 165 /* TypeReference */:
                    return checkTypeReferenceNode(node);
                case 164 /* TypePredicate */:
                    return checkTypePredicate(node);
                case 168 /* TypeQuery */:
                    return checkTypeQuery(node);
                case 169 /* TypeLiteral */:
                    return checkTypeLiteral(node);
                case 170 /* ArrayType */:
                    return checkArrayType(node);
                case 171 /* TupleType */:
                    return checkTupleType(node);
                case 174 /* UnionType */:
                case 175 /* IntersectionType */:
                    return checkUnionOrIntersectionType(node);
                case 178 /* ParenthesizedType */:
                case 172 /* OptionalType */:
                case 173 /* RestType */:
                    return checkSourceElement(node.type);
                case 179 /* ThisType */:
                    return checkThisType(node);
                case 180 /* TypeOperator */:
                    return checkTypeOperator(node);
                case 176 /* ConditionalType */:
                    return checkConditionalType(node);
                case 177 /* InferType */:
                    return checkInferType(node);
                case 184 /* ImportType */:
                    return checkImportType(node);
                case 301 /* JSDocAugmentsTag */:
                    return checkJSDocAugmentsTag(node);
                case 310 /* JSDocTypedefTag */:
                case 303 /* JSDocCallbackTag */:
                    return checkJSDocTypeAliasTag(node);
                case 309 /* JSDocTemplateTag */:
                    return checkJSDocTemplateTag(node);
                case 308 /* JSDocTypeTag */:
                    return checkJSDocTypeTag(node);
                case 305 /* JSDocParameterTag */:
                    return checkJSDocParameterTag(node);
                case 295 /* JSDocFunctionType */:
                    checkJSDocFunctionType(node);
                // falls through
                case 293 /* JSDocNonNullableType */:
                case 292 /* JSDocNullableType */:
                case 290 /* JSDocAllType */:
                case 291 /* JSDocUnknownType */:
                case 298 /* JSDocTypeLiteral */:
                    checkJSDocTypeIsInJsFile(node);
                    ts.forEachChild(node, checkSourceElement);
                    return;
                case 296 /* JSDocVariadicType */:
                    checkJSDocVariadicType(node);
                    return;
                case 289 /* JSDocTypeExpression */:
                    return checkSourceElement(node.type);
                case 181 /* IndexedAccessType */:
                    return checkIndexedAccessType(node);
                case 182 /* MappedType */:
                    return checkMappedType(node);
                case 240 /* FunctionDeclaration */:
                    return checkFunctionDeclaration(node);
                case 219 /* Block */:
                case 246 /* ModuleBlock */:
                    return checkBlock(node);
                case 220 /* VariableStatement */:
                    return checkVariableStatement(node);
                case 222 /* ExpressionStatement */:
                    return checkExpressionStatement(node);
                case 223 /* IfStatement */:
                    return checkIfStatement(node);
                case 224 /* DoStatement */:
                    return checkDoStatement(node);
                case 225 /* WhileStatement */:
                    return checkWhileStatement(node);
                case 226 /* ForStatement */:
                    return checkForStatement(node);
                case 227 /* ForInStatement */:
                    return checkForInStatement(node);
                case 228 /* ForOfStatement */:
                    return checkForOfStatement(node);
                case 229 /* ContinueStatement */:
                case 230 /* BreakStatement */:
                    return checkBreakOrContinueStatement(node);
                case 231 /* ReturnStatement */:
                    return checkReturnStatement(node);
                case 232 /* WithStatement */:
                    return checkWithStatement(node);
                case 233 /* SwitchStatement */:
                    return checkSwitchStatement(node);
                case 234 /* LabeledStatement */:
                    return checkLabeledStatement(node);
                case 235 /* ThrowStatement */:
                    return checkThrowStatement(node);
                case 236 /* TryStatement */:
                    return checkTryStatement(node);
                case 238 /* VariableDeclaration */:
                    return checkVariableDeclaration(node);
                case 187 /* BindingElement */:
                    return checkBindingElement(node);
                case 241 /* ClassDeclaration */:
                    return checkClassDeclaration(node);
                case 242 /* InterfaceDeclaration */:
                    return checkInterfaceDeclaration(node);
                case 243 /* TypeAliasDeclaration */:
                    return checkTypeAliasDeclaration(node);
                case 244 /* EnumDeclaration */:
                    return checkEnumDeclaration(node);
                case 245 /* ModuleDeclaration */:
                    return checkModuleDeclaration(node);
                case 250 /* ImportDeclaration */:
                    return checkImportDeclaration(node);
                case 249 /* ImportEqualsDeclaration */:
                    return checkImportEqualsDeclaration(node);
                case 256 /* ExportDeclaration */:
                    return checkExportDeclaration(node);
                case 255 /* ExportAssignment */:
                    return checkExportAssignment(node);
                case 221 /* EmptyStatement */:
                case 237 /* DebuggerStatement */:
                    checkGrammarStatementInAmbientContext(node);
                    return;
                case 259 /* MissingDeclaration */:
                    return checkMissingDeclaration(node);
            }
        }
        function checkJSDocTypeIsInJsFile(node) {
            if (!ts.isInJSFile(node)) {
                grammarErrorOnNode(node, ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments);
            }
        }
        function checkJSDocVariadicType(node) {
            checkJSDocTypeIsInJsFile(node);
            checkSourceElement(node.type);
            // Only legal location is in the *last* parameter tag or last parameter of a JSDoc function.
            var parent = node.parent;
            if (ts.isParameter(parent) && ts.isJSDocFunctionType(parent.parent)) {
                if (ts.last(parent.parent.parameters) !== parent) {
                    error(node, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
                }
                return;
            }
            if (!ts.isJSDocTypeExpression(parent)) {
                error(node, ts.Diagnostics.JSDoc_may_only_appear_in_the_last_parameter_of_a_signature);
            }
            var paramTag = node.parent.parent;
            if (!ts.isJSDocParameterTag(paramTag)) {
                error(node, ts.Diagnostics.JSDoc_may_only_appear_in_the_last_parameter_of_a_signature);
                return;
            }
            var param = ts.getParameterSymbolFromJSDoc(paramTag);
            if (!param) {
                // We will error in `checkJSDocParameterTag`.
                return;
            }
            var host = ts.getHostSignatureFromJSDoc(paramTag);
            if (!host || ts.last(host.parameters).symbol !== param) {
                error(node, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
            }
        }
        function getTypeFromJSDocVariadicType(node) {
            var type = getTypeFromTypeNode(node.type);
            var parent = node.parent;
            var paramTag = node.parent.parent;
            if (ts.isJSDocTypeExpression(node.parent) && ts.isJSDocParameterTag(paramTag)) {
                // Else we will add a diagnostic, see `checkJSDocVariadicType`.
                var host_1 = ts.getHostSignatureFromJSDoc(paramTag);
                if (host_1) {
                    /*
                    Only return an array type if the corresponding parameter is marked as a rest parameter, or if there are no parameters.
                    So in the following situation we will not create an array type:
                        /** @param {...number} a * /
                        function f(a) {}
                    Because `a` will just be of type `number | undefined`. A synthetic `...args` will also be added, which *will* get an array type.
                    */
                    var lastParamDeclaration = ts.lastOrUndefined(host_1.parameters);
                    var symbol = ts.getParameterSymbolFromJSDoc(paramTag);
                    if (!lastParamDeclaration ||
                        symbol && lastParamDeclaration.symbol === symbol && ts.isRestParameter(lastParamDeclaration)) {
                        return createArrayType(type);
                    }
                }
            }
            if (ts.isParameter(parent) && ts.isJSDocFunctionType(parent.parent)) {
                return createArrayType(type);
            }
            return addOptionality(type);
        }
        // Function and class expression bodies are checked after all statements in the enclosing body. This is
        // to ensure constructs like the following are permitted:
        //     const foo = function () {
        //        const s = foo();
        //        return "hello";
        //     }
        // Here, performing a full type check of the body of the function expression whilst in the process of
        // determining the type of foo would cause foo to be given type any because of the recursive reference.
        // Delaying the type check of the body ensures foo has been assigned a type.
        function checkNodeDeferred(node) {
            var enclosingFile = ts.getSourceFileOfNode(node);
            var links = getNodeLinks(enclosingFile);
            if (!(links.flags & 1 /* TypeChecked */)) {
                links.deferredNodes = links.deferredNodes || ts.createMap();
                var id = "" + getNodeId(node);
                links.deferredNodes.set(id, node);
            }
        }
        function checkDeferredNodes(context) {
            var links = getNodeLinks(context);
            if (links.deferredNodes) {
                links.deferredNodes.forEach(checkDeferredNode);
            }
        }
        function checkDeferredNode(node) {
            var saveCurrentNode = currentNode;
            currentNode = node;
            switch (node.kind) {
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */:
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                    checkFunctionExpressionOrObjectLiteralMethodDeferred(node);
                    break;
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    checkAccessorDeclaration(node);
                    break;
                case 210 /* ClassExpression */:
                    checkClassExpressionDeferred(node);
                    break;
                case 262 /* JsxSelfClosingElement */:
                    checkJsxSelfClosingElementDeferred(node);
                    break;
                case 261 /* JsxElement */:
                    checkJsxElementDeferred(node);
                    break;
            }
            currentNode = saveCurrentNode;
        }
        function checkSourceFile(node) {
            ts.performance.mark("beforeCheck");
            checkSourceFileWorker(node);
            ts.performance.mark("afterCheck");
            ts.performance.measure("Check", "beforeCheck", "afterCheck");
        }
        function unusedIsError(kind) {
            switch (kind) {
                case 0 /* Local */:
                    return !!compilerOptions.noUnusedLocals;
                case 1 /* Parameter */:
                    return !!compilerOptions.noUnusedParameters;
                default:
                    return ts.Debug.assertNever(kind);
            }
        }
        function getPotentiallyUnusedIdentifiers(sourceFile) {
            return allPotentiallyUnusedIdentifiers.get(sourceFile.path) || ts.emptyArray;
        }
        // Fully type check a source file and collect the relevant diagnostics.
        function checkSourceFileWorker(node) {
            var links = getNodeLinks(node);
            if (!(links.flags & 1 /* TypeChecked */)) {
                if (ts.skipTypeChecking(node, compilerOptions)) {
                    return;
                }
                // Grammar checking
                checkGrammarSourceFile(node);
                ts.clear(potentialThisCollisions);
                ts.clear(potentialNewTargetCollisions);
                ts.forEach(node.statements, checkSourceElement);
                checkSourceElement(node.endOfFileToken);
                checkDeferredNodes(node);
                if (ts.isExternalOrCommonJsModule(node)) {
                    registerForUnusedIdentifiersCheck(node);
                }
                if (!node.isDeclarationFile && (compilerOptions.noUnusedLocals || compilerOptions.noUnusedParameters)) {
                    checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(node), function (containingNode, kind, diag) {
                        if (!ts.containsParseError(containingNode) && unusedIsError(kind)) {
                            diagnostics.add(diag);
                        }
                    });
                }
                if (ts.isExternalOrCommonJsModule(node)) {
                    checkExternalModuleExports(node);
                }
                if (potentialThisCollisions.length) {
                    ts.forEach(potentialThisCollisions, checkIfThisIsCapturedInEnclosingScope);
                    ts.clear(potentialThisCollisions);
                }
                if (potentialNewTargetCollisions.length) {
                    ts.forEach(potentialNewTargetCollisions, checkIfNewTargetIsCapturedInEnclosingScope);
                    ts.clear(potentialNewTargetCollisions);
                }
                links.flags |= 1 /* TypeChecked */;
            }
        }
        function getDiagnostics(sourceFile, ct) {
            try {
                // Record the cancellation token so it can be checked later on during checkSourceElement.
                // Do this in a finally block so we can ensure that it gets reset back to nothing after
                // this call is done.
                cancellationToken = ct;
                return getDiagnosticsWorker(sourceFile);
            }
            finally {
                cancellationToken = undefined;
            }
        }
        function getDiagnosticsWorker(sourceFile) {
            throwIfNonDiagnosticsProducing();
            if (sourceFile) {
                // Some global diagnostics are deferred until they are needed and
                // may not be reported in the first call to getGlobalDiagnostics.
                // We should catch these changes and report them.
                var previousGlobalDiagnostics = diagnostics.getGlobalDiagnostics();
                var previousGlobalDiagnosticsSize = previousGlobalDiagnostics.length;
                checkSourceFile(sourceFile);
                var semanticDiagnostics = diagnostics.getDiagnostics(sourceFile.fileName);
                var currentGlobalDiagnostics = diagnostics.getGlobalDiagnostics();
                if (currentGlobalDiagnostics !== previousGlobalDiagnostics) {
                    // If the arrays are not the same reference, new diagnostics were added.
                    var deferredGlobalDiagnostics = ts.relativeComplement(previousGlobalDiagnostics, currentGlobalDiagnostics, ts.compareDiagnostics);
                    return ts.concatenate(deferredGlobalDiagnostics, semanticDiagnostics);
                }
                else if (previousGlobalDiagnosticsSize === 0 && currentGlobalDiagnostics.length > 0) {
                    // If the arrays are the same reference, but the length has changed, a single
                    // new diagnostic was added as DiagnosticCollection attempts to reuse the
                    // same array.
                    return ts.concatenate(currentGlobalDiagnostics, semanticDiagnostics);
                }
                return semanticDiagnostics;
            }
            // Global diagnostics are always added when a file is not provided to
            // getDiagnostics
            ts.forEach(host.getSourceFiles(), checkSourceFile);
            return diagnostics.getDiagnostics();
        }
        function getGlobalDiagnostics() {
            throwIfNonDiagnosticsProducing();
            return diagnostics.getGlobalDiagnostics();
        }
        function throwIfNonDiagnosticsProducing() {
            if (!produceDiagnostics) {
                throw new Error("Trying to get diagnostics from a type checker that does not produce them.");
            }
        }
        // Language service support
        function getSymbolsInScope(location, meaning) {
            if (location.flags & 8388608 /* InWithStatement */) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return [];
            }
            var symbols = ts.createSymbolTable();
            var isStatic = false;
            populateSymbols();
            symbols.delete("this" /* This */); // Not a symbol, a keyword
            return symbolsToArray(symbols);
            function populateSymbols() {
                while (location) {
                    if (location.locals && !isGlobalSourceFile(location)) {
                        copySymbols(location.locals, meaning);
                    }
                    switch (location.kind) {
                        case 285 /* SourceFile */:
                            if (!ts.isExternalOrCommonJsModule(location))
                                break;
                        // falls through
                        case 245 /* ModuleDeclaration */:
                            copySymbols(getSymbolOfNode(location).exports, meaning & 2623475 /* ModuleMember */);
                            break;
                        case 244 /* EnumDeclaration */:
                            copySymbols(getSymbolOfNode(location).exports, meaning & 8 /* EnumMember */);
                            break;
                        case 210 /* ClassExpression */:
                            var className = location.name;
                            if (className) {
                                copySymbol(location.symbol, meaning);
                            }
                        // falls through
                        // this fall-through is necessary because we would like to handle
                        // type parameter inside class expression similar to how we handle it in classDeclaration and interface Declaration
                        case 241 /* ClassDeclaration */:
                        case 242 /* InterfaceDeclaration */:
                            // If we didn't come from static member of class or interface,
                            // add the type parameters into the symbol table
                            // (type parameters of classDeclaration/classExpression and interface are in member property of the symbol.
                            // Note: that the memberFlags come from previous iteration.
                            if (!isStatic) {
                                copySymbols(getMembersOfSymbol(getSymbolOfNode(location)), meaning & 67897832 /* Type */);
                            }
                            break;
                        case 197 /* FunctionExpression */:
                            var funcName = location.name;
                            if (funcName) {
                                copySymbol(location.symbol, meaning);
                            }
                            break;
                    }
                    if (ts.introducesArgumentsExoticObject(location)) {
                        copySymbol(argumentsSymbol, meaning);
                    }
                    isStatic = ts.hasModifier(location, 32 /* Static */);
                    location = location.parent;
                }
                copySymbols(globals, meaning);
            }
            /**
             * Copy the given symbol into symbol tables if the symbol has the given meaning
             * and it doesn't already existed in the symbol table
             * @param key a key for storing in symbol table; if undefined, use symbol.name
             * @param symbol the symbol to be added into symbol table
             * @param meaning meaning of symbol to filter by before adding to symbol table
             */
            function copySymbol(symbol, meaning) {
                if (ts.getCombinedLocalAndExportSymbolFlags(symbol) & meaning) {
                    var id = symbol.escapedName;
                    // We will copy all symbol regardless of its reserved name because
                    // symbolsToArray will check whether the key is a reserved name and
                    // it will not copy symbol with reserved name to the array
                    if (!symbols.has(id)) {
                        symbols.set(id, symbol);
                    }
                }
            }
            function copySymbols(source, meaning) {
                if (meaning) {
                    source.forEach(function (symbol) {
                        copySymbol(symbol, meaning);
                    });
                }
            }
        }
        function isTypeDeclarationName(name) {
            return name.kind === 73 /* Identifier */ &&
                isTypeDeclaration(name.parent) &&
                name.parent.name === name;
        }
        function isTypeDeclaration(node) {
            switch (node.kind) {
                case 151 /* TypeParameter */:
                case 241 /* ClassDeclaration */:
                case 242 /* InterfaceDeclaration */:
                case 243 /* TypeAliasDeclaration */:
                case 244 /* EnumDeclaration */:
                    return true;
                default:
                    return false;
            }
        }
        // True if the given identifier is part of a type reference
        function isTypeReferenceIdentifier(node) {
            while (node.parent.kind === 149 /* QualifiedName */) {
                node = node.parent;
            }
            return node.parent.kind === 165 /* TypeReference */;
        }
        function isHeritageClauseElementIdentifier(node) {
            while (node.parent.kind === 190 /* PropertyAccessExpression */) {
                node = node.parent;
            }
            return node.parent.kind === 212 /* ExpressionWithTypeArguments */;
        }
        function forEachEnclosingClass(node, callback) {
            var result;
            while (true) {
                node = ts.getContainingClass(node);
                if (!node)
                    break;
                if (result = callback(node))
                    break;
            }
            return result;
        }
        function isNodeUsedDuringClassInitialization(node) {
            return !!ts.findAncestor(node, function (element) {
                if (ts.isConstructorDeclaration(element) && ts.nodeIsPresent(element.body) || ts.isPropertyDeclaration(element)) {
                    return true;
                }
                else if (ts.isClassLike(element) || ts.isFunctionLikeDeclaration(element)) {
                    return "quit";
                }
                return false;
            });
        }
        function isNodeWithinClass(node, classDeclaration) {
            return !!forEachEnclosingClass(node, function (n) { return n === classDeclaration; });
        }
        function getLeftSideOfImportEqualsOrExportAssignment(nodeOnRightSide) {
            while (nodeOnRightSide.parent.kind === 149 /* QualifiedName */) {
                nodeOnRightSide = nodeOnRightSide.parent;
            }
            if (nodeOnRightSide.parent.kind === 249 /* ImportEqualsDeclaration */) {
                return nodeOnRightSide.parent.moduleReference === nodeOnRightSide ? nodeOnRightSide.parent : undefined;
            }
            if (nodeOnRightSide.parent.kind === 255 /* ExportAssignment */) {
                return nodeOnRightSide.parent.expression === nodeOnRightSide ? nodeOnRightSide.parent : undefined;
            }
            return undefined;
        }
        function isInRightSideOfImportOrExportAssignment(node) {
            return getLeftSideOfImportEqualsOrExportAssignment(node) !== undefined;
        }
        function getSpecialPropertyAssignmentSymbolFromEntityName(entityName) {
            var specialPropertyAssignmentKind = ts.getAssignmentDeclarationKind(entityName.parent.parent);
            switch (specialPropertyAssignmentKind) {
                case 1 /* ExportsProperty */:
                case 3 /* PrototypeProperty */:
                    return getSymbolOfNode(entityName.parent);
                case 4 /* ThisProperty */:
                case 2 /* ModuleExports */:
                case 5 /* Property */:
                    return getSymbolOfNode(entityName.parent.parent);
            }
        }
        function isImportTypeQualifierPart(node) {
            var parent = node.parent;
            while (ts.isQualifiedName(parent)) {
                node = parent;
                parent = parent.parent;
            }
            if (parent && parent.kind === 184 /* ImportType */ && parent.qualifier === node) {
                return parent;
            }
            return undefined;
        }
        function getSymbolOfEntityNameOrPropertyAccessExpression(entityName) {
            if (ts.isDeclarationName(entityName)) {
                return getSymbolOfNode(entityName.parent);
            }
            if (ts.isInJSFile(entityName) &&
                entityName.parent.kind === 190 /* PropertyAccessExpression */ &&
                entityName.parent === entityName.parent.parent.left) {
                // Check if this is a special property assignment
                var specialPropertyAssignmentSymbol = getSpecialPropertyAssignmentSymbolFromEntityName(entityName);
                if (specialPropertyAssignmentSymbol) {
                    return specialPropertyAssignmentSymbol;
                }
            }
            if (entityName.parent.kind === 255 /* ExportAssignment */ && ts.isEntityNameExpression(entityName)) {
                // Even an entity name expression that doesn't resolve as an entityname may still typecheck as a property access expression
                var success = resolveEntityName(entityName, 
                /*all meanings*/ 67220415 /* Value */ | 67897832 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */, /*ignoreErrors*/ true);
                if (success && success !== unknownSymbol) {
                    return success;
                }
            }
            else if (!ts.isPropertyAccessExpression(entityName) && isInRightSideOfImportOrExportAssignment(entityName)) {
                // Since we already checked for ExportAssignment, this really could only be an Import
                var importEqualsDeclaration = ts.getAncestor(entityName, 249 /* ImportEqualsDeclaration */);
                ts.Debug.assert(importEqualsDeclaration !== undefined);
                return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, /*dontResolveAlias*/ true);
            }
            if (!ts.isPropertyAccessExpression(entityName)) {
                var possibleImportNode = isImportTypeQualifierPart(entityName);
                if (possibleImportNode) {
                    getTypeFromTypeNode(possibleImportNode);
                    var sym = getNodeLinks(entityName).resolvedSymbol;
                    return sym === unknownSymbol ? undefined : sym;
                }
            }
            while (ts.isRightSideOfQualifiedNameOrPropertyAccess(entityName)) {
                entityName = entityName.parent;
            }
            if (isHeritageClauseElementIdentifier(entityName)) {
                var meaning = 0 /* None */;
                // In an interface or class, we're definitely interested in a type.
                if (entityName.parent.kind === 212 /* ExpressionWithTypeArguments */) {
                    meaning = 67897832 /* Type */;
                    // In a class 'extends' clause we are also looking for a value.
                    if (ts.isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent)) {
                        meaning |= 67220415 /* Value */;
                    }
                }
                else {
                    meaning = 1920 /* Namespace */;
                }
                meaning |= 2097152 /* Alias */;
                var entityNameSymbol = ts.isEntityNameExpression(entityName) ? resolveEntityName(entityName, meaning) : undefined;
                if (entityNameSymbol) {
                    return entityNameSymbol;
                }
            }
            if (entityName.parent.kind === 305 /* JSDocParameterTag */) {
                return ts.getParameterSymbolFromJSDoc(entityName.parent);
            }
            if (entityName.parent.kind === 151 /* TypeParameter */ && entityName.parent.parent.kind === 309 /* JSDocTemplateTag */) {
                ts.Debug.assert(!ts.isInJSFile(entityName)); // Otherwise `isDeclarationName` would have been true.
                var typeParameter = ts.getTypeParameterFromJsDoc(entityName.parent);
                return typeParameter && typeParameter.symbol;
            }
            if (ts.isExpressionNode(entityName)) {
                if (ts.nodeIsMissing(entityName)) {
                    // Missing entity name.
                    return undefined;
                }
                if (entityName.kind === 73 /* Identifier */) {
                    if (ts.isJSXTagName(entityName) && isJsxIntrinsicIdentifier(entityName)) {
                        var symbol = getIntrinsicTagSymbol(entityName.parent);
                        return symbol === unknownSymbol ? undefined : symbol;
                    }
                    return resolveEntityName(entityName, 67220415 /* Value */, /*ignoreErrors*/ false, /*dontResolveAlias*/ true);
                }
                else if (entityName.kind === 190 /* PropertyAccessExpression */ || entityName.kind === 149 /* QualifiedName */) {
                    var links = getNodeLinks(entityName);
                    if (links.resolvedSymbol) {
                        return links.resolvedSymbol;
                    }
                    if (entityName.kind === 190 /* PropertyAccessExpression */) {
                        checkPropertyAccessExpression(entityName);
                    }
                    else {
                        checkQualifiedName(entityName);
                    }
                    return links.resolvedSymbol;
                }
            }
            else if (isTypeReferenceIdentifier(entityName)) {
                var meaning = entityName.parent.kind === 165 /* TypeReference */ ? 67897832 /* Type */ : 1920 /* Namespace */;
                return resolveEntityName(entityName, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true);
            }
            if (entityName.parent.kind === 164 /* TypePredicate */) {
                return resolveEntityName(entityName, /*meaning*/ 1 /* FunctionScopedVariable */);
            }
            // Do we want to return undefined here?
            return undefined;
        }
        function getSymbolAtLocation(node) {
            if (node.kind === 285 /* SourceFile */) {
                return ts.isExternalModule(node) ? getMergedSymbol(node.symbol) : undefined;
            }
            var parent = node.parent;
            var grandParent = parent.parent;
            if (node.flags & 8388608 /* InWithStatement */) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return undefined;
            }
            if (isDeclarationNameOrImportPropertyName(node)) {
                // This is a declaration, call getSymbolOfNode
                var parentSymbol = getSymbolOfNode(parent);
                return ts.isImportOrExportSpecifier(node.parent) && node.parent.propertyName === node
                    ? getImmediateAliasedSymbol(parentSymbol)
                    : parentSymbol;
            }
            else if (ts.isLiteralComputedPropertyDeclarationName(node)) {
                return getSymbolOfNode(parent.parent);
            }
            if (node.kind === 73 /* Identifier */) {
                if (isInRightSideOfImportOrExportAssignment(node)) {
                    return getSymbolOfEntityNameOrPropertyAccessExpression(node);
                }
                else if (parent.kind === 187 /* BindingElement */ &&
                    grandParent.kind === 185 /* ObjectBindingPattern */ &&
                    node === parent.propertyName) {
                    var typeOfPattern = getTypeOfNode(grandParent);
                    var propertyDeclaration = getPropertyOfType(typeOfPattern, node.escapedText);
                    if (propertyDeclaration) {
                        return propertyDeclaration;
                    }
                }
            }
            switch (node.kind) {
                case 73 /* Identifier */:
                case 190 /* PropertyAccessExpression */:
                case 149 /* QualifiedName */:
                    return getSymbolOfEntityNameOrPropertyAccessExpression(node);
                case 101 /* ThisKeyword */:
                    var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
                    if (ts.isFunctionLike(container)) {
                        var sig = getSignatureFromDeclaration(container);
                        if (sig.thisParameter) {
                            return sig.thisParameter;
                        }
                    }
                    if (ts.isInExpressionContext(node)) {
                        return checkExpression(node).symbol;
                    }
                // falls through
                case 179 /* ThisType */:
                    return getTypeFromThisTypeNode(node).symbol;
                case 99 /* SuperKeyword */:
                    return checkExpression(node).symbol;
                case 125 /* ConstructorKeyword */:
                    // constructor keyword for an overload, should take us to the definition if it exist
                    var constructorDeclaration = node.parent;
                    if (constructorDeclaration && constructorDeclaration.kind === 158 /* Constructor */) {
                        return constructorDeclaration.parent.symbol;
                    }
                    return undefined;
                case 10 /* StringLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                    // 1). import x = require("./mo/*gotToDefinitionHere*/d")
                    // 2). External module name in an import declaration
                    // 3). Dynamic import call or require in javascript
                    // 4). type A = import("./f/*gotToDefinitionHere*/oo")
                    if ((ts.isExternalModuleImportEqualsDeclaration(node.parent.parent) && ts.getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) ||
                        ((node.parent.kind === 250 /* ImportDeclaration */ || node.parent.kind === 256 /* ExportDeclaration */) && node.parent.moduleSpecifier === node) ||
                        ((ts.isInJSFile(node) && ts.isRequireCall(node.parent, /*checkArgumentIsStringLiteralLike*/ false)) || ts.isImportCall(node.parent)) ||
                        (ts.isLiteralTypeNode(node.parent) && ts.isLiteralImportTypeNode(node.parent.parent) && node.parent.parent.argument === node.parent)) {
                        return resolveExternalModuleName(node, node);
                    }
                    if (ts.isCallExpression(parent) && ts.isBindableObjectDefinePropertyCall(parent) && parent.arguments[1] === node) {
                        return getSymbolOfNode(parent);
                    }
                // falls through
                case 8 /* NumericLiteral */:
                    // index access
                    var objectType = ts.isElementAccessExpression(parent)
                        ? parent.argumentExpression === node ? getTypeOfExpression(parent.expression) : undefined
                        : ts.isLiteralTypeNode(parent) && ts.isIndexedAccessTypeNode(grandParent)
                            ? getTypeFromTypeNode(grandParent.objectType)
                            : undefined;
                    return objectType && getPropertyOfType(objectType, ts.escapeLeadingUnderscores(node.text));
                case 81 /* DefaultKeyword */:
                case 91 /* FunctionKeyword */:
                case 37 /* EqualsGreaterThanToken */:
                case 77 /* ClassKeyword */:
                    return getSymbolOfNode(node.parent);
                case 184 /* ImportType */:
                    return ts.isLiteralImportTypeNode(node) ? getSymbolAtLocation(node.argument.literal) : undefined;
                case 86 /* ExportKeyword */:
                    return ts.isExportAssignment(node.parent) ? ts.Debug.assertDefined(node.parent.symbol) : undefined;
                default:
                    return undefined;
            }
        }
        function getShorthandAssignmentValueSymbol(location) {
            if (location && location.kind === 277 /* ShorthandPropertyAssignment */) {
                return resolveEntityName(location.name, 67220415 /* Value */ | 2097152 /* Alias */);
            }
            return undefined;
        }
        /** Returns the target of an export specifier without following aliases */
        function getExportSpecifierLocalTargetSymbol(node) {
            return node.parent.parent.moduleSpecifier ?
                getExternalModuleMember(node.parent.parent, node) :
                resolveEntityName(node.propertyName || node.name, 67220415 /* Value */ | 67897832 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */);
        }
        function getTypeOfNode(node) {
            if (node.flags & 8388608 /* InWithStatement */) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return errorType;
            }
            var classDecl = ts.tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node);
            var classType = classDecl && getDeclaredTypeOfClassOrInterface(getSymbolOfNode(classDecl.class));
            if (ts.isPartOfTypeNode(node)) {
                var typeFromTypeNode = getTypeFromTypeNode(node);
                return classType ? getTypeWithThisArgument(typeFromTypeNode, classType.thisType) : typeFromTypeNode;
            }
            if (ts.isExpressionNode(node)) {
                return getRegularTypeOfExpression(node);
            }
            if (classType && !classDecl.isImplements) {
                // A SyntaxKind.ExpressionWithTypeArguments is considered a type node, except when it occurs in the
                // extends clause of a class. We handle that case here.
                var baseType = ts.firstOrUndefined(getBaseTypes(classType));
                return baseType ? getTypeWithThisArgument(baseType, classType.thisType) : errorType;
            }
            if (isTypeDeclaration(node)) {
                // In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration
                var symbol = getSymbolOfNode(node);
                return getDeclaredTypeOfSymbol(symbol);
            }
            if (isTypeDeclarationName(node)) {
                var symbol = getSymbolAtLocation(node);
                return symbol ? getDeclaredTypeOfSymbol(symbol) : errorType;
            }
            if (ts.isDeclaration(node)) {
                // In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration
                var symbol = getSymbolOfNode(node);
                return getTypeOfSymbol(symbol);
            }
            if (isDeclarationNameOrImportPropertyName(node)) {
                var symbol = getSymbolAtLocation(node);
                return symbol ? getTypeOfSymbol(symbol) : errorType;
            }
            if (ts.isBindingPattern(node)) {
                return getTypeForVariableLikeDeclaration(node.parent, /*includeOptionality*/ true) || errorType;
            }
            if (isInRightSideOfImportOrExportAssignment(node)) {
                var symbol = getSymbolAtLocation(node);
                if (symbol) {
                    var declaredType = getDeclaredTypeOfSymbol(symbol);
                    return declaredType !== errorType ? declaredType : getTypeOfSymbol(symbol);
                }
            }
            return errorType;
        }
        // Gets the type of object literal or array literal of destructuring assignment.
        // { a } from
        //     for ( { a } of elems) {
        //     }
        // [ a ] from
        //     [a] = [ some array ...]
        function getTypeOfAssignmentPattern(expr) {
            ts.Debug.assert(expr.kind === 189 /* ObjectLiteralExpression */ || expr.kind === 188 /* ArrayLiteralExpression */);
            // If this is from "for of"
            //     for ( { a } of elems) {
            //     }
            if (expr.parent.kind === 228 /* ForOfStatement */) {
                var iteratedType = checkRightHandSideOfForOf(expr.parent.expression, expr.parent.awaitModifier);
                return checkDestructuringAssignment(expr, iteratedType || errorType);
            }
            // If this is from "for" initializer
            //     for ({a } = elems[0];.....) { }
            if (expr.parent.kind === 205 /* BinaryExpression */) {
                var iteratedType = getTypeOfExpression(expr.parent.right);
                return checkDestructuringAssignment(expr, iteratedType || errorType);
            }
            // If this is from nested object binding pattern
            //     for ({ skills: { primary, secondary } } = multiRobot, i = 0; i < 1; i++) {
            if (expr.parent.kind === 276 /* PropertyAssignment */) {
                var node_3 = ts.cast(expr.parent.parent, ts.isObjectLiteralExpression);
                var typeOfParentObjectLiteral = getTypeOfAssignmentPattern(node_3) || errorType;
                var propertyIndex = ts.indexOfNode(node_3.properties, expr.parent);
                return checkObjectLiteralDestructuringPropertyAssignment(node_3, typeOfParentObjectLiteral, propertyIndex);
            }
            // Array literal assignment - array destructuring pattern
            var node = ts.cast(expr.parent, ts.isArrayLiteralExpression);
            //    [{ property1: p1, property2 }] = elems;
            var typeOfArrayLiteral = getTypeOfAssignmentPattern(node) || errorType;
            var elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral, expr.parent, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || errorType;
            return checkArrayLiteralDestructuringElementAssignment(node, typeOfArrayLiteral, node.elements.indexOf(expr), elementType);
        }
        // Gets the property symbol corresponding to the property in destructuring assignment
        // 'property1' from
        //     for ( { property1: a } of elems) {
        //     }
        // 'property1' at location 'a' from:
        //     [a] = [ property1, property2 ]
        function getPropertySymbolOfDestructuringAssignment(location) {
            // Get the type of the object or array literal and then look for property of given name in the type
            var typeOfObjectLiteral = getTypeOfAssignmentPattern(ts.cast(location.parent.parent, ts.isAssignmentPattern));
            return typeOfObjectLiteral && getPropertyOfType(typeOfObjectLiteral, location.escapedText);
        }
        function getRegularTypeOfExpression(expr) {
            if (ts.isRightSideOfQualifiedNameOrPropertyAccess(expr)) {
                expr = expr.parent;
            }
            return getRegularTypeOfLiteralType(getTypeOfExpression(expr));
        }
        /**
         * Gets either the static or instance type of a class element, based on
         * whether the element is declared as "static".
         */
        function getParentTypeOfClassElement(node) {
            var classSymbol = getSymbolOfNode(node.parent);
            return ts.hasModifier(node, 32 /* Static */)
                ? getTypeOfSymbol(classSymbol)
                : getDeclaredTypeOfSymbol(classSymbol);
        }
        function getClassElementPropertyKeyType(element) {
            var name = element.name;
            switch (name.kind) {
                case 73 /* Identifier */:
                    return getLiteralType(ts.idText(name));
                case 8 /* NumericLiteral */:
                case 10 /* StringLiteral */:
                    return getLiteralType(name.text);
                case 150 /* ComputedPropertyName */:
                    var nameType = checkComputedPropertyName(name);
                    return isTypeAssignableToKind(nameType, 12288 /* ESSymbolLike */) ? nameType : stringType;
                default:
                    ts.Debug.fail("Unsupported property name.");
                    return errorType;
            }
        }
        // Return the list of properties of the given type, augmented with properties from Function
        // if the type has call or construct signatures
        function getAugmentedPropertiesOfType(type) {
            type = getApparentType(type);
            var propsByName = ts.createSymbolTable(getPropertiesOfType(type));
            var functionType = getSignaturesOfType(type, 0 /* Call */).length ? globalCallableFunctionType :
                getSignaturesOfType(type, 1 /* Construct */).length ? globalNewableFunctionType :
                    undefined;
            if (functionType) {
                ts.forEach(getPropertiesOfType(functionType), function (p) {
                    if (!propsByName.has(p.escapedName)) {
                        propsByName.set(p.escapedName, p);
                    }
                });
            }
            return getNamedMembers(propsByName);
        }
        function typeHasCallOrConstructSignatures(type) {
            return ts.typeHasCallOrConstructSignatures(type, checker);
        }
        function getRootSymbols(symbol) {
            var roots = getImmediateRootSymbols(symbol);
            return roots ? ts.flatMap(roots, getRootSymbols) : [symbol];
        }
        function getImmediateRootSymbols(symbol) {
            if (ts.getCheckFlags(symbol) & 6 /* Synthetic */) {
                return ts.mapDefined(getSymbolLinks(symbol).containingType.types, function (type) { return getPropertyOfType(type, symbol.escapedName); });
            }
            else if (symbol.flags & 33554432 /* Transient */) {
                var _a = symbol, leftSpread = _a.leftSpread, rightSpread = _a.rightSpread, syntheticOrigin = _a.syntheticOrigin;
                return leftSpread ? [leftSpread, rightSpread]
                    : syntheticOrigin ? [syntheticOrigin]
                        : ts.singleElementArray(tryGetAliasTarget(symbol));
            }
            return undefined;
        }
        function tryGetAliasTarget(symbol) {
            var target;
            var next = symbol;
            while (next = getSymbolLinks(next).target) {
                target = next;
            }
            return target;
        }
        // Emitter support
        function isArgumentsLocalBinding(nodeIn) {
            if (!ts.isGeneratedIdentifier(nodeIn)) {
                var node = ts.getParseTreeNode(nodeIn, ts.isIdentifier);
                if (node) {
                    var isPropertyName_1 = node.parent.kind === 190 /* PropertyAccessExpression */ && node.parent.name === node;
                    return !isPropertyName_1 && getReferencedValueSymbol(node) === argumentsSymbol;
                }
            }
            return false;
        }
        function moduleExportsSomeValue(moduleReferenceExpression) {
            var moduleSymbol = resolveExternalModuleName(moduleReferenceExpression.parent, moduleReferenceExpression);
            if (!moduleSymbol || ts.isShorthandAmbientModuleSymbol(moduleSymbol)) {
                // If the module is not found or is shorthand, assume that it may export a value.
                return true;
            }
            var hasExportAssignment = hasExportAssignmentSymbol(moduleSymbol);
            // if module has export assignment then 'resolveExternalModuleSymbol' will return resolved symbol for export assignment
            // otherwise it will return moduleSymbol itself
            moduleSymbol = resolveExternalModuleSymbol(moduleSymbol);
            var symbolLinks = getSymbolLinks(moduleSymbol);
            if (symbolLinks.exportsSomeValue === undefined) {
                // for export assignments - check if resolved symbol for RHS is itself a value
                // otherwise - check if at least one export is value
                symbolLinks.exportsSomeValue = hasExportAssignment
                    ? !!(moduleSymbol.flags & 67220415 /* Value */)
                    : ts.forEachEntry(getExportsOfModule(moduleSymbol), isValue);
            }
            return symbolLinks.exportsSomeValue;
            function isValue(s) {
                s = resolveSymbol(s);
                return s && !!(s.flags & 67220415 /* Value */);
            }
        }
        function isNameOfModuleOrEnumDeclaration(node) {
            return ts.isModuleOrEnumDeclaration(node.parent) && node === node.parent.name;
        }
        // When resolved as an expression identifier, if the given node references an exported entity, return the declaration
        // node of the exported entity's container. Otherwise, return undefined.
        function getReferencedExportContainer(nodeIn, prefixLocals) {
            var node = ts.getParseTreeNode(nodeIn, ts.isIdentifier);
            if (node) {
                // When resolving the export container for the name of a module or enum
                // declaration, we need to start resolution at the declaration's container.
                // Otherwise, we could incorrectly resolve the export container as the
                // declaration if it contains an exported member with the same name.
                var symbol = getReferencedValueSymbol(node, /*startInDeclarationContainer*/ isNameOfModuleOrEnumDeclaration(node));
                if (symbol) {
                    if (symbol.flags & 1048576 /* ExportValue */) {
                        // If we reference an exported entity within the same module declaration, then whether
                        // we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the
                        // kinds that we do NOT prefix.
                        var exportSymbol = getMergedSymbol(symbol.exportSymbol);
                        if (!prefixLocals && exportSymbol.flags & 944 /* ExportHasLocal */ && !(exportSymbol.flags & 3 /* Variable */)) {
                            return undefined;
                        }
                        symbol = exportSymbol;
                    }
                    var parentSymbol_1 = getParentOfSymbol(symbol);
                    if (parentSymbol_1) {
                        if (parentSymbol_1.flags & 512 /* ValueModule */ && parentSymbol_1.valueDeclaration.kind === 285 /* SourceFile */) {
                            var symbolFile = parentSymbol_1.valueDeclaration;
                            var referenceFile = ts.getSourceFileOfNode(node);
                            // If `node` accesses an export and that export isn't in the same file, then symbol is a namespace export, so return undefined.
                            var symbolIsUmdExport = symbolFile !== referenceFile;
                            return symbolIsUmdExport ? undefined : symbolFile;
                        }
                        return ts.findAncestor(node.parent, function (n) { return ts.isModuleOrEnumDeclaration(n) && getSymbolOfNode(n) === parentSymbol_1; });
                    }
                }
            }
        }
        // When resolved as an expression identifier, if the given node references an import, return the declaration of
        // that import. Otherwise, return undefined.
        function getReferencedImportDeclaration(nodeIn) {
            var node = ts.getParseTreeNode(nodeIn, ts.isIdentifier);
            if (node) {
                var symbol = getReferencedValueSymbol(node);
                // We should only get the declaration of an alias if there isn't a local value
                // declaration for the symbol
                if (isNonLocalAlias(symbol, /*excludes*/ 67220415 /* Value */)) {
                    return getDeclarationOfAliasSymbol(symbol);
                }
            }
            return undefined;
        }
        function isSymbolOfDestructuredElementOfCatchBinding(symbol) {
            return ts.isBindingElement(symbol.valueDeclaration)
                && ts.walkUpBindingElementsAndPatterns(symbol.valueDeclaration).parent.kind === 275 /* CatchClause */;
        }
        function isSymbolOfDeclarationWithCollidingName(symbol) {
            if (symbol.flags & 418 /* BlockScoped */ && !ts.isSourceFile(symbol.valueDeclaration)) {
                var links = getSymbolLinks(symbol);
                if (links.isDeclarationWithCollidingName === undefined) {
                    var container = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration);
                    if (ts.isStatementWithLocals(container) || isSymbolOfDestructuredElementOfCatchBinding(symbol)) {
                        var nodeLinks_1 = getNodeLinks(symbol.valueDeclaration);
                        if (resolveName(container.parent, symbol.escapedName, 67220415 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)) {
                            // redeclaration - always should be renamed
                            links.isDeclarationWithCollidingName = true;
                        }
                        else if (nodeLinks_1.flags & 262144 /* CapturedBlockScopedBinding */) {
                            // binding is captured in the function
                            // should be renamed if:
                            // - binding is not top level - top level bindings never collide with anything
                            // AND
                            //   - binding is not declared in loop, should be renamed to avoid name reuse across siblings
                            //     let a, b
                            //     { let x = 1; a = () => x; }
                            //     { let x = 100; b = () => x; }
                            //     console.log(a()); // should print '1'
                            //     console.log(b()); // should print '100'
                            //     OR
                            //   - binding is declared inside loop but not in inside initializer of iteration statement or directly inside loop body
                            //     * variables from initializer are passed to rewritten loop body as parameters so they are not captured directly
                            //     * variables that are declared immediately in loop body will become top level variable after loop is rewritten and thus
                            //       they will not collide with anything
                            var isDeclaredInLoop = nodeLinks_1.flags & 524288 /* BlockScopedBindingInLoop */;
                            var inLoopInitializer = ts.isIterationStatement(container, /*lookInLabeledStatements*/ false);
                            var inLoopBodyBlock = container.kind === 219 /* Block */ && ts.isIterationStatement(container.parent, /*lookInLabeledStatements*/ false);
                            links.isDeclarationWithCollidingName = !ts.isBlockScopedContainerTopLevel(container) && (!isDeclaredInLoop || (!inLoopInitializer && !inLoopBodyBlock));
                        }
                        else {
                            links.isDeclarationWithCollidingName = false;
                        }
                    }
                }
                return links.isDeclarationWithCollidingName;
            }
            return false;
        }
        // When resolved as an expression identifier, if the given node references a nested block scoped entity with
        // a name that either hides an existing name or might hide it when compiled downlevel,
        // return the declaration of that entity. Otherwise, return undefined.
        function getReferencedDeclarationWithCollidingName(nodeIn) {
            if (!ts.isGeneratedIdentifier(nodeIn)) {
                var node = ts.getParseTreeNode(nodeIn, ts.isIdentifier);
                if (node) {
                    var symbol = getReferencedValueSymbol(node);
                    if (symbol && isSymbolOfDeclarationWithCollidingName(symbol)) {
                        return symbol.valueDeclaration;
                    }
                }
            }
            return undefined;
        }
        // Return true if the given node is a declaration of a nested block scoped entity with a name that either hides an
        // existing name or might hide a name when compiled downlevel
        function isDeclarationWithCollidingName(nodeIn) {
            var node = ts.getParseTreeNode(nodeIn, ts.isDeclaration);
            if (node) {
                var symbol = getSymbolOfNode(node);
                if (symbol) {
                    return isSymbolOfDeclarationWithCollidingName(symbol);
                }
            }
            return false;
        }
        function isValueAliasDeclaration(node) {
            switch (node.kind) {
                case 249 /* ImportEqualsDeclaration */:
                case 251 /* ImportClause */:
                case 252 /* NamespaceImport */:
                case 254 /* ImportSpecifier */:
                case 258 /* ExportSpecifier */:
                    return isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol);
                case 256 /* ExportDeclaration */:
                    var exportClause = node.exportClause;
                    return !!exportClause && ts.some(exportClause.elements, isValueAliasDeclaration);
                case 255 /* ExportAssignment */:
                    return node.expression
                        && node.expression.kind === 73 /* Identifier */
                        ? isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol)
                        : true;
            }
            return false;
        }
        function isTopLevelValueImportEqualsWithEntityName(nodeIn) {
            var node = ts.getParseTreeNode(nodeIn, ts.isImportEqualsDeclaration);
            if (node === undefined || node.parent.kind !== 285 /* SourceFile */ || !ts.isInternalModuleImportEqualsDeclaration(node)) {
                // parent is not source file or it is not reference to internal module
                return false;
            }
            var isValue = isAliasResolvedToValue(getSymbolOfNode(node));
            return isValue && node.moduleReference && !ts.nodeIsMissing(node.moduleReference);
        }
        function isAliasResolvedToValue(symbol) {
            var target = resolveAlias(symbol);
            if (target === unknownSymbol) {
                return true;
            }
            // const enums and modules that contain only const enums are not considered values from the emit perspective
            // unless 'preserveConstEnums' option is set to true
            return !!(target.flags & 67220415 /* Value */) &&
                (compilerOptions.preserveConstEnums || !isConstEnumOrConstEnumOnlyModule(target));
        }
        function isConstEnumOrConstEnumOnlyModule(s) {
            return isConstEnumSymbol(s) || !!s.constEnumOnlyModule;
        }
        function isReferencedAliasDeclaration(node, checkChildren) {
            if (ts.isAliasSymbolDeclaration(node)) {
                var symbol = getSymbolOfNode(node);
                if (symbol && getSymbolLinks(symbol).referenced) {
                    return true;
                }
                var target = getSymbolLinks(symbol).target; // TODO: GH#18217
                if (target && ts.getModifierFlags(node) & 1 /* Export */ &&
                    target.flags & 67220415 /* Value */ && (compilerOptions.preserveConstEnums || !isConstEnumOrConstEnumOnlyModule(target))) {
                    // An `export import ... =` of a value symbol is always considered referenced
                    return true;
                }
            }
            if (checkChildren) {
                return !!ts.forEachChild(node, function (node) { return isReferencedAliasDeclaration(node, checkChildren); });
            }
            return false;
        }
        function isImplementationOfOverload(node) {
            if (ts.nodeIsPresent(node.body)) {
                if (ts.isGetAccessor(node) || ts.isSetAccessor(node))
                    return false; // Get or set accessors can never be overload implementations, but can have up to 2 signatures
                var symbol = getSymbolOfNode(node);
                var signaturesOfSymbol = getSignaturesOfSymbol(symbol);
                // If this function body corresponds to function with multiple signature, it is implementation of overload
                // e.g.: function foo(a: string): string;
                //       function foo(a: number): number;
                //       function foo(a: any) { // This is implementation of the overloads
                //           return a;
                //       }
                return signaturesOfSymbol.length > 1 ||
                    // If there is single signature for the symbol, it is overload if that signature isn't coming from the node
                    // e.g.: function foo(a: string): string;
                    //       function foo(a: any) { // This is implementation of the overloads
                    //           return a;
                    //       }
                    (signaturesOfSymbol.length === 1 && signaturesOfSymbol[0].declaration !== node);
            }
            return false;
        }
        function isRequiredInitializedParameter(parameter) {
            return !!strictNullChecks &&
                !isOptionalParameter(parameter) &&
                !ts.isJSDocParameterTag(parameter) &&
                !!parameter.initializer &&
                !ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */);
        }
        function isOptionalUninitializedParameterProperty(parameter) {
            return strictNullChecks &&
                isOptionalParameter(parameter) &&
                !parameter.initializer &&
                ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */);
        }
        function isExpandoFunctionDeclaration(node) {
            var declaration = ts.getParseTreeNode(node, ts.isFunctionDeclaration);
            if (!declaration) {
                return false;
            }
            var symbol = getSymbolOfNode(declaration);
            if (!symbol || !(symbol.flags & 16 /* Function */)) {
                return false;
            }
            return !!ts.forEachEntry(getExportsOfSymbol(symbol), function (p) { return p.flags & 67220415 /* Value */ && ts.isPropertyAccessExpression(p.valueDeclaration); });
        }
        function getPropertiesOfContainerFunction(node) {
            var declaration = ts.getParseTreeNode(node, ts.isFunctionDeclaration);
            if (!declaration) {
                return ts.emptyArray;
            }
            var symbol = getSymbolOfNode(declaration);
            return symbol && getPropertiesOfType(getTypeOfSymbol(symbol)) || ts.emptyArray;
        }
        function getNodeCheckFlags(node) {
            return getNodeLinks(node).flags || 0;
        }
        function getEnumMemberValue(node) {
            computeEnumMemberValues(node.parent);
            return getNodeLinks(node).enumMemberValue;
        }
        function canHaveConstantValue(node) {
            switch (node.kind) {
                case 279 /* EnumMember */:
                case 190 /* PropertyAccessExpression */:
                case 191 /* ElementAccessExpression */:
                    return true;
            }
            return false;
        }
        function getConstantValue(node) {
            if (node.kind === 279 /* EnumMember */) {
                return getEnumMemberValue(node);
            }
            var symbol = getNodeLinks(node).resolvedSymbol;
            if (symbol && (symbol.flags & 8 /* EnumMember */)) {
                // inline property\index accesses only for const enums
                var member = symbol.valueDeclaration;
                if (ts.isEnumConst(member.parent)) {
                    return getEnumMemberValue(member);
                }
            }
            return undefined;
        }
        function isFunctionType(type) {
            return !!(type.flags & 524288 /* Object */) && getSignaturesOfType(type, 0 /* Call */).length > 0;
        }
        function getTypeReferenceSerializationKind(typeNameIn, location) {
            // ensure both `typeName` and `location` are parse tree nodes.
            var typeName = ts.getParseTreeNode(typeNameIn, ts.isEntityName);
            if (!typeName)
                return ts.TypeReferenceSerializationKind.Unknown;
            if (location) {
                location = ts.getParseTreeNode(location);
                if (!location)
                    return ts.TypeReferenceSerializationKind.Unknown;
            }
            // Resolve the symbol as a value to ensure the type can be reached at runtime during emit.
            var valueSymbol = resolveEntityName(typeName, 67220415 /* Value */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
            // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer.
            var typeSymbol = resolveEntityName(typeName, 67897832 /* Type */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
            if (valueSymbol && valueSymbol === typeSymbol) {
                var globalPromiseSymbol = getGlobalPromiseConstructorSymbol(/*reportErrors*/ false);
                if (globalPromiseSymbol && valueSymbol === globalPromiseSymbol) {
                    return ts.TypeReferenceSerializationKind.Promise;
                }
                var constructorType = getTypeOfSymbol(valueSymbol);
                if (constructorType && isConstructorType(constructorType)) {
                    return ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue;
                }
            }
            // We might not be able to resolve type symbol so use unknown type in that case (eg error case)
            if (!typeSymbol) {
                return ts.TypeReferenceSerializationKind.Unknown;
            }
            var type = getDeclaredTypeOfSymbol(typeSymbol);
            if (type === errorType) {
                return ts.TypeReferenceSerializationKind.Unknown;
            }
            else if (type.flags & 3 /* AnyOrUnknown */) {
                return ts.TypeReferenceSerializationKind.ObjectType;
            }
            else if (isTypeAssignableToKind(type, 16384 /* Void */ | 98304 /* Nullable */ | 131072 /* Never */)) {
                return ts.TypeReferenceSerializationKind.VoidNullableOrNeverType;
            }
            else if (isTypeAssignableToKind(type, 528 /* BooleanLike */)) {
                return ts.TypeReferenceSerializationKind.BooleanType;
            }
            else if (isTypeAssignableToKind(type, 296 /* NumberLike */)) {
                return ts.TypeReferenceSerializationKind.NumberLikeType;
            }
            else if (isTypeAssignableToKind(type, 2112 /* BigIntLike */)) {
                return ts.TypeReferenceSerializationKind.BigIntLikeType;
            }
            else if (isTypeAssignableToKind(type, 132 /* StringLike */)) {
                return ts.TypeReferenceSerializationKind.StringLikeType;
            }
            else if (isTupleType(type)) {
                return ts.TypeReferenceSerializationKind.ArrayLikeType;
            }
            else if (isTypeAssignableToKind(type, 12288 /* ESSymbolLike */)) {
                return ts.TypeReferenceSerializationKind.ESSymbolType;
            }
            else if (isFunctionType(type)) {
                return ts.TypeReferenceSerializationKind.TypeWithCallSignature;
            }
            else if (isArrayType(type)) {
                return ts.TypeReferenceSerializationKind.ArrayLikeType;
            }
            else {
                return ts.TypeReferenceSerializationKind.ObjectType;
            }
        }
        function createTypeOfDeclaration(declarationIn, enclosingDeclaration, flags, tracker, addUndefined) {
            var declaration = ts.getParseTreeNode(declarationIn, ts.isVariableLikeOrAccessor);
            if (!declaration) {
                return ts.createToken(121 /* AnyKeyword */);
            }
            // Get type of the symbol if this is the valid symbol otherwise get type at location
            var symbol = getSymbolOfNode(declaration);
            var type = symbol && !(symbol.flags & (2048 /* TypeLiteral */ | 131072 /* Signature */))
                ? getWidenedLiteralType(getTypeOfSymbol(symbol))
                : errorType;
            if (type.flags & 8192 /* UniqueESSymbol */ &&
                type.symbol === symbol) {
                flags |= 1048576 /* AllowUniqueESSymbolType */;
            }
            if (addUndefined) {
                type = getOptionalType(type);
            }
            return nodeBuilder.typeToTypeNode(type, enclosingDeclaration, flags | 1024 /* MultilineObjectLiterals */, tracker);
        }
        function createReturnTypeOfSignatureDeclaration(signatureDeclarationIn, enclosingDeclaration, flags, tracker) {
            var signatureDeclaration = ts.getParseTreeNode(signatureDeclarationIn, ts.isFunctionLike);
            if (!signatureDeclaration) {
                return ts.createToken(121 /* AnyKeyword */);
            }
            var signature = getSignatureFromDeclaration(signatureDeclaration);
            return nodeBuilder.typeToTypeNode(getReturnTypeOfSignature(signature), enclosingDeclaration, flags | 1024 /* MultilineObjectLiterals */, tracker);
        }
        function createTypeOfExpression(exprIn, enclosingDeclaration, flags, tracker) {
            var expr = ts.getParseTreeNode(exprIn, ts.isExpression);
            if (!expr) {
                return ts.createToken(121 /* AnyKeyword */);
            }
            var type = getWidenedType(getRegularTypeOfExpression(expr));
            return nodeBuilder.typeToTypeNode(type, enclosingDeclaration, flags | 1024 /* MultilineObjectLiterals */, tracker);
        }
        function hasGlobalName(name) {
            return globals.has(ts.escapeLeadingUnderscores(name));
        }
        function getReferencedValueSymbol(reference, startInDeclarationContainer) {
            var resolvedSymbol = getNodeLinks(reference).resolvedSymbol;
            if (resolvedSymbol) {
                return resolvedSymbol;
            }
            var location = reference;
            if (startInDeclarationContainer) {
                // When resolving the name of a declaration as a value, we need to start resolution
                // at a point outside of the declaration.
                var parent = reference.parent;
                if (ts.isDeclaration(parent) && reference === parent.name) {
                    location = getDeclarationContainer(parent);
                }
            }
            return resolveName(location, reference.escapedText, 67220415 /* Value */ | 1048576 /* ExportValue */ | 2097152 /* Alias */, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
        }
        function getReferencedValueDeclaration(referenceIn) {
            if (!ts.isGeneratedIdentifier(referenceIn)) {
                var reference = ts.getParseTreeNode(referenceIn, ts.isIdentifier);
                if (reference) {
                    var symbol = getReferencedValueSymbol(reference);
                    if (symbol) {
                        return getExportSymbolOfValueSymbolIfExported(symbol).valueDeclaration;
                    }
                }
            }
            return undefined;
        }
        function isLiteralConstDeclaration(node) {
            if (ts.isDeclarationReadonly(node) || ts.isVariableDeclaration(node) && ts.isVarConst(node)) {
                return isFreshLiteralType(getTypeOfSymbol(getSymbolOfNode(node)));
            }
            return false;
        }
        function literalTypeToNode(type, enclosing, tracker) {
            var enumResult = type.flags & 1024 /* EnumLiteral */ ? nodeBuilder.symbolToExpression(type.symbol, 67220415 /* Value */, enclosing, /*flags*/ undefined, tracker)
                : type === trueType ? ts.createTrue() : type === falseType && ts.createFalse();
            return enumResult || ts.createLiteral(type.value);
        }
        function createLiteralConstValue(node, tracker) {
            var type = getTypeOfSymbol(getSymbolOfNode(node));
            return literalTypeToNode(type, node, tracker);
        }
        function createResolver() {
            // this variable and functions that use it are deliberately moved here from the outer scope
            // to avoid scope pollution
            var resolvedTypeReferenceDirectives = host.getResolvedTypeReferenceDirectives();
            var fileToDirective;
            if (resolvedTypeReferenceDirectives) {
                // populate reverse mapping: file path -> type reference directive that was resolved to this file
                fileToDirective = ts.createMap();
                resolvedTypeReferenceDirectives.forEach(function (resolvedDirective, key) {
                    if (!resolvedDirective || !resolvedDirective.resolvedFileName) {
                        return;
                    }
                    var file = host.getSourceFile(resolvedDirective.resolvedFileName);
                    // Add the transitive closure of path references loaded by this file (as long as they are not)
                    // part of an existing type reference.
                    addReferencedFilesToTypeDirective(file, key);
                });
            }
            return {
                getReferencedExportContainer: getReferencedExportContainer,
                getReferencedImportDeclaration: getReferencedImportDeclaration,
                getReferencedDeclarationWithCollidingName: getReferencedDeclarationWithCollidingName,
                isDeclarationWithCollidingName: isDeclarationWithCollidingName,
                isValueAliasDeclaration: function (node) {
                    node = ts.getParseTreeNode(node);
                    // Synthesized nodes are always treated like values.
                    return node ? isValueAliasDeclaration(node) : true;
                },
                hasGlobalName: hasGlobalName,
                isReferencedAliasDeclaration: function (node, checkChildren) {
                    node = ts.getParseTreeNode(node);
                    // Synthesized nodes are always treated as referenced.
                    return node ? isReferencedAliasDeclaration(node, checkChildren) : true;
                },
                getNodeCheckFlags: function (node) {
                    node = ts.getParseTreeNode(node);
                    return node ? getNodeCheckFlags(node) : 0;
                },
                isTopLevelValueImportEqualsWithEntityName: isTopLevelValueImportEqualsWithEntityName,
                isDeclarationVisible: isDeclarationVisible,
                isImplementationOfOverload: isImplementationOfOverload,
                isRequiredInitializedParameter: isRequiredInitializedParameter,
                isOptionalUninitializedParameterProperty: isOptionalUninitializedParameterProperty,
                isExpandoFunctionDeclaration: isExpandoFunctionDeclaration,
                getPropertiesOfContainerFunction: getPropertiesOfContainerFunction,
                createTypeOfDeclaration: createTypeOfDeclaration,
                createReturnTypeOfSignatureDeclaration: createReturnTypeOfSignatureDeclaration,
                createTypeOfExpression: createTypeOfExpression,
                createLiteralConstValue: createLiteralConstValue,
                isSymbolAccessible: isSymbolAccessible,
                isEntityNameVisible: isEntityNameVisible,
                getConstantValue: function (nodeIn) {
                    var node = ts.getParseTreeNode(nodeIn, canHaveConstantValue);
                    return node ? getConstantValue(node) : undefined;
                },
                collectLinkedAliases: collectLinkedAliases,
                getReferencedValueDeclaration: getReferencedValueDeclaration,
                getTypeReferenceSerializationKind: getTypeReferenceSerializationKind,
                isOptionalParameter: isOptionalParameter,
                moduleExportsSomeValue: moduleExportsSomeValue,
                isArgumentsLocalBinding: isArgumentsLocalBinding,
                getExternalModuleFileFromDeclaration: getExternalModuleFileFromDeclaration,
                getTypeReferenceDirectivesForEntityName: getTypeReferenceDirectivesForEntityName,
                getTypeReferenceDirectivesForSymbol: getTypeReferenceDirectivesForSymbol,
                isLiteralConstDeclaration: isLiteralConstDeclaration,
                isLateBound: function (nodeIn) {
                    var node = ts.getParseTreeNode(nodeIn, ts.isDeclaration);
                    var symbol = node && getSymbolOfNode(node);
                    return !!(symbol && ts.getCheckFlags(symbol) & 4096 /* Late */);
                },
                getJsxFactoryEntity: function (location) { return location ? (getJsxNamespace(location), (ts.getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity; },
                getAllAccessorDeclarations: function (accessor) {
                    accessor = ts.getParseTreeNode(accessor, ts.isGetOrSetAccessorDeclaration); // TODO: GH#18217
                    var otherKind = accessor.kind === 160 /* SetAccessor */ ? 159 /* GetAccessor */ : 160 /* SetAccessor */;
                    var otherAccessor = ts.getDeclarationOfKind(getSymbolOfNode(accessor), otherKind);
                    var firstAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? otherAccessor : accessor;
                    var secondAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? accessor : otherAccessor;
                    var setAccessor = accessor.kind === 160 /* SetAccessor */ ? accessor : otherAccessor;
                    var getAccessor = accessor.kind === 159 /* GetAccessor */ ? accessor : otherAccessor;
                    return {
                        firstAccessor: firstAccessor,
                        secondAccessor: secondAccessor,
                        setAccessor: setAccessor,
                        getAccessor: getAccessor
                    };
                },
                getSymbolOfExternalModuleSpecifier: function (moduleName) { return resolveExternalModuleNameWorker(moduleName, moduleName, /*moduleNotFoundError*/ undefined); },
                isBindingCapturedByNode: function (node, decl) {
                    var parseNode = ts.getParseTreeNode(node);
                    var parseDecl = ts.getParseTreeNode(decl);
                    return !!parseNode && !!parseDecl && (ts.isVariableDeclaration(parseDecl) || ts.isBindingElement(parseDecl)) && isBindingCapturedByNode(parseNode, parseDecl);
                }
            };
            function isInHeritageClause(node) {
                return node.parent && node.parent.kind === 212 /* ExpressionWithTypeArguments */ && node.parent.parent && node.parent.parent.kind === 274 /* HeritageClause */;
            }
            // defined here to avoid outer scope pollution
            function getTypeReferenceDirectivesForEntityName(node) {
                // program does not have any files with type reference directives - bail out
                if (!fileToDirective) {
                    return undefined;
                }
                // property access can only be used as values, or types when within an expression with type arguments inside a heritage clause
                // qualified names can only be used as types\namespaces
                // identifiers are treated as values only if they appear in type queries
                var meaning = 67897832 /* Type */ | 1920 /* Namespace */;
                if ((node.kind === 73 /* Identifier */ && isInTypeQuery(node)) || (node.kind === 190 /* PropertyAccessExpression */ && !isInHeritageClause(node))) {
                    meaning = 67220415 /* Value */ | 1048576 /* ExportValue */;
                }
                var symbol = resolveEntityName(node, meaning, /*ignoreErrors*/ true);
                return symbol && symbol !== unknownSymbol ? getTypeReferenceDirectivesForSymbol(symbol, meaning) : undefined;
            }
            // defined here to avoid outer scope pollution
            function getTypeReferenceDirectivesForSymbol(symbol, meaning) {
                // program does not have any files with type reference directives - bail out
                if (!fileToDirective) {
                    return undefined;
                }
                if (!isSymbolFromTypeDeclarationFile(symbol)) {
                    return undefined;
                }
                // check what declarations in the symbol can contribute to the target meaning
                var typeReferenceDirectives;
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    // check meaning of the local symbol to see if declaration needs to be analyzed further
                    if (decl.symbol && decl.symbol.flags & meaning) {
                        var file = ts.getSourceFileOfNode(decl);
                        var typeReferenceDirective = fileToDirective.get(file.path);
                        if (typeReferenceDirective) {
                            (typeReferenceDirectives || (typeReferenceDirectives = [])).push(typeReferenceDirective);
                        }
                        else {
                            // found at least one entry that does not originate from type reference directive
                            return undefined;
                        }
                    }
                }
                return typeReferenceDirectives;
            }
            function isSymbolFromTypeDeclarationFile(symbol) {
                // bail out if symbol does not have associated declarations (i.e. this is transient symbol created for property in binding pattern)
                if (!symbol.declarations) {
                    return false;
                }
                // walk the parent chain for symbols to make sure that top level parent symbol is in the global scope
                // external modules cannot define or contribute to type declaration files
                var current = symbol;
                while (true) {
                    var parent = getParentOfSymbol(current);
                    if (parent) {
                        current = parent;
                    }
                    else {
                        break;
                    }
                }
                if (current.valueDeclaration && current.valueDeclaration.kind === 285 /* SourceFile */ && current.flags & 512 /* ValueModule */) {
                    return false;
                }
                // check that at least one declaration of top level symbol originates from type declaration file
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var file = ts.getSourceFileOfNode(decl);
                    if (fileToDirective.has(file.path)) {
                        return true;
                    }
                }
                return false;
            }
            function addReferencedFilesToTypeDirective(file, key) {
                if (fileToDirective.has(file.path))
                    return;
                fileToDirective.set(file.path, key);
                for (var _i = 0, _a = file.referencedFiles; _i < _a.length; _i++) {
                    var fileName = _a[_i].fileName;
                    var resolvedFile = ts.resolveTripleslashReference(fileName, file.originalFileName);
                    var referencedFile = host.getSourceFile(resolvedFile);
                    if (referencedFile) {
                        addReferencedFilesToTypeDirective(referencedFile, key);
                    }
                }
            }
        }
        function getExternalModuleFileFromDeclaration(declaration) {
            var specifier = declaration.kind === 245 /* ModuleDeclaration */ ? ts.tryCast(declaration.name, ts.isStringLiteral) : ts.getExternalModuleName(declaration);
            var moduleSymbol = resolveExternalModuleNameWorker(specifier, specifier, /*moduleNotFoundError*/ undefined); // TODO: GH#18217
            if (!moduleSymbol) {
                return undefined;
            }
            return ts.getDeclarationOfKind(moduleSymbol, 285 /* SourceFile */);
        }
        function initializeTypeChecker() {
            // Bind all source files and propagate errors
            for (var _i = 0, _a = host.getSourceFiles(); _i < _a.length; _i++) {
                var file = _a[_i];
                ts.bindSourceFile(file, compilerOptions);
            }
            amalgamatedDuplicates = ts.createMap();
            // Initialize global symbol table
            var augmentations;
            for (var _b = 0, _c = host.getSourceFiles(); _b < _c.length; _b++) {
                var file = _c[_b];
                if (file.redirectInfo) {
                    continue;
                }
                if (!ts.isExternalOrCommonJsModule(file)) {
                    // It is an error for a non-external-module (i.e. script) to declare its own `globalThis`.
                    // We can't use `builtinGlobals` for this due to synthetic expando-namespace generation in JS files.
                    var fileGlobalThisSymbol = file.locals.get("globalThis");
                    if (fileGlobalThisSymbol) {
                        for (var _d = 0, _e = fileGlobalThisSymbol.declarations; _d < _e.length; _d++) {
                            var declaration = _e[_d];
                            diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "globalThis"));
                        }
                    }
                    mergeSymbolTable(globals, file.locals);
                }
                if (file.jsGlobalAugmentations) {
                    mergeSymbolTable(globals, file.jsGlobalAugmentations);
                }
                if (file.patternAmbientModules && file.patternAmbientModules.length) {
                    patternAmbientModules = ts.concatenate(patternAmbientModules, file.patternAmbientModules);
                }
                if (file.moduleAugmentations.length) {
                    (augmentations || (augmentations = [])).push(file.moduleAugmentations);
                }
                if (file.symbol && file.symbol.globalExports) {
                    // Merge in UMD exports with first-in-wins semantics (see #9771)
                    var source = file.symbol.globalExports;
                    source.forEach(function (sourceSymbol, id) {
                        if (!globals.has(id)) {
                            globals.set(id, sourceSymbol);
                        }
                    });
                }
            }
            // We do global augmentations separately from module augmentations (and before creating global types) because they
            //  1. Affect global types. We won't have the correct global types until global augmentations are merged. Also,
            //  2. Module augmentation instantiation requires creating the type of a module, which, in turn, can require
            //       checking for an export or property on the module (if export=) which, in turn, can fall back to the
            //       apparent type of the module - either globalObjectType or globalFunctionType - which wouldn't exist if we
            //       did module augmentations prior to finalizing the global types.
            if (augmentations) {
                // merge _global_ module augmentations.
                // this needs to be done after global symbol table is initialized to make sure that all ambient modules are indexed
                for (var _f = 0, augmentations_1 = augmentations; _f < augmentations_1.length; _f++) {
                    var list = augmentations_1[_f];
                    for (var _g = 0, list_1 = list; _g < list_1.length; _g++) {
                        var augmentation = list_1[_g];
                        if (!ts.isGlobalScopeAugmentation(augmentation.parent))
                            continue;
                        mergeModuleAugmentation(augmentation);
                    }
                }
            }
            // Setup global builtins
            addToSymbolTable(globals, builtinGlobals, ts.Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0);
            getSymbolLinks(undefinedSymbol).type = undefinedWideningType;
            getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments", /*arity*/ 0, /*reportErrors*/ true);
            getSymbolLinks(unknownSymbol).type = errorType;
            getSymbolLinks(globalThisSymbol).type = createObjectType(16 /* Anonymous */, globalThisSymbol);
            // Initialize special types
            globalArrayType = getGlobalType("Array", /*arity*/ 1, /*reportErrors*/ true);
            globalObjectType = getGlobalType("Object", /*arity*/ 0, /*reportErrors*/ true);
            globalFunctionType = getGlobalType("Function", /*arity*/ 0, /*reportErrors*/ true);
            globalCallableFunctionType = strictBindCallApply && getGlobalType("CallableFunction", /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType;
            globalNewableFunctionType = strictBindCallApply && getGlobalType("NewableFunction", /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType;
            globalStringType = getGlobalType("String", /*arity*/ 0, /*reportErrors*/ true);
            globalNumberType = getGlobalType("Number", /*arity*/ 0, /*reportErrors*/ true);
            globalBooleanType = getGlobalType("Boolean", /*arity*/ 0, /*reportErrors*/ true);
            globalRegExpType = getGlobalType("RegExp", /*arity*/ 0, /*reportErrors*/ true);
            anyArrayType = createArrayType(anyType);
            autoArrayType = createArrayType(autoType);
            if (autoArrayType === emptyObjectType) {
                // autoArrayType is used as a marker, so even if global Array type is not defined, it needs to be a unique type
                autoArrayType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
            }
            globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray", /*arity*/ 1) || globalArrayType;
            anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType;
            globalThisType = getGlobalTypeOrUndefined("ThisType", /*arity*/ 1);
            if (augmentations) {
                // merge _nonglobal_ module augmentations.
                // this needs to be done after global symbol table is initialized to make sure that all ambient modules are indexed
                for (var _h = 0, augmentations_2 = augmentations; _h < augmentations_2.length; _h++) {
                    var list = augmentations_2[_h];
                    for (var _j = 0, list_2 = list; _j < list_2.length; _j++) {
                        var augmentation = list_2[_j];
                        if (ts.isGlobalScopeAugmentation(augmentation.parent))
                            continue;
                        mergeModuleAugmentation(augmentation);
                    }
                }
            }
            amalgamatedDuplicates.forEach(function (_a) {
                var firstFile = _a.firstFile, secondFile = _a.secondFile, conflictingSymbols = _a.conflictingSymbols;
                // If not many things conflict, issue individual errors
                if (conflictingSymbols.size < 8) {
                    conflictingSymbols.forEach(function (_a, symbolName) {
                        var isBlockScoped = _a.isBlockScoped, firstFileLocations = _a.firstFileLocations, secondFileLocations = _a.secondFileLocations;
                        var message = isBlockScoped ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0 : ts.Diagnostics.Duplicate_identifier_0;
                        for (var _i = 0, firstFileLocations_1 = firstFileLocations; _i < firstFileLocations_1.length; _i++) {
                            var node = firstFileLocations_1[_i];
                            addDuplicateDeclarationError(node, message, symbolName, secondFileLocations);
                        }
                        for (var _b = 0, secondFileLocations_1 = secondFileLocations; _b < secondFileLocations_1.length; _b++) {
                            var node = secondFileLocations_1[_b];
                            addDuplicateDeclarationError(node, message, symbolName, firstFileLocations);
                        }
                    });
                }
                else {
                    // Otherwise issue top-level error since the files appear very identical in terms of what they contain
                    var list = ts.arrayFrom(conflictingSymbols.keys()).join(", ");
                    diagnostics.add(ts.addRelatedInfo(ts.createDiagnosticForNode(firstFile, ts.Diagnostics.Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0, list), ts.createDiagnosticForNode(secondFile, ts.Diagnostics.Conflicts_are_in_this_file)));
                    diagnostics.add(ts.addRelatedInfo(ts.createDiagnosticForNode(secondFile, ts.Diagnostics.Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0, list), ts.createDiagnosticForNode(firstFile, ts.Diagnostics.Conflicts_are_in_this_file)));
                }
            });
            amalgamatedDuplicates = undefined;
        }
        function checkExternalEmitHelpers(location, helpers) {
            if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) {
                var sourceFile = ts.getSourceFileOfNode(location);
                if (ts.isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & 4194304 /* Ambient */)) {
                    var helpersModule = resolveHelpersModule(sourceFile, location);
                    if (helpersModule !== unknownSymbol) {
                        var uncheckedHelpers = helpers & ~requestedExternalEmitHelpers;
                        for (var helper = 1 /* FirstEmitHelper */; helper <= 65536 /* LastEmitHelper */; helper <<= 1) {
                            if (uncheckedHelpers & helper) {
                                var name = getHelperName(helper);
                                var symbol = getSymbol(helpersModule.exports, ts.escapeLeadingUnderscores(name), 67220415 /* Value */);
                                if (!symbol) {
                                    error(location, ts.Diagnostics.This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1, ts.externalHelpersModuleNameText, name);
                                }
                            }
                        }
                    }
                    requestedExternalEmitHelpers |= helpers;
                }
            }
        }
        function getHelperName(helper) {
            switch (helper) {
                case 1 /* Extends */: return "__extends";
                case 2 /* Assign */: return "__assign";
                case 4 /* Rest */: return "__rest";
                case 8 /* Decorate */: return "__decorate";
                case 16 /* Metadata */: return "__metadata";
                case 32 /* Param */: return "__param";
                case 64 /* Awaiter */: return "__awaiter";
                case 128 /* Generator */: return "__generator";
                case 256 /* Values */: return "__values";
                case 512 /* Read */: return "__read";
                case 1024 /* Spread */: return "__spread";
                case 2048 /* Await */: return "__await";
                case 4096 /* AsyncGenerator */: return "__asyncGenerator";
                case 8192 /* AsyncDelegator */: return "__asyncDelegator";
                case 16384 /* AsyncValues */: return "__asyncValues";
                case 32768 /* ExportStar */: return "__exportStar";
                case 65536 /* MakeTemplateObject */: return "__makeTemplateObject";
                default: return ts.Debug.fail("Unrecognized helper");
            }
        }
        function resolveHelpersModule(node, errorNode) {
            if (!externalHelpersModule) {
                externalHelpersModule = resolveExternalModule(node, ts.externalHelpersModuleNameText, ts.Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol;
            }
            return externalHelpersModule;
        }
        // GRAMMAR CHECKING
        function checkGrammarDecoratorsAndModifiers(node) {
            return checkGrammarDecorators(node) || checkGrammarModifiers(node);
        }
        function checkGrammarDecorators(node) {
            if (!node.decorators) {
                return false;
            }
            if (!ts.nodeCanBeDecorated(node, node.parent, node.parent.parent)) {
                if (node.kind === 157 /* MethodDeclaration */ && !ts.nodeIsPresent(node.body)) {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.A_decorator_can_only_decorate_a_method_implementation_not_an_overload);
                }
                else {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.Decorators_are_not_valid_here);
                }
            }
            else if (node.kind === 159 /* GetAccessor */ || node.kind === 160 /* SetAccessor */) {
                var accessors = ts.getAllAccessorDeclarations(node.parent.members, node);
                if (accessors.firstAccessor.decorators && node === accessors.secondAccessor) {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name);
                }
            }
            return false;
        }
        function checkGrammarModifiers(node) {
            var quickResult = reportObviousModifierErrors(node);
            if (quickResult !== undefined) {
                return quickResult;
            }
            var lastStatic, lastDeclare, lastAsync, lastReadonly;
            var flags = 0 /* None */;
            for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
                var modifier = _a[_i];
                if (modifier.kind !== 134 /* ReadonlyKeyword */) {
                    if (node.kind === 154 /* PropertySignature */ || node.kind === 156 /* MethodSignature */) {
                        return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_type_member, ts.tokenToString(modifier.kind));
                    }
                    if (node.kind === 163 /* IndexSignature */) {
                        return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_an_index_signature, ts.tokenToString(modifier.kind));
                    }
                }
                switch (modifier.kind) {
                    case 78 /* ConstKeyword */:
                        if (node.kind !== 244 /* EnumDeclaration */) {
                            return grammarErrorOnNode(node, ts.Diagnostics.A_class_member_cannot_have_the_0_keyword, ts.tokenToString(78 /* ConstKeyword */));
                        }
                        break;
                    case 116 /* PublicKeyword */:
                    case 115 /* ProtectedKeyword */:
                    case 114 /* PrivateKeyword */:
                        var text = visibilityToString(ts.modifierToFlag(modifier.kind));
                        if (flags & 28 /* AccessibilityModifier */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics.Accessibility_modifier_already_seen);
                        }
                        else if (flags & 32 /* Static */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "static");
                        }
                        else if (flags & 64 /* Readonly */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "readonly");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "async");
                        }
                        else if (node.parent.kind === 246 /* ModuleBlock */ || node.parent.kind === 285 /* SourceFile */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, text);
                        }
                        else if (flags & 128 /* Abstract */) {
                            if (modifier.kind === 114 /* PrivateKeyword */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, text, "abstract");
                            }
                            else {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "abstract");
                            }
                        }
                        flags |= ts.modifierToFlag(modifier.kind);
                        break;
                    case 117 /* StaticKeyword */:
                        if (flags & 32 /* Static */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "static");
                        }
                        else if (flags & 64 /* Readonly */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "static", "readonly");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "static", "async");
                        }
                        else if (node.parent.kind === 246 /* ModuleBlock */ || node.parent.kind === 285 /* SourceFile */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, "static");
                        }
                        else if (node.kind === 152 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "static");
                        }
                        else if (flags & 128 /* Abstract */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
                        }
                        flags |= 32 /* Static */;
                        lastStatic = modifier;
                        break;
                    case 134 /* ReadonlyKeyword */:
                        if (flags & 64 /* Readonly */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "readonly");
                        }
                        else if (node.kind !== 155 /* PropertyDeclaration */ && node.kind !== 154 /* PropertySignature */ && node.kind !== 163 /* IndexSignature */ && node.kind !== 152 /* Parameter */) {
                            // If node.kind === SyntaxKind.Parameter, checkParameter report an error if it's not a parameter property.
                            return grammarErrorOnNode(modifier, ts.Diagnostics.readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature);
                        }
                        flags |= 64 /* Readonly */;
                        lastReadonly = modifier;
                        break;
                    case 86 /* ExportKeyword */:
                        if (flags & 1 /* Export */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "export");
                        }
                        else if (flags & 2 /* Ambient */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "declare");
                        }
                        else if (flags & 128 /* Abstract */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "abstract");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "async");
                        }
                        else if (node.parent.kind === 241 /* ClassDeclaration */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "export");
                        }
                        else if (node.kind === 152 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "export");
                        }
                        flags |= 1 /* Export */;
                        break;
                    case 81 /* DefaultKeyword */:
                        var container = node.parent.kind === 285 /* SourceFile */ ? node.parent : node.parent.parent;
                        if (container.kind === 245 /* ModuleDeclaration */ && !ts.isAmbientModule(container)) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module);
                        }
                        flags |= 512 /* Default */;
                        break;
                    case 126 /* DeclareKeyword */:
                        if (flags & 2 /* Ambient */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "declare");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
                        }
                        else if (node.parent.kind === 241 /* ClassDeclaration */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "declare");
                        }
                        else if (node.kind === 152 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "declare");
                        }
                        else if ((node.parent.flags & 4194304 /* Ambient */) && node.parent.kind === 246 /* ModuleBlock */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context);
                        }
                        flags |= 2 /* Ambient */;
                        lastDeclare = modifier;
                        break;
                    case 119 /* AbstractKeyword */:
                        if (flags & 128 /* Abstract */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "abstract");
                        }
                        if (node.kind !== 241 /* ClassDeclaration */) {
                            if (node.kind !== 157 /* MethodDeclaration */ &&
                                node.kind !== 155 /* PropertyDeclaration */ &&
                                node.kind !== 159 /* GetAccessor */ &&
                                node.kind !== 160 /* SetAccessor */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration);
                            }
                            if (!(node.parent.kind === 241 /* ClassDeclaration */ && ts.hasModifier(node.parent, 128 /* Abstract */))) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class);
                            }
                            if (flags & 32 /* Static */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
                            }
                            if (flags & 8 /* Private */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "private", "abstract");
                            }
                        }
                        flags |= 128 /* Abstract */;
                        break;
                    case 122 /* AsyncKeyword */:
                        if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "async");
                        }
                        else if (flags & 2 /* Ambient */ || node.parent.flags & 4194304 /* Ambient */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
                        }
                        else if (node.kind === 152 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "async");
                        }
                        flags |= 256 /* Async */;
                        lastAsync = modifier;
                        break;
                }
            }
            if (node.kind === 158 /* Constructor */) {
                if (flags & 32 /* Static */) {
                    return grammarErrorOnNode(lastStatic, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "static");
                }
                if (flags & 128 /* Abstract */) {
                    return grammarErrorOnNode(lastStatic, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "abstract"); // TODO: GH#18217
                }
                else if (flags & 256 /* Async */) {
                    return grammarErrorOnNode(lastAsync, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "async");
                }
                else if (flags & 64 /* Readonly */) {
                    return grammarErrorOnNode(lastReadonly, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "readonly");
                }
                return false;
            }
            else if ((node.kind === 250 /* ImportDeclaration */ || node.kind === 249 /* ImportEqualsDeclaration */) && flags & 2 /* Ambient */) {
                return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_0_modifier_cannot_be_used_with_an_import_declaration, "declare");
            }
            else if (node.kind === 152 /* Parameter */ && (flags & 92 /* ParameterPropertyModifier */) && ts.isBindingPattern(node.name)) {
                return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_may_not_be_declared_using_a_binding_pattern);
            }
            else if (node.kind === 152 /* Parameter */ && (flags & 92 /* ParameterPropertyModifier */) && node.dotDotDotToken) {
                return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_cannot_be_declared_using_a_rest_parameter);
            }
            if (flags & 256 /* Async */) {
                return checkGrammarAsyncModifier(node, lastAsync);
            }
            return false;
        }
        /**
         * true | false: Early return this value from checkGrammarModifiers.
         * undefined: Need to do full checking on the modifiers.
         */
        function reportObviousModifierErrors(node) {
            return !node.modifiers
                ? false
                : shouldReportBadModifier(node)
                    ? grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here)
                    : undefined;
        }
        function shouldReportBadModifier(node) {
            switch (node.kind) {
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                case 158 /* Constructor */:
                case 155 /* PropertyDeclaration */:
                case 154 /* PropertySignature */:
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                case 163 /* IndexSignature */:
                case 245 /* ModuleDeclaration */:
                case 250 /* ImportDeclaration */:
                case 249 /* ImportEqualsDeclaration */:
                case 256 /* ExportDeclaration */:
                case 255 /* ExportAssignment */:
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */:
                case 152 /* Parameter */:
                    return false;
                default:
                    if (node.parent.kind === 246 /* ModuleBlock */ || node.parent.kind === 285 /* SourceFile */) {
                        return false;
                    }
                    switch (node.kind) {
                        case 240 /* FunctionDeclaration */:
                            return nodeHasAnyModifiersExcept(node, 122 /* AsyncKeyword */);
                        case 241 /* ClassDeclaration */:
                            return nodeHasAnyModifiersExcept(node, 119 /* AbstractKeyword */);
                        case 242 /* InterfaceDeclaration */:
                        case 220 /* VariableStatement */:
                        case 243 /* TypeAliasDeclaration */:
                            return true;
                        case 244 /* EnumDeclaration */:
                            return nodeHasAnyModifiersExcept(node, 78 /* ConstKeyword */);
                        default:
                            ts.Debug.fail();
                            return false;
                    }
            }
        }
        function nodeHasAnyModifiersExcept(node, allowedModifier) {
            return node.modifiers.length > 1 || node.modifiers[0].kind !== allowedModifier;
        }
        function checkGrammarAsyncModifier(node, asyncModifier) {
            switch (node.kind) {
                case 157 /* MethodDeclaration */:
                case 240 /* FunctionDeclaration */:
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */:
                    return false;
            }
            return grammarErrorOnNode(asyncModifier, ts.Diagnostics._0_modifier_cannot_be_used_here, "async");
        }
        function checkGrammarForDisallowedTrailingComma(list, diag) {
            if (diag === void 0) { diag = ts.Diagnostics.Trailing_comma_not_allowed; }
            if (list && list.hasTrailingComma) {
                return grammarErrorAtPos(list[0], list.end - ",".length, ",".length, diag);
            }
            return false;
        }
        function checkGrammarTypeParameterList(typeParameters, file) {
            if (typeParameters && typeParameters.length === 0) {
                var start = typeParameters.pos - "<".length;
                var end = ts.skipTrivia(file.text, typeParameters.end) + ">".length;
                return grammarErrorAtPos(file, start, end - start, ts.Diagnostics.Type_parameter_list_cannot_be_empty);
            }
            return false;
        }
        function checkGrammarParameterList(parameters) {
            var seenOptionalParameter = false;
            var parameterCount = parameters.length;
            for (var i = 0; i < parameterCount; i++) {
                var parameter = parameters[i];
                if (parameter.dotDotDotToken) {
                    if (i !== (parameterCount - 1)) {
                        return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
                    }
                    if (!(parameter.flags & 4194304 /* Ambient */)) { // Allow `...foo,` in ambient declarations; see GH#23070
                        checkGrammarForDisallowedTrailingComma(parameters, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
                    }
                    if (parameter.questionToken) {
                        return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.A_rest_parameter_cannot_be_optional);
                    }
                    if (parameter.initializer) {
                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_rest_parameter_cannot_have_an_initializer);
                    }
                }
                else if (parameter.questionToken) {
                    seenOptionalParameter = true;
                    if (parameter.initializer) {
                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.Parameter_cannot_have_question_mark_and_initializer);
                    }
                }
                else if (seenOptionalParameter && !parameter.initializer) {
                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_required_parameter_cannot_follow_an_optional_parameter);
                }
            }
        }
        function getNonSimpleParameters(parameters) {
            return ts.filter(parameters, function (parameter) { return !!parameter.initializer || ts.isBindingPattern(parameter.name) || ts.isRestParameter(parameter); });
        }
        function checkGrammarForUseStrictSimpleParameterList(node) {
            if (languageVersion >= 3 /* ES2016 */) {
                var useStrictDirective_1 = node.body && ts.isBlock(node.body) && ts.findUseStrictPrologue(node.body.statements);
                if (useStrictDirective_1) {
                    var nonSimpleParameters = getNonSimpleParameters(node.parameters);
                    if (ts.length(nonSimpleParameters)) {
                        ts.forEach(nonSimpleParameters, function (parameter) {
                            ts.addRelatedInfo(error(parameter, ts.Diagnostics.This_parameter_is_not_allowed_with_use_strict_directive), ts.createDiagnosticForNode(useStrictDirective_1, ts.Diagnostics.use_strict_directive_used_here));
                        });
                        var diagnostics_1 = nonSimpleParameters.map(function (parameter, index) { return (index === 0 ? ts.createDiagnosticForNode(parameter, ts.Diagnostics.Non_simple_parameter_declared_here) : ts.createDiagnosticForNode(parameter, ts.Diagnostics.and_here)); });
                        ts.addRelatedInfo.apply(void 0, [error(useStrictDirective_1, ts.Diagnostics.use_strict_directive_cannot_be_used_with_non_simple_parameter_list)].concat(diagnostics_1));
                        return true;
                    }
                }
            }
            return false;
        }
        function checkGrammarFunctionLikeDeclaration(node) {
            // Prevent cascading error by short-circuit
            var file = ts.getSourceFileOfNode(node);
            return checkGrammarDecoratorsAndModifiers(node) || checkGrammarTypeParameterList(node.typeParameters, file) ||
                checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file) ||
                (ts.isFunctionLikeDeclaration(node) && checkGrammarForUseStrictSimpleParameterList(node));
        }
        function checkGrammarClassLikeDeclaration(node) {
            var file = ts.getSourceFileOfNode(node);
            return checkGrammarClassDeclarationHeritageClauses(node) || checkGrammarTypeParameterList(node.typeParameters, file);
        }
        function checkGrammarArrowFunction(node, file) {
            if (!ts.isArrowFunction(node)) {
                return false;
            }
            var equalsGreaterThanToken = node.equalsGreaterThanToken;
            var startLine = ts.getLineAndCharacterOfPosition(file, equalsGreaterThanToken.pos).line;
            var endLine = ts.getLineAndCharacterOfPosition(file, equalsGreaterThanToken.end).line;
            return startLine !== endLine && grammarErrorOnNode(equalsGreaterThanToken, ts.Diagnostics.Line_terminator_not_permitted_before_arrow);
        }
        function checkGrammarIndexSignatureParameters(node) {
            var parameter = node.parameters[0];
            if (node.parameters.length !== 1) {
                if (parameter) {
                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter);
                }
                else {
                    return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter);
                }
            }
            if (parameter.dotDotDotToken) {
                return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.An_index_signature_cannot_have_a_rest_parameter);
            }
            if (ts.hasModifiers(parameter)) {
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier);
            }
            if (parameter.questionToken) {
                return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.An_index_signature_parameter_cannot_have_a_question_mark);
            }
            if (parameter.initializer) {
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_initializer);
            }
            if (!parameter.type) {
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_must_have_a_type_annotation);
            }
            if (parameter.type.kind !== 139 /* StringKeyword */ && parameter.type.kind !== 136 /* NumberKeyword */) {
                var type = getTypeFromTypeNode(parameter.type);
                if (type.flags & 4 /* String */ || type.flags & 8 /* Number */) {
                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead, ts.getTextOfNode(parameter.name), typeToString(type), typeToString(node.type ? getTypeFromTypeNode(node.type) : anyType));
                }
                if (type.flags & 1048576 /* Union */ && allTypesAssignableToKind(type, 128 /* StringLiteral */, /*strict*/ true)) {
                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead);
                }
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_type_must_be_string_or_number);
            }
            if (!node.type) {
                return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_a_type_annotation);
            }
            return false;
        }
        function checkGrammarIndexSignature(node) {
            // Prevent cascading error by short-circuit
            return checkGrammarDecoratorsAndModifiers(node) || checkGrammarIndexSignatureParameters(node);
        }
        function checkGrammarForAtLeastOneTypeArgument(node, typeArguments) {
            if (typeArguments && typeArguments.length === 0) {
                var sourceFile = ts.getSourceFileOfNode(node);
                var start = typeArguments.pos - "<".length;
                var end = ts.skipTrivia(sourceFile.text, typeArguments.end) + ">".length;
                return grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty);
            }
            return false;
        }
        function checkGrammarTypeArguments(node, typeArguments) {
            return checkGrammarForDisallowedTrailingComma(typeArguments) ||
                checkGrammarForAtLeastOneTypeArgument(node, typeArguments);
        }
        function checkGrammarForOmittedArgument(args) {
            if (args) {
                for (var _i = 0, args_4 = args; _i < args_4.length; _i++) {
                    var arg = args_4[_i];
                    if (arg.kind === 211 /* OmittedExpression */) {
                        return grammarErrorAtPos(arg, arg.pos, 0, ts.Diagnostics.Argument_expression_expected);
                    }
                }
            }
            return false;
        }
        function checkGrammarArguments(args) {
            return checkGrammarForOmittedArgument(args);
        }
        function checkGrammarHeritageClause(node) {
            var types = node.types;
            if (checkGrammarForDisallowedTrailingComma(types)) {
                return true;
            }
            if (types && types.length === 0) {
                var listType = ts.tokenToString(node.token);
                return grammarErrorAtPos(node, types.pos, 0, ts.Diagnostics._0_list_cannot_be_empty, listType);
            }
            return ts.some(types, checkGrammarExpressionWithTypeArguments);
        }
        function checkGrammarExpressionWithTypeArguments(node) {
            return checkGrammarTypeArguments(node, node.typeArguments);
        }
        function checkGrammarClassDeclarationHeritageClauses(node) {
            var seenExtendsClause = false;
            var seenImplementsClause = false;
            if (!checkGrammarDecoratorsAndModifiers(node) && node.heritageClauses) {
                for (var _i = 0, _a = node.heritageClauses; _i < _a.length; _i++) {
                    var heritageClause = _a[_i];
                    if (heritageClause.token === 87 /* ExtendsKeyword */) {
                        if (seenExtendsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_already_seen);
                        }
                        if (seenImplementsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_must_precede_implements_clause);
                        }
                        if (heritageClause.types.length > 1) {
                            return grammarErrorOnFirstToken(heritageClause.types[1], ts.Diagnostics.Classes_can_only_extend_a_single_class);
                        }
                        seenExtendsClause = true;
                    }
                    else {
                        ts.Debug.assert(heritageClause.token === 110 /* ImplementsKeyword */);
                        if (seenImplementsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.implements_clause_already_seen);
                        }
                        seenImplementsClause = true;
                    }
                    // Grammar checking heritageClause inside class declaration
                    checkGrammarHeritageClause(heritageClause);
                }
            }
        }
        function checkGrammarInterfaceDeclaration(node) {
            var seenExtendsClause = false;
            if (node.heritageClauses) {
                for (var _i = 0, _a = node.heritageClauses; _i < _a.length; _i++) {
                    var heritageClause = _a[_i];
                    if (heritageClause.token === 87 /* ExtendsKeyword */) {
                        if (seenExtendsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_already_seen);
                        }
                        seenExtendsClause = true;
                    }
                    else {
                        ts.Debug.assert(heritageClause.token === 110 /* ImplementsKeyword */);
                        return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.Interface_declaration_cannot_have_implements_clause);
                    }
                    // Grammar checking heritageClause inside class declaration
                    checkGrammarHeritageClause(heritageClause);
                }
            }
            return false;
        }
        function checkGrammarComputedPropertyName(node) {
            // If node is not a computedPropertyName, just skip the grammar checking
            if (node.kind !== 150 /* ComputedPropertyName */) {
                return false;
            }
            var computedPropertyName = node;
            if (computedPropertyName.expression.kind === 205 /* BinaryExpression */ && computedPropertyName.expression.operatorToken.kind === 27 /* CommaToken */) {
                return grammarErrorOnNode(computedPropertyName.expression, ts.Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name);
            }
            return false;
        }
        function checkGrammarForGenerator(node) {
            if (node.asteriskToken) {
                ts.Debug.assert(node.kind === 240 /* FunctionDeclaration */ ||
                    node.kind === 197 /* FunctionExpression */ ||
                    node.kind === 157 /* MethodDeclaration */);
                if (node.flags & 4194304 /* Ambient */) {
                    return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_not_allowed_in_an_ambient_context);
                }
                if (!node.body) {
                    return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.An_overload_signature_cannot_be_declared_as_a_generator);
                }
            }
        }
        function checkGrammarForInvalidQuestionMark(questionToken, message) {
            return !!questionToken && grammarErrorOnNode(questionToken, message);
        }
        function checkGrammarForInvalidExclamationToken(exclamationToken, message) {
            return !!exclamationToken && grammarErrorOnNode(exclamationToken, message);
        }
        function checkGrammarObjectLiteralExpression(node, inDestructuring) {
            var Flags;
            (function (Flags) {
                Flags[Flags["Property"] = 1] = "Property";
                Flags[Flags["GetAccessor"] = 2] = "GetAccessor";
                Flags[Flags["SetAccessor"] = 4] = "SetAccessor";
                Flags[Flags["GetOrSetAccessor"] = 6] = "GetOrSetAccessor";
            })(Flags || (Flags = {}));
            var seen = ts.createUnderscoreEscapedMap();
            for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                var prop = _a[_i];
                if (prop.kind === 278 /* SpreadAssignment */) {
                    if (inDestructuring) {
                        // a rest property cannot be destructured any further
                        var expression = ts.skipParentheses(prop.expression);
                        if (ts.isArrayLiteralExpression(expression) || ts.isObjectLiteralExpression(expression)) {
                            return grammarErrorOnNode(prop.expression, ts.Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
                        }
                    }
                    continue;
                }
                var name = prop.name;
                if (name.kind === 150 /* ComputedPropertyName */) {
                    // If the name is not a ComputedPropertyName, the grammar checking will skip it
                    checkGrammarComputedPropertyName(name);
                }
                if (prop.kind === 277 /* ShorthandPropertyAssignment */ && !inDestructuring && prop.objectAssignmentInitializer) {
                    // having objectAssignmentInitializer is only valid in ObjectAssignmentPattern
                    // outside of destructuring it is a syntax error
                    return grammarErrorOnNode(prop.equalsToken, ts.Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment);
                }
                // Modifiers are never allowed on properties except for 'async' on a method declaration
                if (prop.modifiers) {
                    for (var _b = 0, _c = prop.modifiers; _b < _c.length; _b++) { // TODO: GH#19955
                        var mod = _c[_b];
                        if (mod.kind !== 122 /* AsyncKeyword */ || prop.kind !== 157 /* MethodDeclaration */) {
                            grammarErrorOnNode(mod, ts.Diagnostics._0_modifier_cannot_be_used_here, ts.getTextOfNode(mod));
                        }
                    }
                }
                // ECMA-262 11.1.5 Object Initializer
                // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
                // a.This production is contained in strict code and IsDataDescriptor(previous) is true and
                // IsDataDescriptor(propId.descriptor) is true.
                //    b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
                //    c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
                //    d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
                // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
                var currentKind = void 0;
                switch (prop.kind) {
                    case 277 /* ShorthandPropertyAssignment */:
                        checkGrammarForInvalidExclamationToken(prop.exclamationToken, ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context);
                    /* tslint:disable:no-switch-case-fall-through */
                    case 276 /* PropertyAssignment */:
                        // Grammar checking for computedPropertyName and shorthandPropertyAssignment
                        checkGrammarForInvalidQuestionMark(prop.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional);
                        if (name.kind === 8 /* NumericLiteral */) {
                            checkGrammarNumericLiteral(name);
                        }
                    // falls through
                    case 157 /* MethodDeclaration */:
                        currentKind = 1 /* Property */;
                        break;
                    case 159 /* GetAccessor */:
                        currentKind = 2 /* GetAccessor */;
                        break;
                    case 160 /* SetAccessor */:
                        currentKind = 4 /* SetAccessor */;
                        break;
                    default:
                        throw ts.Debug.assertNever(prop, "Unexpected syntax kind:" + prop.kind);
                }
                var effectiveName = ts.getPropertyNameForPropertyNameNode(name);
                if (effectiveName === undefined) {
                    continue;
                }
                var existingKind = seen.get(effectiveName);
                if (!existingKind) {
                    seen.set(effectiveName, currentKind);
                }
                else {
                    if (currentKind === 1 /* Property */ && existingKind === 1 /* Property */) {
                        grammarErrorOnNode(name, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(name));
                    }
                    else if ((currentKind & 6 /* GetOrSetAccessor */) && (existingKind & 6 /* GetOrSetAccessor */)) {
                        if (existingKind !== 6 /* GetOrSetAccessor */ && currentKind !== existingKind) {
                            seen.set(effectiveName, currentKind | existingKind);
                        }
                        else {
                            return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name);
                        }
                    }
                    else {
                        return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name);
                    }
                }
            }
        }
        function checkGrammarJsxElement(node) {
            checkGrammarTypeArguments(node, node.typeArguments);
            var seen = ts.createUnderscoreEscapedMap();
            for (var _i = 0, _a = node.attributes.properties; _i < _a.length; _i++) {
                var attr = _a[_i];
                if (attr.kind === 270 /* JsxSpreadAttribute */) {
                    continue;
                }
                var name = attr.name, initializer = attr.initializer;
                if (!seen.get(name.escapedText)) {
                    seen.set(name.escapedText, true);
                }
                else {
                    return grammarErrorOnNode(name, ts.Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name);
                }
                if (initializer && initializer.kind === 271 /* JsxExpression */ && !initializer.expression) {
                    return grammarErrorOnNode(initializer, ts.Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression);
                }
            }
        }
        function checkGrammarForInOrForOfStatement(forInOrOfStatement) {
            if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) {
                return true;
            }
            if (forInOrOfStatement.kind === 228 /* ForOfStatement */ && forInOrOfStatement.awaitModifier) {
                if ((forInOrOfStatement.flags & 16384 /* AwaitContext */) === 0 /* None */) {
                    // use of 'for-await-of' in non-async function
                    var sourceFile = ts.getSourceFileOfNode(forInOrOfStatement);
                    if (!hasParseDiagnostics(sourceFile)) {
                        var diagnostic = ts.createDiagnosticForNode(forInOrOfStatement.awaitModifier, ts.Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator);
                        var func = ts.getContainingFunction(forInOrOfStatement);
                        if (func && func.kind !== 158 /* Constructor */) {
                            ts.Debug.assert((ts.getFunctionFlags(func) & 2 /* Async */) === 0, "Enclosing function should never be an async function.");
                            var relatedInfo = ts.createDiagnosticForNode(func, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async);
                            ts.addRelatedInfo(diagnostic, relatedInfo);
                        }
                        diagnostics.add(diagnostic);
                        return true;
                    }
                    return false;
                }
            }
            if (forInOrOfStatement.initializer.kind === 239 /* VariableDeclarationList */) {
                var variableList = forInOrOfStatement.initializer;
                if (!checkGrammarVariableDeclarationList(variableList)) {
                    var declarations = variableList.declarations;
                    // declarations.length can be zero if there is an error in variable declaration in for-of or for-in
                    // See http://www.ecma-international.org/ecma-262/6.0/#sec-for-in-and-for-of-statements for details
                    // For example:
                    //      var let = 10;
                    //      for (let of [1,2,3]) {} // this is invalid ES6 syntax
                    //      for (let in [1,2,3]) {} // this is invalid ES6 syntax
                    // We will then want to skip on grammar checking on variableList declaration
                    if (!declarations.length) {
                        return false;
                    }
                    if (declarations.length > 1) {
                        var diagnostic = forInOrOfStatement.kind === 227 /* ForInStatement */
                            ? ts.Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement
                            : ts.Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement;
                        return grammarErrorOnFirstToken(variableList.declarations[1], diagnostic);
                    }
                    var firstDeclaration = declarations[0];
                    if (firstDeclaration.initializer) {
                        var diagnostic = forInOrOfStatement.kind === 227 /* ForInStatement */
                            ? ts.Diagnostics.The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer
                            : ts.Diagnostics.The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer;
                        return grammarErrorOnNode(firstDeclaration.name, diagnostic);
                    }
                    if (firstDeclaration.type) {
                        var diagnostic = forInOrOfStatement.kind === 227 /* ForInStatement */
                            ? ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation
                            : ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation;
                        return grammarErrorOnNode(firstDeclaration, diagnostic);
                    }
                }
            }
            return false;
        }
        function checkGrammarAccessor(accessor) {
            var kind = accessor.kind;
            if (languageVersion < 1 /* ES5 */) {
                return grammarErrorOnNode(accessor.name, ts.Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher);
            }
            else if (accessor.flags & 4194304 /* Ambient */) {
                return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context);
            }
            else if (accessor.body === undefined && !ts.hasModifier(accessor, 128 /* Abstract */)) {
                return grammarErrorAtPos(accessor, accessor.end - 1, ";".length, ts.Diagnostics._0_expected, "{");
            }
            else if (accessor.body && ts.hasModifier(accessor, 128 /* Abstract */)) {
                return grammarErrorOnNode(accessor, ts.Diagnostics.An_abstract_accessor_cannot_have_an_implementation);
            }
            else if (accessor.typeParameters) {
                return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_have_type_parameters);
            }
            else if (!doesAccessorHaveCorrectParameterCount(accessor)) {
                return grammarErrorOnNode(accessor.name, kind === 159 /* GetAccessor */ ?
                    ts.Diagnostics.A_get_accessor_cannot_have_parameters :
                    ts.Diagnostics.A_set_accessor_must_have_exactly_one_parameter);
            }
            else if (kind === 160 /* SetAccessor */) {
                if (accessor.type) {
                    return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_cannot_have_a_return_type_annotation);
                }
                else {
                    var parameter = accessor.parameters[0];
                    if (parameter.dotDotDotToken) {
                        return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.A_set_accessor_cannot_have_rest_parameter);
                    }
                    else if (parameter.questionToken) {
                        return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.A_set_accessor_cannot_have_an_optional_parameter);
                    }
                    else if (parameter.initializer) {
                        return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_parameter_cannot_have_an_initializer);
                    }
                }
            }
            return false;
        }
        /** Does the accessor have the right number of parameters?
         * A get accessor has no parameters or a single `this` parameter.
         * A set accessor has one parameter or a `this` parameter and one more parameter.
         */
        function doesAccessorHaveCorrectParameterCount(accessor) {
            return getAccessorThisParameter(accessor) || accessor.parameters.length === (accessor.kind === 159 /* GetAccessor */ ? 0 : 1);
        }
        function getAccessorThisParameter(accessor) {
            if (accessor.parameters.length === (accessor.kind === 159 /* GetAccessor */ ? 1 : 2)) {
                return ts.getThisParameter(accessor);
            }
        }
        function checkGrammarTypeOperatorNode(node) {
            if (node.operator === 143 /* UniqueKeyword */) {
                if (node.type.kind !== 140 /* SymbolKeyword */) {
                    return grammarErrorOnNode(node.type, ts.Diagnostics._0_expected, ts.tokenToString(140 /* SymbolKeyword */));
                }
                var parent = ts.walkUpParenthesizedTypes(node.parent);
                switch (parent.kind) {
                    case 238 /* VariableDeclaration */:
                        var decl = parent;
                        if (decl.name.kind !== 73 /* Identifier */) {
                            return grammarErrorOnNode(node, ts.Diagnostics.unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name);
                        }
                        if (!ts.isVariableDeclarationInVariableStatement(decl)) {
                            return grammarErrorOnNode(node, ts.Diagnostics.unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement);
                        }
                        if (!(decl.parent.flags & 2 /* Const */)) {
                            return grammarErrorOnNode(parent.name, ts.Diagnostics.A_variable_whose_type_is_a_unique_symbol_type_must_be_const);
                        }
                        break;
                    case 155 /* PropertyDeclaration */:
                        if (!ts.hasModifier(parent, 32 /* Static */) ||
                            !ts.hasModifier(parent, 64 /* Readonly */)) {
                            return grammarErrorOnNode(parent.name, ts.Diagnostics.A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly);
                        }
                        break;
                    case 154 /* PropertySignature */:
                        if (!ts.hasModifier(parent, 64 /* Readonly */)) {
                            return grammarErrorOnNode(parent.name, ts.Diagnostics.A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly);
                        }
                        break;
                    default:
                        return grammarErrorOnNode(node, ts.Diagnostics.unique_symbol_types_are_not_allowed_here);
                }
            }
            else if (node.operator === 134 /* ReadonlyKeyword */) {
                if (node.type.kind !== 170 /* ArrayType */ && node.type.kind !== 171 /* TupleType */) {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.readonly_type_modifier_is_only_permitted_on_array_and_tuple_literal_types, ts.tokenToString(140 /* SymbolKeyword */));
                }
            }
        }
        function checkGrammarForInvalidDynamicName(node, message) {
            if (isNonBindableDynamicName(node)) {
                return grammarErrorOnNode(node, message);
            }
        }
        function checkGrammarMethod(node) {
            if (checkGrammarFunctionLikeDeclaration(node)) {
                return true;
            }
            if (node.kind === 157 /* MethodDeclaration */) {
                if (node.parent.kind === 189 /* ObjectLiteralExpression */) {
                    // We only disallow modifier on a method declaration if it is a property of object-literal-expression
                    if (node.modifiers && !(node.modifiers.length === 1 && ts.first(node.modifiers).kind === 122 /* AsyncKeyword */)) {
                        return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here);
                    }
                    else if (checkGrammarForInvalidQuestionMark(node.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional)) {
                        return true;
                    }
                    else if (checkGrammarForInvalidExclamationToken(node.exclamationToken, ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context)) {
                        return true;
                    }
                    else if (node.body === undefined) {
                        return grammarErrorAtPos(node, node.end - 1, ";".length, ts.Diagnostics._0_expected, "{");
                    }
                }
                else if (ts.isClassLike(node.parent) && ts.isStringLiteral(node.name) && node.name.text === "constructor" && (!compilerOptions.target || compilerOptions.target < 1 /* ES5 */)) {
                    return grammarErrorOnNode(node.name, ts.Diagnostics.Quoted_constructors_have_previously_been_interpreted_as_methods_which_is_incorrect_In_TypeScript_3_6_they_will_be_correctly_parsed_as_constructors_In_the_meantime_consider_using_constructor_to_write_a_constructor_or_constructor_to_write_a_method);
                }
                if (checkGrammarForGenerator(node)) {
                    return true;
                }
            }
            if (ts.isClassLike(node.parent)) {
                // Technically, computed properties in ambient contexts is disallowed
                // for property declarations and accessors too, not just methods.
                // However, property declarations disallow computed names in general,
                // and accessors are not allowed in ambient contexts in general,
                // so this error only really matters for methods.
                if (node.flags & 4194304 /* Ambient */) {
                    return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
                }
                else if (node.kind === 157 /* MethodDeclaration */ && !node.body) {
                    return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
                }
            }
            else if (node.parent.kind === 242 /* InterfaceDeclaration */) {
                return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
            }
            else if (node.parent.kind === 169 /* TypeLiteral */) {
                return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
            }
        }
        function checkGrammarBreakOrContinueStatement(node) {
            var current = node;
            while (current) {
                if (ts.isFunctionLike(current)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.Jump_target_cannot_cross_function_boundary);
                }
                switch (current.kind) {
                    case 234 /* LabeledStatement */:
                        if (node.label && current.label.escapedText === node.label.escapedText) {
                            // found matching label - verify that label usage is correct
                            // continue can only target labels that are on iteration statements
                            var isMisplacedContinueLabel = node.kind === 229 /* ContinueStatement */
                                && !ts.isIterationStatement(current.statement, /*lookInLabeledStatement*/ true);
                            if (isMisplacedContinueLabel) {
                                return grammarErrorOnNode(node, ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement);
                            }
                            return false;
                        }
                        break;
                    case 233 /* SwitchStatement */:
                        if (node.kind === 230 /* BreakStatement */ && !node.label) {
                            // unlabeled break within switch statement - ok
                            return false;
                        }
                        break;
                    default:
                        if (ts.isIterationStatement(current, /*lookInLabeledStatement*/ false) && !node.label) {
                            // unlabeled break or continue within iteration statement - ok
                            return false;
                        }
                        break;
                }
                current = current.parent;
            }
            if (node.label) {
                var message = node.kind === 230 /* BreakStatement */
                    ? ts.Diagnostics.A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement
                    : ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement;
                return grammarErrorOnNode(node, message);
            }
            else {
                var message = node.kind === 230 /* BreakStatement */
                    ? ts.Diagnostics.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement
                    : ts.Diagnostics.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement;
                return grammarErrorOnNode(node, message);
            }
        }
        function checkGrammarBindingElement(node) {
            if (node.dotDotDotToken) {
                var elements = node.parent.elements;
                if (node !== ts.last(elements)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
                }
                checkGrammarForDisallowedTrailingComma(elements, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
                if (node.propertyName) {
                    return grammarErrorOnNode(node.name, ts.Diagnostics.A_rest_element_cannot_have_a_property_name);
                }
                if (node.initializer) {
                    // Error on equals token which immediately precedes the initializer
                    return grammarErrorAtPos(node, node.initializer.pos - 1, 1, ts.Diagnostics.A_rest_element_cannot_have_an_initializer);
                }
            }
        }
        function isStringOrNumberLiteralExpression(expr) {
            return expr.kind === 10 /* StringLiteral */ || expr.kind === 8 /* NumericLiteral */ ||
                expr.kind === 203 /* PrefixUnaryExpression */ && expr.operator === 39 /* MinusToken */ &&
                    expr.operand.kind === 8 /* NumericLiteral */;
        }
        function isBigIntLiteralExpression(expr) {
            return expr.kind === 9 /* BigIntLiteral */ ||
                expr.kind === 203 /* PrefixUnaryExpression */ && expr.operator === 39 /* MinusToken */ &&
                    expr.operand.kind === 9 /* BigIntLiteral */;
        }
        function isSimpleLiteralEnumReference(expr) {
            if ((ts.isPropertyAccessExpression(expr) || (ts.isElementAccessExpression(expr) && isStringOrNumberLiteralExpression(expr.argumentExpression))) &&
                ts.isEntityNameExpression(expr.expression))
                return !!(checkExpressionCached(expr).flags & 1024 /* EnumLiteral */);
        }
        function checkAmbientInitializer(node) {
            var initializer = node.initializer;
            if (initializer) {
                var isInvalidInitializer = !(isStringOrNumberLiteralExpression(initializer) ||
                    isSimpleLiteralEnumReference(initializer) ||
                    initializer.kind === 103 /* TrueKeyword */ || initializer.kind === 88 /* FalseKeyword */ ||
                    isBigIntLiteralExpression(initializer));
                var isConstOrReadonly = ts.isDeclarationReadonly(node) || ts.isVariableDeclaration(node) && ts.isVarConst(node);
                if (isConstOrReadonly && !node.type) {
                    if (isInvalidInitializer) {
                        return grammarErrorOnNode(initializer, ts.Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_reference);
                    }
                }
                else {
                    return grammarErrorOnNode(initializer, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
                }
                if (!isConstOrReadonly || isInvalidInitializer) {
                    return grammarErrorOnNode(initializer, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
                }
            }
        }
        function checkGrammarVariableDeclaration(node) {
            if (node.parent.parent.kind !== 227 /* ForInStatement */ && node.parent.parent.kind !== 228 /* ForOfStatement */) {
                if (node.flags & 4194304 /* Ambient */) {
                    checkAmbientInitializer(node);
                }
                else if (!node.initializer) {
                    if (ts.isBindingPattern(node.name) && !ts.isBindingPattern(node.parent)) {
                        return grammarErrorOnNode(node, ts.Diagnostics.A_destructuring_declaration_must_have_an_initializer);
                    }
                    if (ts.isVarConst(node)) {
                        return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_must_be_initialized);
                    }
                }
            }
            if (node.exclamationToken && (node.parent.parent.kind !== 220 /* VariableStatement */ || !node.type || node.initializer || node.flags & 4194304 /* Ambient */)) {
                return grammarErrorOnNode(node.exclamationToken, ts.Diagnostics.Definite_assignment_assertions_can_only_be_used_along_with_a_type_annotation);
            }
            if (compilerOptions.module !== ts.ModuleKind.ES2015 && compilerOptions.module !== ts.ModuleKind.ESNext && compilerOptions.module !== ts.ModuleKind.System && !compilerOptions.noEmit &&
                !(node.parent.parent.flags & 4194304 /* Ambient */) && ts.hasModifier(node.parent.parent, 1 /* Export */)) {
                checkESModuleMarker(node.name);
            }
            var checkLetConstNames = (ts.isLet(node) || ts.isVarConst(node));
            // 1. LexicalDeclaration : LetOrConst BindingList ;
            // It is a Syntax Error if the BoundNames of BindingList contains "let".
            // 2. ForDeclaration: ForDeclaration : LetOrConst ForBinding
            // It is a Syntax Error if the BoundNames of ForDeclaration contains "let".
            // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code
            // and its Identifier is eval or arguments
            return checkLetConstNames && checkGrammarNameInLetOrConstDeclarations(node.name);
        }
        function checkESModuleMarker(name) {
            if (name.kind === 73 /* Identifier */) {
                if (ts.idText(name) === "__esModule") {
                    return grammarErrorOnNode(name, ts.Diagnostics.Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules);
                }
            }
            else {
                var elements = name.elements;
                for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
                    var element = elements_1[_i];
                    if (!ts.isOmittedExpression(element)) {
                        return checkESModuleMarker(element.name);
                    }
                }
            }
            return false;
        }
        function checkGrammarNameInLetOrConstDeclarations(name) {
            if (name.kind === 73 /* Identifier */) {
                if (name.originalKeywordKind === 112 /* LetKeyword */) {
                    return grammarErrorOnNode(name, ts.Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations);
                }
            }
            else {
                var elements = name.elements;
                for (var _i = 0, elements_2 = elements; _i < elements_2.length; _i++) {
                    var element = elements_2[_i];
                    if (!ts.isOmittedExpression(element)) {
                        checkGrammarNameInLetOrConstDeclarations(element.name);
                    }
                }
            }
            return false;
        }
        function checkGrammarVariableDeclarationList(declarationList) {
            var declarations = declarationList.declarations;
            if (checkGrammarForDisallowedTrailingComma(declarationList.declarations)) {
                return true;
            }
            if (!declarationList.declarations.length) {
                return grammarErrorAtPos(declarationList, declarations.pos, declarations.end - declarations.pos, ts.Diagnostics.Variable_declaration_list_cannot_be_empty);
            }
            return false;
        }
        function allowLetAndConstDeclarations(parent) {
            switch (parent.kind) {
                case 223 /* IfStatement */:
                case 224 /* DoStatement */:
                case 225 /* WhileStatement */:
                case 232 /* WithStatement */:
                case 226 /* ForStatement */:
                case 227 /* ForInStatement */:
                case 228 /* ForOfStatement */:
                    return false;
                case 234 /* LabeledStatement */:
                    return allowLetAndConstDeclarations(parent.parent);
            }
            return true;
        }
        function checkGrammarForDisallowedLetOrConstStatement(node) {
            if (!allowLetAndConstDeclarations(node.parent)) {
                if (ts.isLet(node.declarationList)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.let_declarations_can_only_be_declared_inside_a_block);
                }
                else if (ts.isVarConst(node.declarationList)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_can_only_be_declared_inside_a_block);
                }
            }
        }
        function checkGrammarMetaProperty(node) {
            var escapedText = node.name.escapedText;
            switch (node.keywordToken) {
                case 96 /* NewKeyword */:
                    if (escapedText !== "target") {
                        return grammarErrorOnNode(node.name, ts.Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, ts.tokenToString(node.keywordToken), "target");
                    }
                    break;
                case 93 /* ImportKeyword */:
                    if (escapedText !== "meta") {
                        return grammarErrorOnNode(node.name, ts.Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, ts.tokenToString(node.keywordToken), "meta");
                    }
                    break;
            }
        }
        function hasParseDiagnostics(sourceFile) {
            return sourceFile.parseDiagnostics.length > 0;
        }
        function grammarErrorOnFirstToken(node, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                diagnostics.add(ts.createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2));
                return true;
            }
            return false;
        }
        function grammarErrorAtPos(nodeForSourceFile, start, length, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(nodeForSourceFile);
            if (!hasParseDiagnostics(sourceFile)) {
                diagnostics.add(ts.createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2));
                return true;
            }
            return false;
        }
        function grammarErrorOnNode(node, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                diagnostics.add(ts.createDiagnosticForNode(node, message, arg0, arg1, arg2));
                return true;
            }
            return false;
        }
        function checkGrammarConstructorTypeParameters(node) {
            var jsdocTypeParameters = ts.isInJSFile(node) ? ts.getJSDocTypeParameterDeclarations(node) : undefined;
            var range = node.typeParameters || jsdocTypeParameters && ts.firstOrUndefined(jsdocTypeParameters);
            if (range) {
                var pos = range.pos === range.end ? range.pos : ts.skipTrivia(ts.getSourceFileOfNode(node).text, range.pos);
                return grammarErrorAtPos(node, pos, range.end - pos, ts.Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration);
            }
        }
        function checkGrammarConstructorTypeAnnotation(node) {
            var type = ts.getEffectiveReturnTypeNode(node);
            if (type) {
                return grammarErrorOnNode(type, ts.Diagnostics.Type_annotation_cannot_appear_on_a_constructor_declaration);
            }
        }
        function checkGrammarProperty(node) {
            if (ts.isClassLike(node.parent)) {
                if (ts.isStringLiteral(node.name) && node.name.text === "constructor") {
                    return grammarErrorOnNode(node.name, ts.Diagnostics.Classes_may_not_have_a_field_named_constructor);
                }
                if (checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) {
                    return true;
                }
            }
            else if (node.parent.kind === 242 /* InterfaceDeclaration */) {
                if (checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) {
                    return true;
                }
                if (node.initializer) {
                    return grammarErrorOnNode(node.initializer, ts.Diagnostics.An_interface_property_cannot_have_an_initializer);
                }
            }
            else if (node.parent.kind === 169 /* TypeLiteral */) {
                if (checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) {
                    return true;
                }
                if (node.initializer) {
                    return grammarErrorOnNode(node.initializer, ts.Diagnostics.A_type_literal_property_cannot_have_an_initializer);
                }
            }
            if (node.flags & 4194304 /* Ambient */) {
                checkAmbientInitializer(node);
            }
            if (ts.isPropertyDeclaration(node) && node.exclamationToken && (!ts.isClassLike(node.parent) || !node.type || node.initializer ||
                node.flags & 4194304 /* Ambient */ || ts.hasModifier(node, 32 /* Static */ | 128 /* Abstract */))) {
                return grammarErrorOnNode(node.exclamationToken, ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context);
            }
        }
        function checkGrammarTopLevelElementForRequiredDeclareModifier(node) {
            // A declare modifier is required for any top level .d.ts declaration except export=, export default, export as namespace
            // interfaces and imports categories:
            //
            //  DeclarationElement:
            //     ExportAssignment
            //     export_opt   InterfaceDeclaration
            //     export_opt   TypeAliasDeclaration
            //     export_opt   ImportDeclaration
            //     export_opt   ExternalImportDeclaration
            //     export_opt   AmbientDeclaration
            //
            // TODO: The spec needs to be amended to reflect this grammar.
            if (node.kind === 242 /* InterfaceDeclaration */ ||
                node.kind === 243 /* TypeAliasDeclaration */ ||
                node.kind === 250 /* ImportDeclaration */ ||
                node.kind === 249 /* ImportEqualsDeclaration */ ||
                node.kind === 256 /* ExportDeclaration */ ||
                node.kind === 255 /* ExportAssignment */ ||
                node.kind === 248 /* NamespaceExportDeclaration */ ||
                ts.hasModifier(node, 2 /* Ambient */ | 1 /* Export */ | 512 /* Default */)) {
                return false;
            }
            return grammarErrorOnFirstToken(node, ts.Diagnostics.Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier);
        }
        function checkGrammarTopLevelElementsForRequiredDeclareModifier(file) {
            for (var _i = 0, _a = file.statements; _i < _a.length; _i++) {
                var decl = _a[_i];
                if (ts.isDeclaration(decl) || decl.kind === 220 /* VariableStatement */) {
                    if (checkGrammarTopLevelElementForRequiredDeclareModifier(decl)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function checkGrammarSourceFile(node) {
            return !!(node.flags & 4194304 /* Ambient */) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node);
        }
        function checkGrammarStatementInAmbientContext(node) {
            if (node.flags & 4194304 /* Ambient */) {
                // An accessors is already reported about the ambient context
                if (ts.isAccessor(node.parent)) {
                    return getNodeLinks(node).hasReportedStatementInAmbientContext = true;
                }
                // Find containing block which is either Block, ModuleBlock, SourceFile
                var links = getNodeLinks(node);
                if (!links.hasReportedStatementInAmbientContext && ts.isFunctionLike(node.parent)) {
                    return getNodeLinks(node).hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, ts.Diagnostics.An_implementation_cannot_be_declared_in_ambient_contexts);
                }
                // We are either parented by another statement, or some sort of block.
                // If we're in a block, we only want to really report an error once
                // to prevent noisiness.  So use a bit on the block to indicate if
                // this has already been reported, and don't report if it has.
                //
                if (node.parent.kind === 219 /* Block */ || node.parent.kind === 246 /* ModuleBlock */ || node.parent.kind === 285 /* SourceFile */) {
                    var links_2 = getNodeLinks(node.parent);
                    // Check if the containing block ever report this error
                    if (!links_2.hasReportedStatementInAmbientContext) {
                        return links_2.hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, ts.Diagnostics.Statements_are_not_allowed_in_ambient_contexts);
                    }
                }
                else {
                    // We must be parented by a statement.  If so, there's no need
                    // to report the error as our parent will have already done it.
                    // Debug.assert(isStatement(node.parent));
                }
            }
            return false;
        }
        function checkGrammarNumericLiteral(node) {
            // Grammar checking
            if (node.numericLiteralFlags & 32 /* Octal */) {
                var diagnosticMessage = void 0;
                if (languageVersion >= 1 /* ES5 */) {
                    diagnosticMessage = ts.Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0;
                }
                else if (ts.isChildOfNodeWithKind(node, 183 /* LiteralType */)) {
                    diagnosticMessage = ts.Diagnostics.Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0;
                }
                else if (ts.isChildOfNodeWithKind(node, 279 /* EnumMember */)) {
                    diagnosticMessage = ts.Diagnostics.Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0;
                }
                if (diagnosticMessage) {
                    var withMinus = ts.isPrefixUnaryExpression(node.parent) && node.parent.operator === 39 /* MinusToken */;
                    var literal = (withMinus ? "-" : "") + "0o" + node.text;
                    return grammarErrorOnNode(withMinus ? node.parent : node, diagnosticMessage, literal);
                }
            }
            return false;
        }
        function checkGrammarBigIntLiteral(node) {
            var literalType = ts.isLiteralTypeNode(node.parent) ||
                ts.isPrefixUnaryExpression(node.parent) && ts.isLiteralTypeNode(node.parent.parent);
            if (!literalType) {
                if (languageVersion < 8 /* ESNext */) {
                    if (grammarErrorOnNode(node, ts.Diagnostics.BigInt_literals_are_not_available_when_targeting_lower_than_ESNext)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function grammarErrorAfterFirstToken(node, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                diagnostics.add(ts.createFileDiagnostic(sourceFile, ts.textSpanEnd(span), /*length*/ 0, message, arg0, arg1, arg2));
                return true;
            }
            return false;
        }
        function getAmbientModules() {
            if (!ambientModulesCache) {
                ambientModulesCache = [];
                globals.forEach(function (global, sym) {
                    // No need to `unescapeLeadingUnderscores`, an escaped symbol is never an ambient module.
                    if (ambientModuleSymbolRegex.test(sym)) {
                        ambientModulesCache.push(global);
                    }
                });
            }
            return ambientModulesCache;
        }
        function checkGrammarImportCallExpression(node) {
            if (moduleKind === ts.ModuleKind.ES2015) {
                return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_is_only_supported_when_module_flag_is_commonjs_or_esNext);
            }
            if (node.typeArguments) {
                return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_cannot_have_type_arguments);
            }
            var nodeArguments = node.arguments;
            if (nodeArguments.length !== 1) {
                return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_must_have_one_specifier_as_an_argument);
            }
            checkGrammarForDisallowedTrailingComma(nodeArguments);
            // see: parseArgumentOrArrayLiteralElement...we use this function which parse arguments of callExpression to parse specifier for dynamic import.
            // parseArgumentOrArrayLiteralElement allows spread element to be in an argument list which is not allowed as specifier in dynamic import.
            if (ts.isSpreadElement(nodeArguments[0])) {
                return grammarErrorOnNode(nodeArguments[0], ts.Diagnostics.Specifier_of_dynamic_import_cannot_be_spread_element);
            }
            return false;
        }
    }
    ts.createTypeChecker = createTypeChecker;
    /** Like 'isDeclarationName', but returns true for LHS of `import { x as y }` or `export { x as y }`. */
    function isDeclarationNameOrImportPropertyName(name) {
        switch (name.parent.kind) {
            case 254 /* ImportSpecifier */:
            case 258 /* ExportSpecifier */:
                return ts.isIdentifier(name);
            default:
                return ts.isDeclarationName(name);
        }
    }
    function isSomeImportDeclaration(decl) {
        switch (decl.kind) {
            case 251 /* ImportClause */: // For default import
            case 249 /* ImportEqualsDeclaration */:
            case 252 /* NamespaceImport */:
            case 254 /* ImportSpecifier */: // For rename import `x as y`
                return true;
            case 73 /* Identifier */:
                // For regular import, `decl` is an Identifier under the ImportSpecifier.
                return decl.parent.kind === 254 /* ImportSpecifier */;
            default:
                return false;
        }
    }
    var JsxNames;
    (function (JsxNames) {
        // tslint:disable variable-name
        JsxNames.JSX = "JSX";
        JsxNames.IntrinsicElements = "IntrinsicElements";
        JsxNames.ElementClass = "ElementClass";
        JsxNames.ElementAttributesPropertyNameContainer = "ElementAttributesProperty"; // TODO: Deprecate and remove support
        JsxNames.ElementChildrenAttributeNameContainer = "ElementChildrenAttribute";
        JsxNames.Element = "Element";
        JsxNames.IntrinsicAttributes = "IntrinsicAttributes";
        JsxNames.IntrinsicClassAttributes = "IntrinsicClassAttributes";
        JsxNames.LibraryManagedAttributes = "LibraryManagedAttributes";
        // tslint:enable variable-name
    })(JsxNames || (JsxNames = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    function createSynthesizedNode(kind) {
        var node = ts.createNode(kind, -1, -1);
        node.flags |= 8 /* Synthesized */;
        return node;
    }
    /* @internal */
    function updateNode(updated, original) {
        if (updated !== original) {
            setOriginalNode(updated, original);
            setTextRange(updated, original);
            ts.aggregateTransformFlags(updated);
        }
        return updated;
    }
    ts.updateNode = updateNode;
    /**
     * Make `elements` into a `NodeArray<T>`. If `elements` is `undefined`, returns an empty `NodeArray<T>`.
     */
    function createNodeArray(elements, hasTrailingComma) {
        if (!elements || elements === ts.emptyArray) {
            elements = [];
        }
        else if (ts.isNodeArray(elements)) {
            return elements;
        }
        var array = elements;
        array.pos = -1;
        array.end = -1;
        array.hasTrailingComma = hasTrailingComma;
        return array;
    }
    ts.createNodeArray = createNodeArray;
    /**
     * Creates a shallow, memberwise clone of a node with no source map location.
     */
    /* @internal */
    function getSynthesizedClone(node) {
        // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of
        // the original node. We also need to exclude specific properties and only include own-
        // properties (to skip members already defined on the shared prototype).
        if (node === undefined) {
            return node;
        }
        var clone = createSynthesizedNode(node.kind);
        clone.flags |= node.flags;
        setOriginalNode(clone, node);
        for (var key in node) {
            if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) {
                continue;
            }
            clone[key] = node[key];
        }
        return clone;
    }
    ts.getSynthesizedClone = getSynthesizedClone;
    function createLiteral(value, isSingleQuote) {
        if (typeof value === "number") {
            return createNumericLiteral(value + "");
        }
        if (typeof value === "object" && "base10Value" in value) { // PseudoBigInt
            return createBigIntLiteral(ts.pseudoBigIntToString(value) + "n");
        }
        if (typeof value === "boolean") {
            return value ? createTrue() : createFalse();
        }
        if (ts.isString(value)) {
            var res = createStringLiteral(value);
            if (isSingleQuote)
                res.singleQuote = true;
            return res;
        }
        return createLiteralFromNode(value);
    }
    ts.createLiteral = createLiteral;
    function createNumericLiteral(value, numericLiteralFlags) {
        if (numericLiteralFlags === void 0) { numericLiteralFlags = 0 /* None */; }
        var node = createSynthesizedNode(8 /* NumericLiteral */);
        node.text = value;
        node.numericLiteralFlags = numericLiteralFlags;
        return node;
    }
    ts.createNumericLiteral = createNumericLiteral;
    function createBigIntLiteral(value) {
        var node = createSynthesizedNode(9 /* BigIntLiteral */);
        node.text = value;
        return node;
    }
    ts.createBigIntLiteral = createBigIntLiteral;
    function createStringLiteral(text) {
        var node = createSynthesizedNode(10 /* StringLiteral */);
        node.text = text;
        return node;
    }
    ts.createStringLiteral = createStringLiteral;
    function createRegularExpressionLiteral(text) {
        var node = createSynthesizedNode(13 /* RegularExpressionLiteral */);
        node.text = text;
        return node;
    }
    ts.createRegularExpressionLiteral = createRegularExpressionLiteral;
    function createLiteralFromNode(sourceNode) {
        var node = createStringLiteral(ts.getTextOfIdentifierOrLiteral(sourceNode));
        node.textSourceNode = sourceNode;
        return node;
    }
    function createIdentifier(text, typeArguments) {
        var node = createSynthesizedNode(73 /* Identifier */);
        node.escapedText = ts.escapeLeadingUnderscores(text);
        node.originalKeywordKind = text ? ts.stringToToken(text) : 0 /* Unknown */;
        node.autoGenerateFlags = 0 /* None */;
        node.autoGenerateId = 0;
        if (typeArguments) {
            node.typeArguments = createNodeArray(typeArguments);
        }
        return node;
    }
    ts.createIdentifier = createIdentifier;
    function updateIdentifier(node, typeArguments) {
        return node.typeArguments !== typeArguments
            ? updateNode(createIdentifier(ts.idText(node), typeArguments), node)
            : node;
    }
    ts.updateIdentifier = updateIdentifier;
    var nextAutoGenerateId = 0;
    function createTempVariable(recordTempVariable, reservedInNestedScopes) {
        var name = createIdentifier("");
        name.autoGenerateFlags = 1 /* Auto */;
        name.autoGenerateId = nextAutoGenerateId;
        nextAutoGenerateId++;
        if (recordTempVariable) {
            recordTempVariable(name);
        }
        if (reservedInNestedScopes) {
            name.autoGenerateFlags |= 8 /* ReservedInNestedScopes */;
        }
        return name;
    }
    ts.createTempVariable = createTempVariable;
    /** Create a unique temporary variable for use in a loop. */
    function createLoopVariable() {
        var name = createIdentifier("");
        name.autoGenerateFlags = 2 /* Loop */;
        name.autoGenerateId = nextAutoGenerateId;
        nextAutoGenerateId++;
        return name;
    }
    ts.createLoopVariable = createLoopVariable;
    /** Create a unique name based on the supplied text. */
    function createUniqueName(text) {
        var name = createIdentifier(text);
        name.autoGenerateFlags = 3 /* Unique */;
        name.autoGenerateId = nextAutoGenerateId;
        nextAutoGenerateId++;
        return name;
    }
    ts.createUniqueName = createUniqueName;
    function createOptimisticUniqueName(text) {
        var name = createIdentifier(text);
        name.autoGenerateFlags = 3 /* Unique */ | 16 /* Optimistic */;
        name.autoGenerateId = nextAutoGenerateId;
        nextAutoGenerateId++;
        return name;
    }
    ts.createOptimisticUniqueName = createOptimisticUniqueName;
    /** Create a unique name based on the supplied text. This does not consider names injected by the transformer. */
    function createFileLevelUniqueName(text) {
        var name = createOptimisticUniqueName(text);
        name.autoGenerateFlags |= 32 /* FileLevel */;
        return name;
    }
    ts.createFileLevelUniqueName = createFileLevelUniqueName;
    function getGeneratedNameForNode(node, flags) {
        var name = createIdentifier(node && ts.isIdentifier(node) ? ts.idText(node) : "");
        name.autoGenerateFlags = 4 /* Node */ | flags;
        name.autoGenerateId = nextAutoGenerateId;
        name.original = node;
        nextAutoGenerateId++;
        return name;
    }
    ts.getGeneratedNameForNode = getGeneratedNameForNode;
    // Punctuation
    function createToken(token) {
        return createSynthesizedNode(token);
    }
    ts.createToken = createToken;
    // Reserved words
    function createSuper() {
        return createSynthesizedNode(99 /* SuperKeyword */);
    }
    ts.createSuper = createSuper;
    function createThis() {
        return createSynthesizedNode(101 /* ThisKeyword */);
    }
    ts.createThis = createThis;
    function createNull() {
        return createSynthesizedNode(97 /* NullKeyword */);
    }
    ts.createNull = createNull;
    function createTrue() {
        return createSynthesizedNode(103 /* TrueKeyword */);
    }
    ts.createTrue = createTrue;
    function createFalse() {
        return createSynthesizedNode(88 /* FalseKeyword */);
    }
    ts.createFalse = createFalse;
    // Modifiers
    function createModifier(kind) {
        return createToken(kind);
    }
    ts.createModifier = createModifier;
    function createModifiersFromModifierFlags(flags) {
        var result = [];
        if (flags & 1 /* Export */) {
            result.push(createModifier(86 /* ExportKeyword */));
        }
        if (flags & 2 /* Ambient */) {
            result.push(createModifier(126 /* DeclareKeyword */));
        }
        if (flags & 512 /* Default */) {
            result.push(createModifier(81 /* DefaultKeyword */));
        }
        if (flags & 2048 /* Const */) {
            result.push(createModifier(78 /* ConstKeyword */));
        }
        if (flags & 4 /* Public */) {
            result.push(createModifier(116 /* PublicKeyword */));
        }
        if (flags & 8 /* Private */) {
            result.push(createModifier(114 /* PrivateKeyword */));
        }
        if (flags & 16 /* Protected */) {
            result.push(createModifier(115 /* ProtectedKeyword */));
        }
        if (flags & 128 /* Abstract */) {
            result.push(createModifier(119 /* AbstractKeyword */));
        }
        if (flags & 32 /* Static */) {
            result.push(createModifier(117 /* StaticKeyword */));
        }
        if (flags & 64 /* Readonly */) {
            result.push(createModifier(134 /* ReadonlyKeyword */));
        }
        if (flags & 256 /* Async */) {
            result.push(createModifier(122 /* AsyncKeyword */));
        }
        return result;
    }
    ts.createModifiersFromModifierFlags = createModifiersFromModifierFlags;
    // Names
    function createQualifiedName(left, right) {
        var node = createSynthesizedNode(149 /* QualifiedName */);
        node.left = left;
        node.right = asName(right);
        return node;
    }
    ts.createQualifiedName = createQualifiedName;
    function updateQualifiedName(node, left, right) {
        return node.left !== left
            || node.right !== right
            ? updateNode(createQualifiedName(left, right), node)
            : node;
    }
    ts.updateQualifiedName = updateQualifiedName;
    function parenthesizeForComputedName(expression) {
        return ts.isCommaSequence(expression)
            ? createParen(expression)
            : expression;
    }
    function createComputedPropertyName(expression) {
        var node = createSynthesizedNode(150 /* ComputedPropertyName */);
        node.expression = parenthesizeForComputedName(expression);
        return node;
    }
    ts.createComputedPropertyName = createComputedPropertyName;
    function updateComputedPropertyName(node, expression) {
        return node.expression !== expression
            ? updateNode(createComputedPropertyName(expression), node)
            : node;
    }
    ts.updateComputedPropertyName = updateComputedPropertyName;
    // Signature elements
    function createTypeParameterDeclaration(name, constraint, defaultType) {
        var node = createSynthesizedNode(151 /* TypeParameter */);
        node.name = asName(name);
        node.constraint = constraint;
        node.default = defaultType;
        return node;
    }
    ts.createTypeParameterDeclaration = createTypeParameterDeclaration;
    function updateTypeParameterDeclaration(node, name, constraint, defaultType) {
        return node.name !== name
            || node.constraint !== constraint
            || node.default !== defaultType
            ? updateNode(createTypeParameterDeclaration(name, constraint, defaultType), node)
            : node;
    }
    ts.updateTypeParameterDeclaration = updateTypeParameterDeclaration;
    function createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer) {
        var node = createSynthesizedNode(152 /* Parameter */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.dotDotDotToken = dotDotDotToken;
        node.name = asName(name);
        node.questionToken = questionToken;
        node.type = type;
        node.initializer = initializer ? ts.parenthesizeExpressionForList(initializer) : undefined;
        return node;
    }
    ts.createParameter = createParameter;
    function updateParameter(node, decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.dotDotDotToken !== dotDotDotToken
            || node.name !== name
            || node.questionToken !== questionToken
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node)
            : node;
    }
    ts.updateParameter = updateParameter;
    function createDecorator(expression) {
        var node = createSynthesizedNode(153 /* Decorator */);
        node.expression = ts.parenthesizeForAccess(expression);
        return node;
    }
    ts.createDecorator = createDecorator;
    function updateDecorator(node, expression) {
        return node.expression !== expression
            ? updateNode(createDecorator(expression), node)
            : node;
    }
    ts.updateDecorator = updateDecorator;
    // Type Elements
    function createPropertySignature(modifiers, name, questionToken, type, initializer) {
        var node = createSynthesizedNode(154 /* PropertySignature */);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.questionToken = questionToken;
        node.type = type;
        node.initializer = initializer;
        return node;
    }
    ts.createPropertySignature = createPropertySignature;
    function updatePropertySignature(node, modifiers, name, questionToken, type, initializer) {
        return node.modifiers !== modifiers
            || node.name !== name
            || node.questionToken !== questionToken
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createPropertySignature(modifiers, name, questionToken, type, initializer), node)
            : node;
    }
    ts.updatePropertySignature = updatePropertySignature;
    function createProperty(decorators, modifiers, name, questionOrExclamationToken, type, initializer) {
        var node = createSynthesizedNode(155 /* PropertyDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.questionToken = questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === 56 /* QuestionToken */ ? questionOrExclamationToken : undefined;
        node.exclamationToken = questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === 52 /* ExclamationToken */ ? questionOrExclamationToken : undefined;
        node.type = type;
        node.initializer = initializer;
        return node;
    }
    ts.createProperty = createProperty;
    function updateProperty(node, decorators, modifiers, name, questionOrExclamationToken, type, initializer) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.questionToken !== (questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === 56 /* QuestionToken */ ? questionOrExclamationToken : undefined)
            || node.exclamationToken !== (questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === 52 /* ExclamationToken */ ? questionOrExclamationToken : undefined)
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createProperty(decorators, modifiers, name, questionOrExclamationToken, type, initializer), node)
            : node;
    }
    ts.updateProperty = updateProperty;
    function createMethodSignature(typeParameters, parameters, type, name, questionToken) {
        var node = createSignatureDeclaration(156 /* MethodSignature */, typeParameters, parameters, type);
        node.name = asName(name);
        node.questionToken = questionToken;
        return node;
    }
    ts.createMethodSignature = createMethodSignature;
    function updateMethodSignature(node, typeParameters, parameters, type, name, questionToken) {
        return node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.name !== name
            || node.questionToken !== questionToken
            ? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node)
            : node;
    }
    ts.updateMethodSignature = updateMethodSignature;
    function createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body) {
        var node = createSynthesizedNode(157 /* MethodDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.asteriskToken = asteriskToken;
        node.name = asName(name);
        node.questionToken = questionToken;
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createMethod = createMethod;
    function updateMethod(node, decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.asteriskToken !== asteriskToken
            || node.name !== name
            || node.questionToken !== questionToken
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node)
            : node;
    }
    ts.updateMethod = updateMethod;
    function createConstructor(decorators, modifiers, parameters, body) {
        var node = createSynthesizedNode(158 /* Constructor */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.typeParameters = undefined;
        node.parameters = createNodeArray(parameters);
        node.type = undefined;
        node.body = body;
        return node;
    }
    ts.createConstructor = createConstructor;
    function updateConstructor(node, decorators, modifiers, parameters, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.parameters !== parameters
            || node.body !== body
            ? updateNode(createConstructor(decorators, modifiers, parameters, body), node)
            : node;
    }
    ts.updateConstructor = updateConstructor;
    function createGetAccessor(decorators, modifiers, name, parameters, type, body) {
        var node = createSynthesizedNode(159 /* GetAccessor */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = undefined;
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createGetAccessor = createGetAccessor;
    function updateGetAccessor(node, decorators, modifiers, name, parameters, type, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createGetAccessor(decorators, modifiers, name, parameters, type, body), node)
            : node;
    }
    ts.updateGetAccessor = updateGetAccessor;
    function createSetAccessor(decorators, modifiers, name, parameters, body) {
        var node = createSynthesizedNode(160 /* SetAccessor */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = undefined;
        node.parameters = createNodeArray(parameters);
        node.body = body;
        return node;
    }
    ts.createSetAccessor = createSetAccessor;
    function updateSetAccessor(node, decorators, modifiers, name, parameters, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.parameters !== parameters
            || node.body !== body
            ? updateNode(createSetAccessor(decorators, modifiers, name, parameters, body), node)
            : node;
    }
    ts.updateSetAccessor = updateSetAccessor;
    function createCallSignature(typeParameters, parameters, type) {
        return createSignatureDeclaration(161 /* CallSignature */, typeParameters, parameters, type);
    }
    ts.createCallSignature = createCallSignature;
    function updateCallSignature(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateCallSignature = updateCallSignature;
    function createConstructSignature(typeParameters, parameters, type) {
        return createSignatureDeclaration(162 /* ConstructSignature */, typeParameters, parameters, type);
    }
    ts.createConstructSignature = createConstructSignature;
    function updateConstructSignature(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateConstructSignature = updateConstructSignature;
    function createIndexSignature(decorators, modifiers, parameters, type) {
        var node = createSynthesizedNode(163 /* IndexSignature */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        return node;
    }
    ts.createIndexSignature = createIndexSignature;
    function updateIndexSignature(node, decorators, modifiers, parameters, type) {
        return node.parameters !== parameters
            || node.type !== type
            || node.decorators !== decorators
            || node.modifiers !== modifiers
            ? updateNode(createIndexSignature(decorators, modifiers, parameters, type), node)
            : node;
    }
    ts.updateIndexSignature = updateIndexSignature;
    /* @internal */
    function createSignatureDeclaration(kind, typeParameters, parameters, type, typeArguments) {
        var node = createSynthesizedNode(kind);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = asNodeArray(parameters);
        node.type = type;
        node.typeArguments = asNodeArray(typeArguments);
        return node;
    }
    ts.createSignatureDeclaration = createSignatureDeclaration;
    function updateSignatureDeclaration(node, typeParameters, parameters, type) {
        return node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            ? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node)
            : node;
    }
    // Types
    function createKeywordTypeNode(kind) {
        return createSynthesizedNode(kind);
    }
    ts.createKeywordTypeNode = createKeywordTypeNode;
    function createTypePredicateNode(parameterName, type) {
        var node = createSynthesizedNode(164 /* TypePredicate */);
        node.parameterName = asName(parameterName);
        node.type = type;
        return node;
    }
    ts.createTypePredicateNode = createTypePredicateNode;
    function updateTypePredicateNode(node, parameterName, type) {
        return node.parameterName !== parameterName
            || node.type !== type
            ? updateNode(createTypePredicateNode(parameterName, type), node)
            : node;
    }
    ts.updateTypePredicateNode = updateTypePredicateNode;
    function createTypeReferenceNode(typeName, typeArguments) {
        var node = createSynthesizedNode(165 /* TypeReference */);
        node.typeName = asName(typeName);
        node.typeArguments = typeArguments && ts.parenthesizeTypeParameters(typeArguments);
        return node;
    }
    ts.createTypeReferenceNode = createTypeReferenceNode;
    function updateTypeReferenceNode(node, typeName, typeArguments) {
        return node.typeName !== typeName
            || node.typeArguments !== typeArguments
            ? updateNode(createTypeReferenceNode(typeName, typeArguments), node)
            : node;
    }
    ts.updateTypeReferenceNode = updateTypeReferenceNode;
    function createFunctionTypeNode(typeParameters, parameters, type) {
        return createSignatureDeclaration(166 /* FunctionType */, typeParameters, parameters, type);
    }
    ts.createFunctionTypeNode = createFunctionTypeNode;
    function updateFunctionTypeNode(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateFunctionTypeNode = updateFunctionTypeNode;
    function createConstructorTypeNode(typeParameters, parameters, type) {
        return createSignatureDeclaration(167 /* ConstructorType */, typeParameters, parameters, type);
    }
    ts.createConstructorTypeNode = createConstructorTypeNode;
    function updateConstructorTypeNode(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateConstructorTypeNode = updateConstructorTypeNode;
    function createTypeQueryNode(exprName) {
        var node = createSynthesizedNode(168 /* TypeQuery */);
        node.exprName = exprName;
        return node;
    }
    ts.createTypeQueryNode = createTypeQueryNode;
    function updateTypeQueryNode(node, exprName) {
        return node.exprName !== exprName
            ? updateNode(createTypeQueryNode(exprName), node)
            : node;
    }
    ts.updateTypeQueryNode = updateTypeQueryNode;
    function createTypeLiteralNode(members) {
        var node = createSynthesizedNode(169 /* TypeLiteral */);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createTypeLiteralNode = createTypeLiteralNode;
    function updateTypeLiteralNode(node, members) {
        return node.members !== members
            ? updateNode(createTypeLiteralNode(members), node)
            : node;
    }
    ts.updateTypeLiteralNode = updateTypeLiteralNode;
    function createArrayTypeNode(elementType) {
        var node = createSynthesizedNode(170 /* ArrayType */);
        node.elementType = ts.parenthesizeArrayTypeMember(elementType);
        return node;
    }
    ts.createArrayTypeNode = createArrayTypeNode;
    function updateArrayTypeNode(node, elementType) {
        return node.elementType !== elementType
            ? updateNode(createArrayTypeNode(elementType), node)
            : node;
    }
    ts.updateArrayTypeNode = updateArrayTypeNode;
    function createTupleTypeNode(elementTypes) {
        var node = createSynthesizedNode(171 /* TupleType */);
        node.elementTypes = createNodeArray(elementTypes);
        return node;
    }
    ts.createTupleTypeNode = createTupleTypeNode;
    function updateTupleTypeNode(node, elementTypes) {
        return node.elementTypes !== elementTypes
            ? updateNode(createTupleTypeNode(elementTypes), node)
            : node;
    }
    ts.updateTupleTypeNode = updateTupleTypeNode;
    function createOptionalTypeNode(type) {
        var node = createSynthesizedNode(172 /* OptionalType */);
        node.type = ts.parenthesizeArrayTypeMember(type);
        return node;
    }
    ts.createOptionalTypeNode = createOptionalTypeNode;
    function updateOptionalTypeNode(node, type) {
        return node.type !== type
            ? updateNode(createOptionalTypeNode(type), node)
            : node;
    }
    ts.updateOptionalTypeNode = updateOptionalTypeNode;
    function createRestTypeNode(type) {
        var node = createSynthesizedNode(173 /* RestType */);
        node.type = type;
        return node;
    }
    ts.createRestTypeNode = createRestTypeNode;
    function updateRestTypeNode(node, type) {
        return node.type !== type
            ? updateNode(createRestTypeNode(type), node)
            : node;
    }
    ts.updateRestTypeNode = updateRestTypeNode;
    function createUnionTypeNode(types) {
        return createUnionOrIntersectionTypeNode(174 /* UnionType */, types);
    }
    ts.createUnionTypeNode = createUnionTypeNode;
    function updateUnionTypeNode(node, types) {
        return updateUnionOrIntersectionTypeNode(node, types);
    }
    ts.updateUnionTypeNode = updateUnionTypeNode;
    function createIntersectionTypeNode(types) {
        return createUnionOrIntersectionTypeNode(175 /* IntersectionType */, types);
    }
    ts.createIntersectionTypeNode = createIntersectionTypeNode;
    function updateIntersectionTypeNode(node, types) {
        return updateUnionOrIntersectionTypeNode(node, types);
    }
    ts.updateIntersectionTypeNode = updateIntersectionTypeNode;
    function createUnionOrIntersectionTypeNode(kind, types) {
        var node = createSynthesizedNode(kind);
        node.types = ts.parenthesizeElementTypeMembers(types);
        return node;
    }
    ts.createUnionOrIntersectionTypeNode = createUnionOrIntersectionTypeNode;
    function updateUnionOrIntersectionTypeNode(node, types) {
        return node.types !== types
            ? updateNode(createUnionOrIntersectionTypeNode(node.kind, types), node)
            : node;
    }
    function createConditionalTypeNode(checkType, extendsType, trueType, falseType) {
        var node = createSynthesizedNode(176 /* ConditionalType */);
        node.checkType = ts.parenthesizeConditionalTypeMember(checkType);
        node.extendsType = ts.parenthesizeConditionalTypeMember(extendsType);
        node.trueType = trueType;
        node.falseType = falseType;
        return node;
    }
    ts.createConditionalTypeNode = createConditionalTypeNode;
    function updateConditionalTypeNode(node, checkType, extendsType, trueType, falseType) {
        return node.checkType !== checkType
            || node.extendsType !== extendsType
            || node.trueType !== trueType
            || node.falseType !== falseType
            ? updateNode(createConditionalTypeNode(checkType, extendsType, trueType, falseType), node)
            : node;
    }
    ts.updateConditionalTypeNode = updateConditionalTypeNode;
    function createInferTypeNode(typeParameter) {
        var node = createSynthesizedNode(177 /* InferType */);
        node.typeParameter = typeParameter;
        return node;
    }
    ts.createInferTypeNode = createInferTypeNode;
    function updateInferTypeNode(node, typeParameter) {
        return node.typeParameter !== typeParameter
            ? updateNode(createInferTypeNode(typeParameter), node)
            : node;
    }
    ts.updateInferTypeNode = updateInferTypeNode;
    function createImportTypeNode(argument, qualifier, typeArguments, isTypeOf) {
        var node = createSynthesizedNode(184 /* ImportType */);
        node.argument = argument;
        node.qualifier = qualifier;
        node.typeArguments = ts.parenthesizeTypeParameters(typeArguments);
        node.isTypeOf = isTypeOf;
        return node;
    }
    ts.createImportTypeNode = createImportTypeNode;
    function updateImportTypeNode(node, argument, qualifier, typeArguments, isTypeOf) {
        return node.argument !== argument
            || node.qualifier !== qualifier
            || node.typeArguments !== typeArguments
            || node.isTypeOf !== isTypeOf
            ? updateNode(createImportTypeNode(argument, qualifier, typeArguments, isTypeOf), node)
            : node;
    }
    ts.updateImportTypeNode = updateImportTypeNode;
    function createParenthesizedType(type) {
        var node = createSynthesizedNode(178 /* ParenthesizedType */);
        node.type = type;
        return node;
    }
    ts.createParenthesizedType = createParenthesizedType;
    function updateParenthesizedType(node, type) {
        return node.type !== type
            ? updateNode(createParenthesizedType(type), node)
            : node;
    }
    ts.updateParenthesizedType = updateParenthesizedType;
    function createThisTypeNode() {
        return createSynthesizedNode(179 /* ThisType */);
    }
    ts.createThisTypeNode = createThisTypeNode;
    function createTypeOperatorNode(operatorOrType, type) {
        var node = createSynthesizedNode(180 /* TypeOperator */);
        node.operator = typeof operatorOrType === "number" ? operatorOrType : 130 /* KeyOfKeyword */;
        node.type = ts.parenthesizeElementTypeMember(typeof operatorOrType === "number" ? type : operatorOrType);
        return node;
    }
    ts.createTypeOperatorNode = createTypeOperatorNode;
    function updateTypeOperatorNode(node, type) {
        return node.type !== type ? updateNode(createTypeOperatorNode(node.operator, type), node) : node;
    }
    ts.updateTypeOperatorNode = updateTypeOperatorNode;
    function createIndexedAccessTypeNode(objectType, indexType) {
        var node = createSynthesizedNode(181 /* IndexedAccessType */);
        node.objectType = ts.parenthesizeElementTypeMember(objectType);
        node.indexType = indexType;
        return node;
    }
    ts.createIndexedAccessTypeNode = createIndexedAccessTypeNode;
    function updateIndexedAccessTypeNode(node, objectType, indexType) {
        return node.objectType !== objectType
            || node.indexType !== indexType
            ? updateNode(createIndexedAccessTypeNode(objectType, indexType), node)
            : node;
    }
    ts.updateIndexedAccessTypeNode = updateIndexedAccessTypeNode;
    function createMappedTypeNode(readonlyToken, typeParameter, questionToken, type) {
        var node = createSynthesizedNode(182 /* MappedType */);
        node.readonlyToken = readonlyToken;
        node.typeParameter = typeParameter;
        node.questionToken = questionToken;
        node.type = type;
        return node;
    }
    ts.createMappedTypeNode = createMappedTypeNode;
    function updateMappedTypeNode(node, readonlyToken, typeParameter, questionToken, type) {
        return node.readonlyToken !== readonlyToken
            || node.typeParameter !== typeParameter
            || node.questionToken !== questionToken
            || node.type !== type
            ? updateNode(createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), node)
            : node;
    }
    ts.updateMappedTypeNode = updateMappedTypeNode;
    function createLiteralTypeNode(literal) {
        var node = createSynthesizedNode(183 /* LiteralType */);
        node.literal = literal;
        return node;
    }
    ts.createLiteralTypeNode = createLiteralTypeNode;
    function updateLiteralTypeNode(node, literal) {
        return node.literal !== literal
            ? updateNode(createLiteralTypeNode(literal), node)
            : node;
    }
    ts.updateLiteralTypeNode = updateLiteralTypeNode;
    // Binding Patterns
    function createObjectBindingPattern(elements) {
        var node = createSynthesizedNode(185 /* ObjectBindingPattern */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createObjectBindingPattern = createObjectBindingPattern;
    function updateObjectBindingPattern(node, elements) {
        return node.elements !== elements
            ? updateNode(createObjectBindingPattern(elements), node)
            : node;
    }
    ts.updateObjectBindingPattern = updateObjectBindingPattern;
    function createArrayBindingPattern(elements) {
        var node = createSynthesizedNode(186 /* ArrayBindingPattern */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createArrayBindingPattern = createArrayBindingPattern;
    function updateArrayBindingPattern(node, elements) {
        return node.elements !== elements
            ? updateNode(createArrayBindingPattern(elements), node)
            : node;
    }
    ts.updateArrayBindingPattern = updateArrayBindingPattern;
    function createBindingElement(dotDotDotToken, propertyName, name, initializer) {
        var node = createSynthesizedNode(187 /* BindingElement */);
        node.dotDotDotToken = dotDotDotToken;
        node.propertyName = asName(propertyName);
        node.name = asName(name);
        node.initializer = initializer;
        return node;
    }
    ts.createBindingElement = createBindingElement;
    function updateBindingElement(node, dotDotDotToken, propertyName, name, initializer) {
        return node.propertyName !== propertyName
            || node.dotDotDotToken !== dotDotDotToken
            || node.name !== name
            || node.initializer !== initializer
            ? updateNode(createBindingElement(dotDotDotToken, propertyName, name, initializer), node)
            : node;
    }
    ts.updateBindingElement = updateBindingElement;
    // Expression
    function createArrayLiteral(elements, multiLine) {
        var node = createSynthesizedNode(188 /* ArrayLiteralExpression */);
        node.elements = ts.parenthesizeListElements(createNodeArray(elements));
        if (multiLine)
            node.multiLine = true;
        return node;
    }
    ts.createArrayLiteral = createArrayLiteral;
    function updateArrayLiteral(node, elements) {
        return node.elements !== elements
            ? updateNode(createArrayLiteral(elements, node.multiLine), node)
            : node;
    }
    ts.updateArrayLiteral = updateArrayLiteral;
    function createObjectLiteral(properties, multiLine) {
        var node = createSynthesizedNode(189 /* ObjectLiteralExpression */);
        node.properties = createNodeArray(properties);
        if (multiLine)
            node.multiLine = true;
        return node;
    }
    ts.createObjectLiteral = createObjectLiteral;
    function updateObjectLiteral(node, properties) {
        return node.properties !== properties
            ? updateNode(createObjectLiteral(properties, node.multiLine), node)
            : node;
    }
    ts.updateObjectLiteral = updateObjectLiteral;
    function createPropertyAccess(expression, name) {
        var node = createSynthesizedNode(190 /* PropertyAccessExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.name = asName(name);
        setEmitFlags(node, 131072 /* NoIndentation */);
        return node;
    }
    ts.createPropertyAccess = createPropertyAccess;
    function updatePropertyAccess(node, expression, name) {
        // Because we are updating existed propertyAccess we want to inherit its emitFlags
        // instead of using the default from createPropertyAccess
        return node.expression !== expression
            || node.name !== name
            ? updateNode(setEmitFlags(createPropertyAccess(expression, name), ts.getEmitFlags(node)), node)
            : node;
    }
    ts.updatePropertyAccess = updatePropertyAccess;
    function createElementAccess(expression, index) {
        var node = createSynthesizedNode(191 /* ElementAccessExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.argumentExpression = asExpression(index);
        return node;
    }
    ts.createElementAccess = createElementAccess;
    function updateElementAccess(node, expression, argumentExpression) {
        return node.expression !== expression
            || node.argumentExpression !== argumentExpression
            ? updateNode(createElementAccess(expression, argumentExpression), node)
            : node;
    }
    ts.updateElementAccess = updateElementAccess;
    function createCall(expression, typeArguments, argumentsArray) {
        var node = createSynthesizedNode(192 /* CallExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.typeArguments = asNodeArray(typeArguments);
        node.arguments = ts.parenthesizeListElements(createNodeArray(argumentsArray));
        return node;
    }
    ts.createCall = createCall;
    function updateCall(node, expression, typeArguments, argumentsArray) {
        return node.expression !== expression
            || node.typeArguments !== typeArguments
            || node.arguments !== argumentsArray
            ? updateNode(createCall(expression, typeArguments, argumentsArray), node)
            : node;
    }
    ts.updateCall = updateCall;
    function createNew(expression, typeArguments, argumentsArray) {
        var node = createSynthesizedNode(193 /* NewExpression */);
        node.expression = ts.parenthesizeForNew(expression);
        node.typeArguments = asNodeArray(typeArguments);
        node.arguments = argumentsArray ? ts.parenthesizeListElements(createNodeArray(argumentsArray)) : undefined;
        return node;
    }
    ts.createNew = createNew;
    function updateNew(node, expression, typeArguments, argumentsArray) {
        return node.expression !== expression
            || node.typeArguments !== typeArguments
            || node.arguments !== argumentsArray
            ? updateNode(createNew(expression, typeArguments, argumentsArray), node)
            : node;
    }
    ts.updateNew = updateNew;
    function createTaggedTemplate(tag, typeArgumentsOrTemplate, template) {
        var node = createSynthesizedNode(194 /* TaggedTemplateExpression */);
        node.tag = ts.parenthesizeForAccess(tag);
        if (template) {
            node.typeArguments = asNodeArray(typeArgumentsOrTemplate);
            node.template = template;
        }
        else {
            node.typeArguments = undefined;
            node.template = typeArgumentsOrTemplate;
        }
        return node;
    }
    ts.createTaggedTemplate = createTaggedTemplate;
    function updateTaggedTemplate(node, tag, typeArgumentsOrTemplate, template) {
        return node.tag !== tag
            || (template
                ? node.typeArguments !== typeArgumentsOrTemplate || node.template !== template
                : node.typeArguments !== undefined || node.template !== typeArgumentsOrTemplate)
            ? updateNode(createTaggedTemplate(tag, typeArgumentsOrTemplate, template), node)
            : node;
    }
    ts.updateTaggedTemplate = updateTaggedTemplate;
    function createTypeAssertion(type, expression) {
        var node = createSynthesizedNode(195 /* TypeAssertionExpression */);
        node.type = type;
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createTypeAssertion = createTypeAssertion;
    function updateTypeAssertion(node, type, expression) {
        return node.type !== type
            || node.expression !== expression
            ? updateNode(createTypeAssertion(type, expression), node)
            : node;
    }
    ts.updateTypeAssertion = updateTypeAssertion;
    function createParen(expression) {
        var node = createSynthesizedNode(196 /* ParenthesizedExpression */);
        node.expression = expression;
        return node;
    }
    ts.createParen = createParen;
    function updateParen(node, expression) {
        return node.expression !== expression
            ? updateNode(createParen(expression), node)
            : node;
    }
    ts.updateParen = updateParen;
    function createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        var node = createSynthesizedNode(197 /* FunctionExpression */);
        node.modifiers = asNodeArray(modifiers);
        node.asteriskToken = asteriskToken;
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createFunctionExpression = createFunctionExpression;
    function updateFunctionExpression(node, modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        return node.name !== name
            || node.modifiers !== modifiers
            || node.asteriskToken !== asteriskToken
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body), node)
            : node;
    }
    ts.updateFunctionExpression = updateFunctionExpression;
    function createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body) {
        var node = createSynthesizedNode(198 /* ArrowFunction */);
        node.modifiers = asNodeArray(modifiers);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.equalsGreaterThanToken = equalsGreaterThanToken || createToken(37 /* EqualsGreaterThanToken */);
        node.body = ts.parenthesizeConciseBody(body);
        return node;
    }
    ts.createArrowFunction = createArrowFunction;
    function updateArrowFunction(node, modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body) {
        return node.modifiers !== modifiers
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.equalsGreaterThanToken !== equalsGreaterThanToken
            || node.body !== body
            ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node)
            : node;
    }
    ts.updateArrowFunction = updateArrowFunction;
    function createDelete(expression) {
        var node = createSynthesizedNode(199 /* DeleteExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createDelete = createDelete;
    function updateDelete(node, expression) {
        return node.expression !== expression
            ? updateNode(createDelete(expression), node)
            : node;
    }
    ts.updateDelete = updateDelete;
    function createTypeOf(expression) {
        var node = createSynthesizedNode(200 /* TypeOfExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createTypeOf = createTypeOf;
    function updateTypeOf(node, expression) {
        return node.expression !== expression
            ? updateNode(createTypeOf(expression), node)
            : node;
    }
    ts.updateTypeOf = updateTypeOf;
    function createVoid(expression) {
        var node = createSynthesizedNode(201 /* VoidExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createVoid = createVoid;
    function updateVoid(node, expression) {
        return node.expression !== expression
            ? updateNode(createVoid(expression), node)
            : node;
    }
    ts.updateVoid = updateVoid;
    function createAwait(expression) {
        var node = createSynthesizedNode(202 /* AwaitExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createAwait = createAwait;
    function updateAwait(node, expression) {
        return node.expression !== expression
            ? updateNode(createAwait(expression), node)
            : node;
    }
    ts.updateAwait = updateAwait;
    function createPrefix(operator, operand) {
        var node = createSynthesizedNode(203 /* PrefixUnaryExpression */);
        node.operator = operator;
        node.operand = ts.parenthesizePrefixOperand(operand);
        return node;
    }
    ts.createPrefix = createPrefix;
    function updatePrefix(node, operand) {
        return node.operand !== operand
            ? updateNode(createPrefix(node.operator, operand), node)
            : node;
    }
    ts.updatePrefix = updatePrefix;
    function createPostfix(operand, operator) {
        var node = createSynthesizedNode(204 /* PostfixUnaryExpression */);
        node.operand = ts.parenthesizePostfixOperand(operand);
        node.operator = operator;
        return node;
    }
    ts.createPostfix = createPostfix;
    function updatePostfix(node, operand) {
        return node.operand !== operand
            ? updateNode(createPostfix(operand, node.operator), node)
            : node;
    }
    ts.updatePostfix = updatePostfix;
    function createBinary(left, operator, right) {
        var node = createSynthesizedNode(205 /* BinaryExpression */);
        var operatorToken = asToken(operator);
        var operatorKind = operatorToken.kind;
        node.left = ts.parenthesizeBinaryOperand(operatorKind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined);
        node.operatorToken = operatorToken;
        node.right = ts.parenthesizeBinaryOperand(operatorKind, right, /*isLeftSideOfBinary*/ false, node.left);
        return node;
    }
    ts.createBinary = createBinary;
    function updateBinary(node, left, right, operator) {
        return node.left !== left
            || node.right !== right
            ? updateNode(createBinary(left, operator || node.operatorToken, right), node)
            : node;
    }
    ts.updateBinary = updateBinary;
    function createConditional(condition, questionTokenOrWhenTrue, whenTrueOrWhenFalse, colonToken, whenFalse) {
        var node = createSynthesizedNode(206 /* ConditionalExpression */);
        node.condition = ts.parenthesizeForConditionalHead(condition);
        node.questionToken = whenFalse ? questionTokenOrWhenTrue : createToken(56 /* QuestionToken */);
        node.whenTrue = ts.parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenTrueOrWhenFalse : questionTokenOrWhenTrue);
        node.colonToken = whenFalse ? colonToken : createToken(57 /* ColonToken */);
        node.whenFalse = ts.parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenFalse : whenTrueOrWhenFalse);
        return node;
    }
    ts.createConditional = createConditional;
    function updateConditional(node, condition, questionToken, whenTrue, colonToken, whenFalse) {
        return node.condition !== condition
            || node.questionToken !== questionToken
            || node.whenTrue !== whenTrue
            || node.colonToken !== colonToken
            || node.whenFalse !== whenFalse
            ? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node)
            : node;
    }
    ts.updateConditional = updateConditional;
    function createTemplateExpression(head, templateSpans) {
        var node = createSynthesizedNode(207 /* TemplateExpression */);
        node.head = head;
        node.templateSpans = createNodeArray(templateSpans);
        return node;
    }
    ts.createTemplateExpression = createTemplateExpression;
    function updateTemplateExpression(node, head, templateSpans) {
        return node.head !== head
            || node.templateSpans !== templateSpans
            ? updateNode(createTemplateExpression(head, templateSpans), node)
            : node;
    }
    ts.updateTemplateExpression = updateTemplateExpression;
    function createTemplateHead(text) {
        var node = createSynthesizedNode(15 /* TemplateHead */);
        node.text = text;
        return node;
    }
    ts.createTemplateHead = createTemplateHead;
    function createTemplateMiddle(text) {
        var node = createSynthesizedNode(16 /* TemplateMiddle */);
        node.text = text;
        return node;
    }
    ts.createTemplateMiddle = createTemplateMiddle;
    function createTemplateTail(text) {
        var node = createSynthesizedNode(17 /* TemplateTail */);
        node.text = text;
        return node;
    }
    ts.createTemplateTail = createTemplateTail;
    function createNoSubstitutionTemplateLiteral(text) {
        var node = createSynthesizedNode(14 /* NoSubstitutionTemplateLiteral */);
        node.text = text;
        return node;
    }
    ts.createNoSubstitutionTemplateLiteral = createNoSubstitutionTemplateLiteral;
    function createYield(asteriskTokenOrExpression, expression) {
        var node = createSynthesizedNode(208 /* YieldExpression */);
        node.asteriskToken = asteriskTokenOrExpression && asteriskTokenOrExpression.kind === 40 /* AsteriskToken */ ? asteriskTokenOrExpression : undefined;
        node.expression = asteriskTokenOrExpression && asteriskTokenOrExpression.kind !== 40 /* AsteriskToken */ ? asteriskTokenOrExpression : expression;
        return node;
    }
    ts.createYield = createYield;
    function updateYield(node, asteriskToken, expression) {
        return node.expression !== expression
            || node.asteriskToken !== asteriskToken
            ? updateNode(createYield(asteriskToken, expression), node)
            : node;
    }
    ts.updateYield = updateYield;
    function createSpread(expression) {
        var node = createSynthesizedNode(209 /* SpreadElement */);
        node.expression = ts.parenthesizeExpressionForList(expression);
        return node;
    }
    ts.createSpread = createSpread;
    function updateSpread(node, expression) {
        return node.expression !== expression
            ? updateNode(createSpread(expression), node)
            : node;
    }
    ts.updateSpread = updateSpread;
    function createClassExpression(modifiers, name, typeParameters, heritageClauses, members) {
        var node = createSynthesizedNode(210 /* ClassExpression */);
        node.decorators = undefined;
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.heritageClauses = asNodeArray(heritageClauses);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createClassExpression = createClassExpression;
    function updateClassExpression(node, modifiers, name, typeParameters, heritageClauses, members) {
        return node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.heritageClauses !== heritageClauses
            || node.members !== members
            ? updateNode(createClassExpression(modifiers, name, typeParameters, heritageClauses, members), node)
            : node;
    }
    ts.updateClassExpression = updateClassExpression;
    function createOmittedExpression() {
        return createSynthesizedNode(211 /* OmittedExpression */);
    }
    ts.createOmittedExpression = createOmittedExpression;
    function createExpressionWithTypeArguments(typeArguments, expression) {
        var node = createSynthesizedNode(212 /* ExpressionWithTypeArguments */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.typeArguments = asNodeArray(typeArguments);
        return node;
    }
    ts.createExpressionWithTypeArguments = createExpressionWithTypeArguments;
    function updateExpressionWithTypeArguments(node, typeArguments, expression) {
        return node.typeArguments !== typeArguments
            || node.expression !== expression
            ? updateNode(createExpressionWithTypeArguments(typeArguments, expression), node)
            : node;
    }
    ts.updateExpressionWithTypeArguments = updateExpressionWithTypeArguments;
    function createAsExpression(expression, type) {
        var node = createSynthesizedNode(213 /* AsExpression */);
        node.expression = expression;
        node.type = type;
        return node;
    }
    ts.createAsExpression = createAsExpression;
    function updateAsExpression(node, expression, type) {
        return node.expression !== expression
            || node.type !== type
            ? updateNode(createAsExpression(expression, type), node)
            : node;
    }
    ts.updateAsExpression = updateAsExpression;
    function createNonNullExpression(expression) {
        var node = createSynthesizedNode(214 /* NonNullExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        return node;
    }
    ts.createNonNullExpression = createNonNullExpression;
    function updateNonNullExpression(node, expression) {
        return node.expression !== expression
            ? updateNode(createNonNullExpression(expression), node)
            : node;
    }
    ts.updateNonNullExpression = updateNonNullExpression;
    function createMetaProperty(keywordToken, name) {
        var node = createSynthesizedNode(215 /* MetaProperty */);
        node.keywordToken = keywordToken;
        node.name = name;
        return node;
    }
    ts.createMetaProperty = createMetaProperty;
    function updateMetaProperty(node, name) {
        return node.name !== name
            ? updateNode(createMetaProperty(node.keywordToken, name), node)
            : node;
    }
    ts.updateMetaProperty = updateMetaProperty;
    // Misc
    function createTemplateSpan(expression, literal) {
        var node = createSynthesizedNode(217 /* TemplateSpan */);
        node.expression = expression;
        node.literal = literal;
        return node;
    }
    ts.createTemplateSpan = createTemplateSpan;
    function updateTemplateSpan(node, expression, literal) {
        return node.expression !== expression
            || node.literal !== literal
            ? updateNode(createTemplateSpan(expression, literal), node)
            : node;
    }
    ts.updateTemplateSpan = updateTemplateSpan;
    function createSemicolonClassElement() {
        return createSynthesizedNode(218 /* SemicolonClassElement */);
    }
    ts.createSemicolonClassElement = createSemicolonClassElement;
    // Element
    function createBlock(statements, multiLine) {
        var block = createSynthesizedNode(219 /* Block */);
        block.statements = createNodeArray(statements);
        if (multiLine)
            block.multiLine = multiLine;
        return block;
    }
    ts.createBlock = createBlock;
    function updateBlock(node, statements) {
        return node.statements !== statements
            ? updateNode(createBlock(statements, node.multiLine), node)
            : node;
    }
    ts.updateBlock = updateBlock;
    function createVariableStatement(modifiers, declarationList) {
        var node = createSynthesizedNode(220 /* VariableStatement */);
        node.decorators = undefined;
        node.modifiers = asNodeArray(modifiers);
        node.declarationList = ts.isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList;
        return node;
    }
    ts.createVariableStatement = createVariableStatement;
    function updateVariableStatement(node, modifiers, declarationList) {
        return node.modifiers !== modifiers
            || node.declarationList !== declarationList
            ? updateNode(createVariableStatement(modifiers, declarationList), node)
            : node;
    }
    ts.updateVariableStatement = updateVariableStatement;
    function createEmptyStatement() {
        return createSynthesizedNode(221 /* EmptyStatement */);
    }
    ts.createEmptyStatement = createEmptyStatement;
    function createExpressionStatement(expression) {
        var node = createSynthesizedNode(222 /* ExpressionStatement */);
        node.expression = ts.parenthesizeExpressionForExpressionStatement(expression);
        return node;
    }
    ts.createExpressionStatement = createExpressionStatement;
    function updateExpressionStatement(node, expression) {
        return node.expression !== expression
            ? updateNode(createExpressionStatement(expression), node)
            : node;
    }
    ts.updateExpressionStatement = updateExpressionStatement;
    /** @deprecated Use `createExpressionStatement` instead.  */
    ts.createStatement = createExpressionStatement;
    /** @deprecated Use `updateExpressionStatement` instead.  */
    ts.updateStatement = updateExpressionStatement;
    function createIf(expression, thenStatement, elseStatement) {
        var node = createSynthesizedNode(223 /* IfStatement */);
        node.expression = expression;
        node.thenStatement = thenStatement;
        node.elseStatement = elseStatement;
        return node;
    }
    ts.createIf = createIf;
    function updateIf(node, expression, thenStatement, elseStatement) {
        return node.expression !== expression
            || node.thenStatement !== thenStatement
            || node.elseStatement !== elseStatement
            ? updateNode(createIf(expression, thenStatement, elseStatement), node)
            : node;
    }
    ts.updateIf = updateIf;
    function createDo(statement, expression) {
        var node = createSynthesizedNode(224 /* DoStatement */);
        node.statement = statement;
        node.expression = expression;
        return node;
    }
    ts.createDo = createDo;
    function updateDo(node, statement, expression) {
        return node.statement !== statement
            || node.expression !== expression
            ? updateNode(createDo(statement, expression), node)
            : node;
    }
    ts.updateDo = updateDo;
    function createWhile(expression, statement) {
        var node = createSynthesizedNode(225 /* WhileStatement */);
        node.expression = expression;
        node.statement = statement;
        return node;
    }
    ts.createWhile = createWhile;
    function updateWhile(node, expression, statement) {
        return node.expression !== expression
            || node.statement !== statement
            ? updateNode(createWhile(expression, statement), node)
            : node;
    }
    ts.updateWhile = updateWhile;
    function createFor(initializer, condition, incrementor, statement) {
        var node = createSynthesizedNode(226 /* ForStatement */);
        node.initializer = initializer;
        node.condition = condition;
        node.incrementor = incrementor;
        node.statement = statement;
        return node;
    }
    ts.createFor = createFor;
    function updateFor(node, initializer, condition, incrementor, statement) {
        return node.initializer !== initializer
            || node.condition !== condition
            || node.incrementor !== incrementor
            || node.statement !== statement
            ? updateNode(createFor(initializer, condition, incrementor, statement), node)
            : node;
    }
    ts.updateFor = updateFor;
    function createForIn(initializer, expression, statement) {
        var node = createSynthesizedNode(227 /* ForInStatement */);
        node.initializer = initializer;
        node.expression = expression;
        node.statement = statement;
        return node;
    }
    ts.createForIn = createForIn;
    function updateForIn(node, initializer, expression, statement) {
        return node.initializer !== initializer
            || node.expression !== expression
            || node.statement !== statement
            ? updateNode(createForIn(initializer, expression, statement), node)
            : node;
    }
    ts.updateForIn = updateForIn;
    function createForOf(awaitModifier, initializer, expression, statement) {
        var node = createSynthesizedNode(228 /* ForOfStatement */);
        node.awaitModifier = awaitModifier;
        node.initializer = initializer;
        node.expression = expression;
        node.statement = statement;
        return node;
    }
    ts.createForOf = createForOf;
    function updateForOf(node, awaitModifier, initializer, expression, statement) {
        return node.awaitModifier !== awaitModifier
            || node.initializer !== initializer
            || node.expression !== expression
            || node.statement !== statement
            ? updateNode(createForOf(awaitModifier, initializer, expression, statement), node)
            : node;
    }
    ts.updateForOf = updateForOf;
    function createContinue(label) {
        var node = createSynthesizedNode(229 /* ContinueStatement */);
        node.label = asName(label);
        return node;
    }
    ts.createContinue = createContinue;
    function updateContinue(node, label) {
        return node.label !== label
            ? updateNode(createContinue(label), node)
            : node;
    }
    ts.updateContinue = updateContinue;
    function createBreak(label) {
        var node = createSynthesizedNode(230 /* BreakStatement */);
        node.label = asName(label);
        return node;
    }
    ts.createBreak = createBreak;
    function updateBreak(node, label) {
        return node.label !== label
            ? updateNode(createBreak(label), node)
            : node;
    }
    ts.updateBreak = updateBreak;
    function createReturn(expression) {
        var node = createSynthesizedNode(231 /* ReturnStatement */);
        node.expression = expression;
        return node;
    }
    ts.createReturn = createReturn;
    function updateReturn(node, expression) {
        return node.expression !== expression
            ? updateNode(createReturn(expression), node)
            : node;
    }
    ts.updateReturn = updateReturn;
    function createWith(expression, statement) {
        var node = createSynthesizedNode(232 /* WithStatement */);
        node.expression = expression;
        node.statement = statement;
        return node;
    }
    ts.createWith = createWith;
    function updateWith(node, expression, statement) {
        return node.expression !== expression
            || node.statement !== statement
            ? updateNode(createWith(expression, statement), node)
            : node;
    }
    ts.updateWith = updateWith;
    function createSwitch(expression, caseBlock) {
        var node = createSynthesizedNode(233 /* SwitchStatement */);
        node.expression = ts.parenthesizeExpressionForList(expression);
        node.caseBlock = caseBlock;
        return node;
    }
    ts.createSwitch = createSwitch;
    function updateSwitch(node, expression, caseBlock) {
        return node.expression !== expression
            || node.caseBlock !== caseBlock
            ? updateNode(createSwitch(expression, caseBlock), node)
            : node;
    }
    ts.updateSwitch = updateSwitch;
    function createLabel(label, statement) {
        var node = createSynthesizedNode(234 /* LabeledStatement */);
        node.label = asName(label);
        node.statement = statement;
        return node;
    }
    ts.createLabel = createLabel;
    function updateLabel(node, label, statement) {
        return node.label !== label
            || node.statement !== statement
            ? updateNode(createLabel(label, statement), node)
            : node;
    }
    ts.updateLabel = updateLabel;
    function createThrow(expression) {
        var node = createSynthesizedNode(235 /* ThrowStatement */);
        node.expression = expression;
        return node;
    }
    ts.createThrow = createThrow;
    function updateThrow(node, expression) {
        return node.expression !== expression
            ? updateNode(createThrow(expression), node)
            : node;
    }
    ts.updateThrow = updateThrow;
    function createTry(tryBlock, catchClause, finallyBlock) {
        var node = createSynthesizedNode(236 /* TryStatement */);
        node.tryBlock = tryBlock;
        node.catchClause = catchClause;
        node.finallyBlock = finallyBlock;
        return node;
    }
    ts.createTry = createTry;
    function updateTry(node, tryBlock, catchClause, finallyBlock) {
        return node.tryBlock !== tryBlock
            || node.catchClause !== catchClause
            || node.finallyBlock !== finallyBlock
            ? updateNode(createTry(tryBlock, catchClause, finallyBlock), node)
            : node;
    }
    ts.updateTry = updateTry;
    function createDebuggerStatement() {
        return createSynthesizedNode(237 /* DebuggerStatement */);
    }
    ts.createDebuggerStatement = createDebuggerStatement;
    function createVariableDeclaration(name, type, initializer) {
        var node = createSynthesizedNode(238 /* VariableDeclaration */);
        node.name = asName(name);
        node.type = type;
        node.initializer = initializer !== undefined ? ts.parenthesizeExpressionForList(initializer) : undefined;
        return node;
    }
    ts.createVariableDeclaration = createVariableDeclaration;
    function updateVariableDeclaration(node, name, type, initializer) {
        return node.name !== name
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createVariableDeclaration(name, type, initializer), node)
            : node;
    }
    ts.updateVariableDeclaration = updateVariableDeclaration;
    function createVariableDeclarationList(declarations, flags) {
        if (flags === void 0) { flags = 0 /* None */; }
        var node = createSynthesizedNode(239 /* VariableDeclarationList */);
        node.flags |= flags & 3 /* BlockScoped */;
        node.declarations = createNodeArray(declarations);
        return node;
    }
    ts.createVariableDeclarationList = createVariableDeclarationList;
    function updateVariableDeclarationList(node, declarations) {
        return node.declarations !== declarations
            ? updateNode(createVariableDeclarationList(declarations, node.flags), node)
            : node;
    }
    ts.updateVariableDeclarationList = updateVariableDeclarationList;
    function createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        var node = createSynthesizedNode(240 /* FunctionDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.asteriskToken = asteriskToken;
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createFunctionDeclaration = createFunctionDeclaration;
    function updateFunctionDeclaration(node, decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.asteriskToken !== asteriskToken
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body), node)
            : node;
    }
    ts.updateFunctionDeclaration = updateFunctionDeclaration;
    function createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members) {
        var node = createSynthesizedNode(241 /* ClassDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.heritageClauses = asNodeArray(heritageClauses);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createClassDeclaration = createClassDeclaration;
    function updateClassDeclaration(node, decorators, modifiers, name, typeParameters, heritageClauses, members) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.heritageClauses !== heritageClauses
            || node.members !== members
            ? updateNode(createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node)
            : node;
    }
    ts.updateClassDeclaration = updateClassDeclaration;
    function createInterfaceDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members) {
        var node = createSynthesizedNode(242 /* InterfaceDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.heritageClauses = asNodeArray(heritageClauses);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createInterfaceDeclaration = createInterfaceDeclaration;
    function updateInterfaceDeclaration(node, decorators, modifiers, name, typeParameters, heritageClauses, members) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.heritageClauses !== heritageClauses
            || node.members !== members
            ? updateNode(createInterfaceDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node)
            : node;
    }
    ts.updateInterfaceDeclaration = updateInterfaceDeclaration;
    function createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type) {
        var node = createSynthesizedNode(243 /* TypeAliasDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.type = type;
        return node;
    }
    ts.createTypeAliasDeclaration = createTypeAliasDeclaration;
    function updateTypeAliasDeclaration(node, decorators, modifiers, name, typeParameters, type) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.type !== type
            ? updateNode(createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type), node)
            : node;
    }
    ts.updateTypeAliasDeclaration = updateTypeAliasDeclaration;
    function createEnumDeclaration(decorators, modifiers, name, members) {
        var node = createSynthesizedNode(244 /* EnumDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createEnumDeclaration = createEnumDeclaration;
    function updateEnumDeclaration(node, decorators, modifiers, name, members) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.members !== members
            ? updateNode(createEnumDeclaration(decorators, modifiers, name, members), node)
            : node;
    }
    ts.updateEnumDeclaration = updateEnumDeclaration;
    function createModuleDeclaration(decorators, modifiers, name, body, flags) {
        if (flags === void 0) { flags = 0 /* None */; }
        var node = createSynthesizedNode(245 /* ModuleDeclaration */);
        node.flags |= flags & (16 /* Namespace */ | 4 /* NestedNamespace */ | 512 /* GlobalAugmentation */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = name;
        node.body = body;
        return node;
    }
    ts.createModuleDeclaration = createModuleDeclaration;
    function updateModuleDeclaration(node, decorators, modifiers, name, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.body !== body
            ? updateNode(createModuleDeclaration(decorators, modifiers, name, body, node.flags), node)
            : node;
    }
    ts.updateModuleDeclaration = updateModuleDeclaration;
    function createModuleBlock(statements) {
        var node = createSynthesizedNode(246 /* ModuleBlock */);
        node.statements = createNodeArray(statements);
        return node;
    }
    ts.createModuleBlock = createModuleBlock;
    function updateModuleBlock(node, statements) {
        return node.statements !== statements
            ? updateNode(createModuleBlock(statements), node)
            : node;
    }
    ts.updateModuleBlock = updateModuleBlock;
    function createCaseBlock(clauses) {
        var node = createSynthesizedNode(247 /* CaseBlock */);
        node.clauses = createNodeArray(clauses);
        return node;
    }
    ts.createCaseBlock = createCaseBlock;
    function updateCaseBlock(node, clauses) {
        return node.clauses !== clauses
            ? updateNode(createCaseBlock(clauses), node)
            : node;
    }
    ts.updateCaseBlock = updateCaseBlock;
    function createNamespaceExportDeclaration(name) {
        var node = createSynthesizedNode(248 /* NamespaceExportDeclaration */);
        node.name = asName(name);
        return node;
    }
    ts.createNamespaceExportDeclaration = createNamespaceExportDeclaration;
    function updateNamespaceExportDeclaration(node, name) {
        return node.name !== name
            ? updateNode(createNamespaceExportDeclaration(name), node)
            : node;
    }
    ts.updateNamespaceExportDeclaration = updateNamespaceExportDeclaration;
    function createImportEqualsDeclaration(decorators, modifiers, name, moduleReference) {
        var node = createSynthesizedNode(249 /* ImportEqualsDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.moduleReference = moduleReference;
        return node;
    }
    ts.createImportEqualsDeclaration = createImportEqualsDeclaration;
    function updateImportEqualsDeclaration(node, decorators, modifiers, name, moduleReference) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.moduleReference !== moduleReference
            ? updateNode(createImportEqualsDeclaration(decorators, modifiers, name, moduleReference), node)
            : node;
    }
    ts.updateImportEqualsDeclaration = updateImportEqualsDeclaration;
    function createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier) {
        var node = createSynthesizedNode(250 /* ImportDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.importClause = importClause;
        node.moduleSpecifier = moduleSpecifier;
        return node;
    }
    ts.createImportDeclaration = createImportDeclaration;
    function updateImportDeclaration(node, decorators, modifiers, importClause, moduleSpecifier) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.importClause !== importClause
            || node.moduleSpecifier !== moduleSpecifier
            ? updateNode(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier), node)
            : node;
    }
    ts.updateImportDeclaration = updateImportDeclaration;
    function createImportClause(name, namedBindings) {
        var node = createSynthesizedNode(251 /* ImportClause */);
        node.name = name;
        node.namedBindings = namedBindings;
        return node;
    }
    ts.createImportClause = createImportClause;
    function updateImportClause(node, name, namedBindings) {
        return node.name !== name
            || node.namedBindings !== namedBindings
            ? updateNode(createImportClause(name, namedBindings), node)
            : node;
    }
    ts.updateImportClause = updateImportClause;
    function createNamespaceImport(name) {
        var node = createSynthesizedNode(252 /* NamespaceImport */);
        node.name = name;
        return node;
    }
    ts.createNamespaceImport = createNamespaceImport;
    function updateNamespaceImport(node, name) {
        return node.name !== name
            ? updateNode(createNamespaceImport(name), node)
            : node;
    }
    ts.updateNamespaceImport = updateNamespaceImport;
    function createNamedImports(elements) {
        var node = createSynthesizedNode(253 /* NamedImports */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createNamedImports = createNamedImports;
    function updateNamedImports(node, elements) {
        return node.elements !== elements
            ? updateNode(createNamedImports(elements), node)
            : node;
    }
    ts.updateNamedImports = updateNamedImports;
    function createImportSpecifier(propertyName, name) {
        var node = createSynthesizedNode(254 /* ImportSpecifier */);
        node.propertyName = propertyName;
        node.name = name;
        return node;
    }
    ts.createImportSpecifier = createImportSpecifier;
    function updateImportSpecifier(node, propertyName, name) {
        return node.propertyName !== propertyName
            || node.name !== name
            ? updateNode(createImportSpecifier(propertyName, name), node)
            : node;
    }
    ts.updateImportSpecifier = updateImportSpecifier;
    function createExportAssignment(decorators, modifiers, isExportEquals, expression) {
        var node = createSynthesizedNode(255 /* ExportAssignment */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.isExportEquals = isExportEquals;
        node.expression = isExportEquals ? ts.parenthesizeBinaryOperand(60 /* EqualsToken */, expression, /*isLeftSideOfBinary*/ false, /*leftOperand*/ undefined) : ts.parenthesizeDefaultExpression(expression);
        return node;
    }
    ts.createExportAssignment = createExportAssignment;
    function updateExportAssignment(node, decorators, modifiers, expression) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.expression !== expression
            ? updateNode(createExportAssignment(decorators, modifiers, node.isExportEquals, expression), node)
            : node;
    }
    ts.updateExportAssignment = updateExportAssignment;
    function createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier) {
        var node = createSynthesizedNode(256 /* ExportDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.exportClause = exportClause;
        node.moduleSpecifier = moduleSpecifier;
        return node;
    }
    ts.createExportDeclaration = createExportDeclaration;
    function updateExportDeclaration(node, decorators, modifiers, exportClause, moduleSpecifier) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.exportClause !== exportClause
            || node.moduleSpecifier !== moduleSpecifier
            ? updateNode(createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier), node)
            : node;
    }
    ts.updateExportDeclaration = updateExportDeclaration;
    function createNamedExports(elements) {
        var node = createSynthesizedNode(257 /* NamedExports */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createNamedExports = createNamedExports;
    function updateNamedExports(node, elements) {
        return node.elements !== elements
            ? updateNode(createNamedExports(elements), node)
            : node;
    }
    ts.updateNamedExports = updateNamedExports;
    function createExportSpecifier(propertyName, name) {
        var node = createSynthesizedNode(258 /* ExportSpecifier */);
        node.propertyName = asName(propertyName);
        node.name = asName(name);
        return node;
    }
    ts.createExportSpecifier = createExportSpecifier;
    function updateExportSpecifier(node, propertyName, name) {
        return node.propertyName !== propertyName
            || node.name !== name
            ? updateNode(createExportSpecifier(propertyName, name), node)
            : node;
    }
    ts.updateExportSpecifier = updateExportSpecifier;
    // Module references
    function createExternalModuleReference(expression) {
        var node = createSynthesizedNode(260 /* ExternalModuleReference */);
        node.expression = expression;
        return node;
    }
    ts.createExternalModuleReference = createExternalModuleReference;
    function updateExternalModuleReference(node, expression) {
        return node.expression !== expression
            ? updateNode(createExternalModuleReference(expression), node)
            : node;
    }
    ts.updateExternalModuleReference = updateExternalModuleReference;
    // JSDoc
    /* @internal */
    function createJSDocTypeExpression(type) {
        var node = createSynthesizedNode(289 /* JSDocTypeExpression */);
        node.type = type;
        return node;
    }
    ts.createJSDocTypeExpression = createJSDocTypeExpression;
    /* @internal */
    function createJSDocTypeTag(typeExpression, comment) {
        var tag = createJSDocTag(308 /* JSDocTypeTag */, "type");
        tag.typeExpression = typeExpression;
        tag.comment = comment;
        return tag;
    }
    ts.createJSDocTypeTag = createJSDocTypeTag;
    /* @internal */
    function createJSDocReturnTag(typeExpression, comment) {
        var tag = createJSDocTag(306 /* JSDocReturnTag */, "returns");
        tag.typeExpression = typeExpression;
        tag.comment = comment;
        return tag;
    }
    ts.createJSDocReturnTag = createJSDocReturnTag;
    /* @internal */
    function createJSDocParamTag(name, isBracketed, typeExpression, comment) {
        var tag = createJSDocTag(305 /* JSDocParameterTag */, "param");
        tag.typeExpression = typeExpression;
        tag.name = name;
        tag.isBracketed = isBracketed;
        tag.comment = comment;
        return tag;
    }
    ts.createJSDocParamTag = createJSDocParamTag;
    /* @internal */
    function createJSDocComment(comment, tags) {
        var node = createSynthesizedNode(297 /* JSDocComment */);
        node.comment = comment;
        node.tags = tags;
        return node;
    }
    ts.createJSDocComment = createJSDocComment;
    /* @internal */
    function createJSDocTag(kind, tagName) {
        var node = createSynthesizedNode(kind);
        node.tagName = createIdentifier(tagName);
        return node;
    }
    // JSX
    function createJsxElement(openingElement, children, closingElement) {
        var node = createSynthesizedNode(261 /* JsxElement */);
        node.openingElement = openingElement;
        node.children = createNodeArray(children);
        node.closingElement = closingElement;
        return node;
    }
    ts.createJsxElement = createJsxElement;
    function updateJsxElement(node, openingElement, children, closingElement) {
        return node.openingElement !== openingElement
            || node.children !== children
            || node.closingElement !== closingElement
            ? updateNode(createJsxElement(openingElement, children, closingElement), node)
            : node;
    }
    ts.updateJsxElement = updateJsxElement;
    function createJsxSelfClosingElement(tagName, typeArguments, attributes) {
        var node = createSynthesizedNode(262 /* JsxSelfClosingElement */);
        node.tagName = tagName;
        node.typeArguments = asNodeArray(typeArguments);
        node.attributes = attributes;
        return node;
    }
    ts.createJsxSelfClosingElement = createJsxSelfClosingElement;
    function updateJsxSelfClosingElement(node, tagName, typeArguments, attributes) {
        return node.tagName !== tagName
            || node.typeArguments !== typeArguments
            || node.attributes !== attributes
            ? updateNode(createJsxSelfClosingElement(tagName, typeArguments, attributes), node)
            : node;
    }
    ts.updateJsxSelfClosingElement = updateJsxSelfClosingElement;
    function createJsxOpeningElement(tagName, typeArguments, attributes) {
        var node = createSynthesizedNode(263 /* JsxOpeningElement */);
        node.tagName = tagName;
        node.typeArguments = asNodeArray(typeArguments);
        node.attributes = attributes;
        return node;
    }
    ts.createJsxOpeningElement = createJsxOpeningElement;
    function updateJsxOpeningElement(node, tagName, typeArguments, attributes) {
        return node.tagName !== tagName
            || node.typeArguments !== typeArguments
            || node.attributes !== attributes
            ? updateNode(createJsxOpeningElement(tagName, typeArguments, attributes), node)
            : node;
    }
    ts.updateJsxOpeningElement = updateJsxOpeningElement;
    function createJsxClosingElement(tagName) {
        var node = createSynthesizedNode(264 /* JsxClosingElement */);
        node.tagName = tagName;
        return node;
    }
    ts.createJsxClosingElement = createJsxClosingElement;
    function updateJsxClosingElement(node, tagName) {
        return node.tagName !== tagName
            ? updateNode(createJsxClosingElement(tagName), node)
            : node;
    }
    ts.updateJsxClosingElement = updateJsxClosingElement;
    function createJsxFragment(openingFragment, children, closingFragment) {
        var node = createSynthesizedNode(265 /* JsxFragment */);
        node.openingFragment = openingFragment;
        node.children = createNodeArray(children);
        node.closingFragment = closingFragment;
        return node;
    }
    ts.createJsxFragment = createJsxFragment;
    function createJsxText(text, containsOnlyTriviaWhiteSpaces) {
        var node = createSynthesizedNode(11 /* JsxText */);
        node.text = text;
        node.containsOnlyTriviaWhiteSpaces = !!containsOnlyTriviaWhiteSpaces;
        return node;
    }
    ts.createJsxText = createJsxText;
    function updateJsxText(node, text, containsOnlyTriviaWhiteSpaces) {
        return node.text !== text
            || node.containsOnlyTriviaWhiteSpaces !== containsOnlyTriviaWhiteSpaces
            ? updateNode(createJsxText(text, containsOnlyTriviaWhiteSpaces), node)
            : node;
    }
    ts.updateJsxText = updateJsxText;
    function createJsxOpeningFragment() {
        return createSynthesizedNode(266 /* JsxOpeningFragment */);
    }
    ts.createJsxOpeningFragment = createJsxOpeningFragment;
    function createJsxJsxClosingFragment() {
        return createSynthesizedNode(267 /* JsxClosingFragment */);
    }
    ts.createJsxJsxClosingFragment = createJsxJsxClosingFragment;
    function updateJsxFragment(node, openingFragment, children, closingFragment) {
        return node.openingFragment !== openingFragment
            || node.children !== children
            || node.closingFragment !== closingFragment
            ? updateNode(createJsxFragment(openingFragment, children, closingFragment), node)
            : node;
    }
    ts.updateJsxFragment = updateJsxFragment;
    function createJsxAttribute(name, initializer) {
        var node = createSynthesizedNode(268 /* JsxAttribute */);
        node.name = name;
        node.initializer = initializer;
        return node;
    }
    ts.createJsxAttribute = createJsxAttribute;
    function updateJsxAttribute(node, name, initializer) {
        return node.name !== name
            || node.initializer !== initializer
            ? updateNode(createJsxAttribute(name, initializer), node)
            : node;
    }
    ts.updateJsxAttribute = updateJsxAttribute;
    function createJsxAttributes(properties) {
        var node = createSynthesizedNode(269 /* JsxAttributes */);
        node.properties = createNodeArray(properties);
        return node;
    }
    ts.createJsxAttributes = createJsxAttributes;
    function updateJsxAttributes(node, properties) {
        return node.properties !== properties
            ? updateNode(createJsxAttributes(properties), node)
            : node;
    }
    ts.updateJsxAttributes = updateJsxAttributes;
    function createJsxSpreadAttribute(expression) {
        var node = createSynthesizedNode(270 /* JsxSpreadAttribute */);
        node.expression = expression;
        return node;
    }
    ts.createJsxSpreadAttribute = createJsxSpreadAttribute;
    function updateJsxSpreadAttribute(node, expression) {
        return node.expression !== expression
            ? updateNode(createJsxSpreadAttribute(expression), node)
            : node;
    }
    ts.updateJsxSpreadAttribute = updateJsxSpreadAttribute;
    function createJsxExpression(dotDotDotToken, expression) {
        var node = createSynthesizedNode(271 /* JsxExpression */);
        node.dotDotDotToken = dotDotDotToken;
        node.expression = expression;
        return node;
    }
    ts.createJsxExpression = createJsxExpression;
    function updateJsxExpression(node, expression) {
        return node.expression !== expression
            ? updateNode(createJsxExpression(node.dotDotDotToken, expression), node)
            : node;
    }
    ts.updateJsxExpression = updateJsxExpression;
    // Clauses
    function createCaseClause(expression, statements) {
        var node = createSynthesizedNode(272 /* CaseClause */);
        node.expression = ts.parenthesizeExpressionForList(expression);
        node.statements = createNodeArray(statements);
        return node;
    }
    ts.createCaseClause = createCaseClause;
    function updateCaseClause(node, expression, statements) {
        return node.expression !== expression
            || node.statements !== statements
            ? updateNode(createCaseClause(expression, statements), node)
            : node;
    }
    ts.updateCaseClause = updateCaseClause;
    function createDefaultClause(statements) {
        var node = createSynthesizedNode(273 /* DefaultClause */);
        node.statements = createNodeArray(statements);
        return node;
    }
    ts.createDefaultClause = createDefaultClause;
    function updateDefaultClause(node, statements) {
        return node.statements !== statements
            ? updateNode(createDefaultClause(statements), node)
            : node;
    }
    ts.updateDefaultClause = updateDefaultClause;
    function createHeritageClause(token, types) {
        var node = createSynthesizedNode(274 /* HeritageClause */);
        node.token = token;
        node.types = createNodeArray(types);
        return node;
    }
    ts.createHeritageClause = createHeritageClause;
    function updateHeritageClause(node, types) {
        return node.types !== types
            ? updateNode(createHeritageClause(node.token, types), node)
            : node;
    }
    ts.updateHeritageClause = updateHeritageClause;
    function createCatchClause(variableDeclaration, block) {
        var node = createSynthesizedNode(275 /* CatchClause */);
        node.variableDeclaration = ts.isString(variableDeclaration) ? createVariableDeclaration(variableDeclaration) : variableDeclaration;
        node.block = block;
        return node;
    }
    ts.createCatchClause = createCatchClause;
    function updateCatchClause(node, variableDeclaration, block) {
        return node.variableDeclaration !== variableDeclaration
            || node.block !== block
            ? updateNode(createCatchClause(variableDeclaration, block), node)
            : node;
    }
    ts.updateCatchClause = updateCatchClause;
    // Property assignments
    function createPropertyAssignment(name, initializer) {
        var node = createSynthesizedNode(276 /* PropertyAssignment */);
        node.name = asName(name);
        node.questionToken = undefined;
        node.initializer = ts.parenthesizeExpressionForList(initializer);
        return node;
    }
    ts.createPropertyAssignment = createPropertyAssignment;
    function updatePropertyAssignment(node, name, initializer) {
        return node.name !== name
            || node.initializer !== initializer
            ? updateNode(createPropertyAssignment(name, initializer), node)
            : node;
    }
    ts.updatePropertyAssignment = updatePropertyAssignment;
    function createShorthandPropertyAssignment(name, objectAssignmentInitializer) {
        var node = createSynthesizedNode(277 /* ShorthandPropertyAssignment */);
        node.name = asName(name);
        node.objectAssignmentInitializer = objectAssignmentInitializer !== undefined ? ts.parenthesizeExpressionForList(objectAssignmentInitializer) : undefined;
        return node;
    }
    ts.createShorthandPropertyAssignment = createShorthandPropertyAssignment;
    function updateShorthandPropertyAssignment(node, name, objectAssignmentInitializer) {
        return node.name !== name
            || node.objectAssignmentInitializer !== objectAssignmentInitializer
            ? updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer), node)
            : node;
    }
    ts.updateShorthandPropertyAssignment = updateShorthandPropertyAssignment;
    function createSpreadAssignment(expression) {
        var node = createSynthesizedNode(278 /* SpreadAssignment */);
        node.expression = ts.parenthesizeExpressionForList(expression);
        return node;
    }
    ts.createSpreadAssignment = createSpreadAssignment;
    function updateSpreadAssignment(node, expression) {
        return node.expression !== expression
            ? updateNode(createSpreadAssignment(expression), node)
            : node;
    }
    ts.updateSpreadAssignment = updateSpreadAssignment;
    // Enum
    function createEnumMember(name, initializer) {
        var node = createSynthesizedNode(279 /* EnumMember */);
        node.name = asName(name);
        node.initializer = initializer && ts.parenthesizeExpressionForList(initializer);
        return node;
    }
    ts.createEnumMember = createEnumMember;
    function updateEnumMember(node, name, initializer) {
        return node.name !== name
            || node.initializer !== initializer
            ? updateNode(createEnumMember(name, initializer), node)
            : node;
    }
    ts.updateEnumMember = updateEnumMember;
    // Top-level nodes
    function updateSourceFileNode(node, statements, isDeclarationFile, referencedFiles, typeReferences, hasNoDefaultLib, libReferences) {
        if (node.statements !== statements ||
            (isDeclarationFile !== undefined && node.isDeclarationFile !== isDeclarationFile) ||
            (referencedFiles !== undefined && node.referencedFiles !== referencedFiles) ||
            (typeReferences !== undefined && node.typeReferenceDirectives !== typeReferences) ||
            (libReferences !== undefined && node.libReferenceDirectives !== libReferences) ||
            (hasNoDefaultLib !== undefined && node.hasNoDefaultLib !== hasNoDefaultLib)) {
            var updated = createSynthesizedNode(285 /* SourceFile */);
            updated.flags |= node.flags;
            updated.statements = createNodeArray(statements);
            updated.endOfFileToken = node.endOfFileToken;
            updated.fileName = node.fileName;
            updated.path = node.path;
            updated.text = node.text;
            updated.isDeclarationFile = isDeclarationFile === undefined ? node.isDeclarationFile : isDeclarationFile;
            updated.referencedFiles = referencedFiles === undefined ? node.referencedFiles : referencedFiles;
            updated.typeReferenceDirectives = typeReferences === undefined ? node.typeReferenceDirectives : typeReferences;
            updated.hasNoDefaultLib = hasNoDefaultLib === undefined ? node.hasNoDefaultLib : hasNoDefaultLib;
            updated.libReferenceDirectives = libReferences === undefined ? node.libReferenceDirectives : libReferences;
            if (node.amdDependencies !== undefined)
                updated.amdDependencies = node.amdDependencies;
            if (node.moduleName !== undefined)
                updated.moduleName = node.moduleName;
            if (node.languageVariant !== undefined)
                updated.languageVariant = node.languageVariant;
            if (node.renamedDependencies !== undefined)
                updated.renamedDependencies = node.renamedDependencies;
            if (node.languageVersion !== undefined)
                updated.languageVersion = node.languageVersion;
            if (node.scriptKind !== undefined)
                updated.scriptKind = node.scriptKind;
            if (node.externalModuleIndicator !== undefined)
                updated.externalModuleIndicator = node.externalModuleIndicator;
            if (node.commonJsModuleIndicator !== undefined)
                updated.commonJsModuleIndicator = node.commonJsModuleIndicator;
            if (node.identifiers !== undefined)
                updated.identifiers = node.identifiers;
            if (node.nodeCount !== undefined)
                updated.nodeCount = node.nodeCount;
            if (node.identifierCount !== undefined)
                updated.identifierCount = node.identifierCount;
            if (node.symbolCount !== undefined)
                updated.symbolCount = node.symbolCount;
            if (node.parseDiagnostics !== undefined)
                updated.parseDiagnostics = node.parseDiagnostics;
            if (node.bindDiagnostics !== undefined)
                updated.bindDiagnostics = node.bindDiagnostics;
            if (node.bindSuggestionDiagnostics !== undefined)
                updated.bindSuggestionDiagnostics = node.bindSuggestionDiagnostics;
            if (node.lineMap !== undefined)
                updated.lineMap = node.lineMap;
            if (node.classifiableNames !== undefined)
                updated.classifiableNames = node.classifiableNames;
            if (node.resolvedModules !== undefined)
                updated.resolvedModules = node.resolvedModules;
            if (node.resolvedTypeReferenceDirectiveNames !== undefined)
                updated.resolvedTypeReferenceDirectiveNames = node.resolvedTypeReferenceDirectiveNames;
            if (node.imports !== undefined)
                updated.imports = node.imports;
            if (node.moduleAugmentations !== undefined)
                updated.moduleAugmentations = node.moduleAugmentations;
            if (node.pragmas !== undefined)
                updated.pragmas = node.pragmas;
            if (node.localJsxFactory !== undefined)
                updated.localJsxFactory = node.localJsxFactory;
            if (node.localJsxNamespace !== undefined)
                updated.localJsxNamespace = node.localJsxNamespace;
            return updateNode(updated, node);
        }
        return node;
    }
    ts.updateSourceFileNode = updateSourceFileNode;
    /**
     * Creates a shallow, memberwise clone of a node for mutation.
     */
    function getMutableClone(node) {
        var clone = getSynthesizedClone(node);
        clone.pos = node.pos;
        clone.end = node.end;
        clone.parent = node.parent;
        return clone;
    }
    ts.getMutableClone = getMutableClone;
    // Transformation nodes
    /**
     * Creates a synthetic statement to act as a placeholder for a not-emitted statement in
     * order to preserve comments.
     *
     * @param original The original statement.
     */
    function createNotEmittedStatement(original) {
        var node = createSynthesizedNode(313 /* NotEmittedStatement */);
        node.original = original;
        setTextRange(node, original);
        return node;
    }
    ts.createNotEmittedStatement = createNotEmittedStatement;
    /**
     * Creates a synthetic element to act as a placeholder for the end of an emitted declaration in
     * order to properly emit exports.
     */
    /* @internal */
    function createEndOfDeclarationMarker(original) {
        var node = createSynthesizedNode(317 /* EndOfDeclarationMarker */);
        node.emitNode = {};
        node.original = original;
        return node;
    }
    ts.createEndOfDeclarationMarker = createEndOfDeclarationMarker;
    /**
     * Creates a synthetic element to act as a placeholder for the beginning of a merged declaration in
     * order to properly emit exports.
     */
    /* @internal */
    function createMergeDeclarationMarker(original) {
        var node = createSynthesizedNode(316 /* MergeDeclarationMarker */);
        node.emitNode = {};
        node.original = original;
        return node;
    }
    ts.createMergeDeclarationMarker = createMergeDeclarationMarker;
    /**
     * Creates a synthetic expression to act as a placeholder for a not-emitted expression in
     * order to preserve comments or sourcemap positions.
     *
     * @param expression The inner expression to emit.
     * @param original The original outer expression.
     * @param location The location for the expression. Defaults to the positions from "original" if provided.
     */
    function createPartiallyEmittedExpression(expression, original) {
        var node = createSynthesizedNode(314 /* PartiallyEmittedExpression */);
        node.expression = expression;
        node.original = original;
        setTextRange(node, original);
        return node;
    }
    ts.createPartiallyEmittedExpression = createPartiallyEmittedExpression;
    function updatePartiallyEmittedExpression(node, expression) {
        if (node.expression !== expression) {
            return updateNode(createPartiallyEmittedExpression(expression, node.original), node);
        }
        return node;
    }
    ts.updatePartiallyEmittedExpression = updatePartiallyEmittedExpression;
    function flattenCommaElements(node) {
        if (ts.nodeIsSynthesized(node) && !ts.isParseTreeNode(node) && !node.original && !node.emitNode && !node.id) {
            if (node.kind === 315 /* CommaListExpression */) {
                return node.elements;
            }
            if (ts.isBinaryExpression(node) && node.operatorToken.kind === 27 /* CommaToken */) {
                return [node.left, node.right];
            }
        }
        return node;
    }
    function createCommaList(elements) {
        var node = createSynthesizedNode(315 /* CommaListExpression */);
        node.elements = createNodeArray(ts.sameFlatMap(elements, flattenCommaElements));
        return node;
    }
    ts.createCommaList = createCommaList;
    function updateCommaList(node, elements) {
        return node.elements !== elements
            ? updateNode(createCommaList(elements), node)
            : node;
    }
    ts.updateCommaList = updateCommaList;
    function createBundle(sourceFiles, prepends) {
        if (prepends === void 0) { prepends = ts.emptyArray; }
        var node = ts.createNode(286 /* Bundle */);
        node.prepends = prepends;
        node.sourceFiles = sourceFiles;
        return node;
    }
    ts.createBundle = createBundle;
    var allUnscopedEmitHelpers;
    function getAllUnscopedEmitHelpers() {
        return allUnscopedEmitHelpers || (allUnscopedEmitHelpers = ts.arrayToMap([
            ts.valuesHelper,
            ts.readHelper,
            ts.spreadHelper,
            ts.restHelper,
            ts.decorateHelper,
            ts.metadataHelper,
            ts.paramHelper,
            ts.awaiterHelper,
            ts.assignHelper,
            ts.awaitHelper,
            ts.asyncGeneratorHelper,
            ts.asyncDelegator,
            ts.asyncValues,
            ts.extendsHelper,
            ts.templateObjectHelper,
            ts.generatorHelper,
            ts.importStarHelper,
            ts.importDefaultHelper
        ], function (helper) { return helper.name; }));
    }
    function createUnparsedSource() {
        var node = ts.createNode(287 /* UnparsedSource */);
        node.prologues = ts.emptyArray;
        node.referencedFiles = ts.emptyArray;
        node.libReferenceDirectives = ts.emptyArray;
        node.getLineAndCharacterOfPosition = function (pos) { return ts.getLineAndCharacterOfPosition(node, pos); };
        return node;
    }
    function createUnparsedSourceFile(textOrInputFiles, mapPathOrType, mapTextOrStripInternal) {
        var node = createUnparsedSource();
        var stripInternal;
        var bundleFileInfo;
        if (!ts.isString(textOrInputFiles)) {
            ts.Debug.assert(mapPathOrType === "js" || mapPathOrType === "dts");
            node.fileName = (mapPathOrType === "js" ? textOrInputFiles.javascriptPath : textOrInputFiles.declarationPath) || "";
            node.sourceMapPath = mapPathOrType === "js" ? textOrInputFiles.javascriptMapPath : textOrInputFiles.declarationMapPath;
            Object.defineProperties(node, {
                text: { get: function () { return mapPathOrType === "js" ? textOrInputFiles.javascriptText : textOrInputFiles.declarationText; } },
                sourceMapText: { get: function () { return mapPathOrType === "js" ? textOrInputFiles.javascriptMapText : textOrInputFiles.declarationMapText; } },
            });
            if (textOrInputFiles.buildInfo && textOrInputFiles.buildInfo.bundle) {
                node.oldFileOfCurrentEmit = textOrInputFiles.oldFileOfCurrentEmit;
                ts.Debug.assert(mapTextOrStripInternal === undefined || typeof mapTextOrStripInternal === "boolean");
                stripInternal = mapTextOrStripInternal;
                bundleFileInfo = mapPathOrType === "js" ? textOrInputFiles.buildInfo.bundle.js : textOrInputFiles.buildInfo.bundle.dts;
                if (node.oldFileOfCurrentEmit) {
                    parseOldFileOfCurrentEmit(node, ts.Debug.assertDefined(bundleFileInfo));
                    return node;
                }
            }
        }
        else {
            node.fileName = "";
            node.text = textOrInputFiles;
            node.sourceMapPath = mapPathOrType;
            node.sourceMapText = mapTextOrStripInternal;
        }
        ts.Debug.assert(!node.oldFileOfCurrentEmit);
        parseUnparsedSourceFile(node, bundleFileInfo, stripInternal);
        return node;
    }
    ts.createUnparsedSourceFile = createUnparsedSourceFile;
    function parseUnparsedSourceFile(node, bundleFileInfo, stripInternal) {
        var prologues;
        var helpers;
        var referencedFiles;
        var typeReferenceDirectives;
        var libReferenceDirectives;
        var texts;
        for (var _i = 0, _a = bundleFileInfo ? bundleFileInfo.sections : ts.emptyArray; _i < _a.length; _i++) {
            var section = _a[_i];
            switch (section.kind) {
                case "prologue" /* Prologue */:
                    (prologues || (prologues = [])).push(createUnparsedNode(section, node));
                    break;
                case "emitHelpers" /* EmitHelpers */:
                    (helpers || (helpers = [])).push(getAllUnscopedEmitHelpers().get(section.data));
                    break;
                case "no-default-lib" /* NoDefaultLib */:
                    node.hasNoDefaultLib = true;
                    break;
                case "reference" /* Reference */:
                    (referencedFiles || (referencedFiles = [])).push({ pos: -1, end: -1, fileName: section.data });
                    break;
                case "type" /* Type */:
                    (typeReferenceDirectives || (typeReferenceDirectives = [])).push(section.data);
                    break;
                case "lib" /* Lib */:
                    (libReferenceDirectives || (libReferenceDirectives = [])).push({ pos: -1, end: -1, fileName: section.data });
                    break;
                case "prepend" /* Prepend */:
                    var prependNode = createUnparsedNode(section, node);
                    var prependTexts = void 0;
                    for (var _b = 0, _c = section.texts; _b < _c.length; _b++) {
                        var text = _c[_b];
                        if (!stripInternal || text.kind !== "internal" /* Internal */) {
                            (prependTexts || (prependTexts = [])).push(createUnparsedNode(text, node));
                        }
                    }
                    prependNode.texts = prependTexts || ts.emptyArray;
                    (texts || (texts = [])).push(prependNode);
                    break;
                case "internal" /* Internal */:
                    if (stripInternal)
                        break;
                // falls through
                case "text" /* Text */:
                    (texts || (texts = [])).push(createUnparsedNode(section, node));
                    break;
                default:
                    ts.Debug.assertNever(section);
            }
        }
        node.prologues = prologues || ts.emptyArray;
        node.helpers = helpers;
        node.referencedFiles = referencedFiles || ts.emptyArray;
        node.typeReferenceDirectives = typeReferenceDirectives;
        node.libReferenceDirectives = libReferenceDirectives || ts.emptyArray;
        node.texts = texts || [createUnparsedNode({ kind: "text" /* Text */, pos: 0, end: node.text.length }, node)];
    }
    function parseOldFileOfCurrentEmit(node, bundleFileInfo) {
        ts.Debug.assert(!!node.oldFileOfCurrentEmit);
        var texts;
        var syntheticReferences;
        for (var _i = 0, _a = bundleFileInfo.sections; _i < _a.length; _i++) {
            var section = _a[_i];
            switch (section.kind) {
                case "internal" /* Internal */:
                case "text" /* Text */:
                    (texts || (texts = [])).push(createUnparsedNode(section, node));
                    break;
                case "no-default-lib" /* NoDefaultLib */:
                case "reference" /* Reference */:
                case "type" /* Type */:
                case "lib" /* Lib */:
                    (syntheticReferences || (syntheticReferences = [])).push(createUnparsedSyntheticReference(section, node));
                    break;
                // Ignore
                case "prologue" /* Prologue */:
                case "emitHelpers" /* EmitHelpers */:
                case "prepend" /* Prepend */:
                    break;
                default:
                    ts.Debug.assertNever(section);
            }
        }
        node.texts = texts || ts.emptyArray;
        node.helpers = ts.map(bundleFileInfo.sources && bundleFileInfo.sources.helpers, function (name) { return getAllUnscopedEmitHelpers().get(name); });
        node.syntheticReferences = syntheticReferences;
        return node;
    }
    function mapBundleFileSectionKindToSyntaxKind(kind) {
        switch (kind) {
            case "prologue" /* Prologue */: return 280 /* UnparsedPrologue */;
            case "prepend" /* Prepend */: return 281 /* UnparsedPrepend */;
            case "internal" /* Internal */: return 283 /* UnparsedInternalText */;
            case "text" /* Text */: return 282 /* UnparsedText */;
            case "emitHelpers" /* EmitHelpers */:
            case "no-default-lib" /* NoDefaultLib */:
            case "reference" /* Reference */:
            case "type" /* Type */:
            case "lib" /* Lib */:
                return ts.Debug.fail("BundleFileSectionKind: " + kind + " not yet mapped to SyntaxKind");
            default:
                return ts.Debug.assertNever(kind);
        }
    }
    function createUnparsedNode(section, parent) {
        var node = ts.createNode(mapBundleFileSectionKindToSyntaxKind(section.kind), section.pos, section.end);
        node.parent = parent;
        node.data = section.data;
        return node;
    }
    function createUnparsedSyntheticReference(section, parent) {
        var node = ts.createNode(284 /* UnparsedSyntheticReference */, section.pos, section.end);
        node.parent = parent;
        node.data = section.data;
        node.section = section;
        return node;
    }
    function createInputFiles(javascriptTextOrReadFileText, declarationTextOrJavascriptPath, javascriptMapPath, javascriptMapTextOrDeclarationPath, declarationMapPath, declarationMapTextOrBuildInfoPath, javascriptPath, declarationPath, buildInfoPath, buildInfo, oldFileOfCurrentEmit) {
        var node = ts.createNode(288 /* InputFiles */);
        if (!ts.isString(javascriptTextOrReadFileText)) {
            var cache_1 = ts.createMap();
            var textGetter_1 = function (path) {
                if (path === undefined)
                    return undefined;
                var value = cache_1.get(path);
                if (value === undefined) {
                    value = javascriptTextOrReadFileText(path);
                    cache_1.set(path, value !== undefined ? value : false);
                }
                return value !== false ? value : undefined;
            };
            var definedTextGetter_1 = function (path) {
                var result = textGetter_1(path);
                return result !== undefined ? result : "/* Input file " + path + " was missing */\r\n";
            };
            var buildInfo_1;
            var getAndCacheBuildInfo_1 = function (getText) {
                if (buildInfo_1 === undefined) {
                    var result = getText();
                    buildInfo_1 = result !== undefined ? ts.getBuildInfo(result) : false;
                }
                return buildInfo_1 || undefined;
            };
            node.javascriptPath = declarationTextOrJavascriptPath;
            node.javascriptMapPath = javascriptMapPath;
            node.declarationPath = ts.Debug.assertDefined(javascriptMapTextOrDeclarationPath);
            node.declarationMapPath = declarationMapPath;
            node.buildInfoPath = declarationMapTextOrBuildInfoPath;
            Object.defineProperties(node, {
                javascriptText: { get: function () { return definedTextGetter_1(declarationTextOrJavascriptPath); } },
                javascriptMapText: { get: function () { return textGetter_1(javascriptMapPath); } },
                declarationText: { get: function () { return definedTextGetter_1(ts.Debug.assertDefined(javascriptMapTextOrDeclarationPath)); } },
                declarationMapText: { get: function () { return textGetter_1(declarationMapPath); } },
                buildInfo: { get: function () { return getAndCacheBuildInfo_1(function () { return textGetter_1(declarationMapTextOrBuildInfoPath); }); } }
            });
        }
        else {
            node.javascriptText = javascriptTextOrReadFileText;
            node.javascriptMapPath = javascriptMapPath;
            node.javascriptMapText = javascriptMapTextOrDeclarationPath;
            node.declarationText = declarationTextOrJavascriptPath;
            node.declarationMapPath = declarationMapPath;
            node.declarationMapText = declarationMapTextOrBuildInfoPath;
            node.javascriptPath = javascriptPath;
            node.declarationPath = declarationPath,
                node.buildInfoPath = buildInfoPath;
            node.buildInfo = buildInfo;
            node.oldFileOfCurrentEmit = oldFileOfCurrentEmit;
        }
        return node;
    }
    ts.createInputFiles = createInputFiles;
    function updateBundle(node, sourceFiles, prepends) {
        if (prepends === void 0) { prepends = ts.emptyArray; }
        if (node.sourceFiles !== sourceFiles || node.prepends !== prepends) {
            return createBundle(sourceFiles, prepends);
        }
        return node;
    }
    ts.updateBundle = updateBundle;
    function createImmediatelyInvokedFunctionExpression(statements, param, paramValue) {
        return createCall(createFunctionExpression(
        /*modifiers*/ undefined, 
        /*asteriskToken*/ undefined, 
        /*name*/ undefined, 
        /*typeParameters*/ undefined, 
        /*parameters*/ param ? [param] : [], 
        /*type*/ undefined, createBlock(statements, /*multiLine*/ true)), 
        /*typeArguments*/ undefined, 
        /*argumentsArray*/ paramValue ? [paramValue] : []);
    }
    ts.createImmediatelyInvokedFunctionExpression = createImmediatelyInvokedFunctionExpression;
    function createImmediatelyInvokedArrowFunction(statements, param, paramValue) {
        return createCall(createArrowFunction(
        /*modifiers*/ undefined, 
        /*typeParameters*/ undefined, 
        /*parameters*/ param ? [param] : [], 
        /*type*/ undefined, 
        /*equalsGreaterThanToken*/ undefined, createBlock(statements, /*multiLine*/ true)), 
        /*typeArguments*/ undefined, 
        /*argumentsArray*/ paramValue ? [paramValue] : []);
    }
    ts.createImmediatelyInvokedArrowFunction = createImmediatelyInvokedArrowFunction;
    function createComma(left, right) {
        return createBinary(left, 27 /* CommaToken */, right);
    }
    ts.createComma = createComma;
    function createLessThan(left, right) {
        return createBinary(left, 28 /* LessThanToken */, right);
    }
    ts.createLessThan = createLessThan;
    function createAssignment(left, right) {
        return createBinary(left, 60 /* EqualsToken */, right);
    }
    ts.createAssignment = createAssignment;
    function createStrictEquality(left, right) {
        return createBinary(left, 35 /* EqualsEqualsEqualsToken */, right);
    }
    ts.createStrictEquality = createStrictEquality;
    function createStrictInequality(left, right) {
        return createBinary(left, 36 /* ExclamationEqualsEqualsToken */, right);
    }
    ts.createStrictInequality = createStrictInequality;
    function createAdd(left, right) {
        return createBinary(left, 38 /* PlusToken */, right);
    }
    ts.createAdd = createAdd;
    function createSubtract(left, right) {
        return createBinary(left, 39 /* MinusToken */, right);
    }
    ts.createSubtract = createSubtract;
    function createPostfixIncrement(operand) {
        return createPostfix(operand, 44 /* PlusPlusToken */);
    }
    ts.createPostfixIncrement = createPostfixIncrement;
    function createLogicalAnd(left, right) {
        return createBinary(left, 54 /* AmpersandAmpersandToken */, right);
    }
    ts.createLogicalAnd = createLogicalAnd;
    function createLogicalOr(left, right) {
        return createBinary(left, 55 /* BarBarToken */, right);
    }
    ts.createLogicalOr = createLogicalOr;
    function createLogicalNot(operand) {
        return createPrefix(52 /* ExclamationToken */, operand);
    }
    ts.createLogicalNot = createLogicalNot;
    function createVoidZero() {
        return createVoid(createLiteral(0));
    }
    ts.createVoidZero = createVoidZero;
    function createExportDefault(expression) {
        return createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, expression);
    }
    ts.createExportDefault = createExportDefault;
    function createExternalModuleExport(exportName) {
        return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(/*propertyName*/ undefined, exportName)]));
    }
    ts.createExternalModuleExport = createExternalModuleExport;
    // Utilities
    function asName(name) {
        return ts.isString(name) ? createIdentifier(name) : name;
    }
    function asExpression(value) {
        return ts.isString(value) || typeof value === "number" ? createLiteral(value) : value;
    }
    function asNodeArray(array) {
        return array ? createNodeArray(array) : undefined;
    }
    function asToken(value) {
        return typeof value === "number" ? createToken(value) : value;
    }
    /**
     * Clears any EmitNode entries from parse-tree nodes.
     * @param sourceFile A source file.
     */
    function disposeEmitNodes(sourceFile) {
        // During transformation we may need to annotate a parse tree node with transient
        // transformation properties. As parse tree nodes live longer than transformation
        // nodes, we need to make sure we reclaim any memory allocated for custom ranges
        // from these nodes to ensure we do not hold onto entire subtrees just for position
        // information. We also need to reset these nodes to a pre-transformation state
        // for incremental parsing scenarios so that we do not impact later emit.
        sourceFile = ts.getSourceFileOfNode(ts.getParseTreeNode(sourceFile));
        var emitNode = sourceFile && sourceFile.emitNode;
        var annotatedNodes = emitNode && emitNode.annotatedNodes;
        if (annotatedNodes) {
            for (var _i = 0, annotatedNodes_1 = annotatedNodes; _i < annotatedNodes_1.length; _i++) {
                var node = annotatedNodes_1[_i];
                node.emitNode = undefined;
            }
        }
    }
    ts.disposeEmitNodes = disposeEmitNodes;
    /**
     * Associates a node with the current transformation, initializing
     * various transient transformation properties.
     */
    /* @internal */
    function getOrCreateEmitNode(node) {
        if (!node.emitNode) {
            if (ts.isParseTreeNode(node)) {
                // To avoid holding onto transformation artifacts, we keep track of any
                // parse tree node we are annotating. This allows us to clean them up after
                // all transformations have completed.
                if (node.kind === 285 /* SourceFile */) {
                    return node.emitNode = { annotatedNodes: [node] };
                }
                var sourceFile = ts.getSourceFileOfNode(ts.getParseTreeNode(ts.getSourceFileOfNode(node)));
                getOrCreateEmitNode(sourceFile).annotatedNodes.push(node);
            }
            node.emitNode = {};
        }
        return node.emitNode;
    }
    ts.getOrCreateEmitNode = getOrCreateEmitNode;
    function setTextRange(range, location) {
        if (location) {
            range.pos = location.pos;
            range.end = location.end;
        }
        return range;
    }
    ts.setTextRange = setTextRange;
    /**
     * Sets flags that control emit behavior of a node.
     */
    function setEmitFlags(node, emitFlags) {
        getOrCreateEmitNode(node).flags = emitFlags;
        return node;
    }
    ts.setEmitFlags = setEmitFlags;
    /**
     * Sets flags that control emit behavior of a node.
     */
    /* @internal */
    function addEmitFlags(node, emitFlags) {
        var emitNode = getOrCreateEmitNode(node);
        emitNode.flags = emitNode.flags | emitFlags;
        return node;
    }
    ts.addEmitFlags = addEmitFlags;
    /**
     * Gets a custom text range to use when emitting source maps.
     */
    function getSourceMapRange(node) {
        var emitNode = node.emitNode;
        return (emitNode && emitNode.sourceMapRange) || node;
    }
    ts.getSourceMapRange = getSourceMapRange;
    /**
     * Sets a custom text range to use when emitting source maps.
     */
    function setSourceMapRange(node, range) {
        getOrCreateEmitNode(node).sourceMapRange = range;
        return node;
    }
    ts.setSourceMapRange = setSourceMapRange;
    // tslint:disable-next-line variable-name
    var SourceMapSource;
    /**
     * Create an external source map source file reference
     */
    function createSourceMapSource(fileName, text, skipTrivia) {
        return new (SourceMapSource || (SourceMapSource = ts.objectAllocator.getSourceMapSourceConstructor()))(fileName, text, skipTrivia);
    }
    ts.createSourceMapSource = createSourceMapSource;
    /**
     * Gets the TextRange to use for source maps for a token of a node.
     */
    function getTokenSourceMapRange(node, token) {
        var emitNode = node.emitNode;
        var tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges;
        return tokenSourceMapRanges && tokenSourceMapRanges[token];
    }
    ts.getTokenSourceMapRange = getTokenSourceMapRange;
    /**
     * Sets the TextRange to use for source maps for a token of a node.
     */
    function setTokenSourceMapRange(node, token, range) {
        var emitNode = getOrCreateEmitNode(node);
        var tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = []);
        tokenSourceMapRanges[token] = range;
        return node;
    }
    ts.setTokenSourceMapRange = setTokenSourceMapRange;
    /**
     * Gets a custom text range to use when emitting comments.
     */
    /*@internal*/
    function getStartsOnNewLine(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.startsOnNewLine;
    }
    ts.getStartsOnNewLine = getStartsOnNewLine;
    /**
     * Sets a custom text range to use when emitting comments.
     */
    /*@internal*/
    function setStartsOnNewLine(node, newLine) {
        getOrCreateEmitNode(node).startsOnNewLine = newLine;
        return node;
    }
    ts.setStartsOnNewLine = setStartsOnNewLine;
    /**
     * Gets a custom text range to use when emitting comments.
     */
    function getCommentRange(node) {
        var emitNode = node.emitNode;
        return (emitNode && emitNode.commentRange) || node;
    }
    ts.getCommentRange = getCommentRange;
    /**
     * Sets a custom text range to use when emitting comments.
     */
    function setCommentRange(node, range) {
        getOrCreateEmitNode(node).commentRange = range;
        return node;
    }
    ts.setCommentRange = setCommentRange;
    function getSyntheticLeadingComments(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.leadingComments;
    }
    ts.getSyntheticLeadingComments = getSyntheticLeadingComments;
    function setSyntheticLeadingComments(node, comments) {
        getOrCreateEmitNode(node).leadingComments = comments;
        return node;
    }
    ts.setSyntheticLeadingComments = setSyntheticLeadingComments;
    function addSyntheticLeadingComment(node, kind, text, hasTrailingNewLine) {
        return setSyntheticLeadingComments(node, ts.append(getSyntheticLeadingComments(node), { kind: kind, pos: -1, end: -1, hasTrailingNewLine: hasTrailingNewLine, text: text }));
    }
    ts.addSyntheticLeadingComment = addSyntheticLeadingComment;
    function getSyntheticTrailingComments(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.trailingComments;
    }
    ts.getSyntheticTrailingComments = getSyntheticTrailingComments;
    function setSyntheticTrailingComments(node, comments) {
        getOrCreateEmitNode(node).trailingComments = comments;
        return node;
    }
    ts.setSyntheticTrailingComments = setSyntheticTrailingComments;
    function addSyntheticTrailingComment(node, kind, text, hasTrailingNewLine) {
        return setSyntheticTrailingComments(node, ts.append(getSyntheticTrailingComments(node), { kind: kind, pos: -1, end: -1, hasTrailingNewLine: hasTrailingNewLine, text: text }));
    }
    ts.addSyntheticTrailingComment = addSyntheticTrailingComment;
    function moveSyntheticComments(node, original) {
        setSyntheticLeadingComments(node, getSyntheticLeadingComments(original));
        setSyntheticTrailingComments(node, getSyntheticTrailingComments(original));
        var emit = getOrCreateEmitNode(original);
        emit.leadingComments = undefined;
        emit.trailingComments = undefined;
        return node;
    }
    ts.moveSyntheticComments = moveSyntheticComments;
    /**
     * Gets the constant value to emit for an expression.
     */
    function getConstantValue(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.constantValue;
    }
    ts.getConstantValue = getConstantValue;
    /**
     * Sets the constant value to emit for an expression.
     */
    function setConstantValue(node, value) {
        var emitNode = getOrCreateEmitNode(node);
        emitNode.constantValue = value;
        return node;
    }
    ts.setConstantValue = setConstantValue;
    /**
     * Adds an EmitHelper to a node.
     */
    function addEmitHelper(node, helper) {
        var emitNode = getOrCreateEmitNode(node);
        emitNode.helpers = ts.append(emitNode.helpers, helper);
        return node;
    }
    ts.addEmitHelper = addEmitHelper;
    /**
     * Add EmitHelpers to a node.
     */
    function addEmitHelpers(node, helpers) {
        if (ts.some(helpers)) {
            var emitNode = getOrCreateEmitNode(node);
            for (var _i = 0, helpers_1 = helpers; _i < helpers_1.length; _i++) {
                var helper = helpers_1[_i];
                emitNode.helpers = ts.appendIfUnique(emitNode.helpers, helper);
            }
        }
        return node;
    }
    ts.addEmitHelpers = addEmitHelpers;
    /**
     * Removes an EmitHelper from a node.
     */
    function removeEmitHelper(node, helper) {
        var emitNode = node.emitNode;
        if (emitNode) {
            var helpers = emitNode.helpers;
            if (helpers) {
                return ts.orderedRemoveItem(helpers, helper);
            }
        }
        return false;
    }
    ts.removeEmitHelper = removeEmitHelper;
    /**
     * Gets the EmitHelpers of a node.
     */
    function getEmitHelpers(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.helpers;
    }
    ts.getEmitHelpers = getEmitHelpers;
    /**
     * Moves matching emit helpers from a source node to a target node.
     */
    function moveEmitHelpers(source, target, predicate) {
        var sourceEmitNode = source.emitNode;
        var sourceEmitHelpers = sourceEmitNode && sourceEmitNode.helpers;
        if (!ts.some(sourceEmitHelpers))
            return;
        var targetEmitNode = getOrCreateEmitNode(target);
        var helpersRemoved = 0;
        for (var i = 0; i < sourceEmitHelpers.length; i++) {
            var helper = sourceEmitHelpers[i];
            if (predicate(helper)) {
                helpersRemoved++;
                targetEmitNode.helpers = ts.appendIfUnique(targetEmitNode.helpers, helper);
            }
            else if (helpersRemoved > 0) {
                sourceEmitHelpers[i - helpersRemoved] = helper;
            }
        }
        if (helpersRemoved > 0) {
            sourceEmitHelpers.length -= helpersRemoved;
        }
    }
    ts.moveEmitHelpers = moveEmitHelpers;
    /* @internal */
    function compareEmitHelpers(x, y) {
        if (x === y)
            return 0 /* EqualTo */;
        if (x.priority === y.priority)
            return 0 /* EqualTo */;
        if (x.priority === undefined)
            return 1 /* GreaterThan */;
        if (y.priority === undefined)
            return -1 /* LessThan */;
        return ts.compareValues(x.priority, y.priority);
    }
    ts.compareEmitHelpers = compareEmitHelpers;
    function setOriginalNode(node, original) {
        node.original = original;
        if (original) {
            var emitNode = original.emitNode;
            if (emitNode)
                node.emitNode = mergeEmitNode(emitNode, node.emitNode);
        }
        return node;
    }
    ts.setOriginalNode = setOriginalNode;
    function mergeEmitNode(sourceEmitNode, destEmitNode) {
        var flags = sourceEmitNode.flags, leadingComments = sourceEmitNode.leadingComments, trailingComments = sourceEmitNode.trailingComments, commentRange = sourceEmitNode.commentRange, sourceMapRange = sourceEmitNode.sourceMapRange, tokenSourceMapRanges = sourceEmitNode.tokenSourceMapRanges, constantValue = sourceEmitNode.constantValue, helpers = sourceEmitNode.helpers, startsOnNewLine = sourceEmitNode.startsOnNewLine;
        if (!destEmitNode)
            destEmitNode = {};
        // We are using `.slice()` here in case `destEmitNode.leadingComments` is pushed to later.
        if (leadingComments)
            destEmitNode.leadingComments = ts.addRange(leadingComments.slice(), destEmitNode.leadingComments);
        if (trailingComments)
            destEmitNode.trailingComments = ts.addRange(trailingComments.slice(), destEmitNode.trailingComments);
        if (flags)
            destEmitNode.flags = flags;
        if (commentRange)
            destEmitNode.commentRange = commentRange;
        if (sourceMapRange)
            destEmitNode.sourceMapRange = sourceMapRange;
        if (tokenSourceMapRanges)
            destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges);
        if (constantValue !== undefined)
            destEmitNode.constantValue = constantValue;
        if (helpers)
            destEmitNode.helpers = ts.addRange(destEmitNode.helpers, helpers);
        if (startsOnNewLine !== undefined)
            destEmitNode.startsOnNewLine = startsOnNewLine;
        return destEmitNode;
    }
    function mergeTokenSourceMapRanges(sourceRanges, destRanges) {
        if (!destRanges)
            destRanges = [];
        for (var key in sourceRanges) {
            destRanges[key] = sourceRanges[key];
        }
        return destRanges;
    }
})(ts || (ts = {}));
/* @internal */
(function (ts) {
    ts.nullTransformationContext = {
        enableEmitNotification: ts.noop,
        enableSubstitution: ts.noop,
        endLexicalEnvironment: ts.returnUndefined,
        getCompilerOptions: ts.notImplemented,
        getEmitHost: ts.notImplemented,
        getEmitResolver: ts.notImplemented,
        hoistFunctionDeclaration: ts.noop,
        hoistVariableDeclaration: ts.noop,
        isEmitNotificationEnabled: ts.notImplemented,
        isSubstitutionEnabled: ts.notImplemented,
        onEmitNode: ts.noop,
        onSubstituteNode: ts.notImplemented,
        readEmitHelpers: ts.notImplemented,
        requestEmitHelper: ts.noop,
        resumeLexicalEnvironment: ts.noop,
        startLexicalEnvironment: ts.noop,
        suspendLexicalEnvironment: ts.noop,
        addDiagnostic: ts.noop,
    };
    function createTypeCheck(value, tag) {
        return tag === "undefined"
            ? ts.createStrictEquality(value, ts.createVoidZero())
            : ts.createStrictEquality(ts.createTypeOf(value), ts.createLiteral(tag));
    }
    ts.createTypeCheck = createTypeCheck;
    function createMemberAccessForPropertyName(target, memberName, location) {
        if (ts.isComputedPropertyName(memberName)) {
            return ts.setTextRange(ts.createElementAccess(target, memberName.expression), location);
        }
        else {
            var expression = ts.setTextRange(ts.isIdentifier(memberName)
                ? ts.createPropertyAccess(target, memberName)
                : ts.createElementAccess(target, memberName), memberName);
            ts.getOrCreateEmitNode(expression).flags |= 64 /* NoNestedSourceMaps */;
            return expression;
        }
    }
    ts.createMemberAccessForPropertyName = createMemberAccessForPropertyName;
    function createFunctionCall(func, thisArg, argumentsList, location) {
        return ts.setTextRange(ts.createCall(ts.createPropertyAccess(func, "call"), 
        /*typeArguments*/ undefined, [
            thisArg
        ].concat(argumentsList)), location);
    }
    ts.createFunctionCall = createFunctionCall;
    function createFunctionApply(func, thisArg, argumentsExpression, location) {
        return ts.setTextRange(ts.createCall(ts.createPropertyAccess(func, "apply"), 
        /*typeArguments*/ undefined, [
            thisArg,
            argumentsExpression
        ]), location);
    }
    ts.createFunctionApply = createFunctionApply;
    function createArraySlice(array, start) {
        var argumentsList = [];
        if (start !== undefined) {
            argumentsList.push(typeof start === "number" ? ts.createLiteral(start) : start);
        }
        return ts.createCall(ts.createPropertyAccess(array, "slice"), /*typeArguments*/ undefined, argumentsList);
    }
    ts.createArraySlice = createArraySlice;
    function createArrayConcat(array, values) {
        return ts.createCall(ts.createPropertyAccess(array, "concat"), 
        /*typeArguments*/ undefined, values);
    }
    ts.createArrayConcat = createArrayConcat;
    function createMathPow(left, right, location) {
        return ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Math"), "pow"), 
        /*typeArguments*/ undefined, [left, right]), location);
    }
    ts.createMathPow = createMathPow;
    function createReactNamespace(reactNamespace, parent) {
        // To ensure the emit resolver can properly resolve the namespace, we need to
        // treat this identifier as if it were a source tree node by clearing the `Synthesized`
        // flag and setting a parent node.
        var react = ts.createIdentifier(reactNamespace || "React");
        react.flags &= ~8 /* Synthesized */;
        // Set the parent that is in parse tree
        // this makes sure that parent chain is intact for checker to traverse complete scope tree
        react.parent = ts.getParseTreeNode(parent);
        return react;
    }
    function createJsxFactoryExpressionFromEntityName(jsxFactory, parent) {
        if (ts.isQualifiedName(jsxFactory)) {
            var left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent);
            var right = ts.createIdentifier(ts.idText(jsxFactory.right));
            right.escapedText = jsxFactory.right.escapedText;
            return ts.createPropertyAccess(left, right);
        }
        else {
            return createReactNamespace(ts.idText(jsxFactory), parent);
        }
    }
    function createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parent) {
        return jsxFactoryEntity ?
            createJsxFactoryExpressionFromEntityName(jsxFactoryEntity, parent) :
            ts.createPropertyAccess(createReactNamespace(reactNamespace, parent), "createElement");
    }
    function createExpressionForJsxElement(jsxFactoryEntity, reactNamespace, tagName, props, children, parentElement, location) {
        var argumentsList = [tagName];
        if (props) {
            argumentsList.push(props);
        }
        if (children && children.length > 0) {
            if (!props) {
                argumentsList.push(ts.createNull());
            }
            if (children.length > 1) {
                for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
                    var child = children_1[_i];
                    startOnNewLine(child);
                    argumentsList.push(child);
                }
            }
            else {
                argumentsList.push(children[0]);
            }
        }
        return ts.setTextRange(ts.createCall(createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement), 
        /*typeArguments*/ undefined, argumentsList), location);
    }
    ts.createExpressionForJsxElement = createExpressionForJsxElement;
    function createExpressionForJsxFragment(jsxFactoryEntity, reactNamespace, children, parentElement, location) {
        var tagName = ts.createPropertyAccess(createReactNamespace(reactNamespace, parentElement), "Fragment");
        var argumentsList = [tagName];
        argumentsList.push(ts.createNull());
        if (children && children.length > 0) {
            if (children.length > 1) {
                for (var _i = 0, children_2 = children; _i < children_2.length; _i++) {
                    var child = children_2[_i];
                    startOnNewLine(child);
                    argumentsList.push(child);
                }
            }
            else {
                argumentsList.push(children[0]);
            }
        }
        return ts.setTextRange(ts.createCall(createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement), 
        /*typeArguments*/ undefined, argumentsList), location);
    }
    ts.createExpressionForJsxFragment = createExpressionForJsxFragment;
    // Helpers
    function getHelperName(name) {
        return ts.setEmitFlags(ts.createIdentifier(name), 4096 /* HelperName */ | 2 /* AdviseOnEmitNode */);
    }
    ts.getHelperName = getHelperName;
    ts.valuesHelper = {
        name: "typescript:values",
        scoped: false,
        text: "\n            var __values = (this && this.__values) || function (o) {\n                var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\n                if (m) return m.call(o);\n                return {\n                    next: function () {\n                        if (o && i >= o.length) o = void 0;\n                        return { value: o && o[i++], done: !o };\n                    }\n                };\n            };"
    };
    function createValuesHelper(context, expression, location) {
        context.requestEmitHelper(ts.valuesHelper);
        return ts.setTextRange(ts.createCall(getHelperName("__values"), 
        /*typeArguments*/ undefined, [expression]), location);
    }
    ts.createValuesHelper = createValuesHelper;
    ts.readHelper = {
        name: "typescript:read",
        scoped: false,
        text: "\n            var __read = (this && this.__read) || function (o, n) {\n                var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n                if (!m) return o;\n                var i = m.call(o), r, ar = [], e;\n                try {\n                    while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n                }\n                catch (error) { e = { error: error }; }\n                finally {\n                    try {\n                        if (r && !r.done && (m = i[\"return\"])) m.call(i);\n                    }\n                    finally { if (e) throw e.error; }\n                }\n                return ar;\n            };"
    };
    function createReadHelper(context, iteratorRecord, count, location) {
        context.requestEmitHelper(ts.readHelper);
        return ts.setTextRange(ts.createCall(getHelperName("__read"), 
        /*typeArguments*/ undefined, count !== undefined
            ? [iteratorRecord, ts.createLiteral(count)]
            : [iteratorRecord]), location);
    }
    ts.createReadHelper = createReadHelper;
    ts.spreadHelper = {
        name: "typescript:spread",
        scoped: false,
        text: "\n            var __spread = (this && this.__spread) || function () {\n                for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));\n                return ar;\n            };"
    };
    function createSpreadHelper(context, argumentList, location) {
        context.requestEmitHelper(ts.readHelper);
        context.requestEmitHelper(ts.spreadHelper);
        return ts.setTextRange(ts.createCall(getHelperName("__spread"), 
        /*typeArguments*/ undefined, argumentList), location);
    }
    ts.createSpreadHelper = createSpreadHelper;
    // Utilities
    function createForOfBindingStatement(node, boundValue) {
        if (ts.isVariableDeclarationList(node)) {
            var firstDeclaration = ts.first(node.declarations);
            var updatedDeclaration = ts.updateVariableDeclaration(firstDeclaration, firstDeclaration.name, 
            /*typeNode*/ undefined, boundValue);
            return ts.setTextRange(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.updateVariableDeclarationList(node, [updatedDeclaration])), 
            /*location*/ node);
        }
        else {
            var updatedExpression = ts.setTextRange(ts.createAssignment(node, boundValue), /*location*/ node);
            return ts.setTextRange(ts.createStatement(updatedExpression), /*location*/ node);
        }
    }
    ts.createForOfBindingStatement = createForOfBindingStatement;
    function insertLeadingStatement(dest, source) {
        if (ts.isBlock(dest)) {
            return ts.updateBlock(dest, ts.setTextRange(ts.createNodeArray([source].concat(dest.statements)), dest.statements));
        }
        else {
            return ts.createBlock(ts.createNodeArray([dest, source]), /*multiLine*/ true);
        }
    }
    ts.insertLeadingStatement = insertLeadingStatement;
    function restoreEnclosingLabel(node, outermostLabeledStatement, afterRestoreLabelCallback) {
        if (!outermostLabeledStatement) {
            return node;
        }
        var updated = ts.updateLabel(outermostLabeledStatement, outermostLabeledStatement.label, outermostLabeledStatement.statement.kind === 234 /* LabeledStatement */
            ? restoreEnclosingLabel(node, outermostLabeledStatement.statement)
            : node);
        if (afterRestoreLabelCallback) {
            afterRestoreLabelCallback(outermostLabeledStatement);
        }
        return updated;
    }
    ts.restoreEnclosingLabel = restoreEnclosingLabel;
    function shouldBeCapturedInTempVariable(node, cacheIdentifiers) {
        var target = ts.skipParentheses(node);
        switch (target.kind) {
            case 73 /* Identifier */:
                return cacheIdentifiers;
            case 101 /* ThisKeyword */:
            case 8 /* NumericLiteral */:
            case 9 /* BigIntLiteral */:
            case 10 /* StringLiteral */:
                return false;
            case 188 /* ArrayLiteralExpression */:
                var elements = target.elements;
                if (elements.length === 0) {
                    return false;
                }
                return true;
            case 189 /* ObjectLiteralExpression */:
                return target.properties.length > 0;
            default:
                return true;
        }
    }
    function createCallBinding(expression, recordTempVariable, languageVersion, cacheIdentifiers) {
        if (cacheIdentifiers === void 0) { cacheIdentifiers = false; }
        var callee = skipOuterExpressions(expression, 7 /* All */);
        var thisArg;
        var target;
        if (ts.isSuperProperty(callee)) {
            thisArg = ts.createThis();
            target = callee;
        }
        else if (callee.kind === 99 /* SuperKeyword */) {
            thisArg = ts.createThis();
            target = languageVersion < 2 /* ES2015 */
                ? ts.setTextRange(ts.createIdentifier("_super"), callee)
                : callee;
        }
        else if (ts.getEmitFlags(callee) & 4096 /* HelperName */) {
            thisArg = ts.createVoidZero();
            target = parenthesizeForAccess(callee);
        }
        else {
            switch (callee.kind) {
                case 190 /* PropertyAccessExpression */: {
                    if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) {
                        // for `a.b()` target is `(_a = a).b` and thisArg is `_a`
                        thisArg = ts.createTempVariable(recordTempVariable);
                        target = ts.createPropertyAccess(ts.setTextRange(ts.createAssignment(thisArg, callee.expression), callee.expression), callee.name);
                        ts.setTextRange(target, callee);
                    }
                    else {
                        thisArg = callee.expression;
                        target = callee;
                    }
                    break;
                }
                case 191 /* ElementAccessExpression */: {
                    if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) {
                        // for `a[b]()` target is `(_a = a)[b]` and thisArg is `_a`
                        thisArg = ts.createTempVariable(recordTempVariable);
                        target = ts.createElementAccess(ts.setTextRange(ts.createAssignment(thisArg, callee.expression), callee.expression), callee.argumentExpression);
                        ts.setTextRange(target, callee);
                    }
                    else {
                        thisArg = callee.expression;
                        target = callee;
                    }
                    break;
                }
                default: {
                    // for `a()` target is `a` and thisArg is `void 0`
                    thisArg = ts.createVoidZero();
                    target = parenthesizeForAccess(expression);
                    break;
                }
            }
        }
        return { target: target, thisArg: thisArg };
    }
    ts.createCallBinding = createCallBinding;
    function inlineExpressions(expressions) {
        // Avoid deeply nested comma expressions as traversing them during emit can result in "Maximum call
        // stack size exceeded" errors.
        return expressions.length > 10
            ? ts.createCommaList(expressions)
            : ts.reduceLeft(expressions, ts.createComma);
    }
    ts.inlineExpressions = inlineExpressions;
    function createExpressionFromEntityName(node) {
        if (ts.isQualifiedName(node)) {
            var left = createExpressionFromEntityName(node.left);
            var right = ts.getMutableClone(node.right);
            return ts.setTextRange(ts.createPropertyAccess(left, right), node);
        }
        else {
            return ts.getMutableClone(node);
        }
    }
    ts.createExpressionFromEntityName = createExpressionFromEntityName;
    function createExpressionForPropertyName(memberName) {
        if (ts.isIdentifier(memberName)) {
            return ts.createLiteral(memberName);
        }
        else if (ts.isComputedPropertyName(memberName)) {
            return ts.getMutableClone(memberName.expression);
        }
        else {
            return ts.getMutableClone(memberName);
        }
    }
    ts.createExpressionForPropertyName = createExpressionForPropertyName;
    function createExpressionForObjectLiteralElementLike(node, property, receiver) {
        switch (property.kind) {
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
                return createExpressionForAccessorDeclaration(node.properties, property, receiver, !!node.multiLine);
            case 276 /* PropertyAssignment */:
                return createExpressionForPropertyAssignment(property, receiver);
            case 277 /* ShorthandPropertyAssignment */:
                return createExpressionForShorthandPropertyAssignment(property, receiver);
            case 157 /* MethodDeclaration */:
                return createExpressionForMethodDeclaration(property, receiver);
        }
    }
    ts.createExpressionForObjectLiteralElementLike = createExpressionForObjectLiteralElementLike;
    function createExpressionForAccessorDeclaration(properties, property, receiver, multiLine) {
        var _a = ts.getAllAccessorDeclarations(properties, property), firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor;
        if (property === firstAccessor) {
            var properties_5 = [];
            if (getAccessor) {
                var getterFunction = ts.createFunctionExpression(getAccessor.modifiers, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, getAccessor.parameters, 
                /*type*/ undefined, getAccessor.body // TODO: GH#18217
                );
                ts.setTextRange(getterFunction, getAccessor);
                ts.setOriginalNode(getterFunction, getAccessor);
                var getter = ts.createPropertyAssignment("get", getterFunction);
                properties_5.push(getter);
            }
            if (setAccessor) {
                var setterFunction = ts.createFunctionExpression(setAccessor.modifiers, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, setAccessor.parameters, 
                /*type*/ undefined, setAccessor.body // TODO: GH#18217
                );
                ts.setTextRange(setterFunction, setAccessor);
                ts.setOriginalNode(setterFunction, setAccessor);
                var setter = ts.createPropertyAssignment("set", setterFunction);
                properties_5.push(setter);
            }
            properties_5.push(ts.createPropertyAssignment("enumerable", ts.createTrue()));
            properties_5.push(ts.createPropertyAssignment("configurable", ts.createTrue()));
            var expression = ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
            /*typeArguments*/ undefined, [
                receiver,
                createExpressionForPropertyName(property.name),
                ts.createObjectLiteral(properties_5, multiLine)
            ]), 
            /*location*/ firstAccessor);
            return ts.aggregateTransformFlags(expression);
        }
        return undefined;
    }
    function createExpressionForPropertyAssignment(property, receiver) {
        return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), property.initializer), property), property));
    }
    function createExpressionForShorthandPropertyAssignment(property, receiver) {
        return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), ts.getSynthesizedClone(property.name)), 
        /*location*/ property), 
        /*original*/ property));
    }
    function createExpressionForMethodDeclaration(method, receiver) {
        return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, method.name, /*location*/ method.name), ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(method.modifiers, method.asteriskToken, 
        /*name*/ undefined, 
        /*typeParameters*/ undefined, method.parameters, 
        /*type*/ undefined, method.body // TODO: GH#18217
        ), 
        /*location*/ method), 
        /*original*/ method)), 
        /*location*/ method), 
        /*original*/ method));
    }
    /**
     * Gets the internal name of a declaration. This is primarily used for declarations that can be
     * referred to by name in the body of an ES5 class function body. An internal name will *never*
     * be prefixed with an module or namespace export modifier like "exports." when emitted as an
     * expression. An internal name will also *never* be renamed due to a collision with a block
     * scoped variable.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getInternalName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps, 16384 /* LocalName */ | 32768 /* InternalName */);
    }
    ts.getInternalName = getInternalName;
    /**
     * Gets whether an identifier should only be referred to by its internal name.
     */
    function isInternalName(node) {
        return (ts.getEmitFlags(node) & 32768 /* InternalName */) !== 0;
    }
    ts.isInternalName = isInternalName;
    /**
     * Gets the local name of a declaration. This is primarily used for declarations that can be
     * referred to by name in the declaration's immediate scope (classes, enums, namespaces). A
     * local name will *never* be prefixed with an module or namespace export modifier like
     * "exports." when emitted as an expression.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getLocalName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps, 16384 /* LocalName */);
    }
    ts.getLocalName = getLocalName;
    /**
     * Gets whether an identifier should only be referred to by its local name.
     */
    function isLocalName(node) {
        return (ts.getEmitFlags(node) & 16384 /* LocalName */) !== 0;
    }
    ts.isLocalName = isLocalName;
    /**
     * Gets the export name of a declaration. This is primarily used for declarations that can be
     * referred to by name in the declaration's immediate scope (classes, enums, namespaces). An
     * export name will *always* be prefixed with an module or namespace export modifier like
     * `"exports."` when emitted as an expression if the name points to an exported symbol.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getExportName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps, 8192 /* ExportName */);
    }
    ts.getExportName = getExportName;
    /**
     * Gets whether an identifier should only be referred to by its export representation if the
     * name points to an exported symbol.
     */
    function isExportName(node) {
        return (ts.getEmitFlags(node) & 8192 /* ExportName */) !== 0;
    }
    ts.isExportName = isExportName;
    /**
     * Gets the name of a declaration for use in declarations.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getDeclarationName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps);
    }
    ts.getDeclarationName = getDeclarationName;
    function getName(node, allowComments, allowSourceMaps, emitFlags) {
        if (emitFlags === void 0) { emitFlags = 0; }
        var nodeName = ts.getNameOfDeclaration(node);
        if (nodeName && ts.isIdentifier(nodeName) && !ts.isGeneratedIdentifier(nodeName)) {
            var name = ts.getMutableClone(nodeName);
            emitFlags |= ts.getEmitFlags(nodeName);
            if (!allowSourceMaps)
                emitFlags |= 48 /* NoSourceMap */;
            if (!allowComments)
                emitFlags |= 1536 /* NoComments */;
            if (emitFlags)
                ts.setEmitFlags(name, emitFlags);
            return name;
        }
        return ts.getGeneratedNameForNode(node);
    }
    /**
     * Gets the exported name of a declaration for use in expressions.
     *
     * An exported name will *always* be prefixed with an module or namespace export modifier like
     * "exports." if the name points to an exported symbol.
     *
     * @param ns The namespace identifier.
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getExternalModuleOrNamespaceExportName(ns, node, allowComments, allowSourceMaps) {
        if (ns && ts.hasModifier(node, 1 /* Export */)) {
            return getNamespaceMemberName(ns, getName(node), allowComments, allowSourceMaps);
        }
        return getExportName(node, allowComments, allowSourceMaps);
    }
    ts.getExternalModuleOrNamespaceExportName = getExternalModuleOrNamespaceExportName;
    /**
     * Gets a namespace-qualified name for use in expressions.
     *
     * @param ns The namespace identifier.
     * @param name The name.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getNamespaceMemberName(ns, name, allowComments, allowSourceMaps) {
        var qualifiedName = ts.createPropertyAccess(ns, ts.nodeIsSynthesized(name) ? name : ts.getSynthesizedClone(name));
        ts.setTextRange(qualifiedName, name);
        var emitFlags = 0;
        if (!allowSourceMaps)
            emitFlags |= 48 /* NoSourceMap */;
        if (!allowComments)
            emitFlags |= 1536 /* NoComments */;
        if (emitFlags)
            ts.setEmitFlags(qualifiedName, emitFlags);
        return qualifiedName;
    }
    ts.getNamespaceMemberName = getNamespaceMemberName;
    function convertToFunctionBody(node, multiLine) {
        return ts.isBlock(node) ? node : ts.setTextRange(ts.createBlock([ts.setTextRange(ts.createReturn(node), node)], multiLine), node);
    }
    ts.convertToFunctionBody = convertToFunctionBody;
    function convertFunctionDeclarationToExpression(node) {
        if (!node.body)
            return ts.Debug.fail();
        var updated = ts.createFunctionExpression(node.modifiers, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body);
        ts.setOriginalNode(updated, node);
        ts.setTextRange(updated, node);
        if (ts.getStartsOnNewLine(node)) {
            ts.setStartsOnNewLine(updated, /*newLine*/ true);
        }
        ts.aggregateTransformFlags(updated);
        return updated;
    }
    ts.convertFunctionDeclarationToExpression = convertFunctionDeclarationToExpression;
    function isUseStrictPrologue(node) {
        return ts.isStringLiteral(node.expression) && node.expression.text === "use strict";
    }
    /**
     * Add any necessary prologue-directives into target statement-array.
     * The function needs to be called during each transformation step.
     * This function needs to be called whenever we transform the statement
     * list of a source file, namespace, or function-like body.
     *
     * @param target: result statements array
     * @param source: origin statements array
     * @param ensureUseStrict: boolean determining whether the function need to add prologue-directives
     * @param visitor: Optional callback used to visit any custom prologue directives.
     */
    function addPrologue(target, source, ensureUseStrict, visitor) {
        var offset = addStandardPrologue(target, source, ensureUseStrict);
        return addCustomPrologue(target, source, offset, visitor);
    }
    ts.addPrologue = addPrologue;
    /**
     * Add just the standard (string-expression) prologue-directives into target statement-array.
     * The function needs to be called during each transformation step.
     * This function needs to be called whenever we transform the statement
     * list of a source file, namespace, or function-like body.
     */
    function addStandardPrologue(target, source, ensureUseStrict) {
        ts.Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array");
        var foundUseStrict = false;
        var statementOffset = 0;
        var numStatements = source.length;
        while (statementOffset < numStatements) {
            var statement = source[statementOffset];
            if (ts.isPrologueDirective(statement)) {
                if (isUseStrictPrologue(statement)) {
                    foundUseStrict = true;
                }
                target.push(statement);
            }
            else {
                break;
            }
            statementOffset++;
        }
        if (ensureUseStrict && !foundUseStrict) {
            target.push(startOnNewLine(ts.createStatement(ts.createLiteral("use strict"))));
        }
        return statementOffset;
    }
    ts.addStandardPrologue = addStandardPrologue;
    function addCustomPrologue(target, source, statementOffset, visitor) {
        var numStatements = source.length;
        while (statementOffset !== undefined && statementOffset < numStatements) {
            var statement = source[statementOffset];
            if (ts.getEmitFlags(statement) & 1048576 /* CustomPrologue */) {
                ts.append(target, visitor ? ts.visitNode(statement, visitor, ts.isStatement) : statement);
            }
            else {
                break;
            }
            statementOffset++;
        }
        return statementOffset;
    }
    ts.addCustomPrologue = addCustomPrologue;
    function findUseStrictPrologue(statements) {
        for (var _i = 0, statements_3 = statements; _i < statements_3.length; _i++) {
            var statement = statements_3[_i];
            if (ts.isPrologueDirective(statement)) {
                if (isUseStrictPrologue(statement)) {
                    return statement;
                }
            }
            else {
                break;
            }
        }
        return undefined;
    }
    ts.findUseStrictPrologue = findUseStrictPrologue;
    function startsWithUseStrict(statements) {
        var firstStatement = ts.firstOrUndefined(statements);
        return firstStatement !== undefined
            && ts.isPrologueDirective(firstStatement)
            && isUseStrictPrologue(firstStatement);
    }
    ts.startsWithUseStrict = startsWithUseStrict;
    /**
     * Ensures "use strict" directive is added
     *
     * @param statements An array of statements
     */
    function ensureUseStrict(statements) {
        var foundUseStrict = findUseStrictPrologue(statements);
        if (!foundUseStrict) {
            return ts.setTextRange(ts.createNodeArray([
                startOnNewLine(ts.createStatement(ts.createLiteral("use strict")))
            ].concat(statements)), statements);
        }
        return statements;
    }
    ts.ensureUseStrict = ensureUseStrict;
    /**
     * Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended
     * order of operations.
     *
     * @param binaryOperator The operator for the BinaryExpression.
     * @param operand The operand for the BinaryExpression.
     * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the
     *                           BinaryExpression.
     */
    function parenthesizeBinaryOperand(binaryOperator, operand, isLeftSideOfBinary, leftOperand) {
        var skipped = ts.skipPartiallyEmittedExpressions(operand);
        // If the resulting expression is already parenthesized, we do not need to do any further processing.
        if (skipped.kind === 196 /* ParenthesizedExpression */) {
            return operand;
        }
        return binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand)
            ? ts.createParen(operand)
            : operand;
    }
    ts.parenthesizeBinaryOperand = parenthesizeBinaryOperand;
    /**
     * Determines whether the operand to a BinaryExpression needs to be parenthesized.
     *
     * @param binaryOperator The operator for the BinaryExpression.
     * @param operand The operand for the BinaryExpression.
     * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the
     *                           BinaryExpression.
     */
    function binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand) {
        // If the operand has lower precedence, then it needs to be parenthesized to preserve the
        // intent of the expression. For example, if the operand is `a + b` and the operator is
        // `*`, then we need to parenthesize the operand to preserve the intended order of
        // operations: `(a + b) * x`.
        //
        // If the operand has higher precedence, then it does not need to be parenthesized. For
        // example, if the operand is `a * b` and the operator is `+`, then we do not need to
        // parenthesize to preserve the intended order of operations: `a * b + x`.
        //
        // If the operand has the same precedence, then we need to check the associativity of
        // the operator based on whether this is the left or right operand of the expression.
        //
        // For example, if `a / d` is on the right of operator `*`, we need to parenthesize
        // to preserve the intended order of operations: `x * (a / d)`
        //
        // If `a ** d` is on the left of operator `**`, we need to parenthesize to preserve
        // the intended order of operations: `(a ** b) ** c`
        var binaryOperatorPrecedence = ts.getOperatorPrecedence(205 /* BinaryExpression */, binaryOperator);
        var binaryOperatorAssociativity = ts.getOperatorAssociativity(205 /* BinaryExpression */, binaryOperator);
        var emittedOperand = ts.skipPartiallyEmittedExpressions(operand);
        if (!isLeftSideOfBinary && operand.kind === 198 /* ArrowFunction */ && binaryOperatorPrecedence > 4) {
            // We need to parenthesize arrow functions on the right side to avoid it being
            // parsed as parenthesized expression: `a && (() => {})`
            return true;
        }
        var operandPrecedence = ts.getExpressionPrecedence(emittedOperand);
        switch (ts.compareValues(operandPrecedence, binaryOperatorPrecedence)) {
            case -1 /* LessThan */:
                // If the operand is the right side of a right-associative binary operation
                // and is a yield expression, then we do not need parentheses.
                if (!isLeftSideOfBinary
                    && binaryOperatorAssociativity === 1 /* Right */
                    && operand.kind === 208 /* YieldExpression */) {
                    return false;
                }
                return true;
            case 1 /* GreaterThan */:
                return false;
            case 0 /* EqualTo */:
                if (isLeftSideOfBinary) {
                    // No need to parenthesize the left operand when the binary operator is
                    // left associative:
                    //  (a*b)/x    -> a*b/x
                    //  (a**b)/x   -> a**b/x
                    //
                    // Parentheses are needed for the left operand when the binary operator is
                    // right associative:
                    //  (a/b)**x   -> (a/b)**x
                    //  (a**b)**x  -> (a**b)**x
                    return binaryOperatorAssociativity === 1 /* Right */;
                }
                else {
                    if (ts.isBinaryExpression(emittedOperand)
                        && emittedOperand.operatorToken.kind === binaryOperator) {
                        // No need to parenthesize the right operand when the binary operator and
                        // operand are the same and one of the following:
                        //  x*(a*b)     => x*a*b
                        //  x|(a|b)     => x|a|b
                        //  x&(a&b)     => x&a&b
                        //  x^(a^b)     => x^a^b
                        if (operatorHasAssociativeProperty(binaryOperator)) {
                            return false;
                        }
                        // No need to parenthesize the right operand when the binary operator
                        // is plus (+) if both the left and right operands consist solely of either
                        // literals of the same kind or binary plus (+) expressions for literals of
                        // the same kind (recursively).
                        //  "a"+(1+2)       => "a"+(1+2)
                        //  "a"+("b"+"c")   => "a"+"b"+"c"
                        if (binaryOperator === 38 /* PlusToken */) {
                            var leftKind = leftOperand ? getLiteralKindOfBinaryPlusOperand(leftOperand) : 0 /* Unknown */;
                            if (ts.isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand(emittedOperand)) {
                                return false;
                            }
                        }
                    }
                    // No need to parenthesize the right operand when the operand is right
                    // associative:
                    //  x/(a**b)    -> x/a**b
                    //  x**(a**b)   -> x**a**b
                    //
                    // Parentheses are needed for the right operand when the operand is left
                    // associative:
                    //  x/(a*b)     -> x/(a*b)
                    //  x**(a/b)    -> x**(a/b)
                    var operandAssociativity = ts.getExpressionAssociativity(emittedOperand);
                    return operandAssociativity === 0 /* Left */;
                }
        }
    }
    /**
     * Determines whether a binary operator is mathematically associative.
     *
     * @param binaryOperator The binary operator.
     */
    function operatorHasAssociativeProperty(binaryOperator) {
        // The following operators are associative in JavaScript:
        //  (a*b)*c     -> a*(b*c)  -> a*b*c
        //  (a|b)|c     -> a|(b|c)  -> a|b|c
        //  (a&b)&c     -> a&(b&c)  -> a&b&c
        //  (a^b)^c     -> a^(b^c)  -> a^b^c
        //
        // While addition is associative in mathematics, JavaScript's `+` is not
        // guaranteed to be associative as it is overloaded with string concatenation.
        return binaryOperator === 40 /* AsteriskToken */
            || binaryOperator === 50 /* BarToken */
            || binaryOperator === 49 /* AmpersandToken */
            || binaryOperator === 51 /* CaretToken */;
    }
    /**
     * This function determines whether an expression consists of a homogeneous set of
     * literal expressions or binary plus expressions that all share the same literal kind.
     * It is used to determine whether the right-hand operand of a binary plus expression can be
     * emitted without parentheses.
     */
    function getLiteralKindOfBinaryPlusOperand(node) {
        node = ts.skipPartiallyEmittedExpressions(node);
        if (ts.isLiteralKind(node.kind)) {
            return node.kind;
        }
        if (node.kind === 205 /* BinaryExpression */ && node.operatorToken.kind === 38 /* PlusToken */) {
            if (node.cachedLiteralKind !== undefined) {
                return node.cachedLiteralKind;
            }
            var leftKind = getLiteralKindOfBinaryPlusOperand(node.left);
            var literalKind = ts.isLiteralKind(leftKind)
                && leftKind === getLiteralKindOfBinaryPlusOperand(node.right)
                ? leftKind
                : 0 /* Unknown */;
            node.cachedLiteralKind = literalKind;
            return literalKind;
        }
        return 0 /* Unknown */;
    }
    function parenthesizeForConditionalHead(condition) {
        var conditionalPrecedence = ts.getOperatorPrecedence(206 /* ConditionalExpression */, 56 /* QuestionToken */);
        var emittedCondition = ts.skipPartiallyEmittedExpressions(condition);
        var conditionPrecedence = ts.getExpressionPrecedence(emittedCondition);
        if (ts.compareValues(conditionPrecedence, conditionalPrecedence) === -1 /* LessThan */) {
            return ts.createParen(condition);
        }
        return condition;
    }
    ts.parenthesizeForConditionalHead = parenthesizeForConditionalHead;
    function parenthesizeSubexpressionOfConditionalExpression(e) {
        // per ES grammar both 'whenTrue' and 'whenFalse' parts of conditional expression are assignment expressions
        // so in case when comma expression is introduced as a part of previous transformations
        // if should be wrapped in parens since comma operator has the lowest precedence
        var emittedExpression = ts.skipPartiallyEmittedExpressions(e);
        return isCommaSequence(emittedExpression)
            ? ts.createParen(e)
            : e;
    }
    ts.parenthesizeSubexpressionOfConditionalExpression = parenthesizeSubexpressionOfConditionalExpression;
    /**
     *  [Per the spec](https://tc39.github.io/ecma262/#prod-ExportDeclaration), `export default` accepts _AssigmentExpression_ but
     *  has a lookahead restriction for `function`, `async function`, and `class`.
     *
     * Basically, that means we need to parenthesize in the following cases:
     *
     * - BinaryExpression of CommaToken
     * - CommaList (synthetic list of multiple comma expressions)
     * - FunctionExpression
     * - ClassExpression
     */
    function parenthesizeDefaultExpression(e) {
        var check = ts.skipPartiallyEmittedExpressions(e);
        var needsParens = isCommaSequence(check);
        if (!needsParens) {
            switch (getLeftmostExpression(check, /*stopAtCallExpression*/ false).kind) {
                case 210 /* ClassExpression */:
                case 197 /* FunctionExpression */:
                    needsParens = true;
            }
        }
        return needsParens ? ts.createParen(e) : e;
    }
    ts.parenthesizeDefaultExpression = parenthesizeDefaultExpression;
    /**
     * Wraps an expression in parentheses if it is needed in order to use the expression
     * as the expression of a NewExpression node.
     *
     * @param expression The Expression node.
     */
    function parenthesizeForNew(expression) {
        var leftmostExpr = getLeftmostExpression(expression, /*stopAtCallExpressions*/ true);
        switch (leftmostExpr.kind) {
            case 192 /* CallExpression */:
                return ts.createParen(expression);
            case 193 /* NewExpression */:
                return !leftmostExpr.arguments
                    ? ts.createParen(expression)
                    : expression;
        }
        return parenthesizeForAccess(expression);
    }
    ts.parenthesizeForNew = parenthesizeForNew;
    /**
     * Wraps an expression in parentheses if it is needed in order to use the expression for
     * property or element access.
     *
     * @param expr The expression node.
     */
    function parenthesizeForAccess(expression) {
        // isLeftHandSideExpression is almost the correct criterion for when it is not necessary
        // to parenthesize the expression before a dot. The known exception is:
        //
        //    NewExpression:
        //       new C.x        -> not the same as (new C).x
        //
        var emittedExpression = ts.skipPartiallyEmittedExpressions(expression);
        if (ts.isLeftHandSideExpression(emittedExpression)
            && (emittedExpression.kind !== 193 /* NewExpression */ || emittedExpression.arguments)) {
            return expression;
        }
        return ts.setTextRange(ts.createParen(expression), expression);
    }
    ts.parenthesizeForAccess = parenthesizeForAccess;
    function parenthesizePostfixOperand(operand) {
        return ts.isLeftHandSideExpression(operand)
            ? operand
            : ts.setTextRange(ts.createParen(operand), operand);
    }
    ts.parenthesizePostfixOperand = parenthesizePostfixOperand;
    function parenthesizePrefixOperand(operand) {
        return ts.isUnaryExpression(operand)
            ? operand
            : ts.setTextRange(ts.createParen(operand), operand);
    }
    ts.parenthesizePrefixOperand = parenthesizePrefixOperand;
    function parenthesizeListElements(elements) {
        var result;
        for (var i = 0; i < elements.length; i++) {
            var element = parenthesizeExpressionForList(elements[i]);
            if (result !== undefined || element !== elements[i]) {
                if (result === undefined) {
                    result = elements.slice(0, i);
                }
                result.push(element);
            }
        }
        if (result !== undefined) {
            return ts.setTextRange(ts.createNodeArray(result, elements.hasTrailingComma), elements);
        }
        return elements;
    }
    ts.parenthesizeListElements = parenthesizeListElements;
    function parenthesizeExpressionForList(expression) {
        var emittedExpression = ts.skipPartiallyEmittedExpressions(expression);
        var expressionPrecedence = ts.getExpressionPrecedence(emittedExpression);
        var commaPrecedence = ts.getOperatorPrecedence(205 /* BinaryExpression */, 27 /* CommaToken */);
        return expressionPrecedence > commaPrecedence
            ? expression
            : ts.setTextRange(ts.createParen(expression), expression);
    }
    ts.parenthesizeExpressionForList = parenthesizeExpressionForList;
    function parenthesizeExpressionForExpressionStatement(expression) {
        var emittedExpression = ts.skipPartiallyEmittedExpressions(expression);
        if (ts.isCallExpression(emittedExpression)) {
            var callee = emittedExpression.expression;
            var kind = ts.skipPartiallyEmittedExpressions(callee).kind;
            if (kind === 197 /* FunctionExpression */ || kind === 198 /* ArrowFunction */) {
                var mutableCall = ts.getMutableClone(emittedExpression);
                mutableCall.expression = ts.setTextRange(ts.createParen(callee), callee);
                return recreateOuterExpressions(expression, mutableCall, 4 /* PartiallyEmittedExpressions */);
            }
        }
        var leftmostExpressionKind = getLeftmostExpression(emittedExpression, /*stopAtCallExpressions*/ false).kind;
        if (leftmostExpressionKind === 189 /* ObjectLiteralExpression */ || leftmostExpressionKind === 197 /* FunctionExpression */) {
            return ts.setTextRange(ts.createParen(expression), expression);
        }
        return expression;
    }
    ts.parenthesizeExpressionForExpressionStatement = parenthesizeExpressionForExpressionStatement;
    function parenthesizeConditionalTypeMember(member) {
        return member.kind === 176 /* ConditionalType */ ? ts.createParenthesizedType(member) : member;
    }
    ts.parenthesizeConditionalTypeMember = parenthesizeConditionalTypeMember;
    function parenthesizeElementTypeMember(member) {
        switch (member.kind) {
            case 174 /* UnionType */:
            case 175 /* IntersectionType */:
            case 166 /* FunctionType */:
            case 167 /* ConstructorType */:
                return ts.createParenthesizedType(member);
        }
        return parenthesizeConditionalTypeMember(member);
    }
    ts.parenthesizeElementTypeMember = parenthesizeElementTypeMember;
    function parenthesizeArrayTypeMember(member) {
        switch (member.kind) {
            case 168 /* TypeQuery */:
            case 180 /* TypeOperator */:
            case 177 /* InferType */:
                return ts.createParenthesizedType(member);
        }
        return parenthesizeElementTypeMember(member);
    }
    ts.parenthesizeArrayTypeMember = parenthesizeArrayTypeMember;
    function parenthesizeElementTypeMembers(members) {
        return ts.createNodeArray(ts.sameMap(members, parenthesizeElementTypeMember));
    }
    ts.parenthesizeElementTypeMembers = parenthesizeElementTypeMembers;
    function parenthesizeTypeParameters(typeParameters) {
        if (ts.some(typeParameters)) {
            var params = [];
            for (var i = 0; i < typeParameters.length; ++i) {
                var entry = typeParameters[i];
                params.push(i === 0 && ts.isFunctionOrConstructorTypeNode(entry) && entry.typeParameters ?
                    ts.createParenthesizedType(entry) :
                    entry);
            }
            return ts.createNodeArray(params);
        }
    }
    ts.parenthesizeTypeParameters = parenthesizeTypeParameters;
    function getLeftmostExpression(node, stopAtCallExpressions) {
        while (true) {
            switch (node.kind) {
                case 204 /* PostfixUnaryExpression */:
                    node = node.operand;
                    continue;
                case 205 /* BinaryExpression */:
                    node = node.left;
                    continue;
                case 206 /* ConditionalExpression */:
                    node = node.condition;
                    continue;
                case 194 /* TaggedTemplateExpression */:
                    node = node.tag;
                    continue;
                case 192 /* CallExpression */:
                    if (stopAtCallExpressions) {
                        return node;
                    }
                // falls through
                case 213 /* AsExpression */:
                case 191 /* ElementAccessExpression */:
                case 190 /* PropertyAccessExpression */:
                case 214 /* NonNullExpression */:
                case 314 /* PartiallyEmittedExpression */:
                    node = node.expression;
                    continue;
            }
            return node;
        }
    }
    function parenthesizeConciseBody(body) {
        if (!ts.isBlock(body) && (isCommaSequence(body) || getLeftmostExpression(body, /*stopAtCallExpressions*/ false).kind === 189 /* ObjectLiteralExpression */)) {
            return ts.setTextRange(ts.createParen(body), body);
        }
        return body;
    }
    ts.parenthesizeConciseBody = parenthesizeConciseBody;
    function isCommaSequence(node) {
        return node.kind === 205 /* BinaryExpression */ && node.operatorToken.kind === 27 /* CommaToken */ ||
            node.kind === 315 /* CommaListExpression */;
    }
    ts.isCommaSequence = isCommaSequence;
    var OuterExpressionKinds;
    (function (OuterExpressionKinds) {
        OuterExpressionKinds[OuterExpressionKinds["Parentheses"] = 1] = "Parentheses";
        OuterExpressionKinds[OuterExpressionKinds["Assertions"] = 2] = "Assertions";
        OuterExpressionKinds[OuterExpressionKinds["PartiallyEmittedExpressions"] = 4] = "PartiallyEmittedExpressions";
        OuterExpressionKinds[OuterExpressionKinds["All"] = 7] = "All";
    })(OuterExpressionKinds = ts.OuterExpressionKinds || (ts.OuterExpressionKinds = {}));
    function isOuterExpression(node, kinds) {
        if (kinds === void 0) { kinds = 7 /* All */; }
        switch (node.kind) {
            case 196 /* ParenthesizedExpression */:
                return (kinds & 1 /* Parentheses */) !== 0;
            case 195 /* TypeAssertionExpression */:
            case 213 /* AsExpression */:
            case 214 /* NonNullExpression */:
                return (kinds & 2 /* Assertions */) !== 0;
            case 314 /* PartiallyEmittedExpression */:
                return (kinds & 4 /* PartiallyEmittedExpressions */) !== 0;
        }
        return false;
    }
    ts.isOuterExpression = isOuterExpression;
    function skipOuterExpressions(node, kinds) {
        if (kinds === void 0) { kinds = 7 /* All */; }
        var previousNode;
        do {
            previousNode = node;
            if (kinds & 1 /* Parentheses */) {
                node = ts.skipParentheses(node);
            }
            if (kinds & 2 /* Assertions */) {
                node = skipAssertions(node);
            }
            if (kinds & 4 /* PartiallyEmittedExpressions */) {
                node = ts.skipPartiallyEmittedExpressions(node);
            }
        } while (previousNode !== node);
        return node;
    }
    ts.skipOuterExpressions = skipOuterExpressions;
    function skipAssertions(node) {
        while (ts.isAssertionExpression(node) || node.kind === 214 /* NonNullExpression */) {
            node = node.expression;
        }
        return node;
    }
    ts.skipAssertions = skipAssertions;
    function updateOuterExpression(outerExpression, expression) {
        switch (outerExpression.kind) {
            case 196 /* ParenthesizedExpression */: return ts.updateParen(outerExpression, expression);
            case 195 /* TypeAssertionExpression */: return ts.updateTypeAssertion(outerExpression, outerExpression.type, expression);
            case 213 /* AsExpression */: return ts.updateAsExpression(outerExpression, expression, outerExpression.type);
            case 214 /* NonNullExpression */: return ts.updateNonNullExpression(outerExpression, expression);
            case 314 /* PartiallyEmittedExpression */: return ts.updatePartiallyEmittedExpression(outerExpression, expression);
        }
    }
    /**
     * Determines whether a node is a parenthesized expression that can be ignored when recreating outer expressions.
     *
     * A parenthesized expression can be ignored when all of the following are true:
     *
     * - It's `pos` and `end` are not -1
     * - It does not have a custom source map range
     * - It does not have a custom comment range
     * - It does not have synthetic leading or trailing comments
     *
     * If an outermost parenthesized expression is ignored, but the containing expression requires a parentheses around
     * the expression to maintain precedence, a new parenthesized expression should be created automatically when
     * the containing expression is created/updated.
     */
    function isIgnorableParen(node) {
        return node.kind === 196 /* ParenthesizedExpression */
            && ts.nodeIsSynthesized(node)
            && ts.nodeIsSynthesized(ts.getSourceMapRange(node))
            && ts.nodeIsSynthesized(ts.getCommentRange(node))
            && !ts.some(ts.getSyntheticLeadingComments(node))
            && !ts.some(ts.getSyntheticTrailingComments(node));
    }
    function recreateOuterExpressions(outerExpression, innerExpression, kinds) {
        if (kinds === void 0) { kinds = 7 /* All */; }
        if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) {
            return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression));
        }
        return innerExpression;
    }
    ts.recreateOuterExpressions = recreateOuterExpressions;
    function startOnNewLine(node) {
        return ts.setStartsOnNewLine(node, /*newLine*/ true);
    }
    ts.startOnNewLine = startOnNewLine;
    function getExternalHelpersModuleName(node) {
        var parseNode = ts.getOriginalNode(node, ts.isSourceFile);
        var emitNode = parseNode && parseNode.emitNode;
        return emitNode && emitNode.externalHelpersModuleName;
    }
    ts.getExternalHelpersModuleName = getExternalHelpersModuleName;
    function getOrCreateExternalHelpersModuleNameIfNeeded(node, compilerOptions, hasExportStarsToExportValues, hasImportStarOrImportDefault) {
        if (compilerOptions.importHelpers && ts.isEffectiveExternalModule(node, compilerOptions)) {
            var externalHelpersModuleName = getExternalHelpersModuleName(node);
            if (externalHelpersModuleName) {
                return externalHelpersModuleName;
            }
            var moduleKind = ts.getEmitModuleKind(compilerOptions);
            var create = (hasExportStarsToExportValues || (compilerOptions.esModuleInterop && hasImportStarOrImportDefault))
                && moduleKind !== ts.ModuleKind.System
                && moduleKind !== ts.ModuleKind.ES2015
                && moduleKind !== ts.ModuleKind.ESNext;
            if (!create) {
                var helpers = ts.getEmitHelpers(node);
                if (helpers) {
                    for (var _i = 0, helpers_2 = helpers; _i < helpers_2.length; _i++) {
                        var helper = helpers_2[_i];
                        if (!helper.scoped) {
                            create = true;
                            break;
                        }
                    }
                }
            }
            if (create) {
                var parseNode = ts.getOriginalNode(node, ts.isSourceFile);
                var emitNode = ts.getOrCreateEmitNode(parseNode);
                return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = ts.createUniqueName(ts.externalHelpersModuleNameText));
            }
        }
    }
    ts.getOrCreateExternalHelpersModuleNameIfNeeded = getOrCreateExternalHelpersModuleNameIfNeeded;
    /**
     * Get the name of that target module from an import or export declaration
     */
    function getLocalNameForExternalImport(node, sourceFile) {
        var namespaceDeclaration = ts.getNamespaceDeclarationNode(node);
        if (namespaceDeclaration && !ts.isDefaultImport(node)) {
            var name = namespaceDeclaration.name;
            return ts.isGeneratedIdentifier(name) ? name : ts.createIdentifier(ts.getSourceTextOfNodeFromSourceFile(sourceFile, name) || ts.idText(name));
        }
        if (node.kind === 250 /* ImportDeclaration */ && node.importClause) {
            return ts.getGeneratedNameForNode(node);
        }
        if (node.kind === 256 /* ExportDeclaration */ && node.moduleSpecifier) {
            return ts.getGeneratedNameForNode(node);
        }
        return undefined;
    }
    ts.getLocalNameForExternalImport = getLocalNameForExternalImport;
    /**
     * Get the name of a target module from an import/export declaration as should be written in the emitted output.
     * The emitted output name can be different from the input if:
     *  1. The module has a /// <amd-module name="<new name>" />
     *  2. --out or --outFile is used, making the name relative to the rootDir
     *  3- The containing SourceFile has an entry in renamedDependencies for the import as requested by some module loaders (e.g. System).
     * Otherwise, a new StringLiteral node representing the module name will be returned.
     */
    function getExternalModuleNameLiteral(importNode, sourceFile, host, resolver, compilerOptions) {
        var moduleName = ts.getExternalModuleName(importNode); // TODO: GH#18217
        if (moduleName.kind === 10 /* StringLiteral */) {
            return tryGetModuleNameFromDeclaration(importNode, host, resolver, compilerOptions)
                || tryRenameExternalModule(moduleName, sourceFile)
                || ts.getSynthesizedClone(moduleName);
        }
        return undefined;
    }
    ts.getExternalModuleNameLiteral = getExternalModuleNameLiteral;
    /**
     * Some bundlers (SystemJS builder) sometimes want to rename dependencies.
     * Here we check if alternative name was provided for a given moduleName and return it if possible.
     */
    function tryRenameExternalModule(moduleName, sourceFile) {
        var rename = sourceFile.renamedDependencies && sourceFile.renamedDependencies.get(moduleName.text);
        return rename && ts.createLiteral(rename);
    }
    /**
     * Get the name of a module as should be written in the emitted output.
     * The emitted output name can be different from the input if:
     *  1. The module has a /// <amd-module name="<new name>" />
     *  2. --out or --outFile is used, making the name relative to the rootDir
     * Otherwise, a new StringLiteral node representing the module name will be returned.
     */
    function tryGetModuleNameFromFile(file, host, options) {
        if (!file) {
            return undefined;
        }
        if (file.moduleName) {
            return ts.createLiteral(file.moduleName);
        }
        if (!file.isDeclarationFile && (options.out || options.outFile)) {
            return ts.createLiteral(ts.getExternalModuleNameFromPath(host, file.fileName));
        }
        return undefined;
    }
    ts.tryGetModuleNameFromFile = tryGetModuleNameFromFile;
    function tryGetModuleNameFromDeclaration(declaration, host, resolver, compilerOptions) {
        return tryGetModuleNameFromFile(resolver.getExternalModuleFileFromDeclaration(declaration), host, compilerOptions);
    }
    /**
     * Gets the initializer of an BindingOrAssignmentElement.
     */
    function getInitializerOfBindingOrAssignmentElement(bindingElement) {
        if (ts.isDeclarationBindingElement(bindingElement)) {
            // `1` in `let { a = 1 } = ...`
            // `1` in `let { a: b = 1 } = ...`
            // `1` in `let { a: {b} = 1 } = ...`
            // `1` in `let { a: [b] = 1 } = ...`
            // `1` in `let [a = 1] = ...`
            // `1` in `let [{a} = 1] = ...`
            // `1` in `let [[a] = 1] = ...`
            return bindingElement.initializer;
        }
        if (ts.isPropertyAssignment(bindingElement)) {
            // `1` in `({ a: b = 1 } = ...)`
            // `1` in `({ a: {b} = 1 } = ...)`
            // `1` in `({ a: [b] = 1 } = ...)`
            var initializer = bindingElement.initializer;
            return ts.isAssignmentExpression(initializer, /*excludeCompoundAssignment*/ true)
                ? initializer.right
                : undefined;
        }
        if (ts.isShorthandPropertyAssignment(bindingElement)) {
            // `1` in `({ a = 1 } = ...)`
            return bindingElement.objectAssignmentInitializer;
        }
        if (ts.isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) {
            // `1` in `[a = 1] = ...`
            // `1` in `[{a} = 1] = ...`
            // `1` in `[[a] = 1] = ...`
            return bindingElement.right;
        }
        if (ts.isSpreadElement(bindingElement)) {
            // Recovery consistent with existing emit.
            return getInitializerOfBindingOrAssignmentElement(bindingElement.expression);
        }
    }
    ts.getInitializerOfBindingOrAssignmentElement = getInitializerOfBindingOrAssignmentElement;
    /**
     * Gets the name of an BindingOrAssignmentElement.
     */
    function getTargetOfBindingOrAssignmentElement(bindingElement) {
        if (ts.isDeclarationBindingElement(bindingElement)) {
            // `a` in `let { a } = ...`
            // `a` in `let { a = 1 } = ...`
            // `b` in `let { a: b } = ...`
            // `b` in `let { a: b = 1 } = ...`
            // `a` in `let { ...a } = ...`
            // `{b}` in `let { a: {b} } = ...`
            // `{b}` in `let { a: {b} = 1 } = ...`
            // `[b]` in `let { a: [b] } = ...`
            // `[b]` in `let { a: [b] = 1 } = ...`
            // `a` in `let [a] = ...`
            // `a` in `let [a = 1] = ...`
            // `a` in `let [...a] = ...`
            // `{a}` in `let [{a}] = ...`
            // `{a}` in `let [{a} = 1] = ...`
            // `[a]` in `let [[a]] = ...`
            // `[a]` in `let [[a] = 1] = ...`
            return bindingElement.name;
        }
        if (ts.isObjectLiteralElementLike(bindingElement)) {
            switch (bindingElement.kind) {
                case 276 /* PropertyAssignment */:
                    // `b` in `({ a: b } = ...)`
                    // `b` in `({ a: b = 1 } = ...)`
                    // `{b}` in `({ a: {b} } = ...)`
                    // `{b}` in `({ a: {b} = 1 } = ...)`
                    // `[b]` in `({ a: [b] } = ...)`
                    // `[b]` in `({ a: [b] = 1 } = ...)`
                    // `b.c` in `({ a: b.c } = ...)`
                    // `b.c` in `({ a: b.c = 1 } = ...)`
                    // `b[0]` in `({ a: b[0] } = ...)`
                    // `b[0]` in `({ a: b[0] = 1 } = ...)`
                    return getTargetOfBindingOrAssignmentElement(bindingElement.initializer);
                case 277 /* ShorthandPropertyAssignment */:
                    // `a` in `({ a } = ...)`
                    // `a` in `({ a = 1 } = ...)`
                    return bindingElement.name;
                case 278 /* SpreadAssignment */:
                    // `a` in `({ ...a } = ...)`
                    return getTargetOfBindingOrAssignmentElement(bindingElement.expression);
            }
            // no target
            return undefined;
        }
        if (ts.isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) {
            // `a` in `[a = 1] = ...`
            // `{a}` in `[{a} = 1] = ...`
            // `[a]` in `[[a] = 1] = ...`
            // `a.b` in `[a.b = 1] = ...`
            // `a[0]` in `[a[0] = 1] = ...`
            return getTargetOfBindingOrAssignmentElement(bindingElement.left);
        }
        if (ts.isSpreadElement(bindingElement)) {
            // `a` in `[...a] = ...`
            return getTargetOfBindingOrAssignmentElement(bindingElement.expression);
        }
        // `a` in `[a] = ...`
        // `{a}` in `[{a}] = ...`
        // `[a]` in `[[a]] = ...`
        // `a.b` in `[a.b] = ...`
        // `a[0]` in `[a[0]] = ...`
        return bindingElement;
    }
    ts.getTargetOfBindingOrAssignmentElement = getTargetOfBindingOrAssignmentElement;
    /**
     * Determines whether an BindingOrAssignmentElement is a rest element.
     */
    function getRestIndicatorOfBindingOrAssignmentElement(bindingElement) {
        switch (bindingElement.kind) {
            case 152 /* Parameter */:
            case 187 /* BindingElement */:
                // `...` in `let [...a] = ...`
                return bindingElement.dotDotDotToken;
            case 209 /* SpreadElement */:
            case 278 /* SpreadAssignment */:
                // `...` in `[...a] = ...`
                return bindingElement;
        }
        return undefined;
    }
    ts.getRestIndicatorOfBindingOrAssignmentElement = getRestIndicatorOfBindingOrAssignmentElement;
    /**
     * Gets the property name of a BindingOrAssignmentElement
     */
    function getPropertyNameOfBindingOrAssignmentElement(bindingElement) {
        switch (bindingElement.kind) {
            case 187 /* BindingElement */:
                // `a` in `let { a: b } = ...`
                // `[a]` in `let { [a]: b } = ...`
                // `"a"` in `let { "a": b } = ...`
                // `1` in `let { 1: b } = ...`
                if (bindingElement.propertyName) {
                    var propertyName = bindingElement.propertyName;
                    return ts.isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression)
                        ? propertyName.expression
                        : propertyName;
                }
                break;
            case 276 /* PropertyAssignment */:
                // `a` in `({ a: b } = ...)`
                // `[a]` in `({ [a]: b } = ...)`
                // `"a"` in `({ "a": b } = ...)`
                // `1` in `({ 1: b } = ...)`
                if (bindingElement.name) {
                    var propertyName = bindingElement.name;
                    return ts.isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression)
                        ? propertyName.expression
                        : propertyName;
                }
                break;
            case 278 /* SpreadAssignment */:
                // `a` in `({ ...a } = ...)`
                return bindingElement.name;
        }
        var target = getTargetOfBindingOrAssignmentElement(bindingElement);
        if (target && ts.isPropertyName(target)) {
            return ts.isComputedPropertyName(target) && isStringOrNumericLiteral(target.expression)
                ? target.expression
                : target;
        }
        ts.Debug.fail("Invalid property name for binding element.");
    }
    ts.getPropertyNameOfBindingOrAssignmentElement = getPropertyNameOfBindingOrAssignmentElement;
    function isStringOrNumericLiteral(node) {
        var kind = node.kind;
        return kind === 10 /* StringLiteral */
            || kind === 8 /* NumericLiteral */;
    }
    /**
     * Gets the elements of a BindingOrAssignmentPattern
     */
    function getElementsOfBindingOrAssignmentPattern(name) {
        switch (name.kind) {
            case 185 /* ObjectBindingPattern */:
            case 186 /* ArrayBindingPattern */:
            case 188 /* ArrayLiteralExpression */:
                // `a` in `{a}`
                // `a` in `[a]`
                return name.elements;
            case 189 /* ObjectLiteralExpression */:
                // `a` in `{a}`
                return name.properties;
        }
    }
    ts.getElementsOfBindingOrAssignmentPattern = getElementsOfBindingOrAssignmentPattern;
    function convertToArrayAssignmentElement(element) {
        if (ts.isBindingElement(element)) {
            if (element.dotDotDotToken) {
                ts.Debug.assertNode(element.name, ts.isIdentifier);
                return ts.setOriginalNode(ts.setTextRange(ts.createSpread(element.name), element), element);
            }
            var expression = convertToAssignmentElementTarget(element.name);
            return element.initializer
                ? ts.setOriginalNode(ts.setTextRange(ts.createAssignment(expression, element.initializer), element), element)
                : expression;
        }
        ts.Debug.assertNode(element, ts.isExpression);
        return element;
    }
    ts.convertToArrayAssignmentElement = convertToArrayAssignmentElement;
    function convertToObjectAssignmentElement(element) {
        if (ts.isBindingElement(element)) {
            if (element.dotDotDotToken) {
                ts.Debug.assertNode(element.name, ts.isIdentifier);
                return ts.setOriginalNode(ts.setTextRange(ts.createSpreadAssignment(element.name), element), element);
            }
            if (element.propertyName) {
                var expression = convertToAssignmentElementTarget(element.name);
                return ts.setOriginalNode(ts.setTextRange(ts.createPropertyAssignment(element.propertyName, element.initializer ? ts.createAssignment(expression, element.initializer) : expression), element), element);
            }
            ts.Debug.assertNode(element.name, ts.isIdentifier);
            return ts.setOriginalNode(ts.setTextRange(ts.createShorthandPropertyAssignment(element.name, element.initializer), element), element);
        }
        ts.Debug.assertNode(element, ts.isObjectLiteralElementLike);
        return element;
    }
    ts.convertToObjectAssignmentElement = convertToObjectAssignmentElement;
    function convertToAssignmentPattern(node) {
        switch (node.kind) {
            case 186 /* ArrayBindingPattern */:
            case 188 /* ArrayLiteralExpression */:
                return convertToArrayAssignmentPattern(node);
            case 185 /* ObjectBindingPattern */:
            case 189 /* ObjectLiteralExpression */:
                return convertToObjectAssignmentPattern(node);
        }
    }
    ts.convertToAssignmentPattern = convertToAssignmentPattern;
    function convertToObjectAssignmentPattern(node) {
        if (ts.isObjectBindingPattern(node)) {
            return ts.setOriginalNode(ts.setTextRange(ts.createObjectLiteral(ts.map(node.elements, convertToObjectAssignmentElement)), node), node);
        }
        ts.Debug.assertNode(node, ts.isObjectLiteralExpression);
        return node;
    }
    ts.convertToObjectAssignmentPattern = convertToObjectAssignmentPattern;
    function convertToArrayAssignmentPattern(node) {
        if (ts.isArrayBindingPattern(node)) {
            return ts.setOriginalNode(ts.setTextRange(ts.createArrayLiteral(ts.map(node.elements, convertToArrayAssignmentElement)), node), node);
        }
        ts.Debug.assertNode(node, ts.isArrayLiteralExpression);
        return node;
    }
    ts.convertToArrayAssignmentPattern = convertToArrayAssignmentPattern;
    function convertToAssignmentElementTarget(node) {
        if (ts.isBindingPattern(node)) {
            return convertToAssignmentPattern(node);
        }
        ts.Debug.assertNode(node, ts.isExpression);
        return node;
    }
    ts.convertToAssignmentElementTarget = convertToAssignmentElementTarget;
})(ts || (ts = {}));
var ts;
(function (ts) {
    var isTypeNodeOrTypeParameterDeclaration = ts.or(ts.isTypeNode, ts.isTypeParameterDeclaration);
    function visitNode(node, visitor, test, lift) {
        if (node === undefined || visitor === undefined) {
            return node;
        }
        ts.aggregateTransformFlags(node);
        var visited = visitor(node);
        if (visited === node) {
            return node;
        }
        var visitedNode;
        if (visited === undefined) {
            return undefined;
        }
        else if (ts.isArray(visited)) {
            visitedNode = (lift || extractSingleNode)(visited);
        }
        else {
            visitedNode = visited;
        }
        ts.Debug.assertNode(visitedNode, test);
        ts.aggregateTransformFlags(visitedNode);
        return visitedNode;
    }
    ts.visitNode = visitNode;
    /**
     * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
     *
     * @param nodes The NodeArray to visit.
     * @param visitor The callback used to visit a Node.
     * @param test A node test to execute for each node.
     * @param start An optional value indicating the starting offset at which to start visiting.
     * @param count An optional value indicating the maximum number of nodes to visit.
     */
    function visitNodes(nodes, visitor, test, start, count) {
        if (nodes === undefined || visitor === undefined) {
            return nodes;
        }
        var updated;
        // Ensure start and count have valid values
        var length = nodes.length;
        if (start === undefined || start < 0) {
            start = 0;
        }
        if (count === undefined || count > length - start) {
            count = length - start;
        }
        if (start > 0 || count < length) {
            // If we are not visiting all of the original nodes, we must always create a new array.
            // Since this is a fragment of a node array, we do not copy over the previous location
            // and will only copy over `hasTrailingComma` if we are including the last element.
            updated = ts.createNodeArray([], /*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length);
        }
        // Visit each original node.
        for (var i = 0; i < count; i++) {
            var node = nodes[i + start];
            ts.aggregateTransformFlags(node);
            var visited = node !== undefined ? visitor(node) : undefined;
            if (updated !== undefined || visited === undefined || visited !== node) {
                if (updated === undefined) {
                    // Ensure we have a copy of `nodes`, up to the current index.
                    updated = ts.createNodeArray(nodes.slice(0, i), nodes.hasTrailingComma);
                    ts.setTextRange(updated, nodes);
                }
                if (visited) {
                    if (ts.isArray(visited)) {
                        for (var _i = 0, visited_1 = visited; _i < visited_1.length; _i++) {
                            var visitedNode = visited_1[_i];
                            ts.Debug.assertNode(visitedNode, test);
                            ts.aggregateTransformFlags(visitedNode);
                            updated.push(visitedNode);
                        }
                    }
                    else {
                        ts.Debug.assertNode(visited, test);
                        ts.aggregateTransformFlags(visited);
                        updated.push(visited);
                    }
                }
            }
        }
        return updated || nodes;
    }
    ts.visitNodes = visitNodes;
    /**
     * Starts a new lexical environment and visits a statement list, ending the lexical environment
     * and merging hoisted declarations upon completion.
     */
    function visitLexicalEnvironment(statements, visitor, context, start, ensureUseStrict) {
        context.startLexicalEnvironment();
        statements = visitNodes(statements, visitor, ts.isStatement, start);
        if (ensureUseStrict && !ts.startsWithUseStrict(statements)) {
            statements = ts.setTextRange(ts.createNodeArray([ts.createExpressionStatement(ts.createLiteral("use strict"))].concat(statements)), statements);
        }
        var declarations = context.endLexicalEnvironment();
        return ts.setTextRange(ts.createNodeArray(ts.concatenate(declarations, statements)), statements);
    }
    ts.visitLexicalEnvironment = visitLexicalEnvironment;
    /**
     * Starts a new lexical environment and visits a parameter list, suspending the lexical
     * environment upon completion.
     */
    function visitParameterList(nodes, visitor, context, nodesVisitor) {
        if (nodesVisitor === void 0) { nodesVisitor = visitNodes; }
        context.startLexicalEnvironment();
        var updated = nodesVisitor(nodes, visitor, ts.isParameterDeclaration);
        context.suspendLexicalEnvironment();
        return updated;
    }
    ts.visitParameterList = visitParameterList;
    function visitFunctionBody(node, visitor, context) {
        context.resumeLexicalEnvironment();
        var updated = visitNode(node, visitor, ts.isConciseBody);
        var declarations = context.endLexicalEnvironment();
        if (ts.some(declarations)) {
            var block = ts.convertToFunctionBody(updated);
            var statements = ts.mergeLexicalEnvironment(block.statements, declarations);
            return ts.updateBlock(block, statements);
        }
        return updated;
    }
    ts.visitFunctionBody = visitFunctionBody;
    function visitEachChild(node, visitor, context, nodesVisitor, tokenVisitor) {
        if (nodesVisitor === void 0) { nodesVisitor = visitNodes; }
        if (node === undefined) {
            return undefined;
        }
        var kind = node.kind;
        // No need to visit nodes with no children.
        if ((kind > 0 /* FirstToken */ && kind <= 148 /* LastToken */) || kind === 179 /* ThisType */) {
            return node;
        }
        switch (kind) {
            // Names
            case 73 /* Identifier */:
                return ts.updateIdentifier(node, nodesVisitor(node.typeArguments, visitor, isTypeNodeOrTypeParameterDeclaration));
            case 149 /* QualifiedName */:
                return ts.updateQualifiedName(node, visitNode(node.left, visitor, ts.isEntityName), visitNode(node.right, visitor, ts.isIdentifier));
            case 150 /* ComputedPropertyName */:
                return ts.updateComputedPropertyName(node, visitNode(node.expression, visitor, ts.isExpression));
            // Signature elements
            case 151 /* TypeParameter */:
                return ts.updateTypeParameterDeclaration(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.constraint, visitor, ts.isTypeNode), visitNode(node.default, visitor, ts.isTypeNode));
            case 152 /* Parameter */:
                return ts.updateParameter(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.dotDotDotToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isBindingName), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 153 /* Decorator */:
                return ts.updateDecorator(node, visitNode(node.expression, visitor, ts.isExpression));
            // Type elements
            case 154 /* PropertySignature */:
                return ts.updatePropertySignature(node, nodesVisitor(node.modifiers, visitor, ts.isToken), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 155 /* PropertyDeclaration */:
                return ts.updateProperty(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), 
                // QuestionToken and ExclamationToken is uniqued in Property Declaration and the signature of 'updateProperty' is that too
                visitNode(node.questionToken || node.exclamationToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 156 /* MethodSignature */:
                return ts.updateMethodSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken));
            case 157 /* MethodDeclaration */:
                return ts.updateMethod(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 158 /* Constructor */:
                return ts.updateConstructor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitFunctionBody(node.body, visitor, context));
            case 159 /* GetAccessor */:
                return ts.updateGetAccessor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 160 /* SetAccessor */:
                return ts.updateSetAccessor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitFunctionBody(node.body, visitor, context));
            case 161 /* CallSignature */:
                return ts.updateCallSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 162 /* ConstructSignature */:
                return ts.updateConstructSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 163 /* IndexSignature */:
                return ts.updateIndexSignature(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            // Types
            case 164 /* TypePredicate */:
                return ts.updateTypePredicateNode(node, visitNode(node.parameterName, visitor), visitNode(node.type, visitor, ts.isTypeNode));
            case 165 /* TypeReference */:
                return ts.updateTypeReferenceNode(node, visitNode(node.typeName, visitor, ts.isEntityName), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode));
            case 166 /* FunctionType */:
                return ts.updateFunctionTypeNode(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 167 /* ConstructorType */:
                return ts.updateConstructorTypeNode(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 168 /* TypeQuery */:
                return ts.updateTypeQueryNode(node, visitNode(node.exprName, visitor, ts.isEntityName));
            case 169 /* TypeLiteral */:
                return ts.updateTypeLiteralNode(node, nodesVisitor(node.members, visitor, ts.isTypeElement));
            case 170 /* ArrayType */:
                return ts.updateArrayTypeNode(node, visitNode(node.elementType, visitor, ts.isTypeNode));
            case 171 /* TupleType */:
                return ts.updateTupleTypeNode(node, nodesVisitor(node.elementTypes, visitor, ts.isTypeNode));
            case 172 /* OptionalType */:
                return ts.updateOptionalTypeNode(node, visitNode(node.type, visitor, ts.isTypeNode));
            case 173 /* RestType */:
                return ts.updateRestTypeNode(node, visitNode(node.type, visitor, ts.isTypeNode));
            case 174 /* UnionType */:
                return ts.updateUnionTypeNode(node, nodesVisitor(node.types, visitor, ts.isTypeNode));
            case 175 /* IntersectionType */:
                return ts.updateIntersectionTypeNode(node, nodesVisitor(node.types, visitor, ts.isTypeNode));
            case 176 /* ConditionalType */:
                return ts.updateConditionalTypeNode(node, visitNode(node.checkType, visitor, ts.isTypeNode), visitNode(node.extendsType, visitor, ts.isTypeNode), visitNode(node.trueType, visitor, ts.isTypeNode), visitNode(node.falseType, visitor, ts.isTypeNode));
            case 177 /* InferType */:
                return ts.updateInferTypeNode(node, visitNode(node.typeParameter, visitor, ts.isTypeParameterDeclaration));
            case 184 /* ImportType */:
                return ts.updateImportTypeNode(node, visitNode(node.argument, visitor, ts.isTypeNode), visitNode(node.qualifier, visitor, ts.isEntityName), visitNodes(node.typeArguments, visitor, ts.isTypeNode), node.isTypeOf);
            case 178 /* ParenthesizedType */:
                return ts.updateParenthesizedType(node, visitNode(node.type, visitor, ts.isTypeNode));
            case 180 /* TypeOperator */:
                return ts.updateTypeOperatorNode(node, visitNode(node.type, visitor, ts.isTypeNode));
            case 181 /* IndexedAccessType */:
                return ts.updateIndexedAccessTypeNode(node, visitNode(node.objectType, visitor, ts.isTypeNode), visitNode(node.indexType, visitor, ts.isTypeNode));
            case 182 /* MappedType */:
                return ts.updateMappedTypeNode(node, visitNode(node.readonlyToken, tokenVisitor, ts.isToken), visitNode(node.typeParameter, visitor, ts.isTypeParameterDeclaration), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode));
            case 183 /* LiteralType */:
                return ts.updateLiteralTypeNode(node, visitNode(node.literal, visitor, ts.isExpression));
            // Binding patterns
            case 185 /* ObjectBindingPattern */:
                return ts.updateObjectBindingPattern(node, nodesVisitor(node.elements, visitor, ts.isBindingElement));
            case 186 /* ArrayBindingPattern */:
                return ts.updateArrayBindingPattern(node, nodesVisitor(node.elements, visitor, ts.isArrayBindingElement));
            case 187 /* BindingElement */:
                return ts.updateBindingElement(node, visitNode(node.dotDotDotToken, tokenVisitor, ts.isToken), visitNode(node.propertyName, visitor, ts.isPropertyName), visitNode(node.name, visitor, ts.isBindingName), visitNode(node.initializer, visitor, ts.isExpression));
            // Expression
            case 188 /* ArrayLiteralExpression */:
                return ts.updateArrayLiteral(node, nodesVisitor(node.elements, visitor, ts.isExpression));
            case 189 /* ObjectLiteralExpression */:
                return ts.updateObjectLiteral(node, nodesVisitor(node.properties, visitor, ts.isObjectLiteralElementLike));
            case 190 /* PropertyAccessExpression */:
                return ts.updatePropertyAccess(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.name, visitor, ts.isIdentifier));
            case 191 /* ElementAccessExpression */:
                return ts.updateElementAccess(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.argumentExpression, visitor, ts.isExpression));
            case 192 /* CallExpression */:
                return ts.updateCall(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), nodesVisitor(node.arguments, visitor, ts.isExpression));
            case 193 /* NewExpression */:
                return ts.updateNew(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), nodesVisitor(node.arguments, visitor, ts.isExpression));
            case 194 /* TaggedTemplateExpression */:
                return ts.updateTaggedTemplate(node, visitNode(node.tag, visitor, ts.isExpression), visitNodes(node.typeArguments, visitor, ts.isExpression), visitNode(node.template, visitor, ts.isTemplateLiteral));
            case 195 /* TypeAssertionExpression */:
                return ts.updateTypeAssertion(node, visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.expression, visitor, ts.isExpression));
            case 196 /* ParenthesizedExpression */:
                return ts.updateParen(node, visitNode(node.expression, visitor, ts.isExpression));
            case 197 /* FunctionExpression */:
                return ts.updateFunctionExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 198 /* ArrowFunction */:
                return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.equalsGreaterThanToken, visitor, ts.isToken), visitFunctionBody(node.body, visitor, context));
            case 199 /* DeleteExpression */:
                return ts.updateDelete(node, visitNode(node.expression, visitor, ts.isExpression));
            case 200 /* TypeOfExpression */:
                return ts.updateTypeOf(node, visitNode(node.expression, visitor, ts.isExpression));
            case 201 /* VoidExpression */:
                return ts.updateVoid(node, visitNode(node.expression, visitor, ts.isExpression));
            case 202 /* AwaitExpression */:
                return ts.updateAwait(node, visitNode(node.expression, visitor, ts.isExpression));
            case 203 /* PrefixUnaryExpression */:
                return ts.updatePrefix(node, visitNode(node.operand, visitor, ts.isExpression));
            case 204 /* PostfixUnaryExpression */:
                return ts.updatePostfix(node, visitNode(node.operand, visitor, ts.isExpression));
            case 205 /* BinaryExpression */:
                return ts.updateBinary(node, visitNode(node.left, visitor, ts.isExpression), visitNode(node.right, visitor, ts.isExpression), visitNode(node.operatorToken, visitor, ts.isToken));
            case 206 /* ConditionalExpression */:
                return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.questionToken, visitor, ts.isToken), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.colonToken, visitor, ts.isToken), visitNode(node.whenFalse, visitor, ts.isExpression));
            case 207 /* TemplateExpression */:
                return ts.updateTemplateExpression(node, visitNode(node.head, visitor, ts.isTemplateHead), nodesVisitor(node.templateSpans, visitor, ts.isTemplateSpan));
            case 208 /* YieldExpression */:
                return ts.updateYield(node, visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.expression, visitor, ts.isExpression));
            case 209 /* SpreadElement */:
                return ts.updateSpread(node, visitNode(node.expression, visitor, ts.isExpression));
            case 210 /* ClassExpression */:
                return ts.updateClassExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isClassElement));
            case 212 /* ExpressionWithTypeArguments */:
                return ts.updateExpressionWithTypeArguments(node, nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), visitNode(node.expression, visitor, ts.isExpression));
            case 213 /* AsExpression */:
                return ts.updateAsExpression(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.type, visitor, ts.isTypeNode));
            case 214 /* NonNullExpression */:
                return ts.updateNonNullExpression(node, visitNode(node.expression, visitor, ts.isExpression));
            case 215 /* MetaProperty */:
                return ts.updateMetaProperty(node, visitNode(node.name, visitor, ts.isIdentifier));
            // Misc
            case 217 /* TemplateSpan */:
                return ts.updateTemplateSpan(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.literal, visitor, ts.isTemplateMiddleOrTemplateTail));
            // Element
            case 219 /* Block */:
                return ts.updateBlock(node, nodesVisitor(node.statements, visitor, ts.isStatement));
            case 220 /* VariableStatement */:
                return ts.updateVariableStatement(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.declarationList, visitor, ts.isVariableDeclarationList));
            case 222 /* ExpressionStatement */:
                return ts.updateExpressionStatement(node, visitNode(node.expression, visitor, ts.isExpression));
            case 223 /* IfStatement */:
                return ts.updateIf(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.thenStatement, visitor, ts.isStatement, ts.liftToBlock), visitNode(node.elseStatement, visitor, ts.isStatement, ts.liftToBlock));
            case 224 /* DoStatement */:
                return ts.updateDo(node, visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock), visitNode(node.expression, visitor, ts.isExpression));
            case 225 /* WhileStatement */:
                return ts.updateWhile(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 226 /* ForStatement */:
                return ts.updateFor(node, visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.condition, visitor, ts.isExpression), visitNode(node.incrementor, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 227 /* ForInStatement */:
                return ts.updateForIn(node, visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 228 /* ForOfStatement */:
                return ts.updateForOf(node, visitNode(node.awaitModifier, visitor, ts.isToken), visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 229 /* ContinueStatement */:
                return ts.updateContinue(node, visitNode(node.label, visitor, ts.isIdentifier));
            case 230 /* BreakStatement */:
                return ts.updateBreak(node, visitNode(node.label, visitor, ts.isIdentifier));
            case 231 /* ReturnStatement */:
                return ts.updateReturn(node, visitNode(node.expression, visitor, ts.isExpression));
            case 232 /* WithStatement */:
                return ts.updateWith(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 233 /* SwitchStatement */:
                return ts.updateSwitch(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.caseBlock, visitor, ts.isCaseBlock));
            case 234 /* LabeledStatement */:
                return ts.updateLabel(node, visitNode(node.label, visitor, ts.isIdentifier), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 235 /* ThrowStatement */:
                return ts.updateThrow(node, visitNode(node.expression, visitor, ts.isExpression));
            case 236 /* TryStatement */:
                return ts.updateTry(node, visitNode(node.tryBlock, visitor, ts.isBlock), visitNode(node.catchClause, visitor, ts.isCatchClause), visitNode(node.finallyBlock, visitor, ts.isBlock));
            case 238 /* VariableDeclaration */:
                return ts.updateVariableDeclaration(node, visitNode(node.name, visitor, ts.isBindingName), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 239 /* VariableDeclarationList */:
                return ts.updateVariableDeclarationList(node, nodesVisitor(node.declarations, visitor, ts.isVariableDeclaration));
            case 240 /* FunctionDeclaration */:
                return ts.updateFunctionDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 241 /* ClassDeclaration */:
                return ts.updateClassDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isClassElement));
            case 242 /* InterfaceDeclaration */:
                return ts.updateInterfaceDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isTypeElement));
            case 243 /* TypeAliasDeclaration */:
                return ts.updateTypeAliasDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 244 /* EnumDeclaration */:
                return ts.updateEnumDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.members, visitor, ts.isEnumMember));
            case 245 /* ModuleDeclaration */:
                return ts.updateModuleDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.body, visitor, ts.isModuleBody));
            case 246 /* ModuleBlock */:
                return ts.updateModuleBlock(node, nodesVisitor(node.statements, visitor, ts.isStatement));
            case 247 /* CaseBlock */:
                return ts.updateCaseBlock(node, nodesVisitor(node.clauses, visitor, ts.isCaseOrDefaultClause));
            case 248 /* NamespaceExportDeclaration */:
                return ts.updateNamespaceExportDeclaration(node, visitNode(node.name, visitor, ts.isIdentifier));
            case 249 /* ImportEqualsDeclaration */:
                return ts.updateImportEqualsDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.moduleReference, visitor, ts.isModuleReference));
            case 250 /* ImportDeclaration */:
                return ts.updateImportDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.importClause, visitor, ts.isImportClause), visitNode(node.moduleSpecifier, visitor, ts.isExpression));
            case 251 /* ImportClause */:
                return ts.updateImportClause(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.namedBindings, visitor, ts.isNamedImportBindings));
            case 252 /* NamespaceImport */:
                return ts.updateNamespaceImport(node, visitNode(node.name, visitor, ts.isIdentifier));
            case 253 /* NamedImports */:
                return ts.updateNamedImports(node, nodesVisitor(node.elements, visitor, ts.isImportSpecifier));
            case 254 /* ImportSpecifier */:
                return ts.updateImportSpecifier(node, visitNode(node.propertyName, visitor, ts.isIdentifier), visitNode(node.name, visitor, ts.isIdentifier));
            case 255 /* ExportAssignment */:
                return ts.updateExportAssignment(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.expression, visitor, ts.isExpression));
            case 256 /* ExportDeclaration */:
                return ts.updateExportDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.exportClause, visitor, ts.isNamedExports), visitNode(node.moduleSpecifier, visitor, ts.isExpression));
            case 257 /* NamedExports */:
                return ts.updateNamedExports(node, nodesVisitor(node.elements, visitor, ts.isExportSpecifier));
            case 258 /* ExportSpecifier */:
                return ts.updateExportSpecifier(node, visitNode(node.propertyName, visitor, ts.isIdentifier), visitNode(node.name, visitor, ts.isIdentifier));
            // Module references
            case 260 /* ExternalModuleReference */:
                return ts.updateExternalModuleReference(node, visitNode(node.expression, visitor, ts.isExpression));
            // JSX
            case 261 /* JsxElement */:
                return ts.updateJsxElement(node, visitNode(node.openingElement, visitor, ts.isJsxOpeningElement), nodesVisitor(node.children, visitor, ts.isJsxChild), visitNode(node.closingElement, visitor, ts.isJsxClosingElement));
            case 262 /* JsxSelfClosingElement */:
                return ts.updateJsxSelfClosingElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), visitNode(node.attributes, visitor, ts.isJsxAttributes));
            case 263 /* JsxOpeningElement */:
                return ts.updateJsxOpeningElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), visitNode(node.attributes, visitor, ts.isJsxAttributes));
            case 264 /* JsxClosingElement */:
                return ts.updateJsxClosingElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression));
            case 265 /* JsxFragment */:
                return ts.updateJsxFragment(node, visitNode(node.openingFragment, visitor, ts.isJsxOpeningFragment), nodesVisitor(node.children, visitor, ts.isJsxChild), visitNode(node.closingFragment, visitor, ts.isJsxClosingFragment));
            case 268 /* JsxAttribute */:
                return ts.updateJsxAttribute(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.initializer, visitor, ts.isStringLiteralOrJsxExpression));
            case 269 /* JsxAttributes */:
                return ts.updateJsxAttributes(node, nodesVisitor(node.properties, visitor, ts.isJsxAttributeLike));
            case 270 /* JsxSpreadAttribute */:
                return ts.updateJsxSpreadAttribute(node, visitNode(node.expression, visitor, ts.isExpression));
            case 271 /* JsxExpression */:
                return ts.updateJsxExpression(node, visitNode(node.expression, visitor, ts.isExpression));
            // Clauses
            case 272 /* CaseClause */:
                return ts.updateCaseClause(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.statements, visitor, ts.isStatement));
            case 273 /* DefaultClause */:
                return ts.updateDefaultClause(node, nodesVisitor(node.statements, visitor, ts.isStatement));
            case 274 /* HeritageClause */:
                return ts.updateHeritageClause(node, nodesVisitor(node.types, visitor, ts.isExpressionWithTypeArguments));
            case 275 /* CatchClause */:
                return ts.updateCatchClause(node, visitNode(node.variableDeclaration, visitor, ts.isVariableDeclaration), visitNode(node.block, visitor, ts.isBlock));
            // Property assignments
            case 276 /* PropertyAssignment */:
                return ts.updatePropertyAssignment(node, visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.initializer, visitor, ts.isExpression));
            case 277 /* ShorthandPropertyAssignment */:
                return ts.updateShorthandPropertyAssignment(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.objectAssignmentInitializer, visitor, ts.isExpression));
            case 278 /* SpreadAssignment */:
                return ts.updateSpreadAssignment(node, visitNode(node.expression, visitor, ts.isExpression));
            // Enum
            case 279 /* EnumMember */:
                return ts.updateEnumMember(node, visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.initializer, visitor, ts.isExpression));
            // Top-level nodes
            case 285 /* SourceFile */:
                return ts.updateSourceFileNode(node, visitLexicalEnvironment(node.statements, visitor, context));
            // Transformation nodes
            case 314 /* PartiallyEmittedExpression */:
                return ts.updatePartiallyEmittedExpression(node, visitNode(node.expression, visitor, ts.isExpression));
            case 315 /* CommaListExpression */:
                return ts.updateCommaList(node, nodesVisitor(node.elements, visitor, ts.isExpression));
            default:
                // No need to visit nodes with no children.
                return node;
        }
    }
    ts.visitEachChild = visitEachChild;
    /**
     * Extracts the single node from a NodeArray.
     *
     * @param nodes The NodeArray.
     */
    function extractSingleNode(nodes) {
        ts.Debug.assert(nodes.length <= 1, "Too many nodes written to output.");
        return ts.singleOrUndefined(nodes);
    }
})(ts || (ts = {}));
/* @internal */
(function (ts) {
    function reduceNode(node, f, initial) {
        return node ? f(initial, node) : initial;
    }
    function reduceNodeArray(nodes, f, initial) {
        return nodes ? f(initial, nodes) : initial;
    }
    /**
     * Similar to `reduceLeft`, performs a reduction against each child of a node.
     * NOTE: Unlike `forEachChild`, this does *not* visit every node.
     *
     * @param node The node containing the children to reduce.
     * @param initial The initial value to supply to the reduction.
     * @param f The callback function
     */
    function reduceEachChild(node, initial, cbNode, cbNodeArray) {
        if (node === undefined) {
            return initial;
        }
        var reduceNodes = cbNodeArray ? reduceNodeArray : ts.reduceLeft;
        var cbNodes = cbNodeArray || cbNode;
        var kind = node.kind;
        // No need to visit nodes with no children.
        if ((kind > 0 /* FirstToken */ && kind <= 148 /* LastToken */)) {
            return initial;
        }
        // We do not yet support types.
        if ((kind >= 164 /* TypePredicate */ && kind <= 183 /* LiteralType */)) {
            return initial;
        }
        var result = initial;
        switch (node.kind) {
            // Leaf nodes
            case 218 /* SemicolonClassElement */:
            case 221 /* EmptyStatement */:
            case 211 /* OmittedExpression */:
            case 237 /* DebuggerStatement */:
            case 313 /* NotEmittedStatement */:
                // No need to visit nodes with no children.
                break;
            // Names
            case 149 /* QualifiedName */:
                result = reduceNode(node.left, cbNode, result);
                result = reduceNode(node.right, cbNode, result);
                break;
            case 150 /* ComputedPropertyName */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Signature elements
            case 152 /* Parameter */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 153 /* Decorator */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Type member
            case 154 /* PropertySignature */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.questionToken, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 155 /* PropertyDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 157 /* MethodDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 158 /* Constructor */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 159 /* GetAccessor */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 160 /* SetAccessor */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            // Binding patterns
            case 185 /* ObjectBindingPattern */:
            case 186 /* ArrayBindingPattern */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            case 187 /* BindingElement */:
                result = reduceNode(node.propertyName, cbNode, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            // Expression
            case 188 /* ArrayLiteralExpression */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            case 189 /* ObjectLiteralExpression */:
                result = reduceNodes(node.properties, cbNodes, result);
                break;
            case 190 /* PropertyAccessExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.name, cbNode, result);
                break;
            case 191 /* ElementAccessExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.argumentExpression, cbNode, result);
                break;
            case 192 /* CallExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNodes, result);
                result = reduceNodes(node.arguments, cbNodes, result);
                break;
            case 193 /* NewExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNodes, result);
                result = reduceNodes(node.arguments, cbNodes, result);
                break;
            case 194 /* TaggedTemplateExpression */:
                result = reduceNode(node.tag, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNodes, result);
                result = reduceNode(node.template, cbNode, result);
                break;
            case 195 /* TypeAssertionExpression */:
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 197 /* FunctionExpression */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 198 /* ArrowFunction */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 196 /* ParenthesizedExpression */:
            case 199 /* DeleteExpression */:
            case 200 /* TypeOfExpression */:
            case 201 /* VoidExpression */:
            case 202 /* AwaitExpression */:
            case 208 /* YieldExpression */:
            case 209 /* SpreadElement */:
            case 214 /* NonNullExpression */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 203 /* PrefixUnaryExpression */:
            case 204 /* PostfixUnaryExpression */:
                result = reduceNode(node.operand, cbNode, result);
                break;
            case 205 /* BinaryExpression */:
                result = reduceNode(node.left, cbNode, result);
                result = reduceNode(node.right, cbNode, result);
                break;
            case 206 /* ConditionalExpression */:
                result = reduceNode(node.condition, cbNode, result);
                result = reduceNode(node.whenTrue, cbNode, result);
                result = reduceNode(node.whenFalse, cbNode, result);
                break;
            case 207 /* TemplateExpression */:
                result = reduceNode(node.head, cbNode, result);
                result = reduceNodes(node.templateSpans, cbNodes, result);
                break;
            case 210 /* ClassExpression */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.heritageClauses, cbNodes, result);
                result = reduceNodes(node.members, cbNodes, result);
                break;
            case 212 /* ExpressionWithTypeArguments */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNodes, result);
                break;
            case 213 /* AsExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                break;
            // Misc
            case 217 /* TemplateSpan */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.literal, cbNode, result);
                break;
            // Element
            case 219 /* Block */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            case 220 /* VariableStatement */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.declarationList, cbNode, result);
                break;
            case 222 /* ExpressionStatement */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 223 /* IfStatement */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.thenStatement, cbNode, result);
                result = reduceNode(node.elseStatement, cbNode, result);
                break;
            case 224 /* DoStatement */:
                result = reduceNode(node.statement, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 225 /* WhileStatement */:
            case 232 /* WithStatement */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 226 /* ForStatement */:
                result = reduceNode(node.initializer, cbNode, result);
                result = reduceNode(node.condition, cbNode, result);
                result = reduceNode(node.incrementor, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 227 /* ForInStatement */:
            case 228 /* ForOfStatement */:
                result = reduceNode(node.initializer, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 231 /* ReturnStatement */:
            case 235 /* ThrowStatement */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 233 /* SwitchStatement */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.caseBlock, cbNode, result);
                break;
            case 234 /* LabeledStatement */:
                result = reduceNode(node.label, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 236 /* TryStatement */:
                result = reduceNode(node.tryBlock, cbNode, result);
                result = reduceNode(node.catchClause, cbNode, result);
                result = reduceNode(node.finallyBlock, cbNode, result);
                break;
            case 238 /* VariableDeclaration */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 239 /* VariableDeclarationList */:
                result = reduceNodes(node.declarations, cbNodes, result);
                break;
            case 240 /* FunctionDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 241 /* ClassDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.heritageClauses, cbNodes, result);
                result = reduceNodes(node.members, cbNodes, result);
                break;
            case 244 /* EnumDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.members, cbNodes, result);
                break;
            case 245 /* ModuleDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 246 /* ModuleBlock */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            case 247 /* CaseBlock */:
                result = reduceNodes(node.clauses, cbNodes, result);
                break;
            case 249 /* ImportEqualsDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.moduleReference, cbNode, result);
                break;
            case 250 /* ImportDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.importClause, cbNode, result);
                result = reduceNode(node.moduleSpecifier, cbNode, result);
                break;
            case 251 /* ImportClause */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.namedBindings, cbNode, result);
                break;
            case 252 /* NamespaceImport */:
                result = reduceNode(node.name, cbNode, result);
                break;
            case 253 /* NamedImports */:
            case 257 /* NamedExports */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            case 254 /* ImportSpecifier */:
            case 258 /* ExportSpecifier */:
                result = reduceNode(node.propertyName, cbNode, result);
                result = reduceNode(node.name, cbNode, result);
                break;
            case 255 /* ExportAssignment */:
                result = ts.reduceLeft(node.decorators, cbNode, result);
                result = ts.reduceLeft(node.modifiers, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 256 /* ExportDeclaration */:
                result = ts.reduceLeft(node.decorators, cbNode, result);
                result = ts.reduceLeft(node.modifiers, cbNode, result);
                result = reduceNode(node.exportClause, cbNode, result);
                result = reduceNode(node.moduleSpecifier, cbNode, result);
                break;
            // Module references
            case 260 /* ExternalModuleReference */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // JSX
            case 261 /* JsxElement */:
                result = reduceNode(node.openingElement, cbNode, result);
                result = ts.reduceLeft(node.children, cbNode, result);
                result = reduceNode(node.closingElement, cbNode, result);
                break;
            case 265 /* JsxFragment */:
                result = reduceNode(node.openingFragment, cbNode, result);
                result = ts.reduceLeft(node.children, cbNode, result);
                result = reduceNode(node.closingFragment, cbNode, result);
                break;
            case 262 /* JsxSelfClosingElement */:
            case 263 /* JsxOpeningElement */:
                result = reduceNode(node.tagName, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNode, result);
                result = reduceNode(node.attributes, cbNode, result);
                break;
            case 269 /* JsxAttributes */:
                result = reduceNodes(node.properties, cbNodes, result);
                break;
            case 264 /* JsxClosingElement */:
                result = reduceNode(node.tagName, cbNode, result);
                break;
            case 268 /* JsxAttribute */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 270 /* JsxSpreadAttribute */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 271 /* JsxExpression */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Clauses
            case 272 /* CaseClause */:
                result = reduceNode(node.expression, cbNode, result);
            // falls through
            case 273 /* DefaultClause */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            case 274 /* HeritageClause */:
                result = reduceNodes(node.types, cbNodes, result);
                break;
            case 275 /* CatchClause */:
                result = reduceNode(node.variableDeclaration, cbNode, result);
                result = reduceNode(node.block, cbNode, result);
                break;
            // Property assignments
            case 276 /* PropertyAssignment */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 277 /* ShorthandPropertyAssignment */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.objectAssignmentInitializer, cbNode, result);
                break;
            case 278 /* SpreadAssignment */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Enum
            case 279 /* EnumMember */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            // Top-level nodes
            case 285 /* SourceFile */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            // Transformation nodes
            case 314 /* PartiallyEmittedExpression */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 315 /* CommaListExpression */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            default:
                break;
        }
        return result;
    }
    ts.reduceEachChild = reduceEachChild;
    function mergeLexicalEnvironment(statements, declarations) {
        if (!ts.some(declarations)) {
            return statements;
        }
        return ts.isNodeArray(statements)
            ? ts.setTextRange(ts.createNodeArray(ts.insertStatementsAfterStandardPrologue(statements.slice(), declarations)), statements)
            : ts.insertStatementsAfterStandardPrologue(statements, declarations);
    }
    ts.mergeLexicalEnvironment = mergeLexicalEnvironment;
    /**
     * Lifts a NodeArray containing only Statement nodes to a block.
     *
     * @param nodes The NodeArray.
     */
    function liftToBlock(nodes) {
        ts.Debug.assert(ts.every(nodes, ts.isStatement), "Cannot lift nodes to a Block.");
        return ts.singleOrUndefined(nodes) || ts.createBlock(nodes);
    }
    ts.liftToBlock = liftToBlock;
    /**
     * Aggregates the TransformFlags for a Node and its subtree.
     */
    function aggregateTransformFlags(node) {
        aggregateTransformFlagsForNode(node);
        return node;
    }
    ts.aggregateTransformFlags = aggregateTransformFlags;
    /**
     * Aggregates the TransformFlags for a Node and its subtree. The flags for the subtree are
     * computed first, then the transform flags for the current node are computed from the subtree
     * flags and the state of the current node. Finally, the transform flags of the node are
     * returned, excluding any flags that should not be included in its parent node's subtree
     * flags.
     */
    function aggregateTransformFlagsForNode(node) {
        if (node === undefined) {
            return 0 /* None */;
        }
        if (node.transformFlags & 536870912 /* HasComputedFlags */) {
            return node.transformFlags & ~ts.getTransformFlagsSubtreeExclusions(node.kind);
        }
        var subtreeFlags = aggregateTransformFlagsForSubtree(node);
        return ts.computeTransformFlagsForNode(node, subtreeFlags);
    }
    function aggregateTransformFlagsForNodeArray(nodes) {
        if (nodes === undefined) {
            return 0 /* None */;
        }
        var subtreeFlags = 0 /* None */;
        var nodeArrayFlags = 0 /* None */;
        for (var _i = 0, nodes_3 = nodes; _i < nodes_3.length; _i++) {
            var node = nodes_3[_i];
            subtreeFlags |= aggregateTransformFlagsForNode(node);
            nodeArrayFlags |= node.transformFlags & ~536870912 /* HasComputedFlags */;
        }
        nodes.transformFlags = nodeArrayFlags | 536870912 /* HasComputedFlags */;
        return subtreeFlags;
    }
    /**
     * Aggregates the transform flags for the subtree of a node.
     */
    function aggregateTransformFlagsForSubtree(node) {
        // We do not transform ambient declarations or types, so there is no need to
        // recursively aggregate transform flags.
        if (ts.hasModifier(node, 2 /* Ambient */) || (ts.isTypeNode(node) && node.kind !== 212 /* ExpressionWithTypeArguments */)) {
            return 0 /* None */;
        }
        // Aggregate the transform flags of each child.
        return reduceEachChild(node, 0 /* None */, aggregateTransformFlagsForChildNode, aggregateTransformFlagsForChildNodes);
    }
    /**
     * Aggregates the TransformFlags of a child node with the TransformFlags of its
     * siblings.
     */
    function aggregateTransformFlagsForChildNode(transformFlags, node) {
        return transformFlags | aggregateTransformFlagsForNode(node);
    }
    function aggregateTransformFlagsForChildNodes(transformFlags, nodes) {
        return transformFlags | aggregateTransformFlagsForNodeArray(nodes);
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function createSourceMapGenerator(host, file, sourceRoot, sourcesDirectoryPath, generatorOptions) {
        var _a = generatorOptions.extendedDiagnostics
            ? ts.performance.createTimer("Source Map", "beforeSourcemap", "afterSourcemap")
            : ts.performance.nullTimer, enter = _a.enter, exit = _a.exit;
        // Current source map file and its index in the sources list
        var rawSources = [];
        var sources = [];
        var sourceToSourceIndexMap = ts.createMap();
        var sourcesContent;
        var names = [];
        var nameToNameIndexMap;
        var mappings = "";
        // Last recorded and encoded mappings
        var lastGeneratedLine = 0;
        var lastGeneratedCharacter = 0;
        var lastSourceIndex = 0;
        var lastSourceLine = 0;
        var lastSourceCharacter = 0;
        var lastNameIndex = 0;
        var hasLast = false;
        var pendingGeneratedLine = 0;
        var pendingGeneratedCharacter = 0;
        var pendingSourceIndex = 0;
        var pendingSourceLine = 0;
        var pendingSourceCharacter = 0;
        var pendingNameIndex = 0;
        var hasPending = false;
        var hasPendingSource = false;
        var hasPendingName = false;
        return {
            getSources: function () { return rawSources; },
            addSource: addSource,
            setSourceContent: setSourceContent,
            addName: addName,
            addMapping: addMapping,
            appendSourceMap: appendSourceMap,
            toJSON: toJSON,
            toString: function () { return JSON.stringify(toJSON()); }
        };
        function addSource(fileName) {
            enter();
            var source = ts.getRelativePathToDirectoryOrUrl(sourcesDirectoryPath, fileName, host.getCurrentDirectory(), host.getCanonicalFileName, 
            /*isAbsolutePathAnUrl*/ true);
            var sourceIndex = sourceToSourceIndexMap.get(source);
            if (sourceIndex === undefined) {
                sourceIndex = sources.length;
                sources.push(source);
                rawSources.push(fileName);
                sourceToSourceIndexMap.set(source, sourceIndex);
            }
            exit();
            return sourceIndex;
        }
        function setSourceContent(sourceIndex, content) {
            enter();
            if (content !== null) {
                if (!sourcesContent)
                    sourcesContent = [];
                while (sourcesContent.length < sourceIndex) {
                    // tslint:disable-next-line:no-null-keyword boolean-trivia
                    sourcesContent.push(null);
                }
                sourcesContent[sourceIndex] = content;
            }
            exit();
        }
        function addName(name) {
            enter();
            if (!nameToNameIndexMap)
                nameToNameIndexMap = ts.createMap();
            var nameIndex = nameToNameIndexMap.get(name);
            if (nameIndex === undefined) {
                nameIndex = names.length;
                names.push(name);
                nameToNameIndexMap.set(name, nameIndex);
            }
            exit();
            return nameIndex;
        }
        function isNewGeneratedPosition(generatedLine, generatedCharacter) {
            return !hasPending
                || pendingGeneratedLine !== generatedLine
                || pendingGeneratedCharacter !== generatedCharacter;
        }
        function isBacktrackingSourcePosition(sourceIndex, sourceLine, sourceCharacter) {
            return sourceIndex !== undefined
                && sourceLine !== undefined
                && sourceCharacter !== undefined
                && pendingSourceIndex === sourceIndex
                && (pendingSourceLine > sourceLine
                    || pendingSourceLine === sourceLine && pendingSourceCharacter > sourceCharacter);
        }
        function addMapping(generatedLine, generatedCharacter, sourceIndex, sourceLine, sourceCharacter, nameIndex) {
            ts.Debug.assert(generatedLine >= pendingGeneratedLine, "generatedLine cannot backtrack");
            ts.Debug.assert(generatedCharacter >= 0, "generatedCharacter cannot be negative");
            ts.Debug.assert(sourceIndex === undefined || sourceIndex >= 0, "sourceIndex cannot be negative");
            ts.Debug.assert(sourceLine === undefined || sourceLine >= 0, "sourceLine cannot be negative");
            ts.Debug.assert(sourceCharacter === undefined || sourceCharacter >= 0, "sourceCharacter cannot be negative");
            enter();
            // If this location wasn't recorded or the location in source is going backwards, record the mapping
            if (isNewGeneratedPosition(generatedLine, generatedCharacter) ||
                isBacktrackingSourcePosition(sourceIndex, sourceLine, sourceCharacter)) {
                commitPendingMapping();
                pendingGeneratedLine = generatedLine;
                pendingGeneratedCharacter = generatedCharacter;
                hasPendingSource = false;
                hasPendingName = false;
                hasPending = true;
            }
            if (sourceIndex !== undefined && sourceLine !== undefined && sourceCharacter !== undefined) {
                pendingSourceIndex = sourceIndex;
                pendingSourceLine = sourceLine;
                pendingSourceCharacter = sourceCharacter;
                hasPendingSource = true;
                if (nameIndex !== undefined) {
                    pendingNameIndex = nameIndex;
                    hasPendingName = true;
                }
            }
            exit();
        }
        function appendSourceMap(generatedLine, generatedCharacter, map, sourceMapPath, start, end) {
            var _a;
            ts.Debug.assert(generatedLine >= pendingGeneratedLine, "generatedLine cannot backtrack");
            ts.Debug.assert(generatedCharacter >= 0, "generatedCharacter cannot be negative");
            enter();
            // First, decode the old component sourcemap
            var sourceIndexToNewSourceIndexMap = [];
            var nameIndexToNewNameIndexMap;
            var mappingIterator = decodeMappings(map.mappings);
            for (var _b = mappingIterator.next(), raw = _b.value, done = _b.done; !done; _a = mappingIterator.next(), raw = _a.value, done = _a.done, _a) {
                if (end && (raw.generatedLine > end.line ||
                    (raw.generatedLine === end.line && raw.generatedCharacter > end.character))) {
                    break;
                }
                if (start && (raw.generatedLine < start.line ||
                    (start.line === raw.generatedLine && raw.generatedCharacter < start.character))) {
                    continue;
                }
                // Then reencode all the updated mappings into the overall map
                var newSourceIndex = void 0;
                var newSourceLine = void 0;
                var newSourceCharacter = void 0;
                var newNameIndex = void 0;
                if (raw.sourceIndex !== undefined) {
                    newSourceIndex = sourceIndexToNewSourceIndexMap[raw.sourceIndex];
                    if (newSourceIndex === undefined) {
                        // Apply offsets to each position and fixup source entries
                        var rawPath = map.sources[raw.sourceIndex];
                        var relativePath = map.sourceRoot ? ts.combinePaths(map.sourceRoot, rawPath) : rawPath;
                        var combinedPath = ts.combinePaths(ts.getDirectoryPath(sourceMapPath), relativePath);
                        sourceIndexToNewSourceIndexMap[raw.sourceIndex] = newSourceIndex = addSource(combinedPath);
                        if (map.sourcesContent && typeof map.sourcesContent[raw.sourceIndex] === "string") {
                            setSourceContent(newSourceIndex, map.sourcesContent[raw.sourceIndex]);
                        }
                    }
                    newSourceLine = raw.sourceLine;
                    newSourceCharacter = raw.sourceCharacter;
                    if (map.names && raw.nameIndex !== undefined) {
                        if (!nameIndexToNewNameIndexMap)
                            nameIndexToNewNameIndexMap = [];
                        newNameIndex = nameIndexToNewNameIndexMap[raw.nameIndex];
                        if (newNameIndex === undefined) {
                            nameIndexToNewNameIndexMap[raw.nameIndex] = newNameIndex = addName(map.names[raw.nameIndex]);
                        }
                    }
                }
                var rawGeneratedLine = raw.generatedLine - (start ? start.line : 0);
                var newGeneratedLine = rawGeneratedLine + generatedLine;
                var rawGeneratedCharacter = start && start.line === raw.generatedLine ? raw.generatedCharacter - start.character : raw.generatedCharacter;
                var newGeneratedCharacter = rawGeneratedLine === 0 ? rawGeneratedCharacter + generatedCharacter : rawGeneratedCharacter;
                addMapping(newGeneratedLine, newGeneratedCharacter, newSourceIndex, newSourceLine, newSourceCharacter, newNameIndex);
            }
            exit();
        }
        function shouldCommitMapping() {
            return !hasLast
                || lastGeneratedLine !== pendingGeneratedLine
                || lastGeneratedCharacter !== pendingGeneratedCharacter
                || lastSourceIndex !== pendingSourceIndex
                || lastSourceLine !== pendingSourceLine
                || lastSourceCharacter !== pendingSourceCharacter
                || lastNameIndex !== pendingNameIndex;
        }
        function commitPendingMapping() {
            if (!hasPending || !shouldCommitMapping()) {
                return;
            }
            enter();
            // Line/Comma delimiters
            if (lastGeneratedLine < pendingGeneratedLine) {
                // Emit line delimiters
                do {
                    mappings += ";";
                    lastGeneratedLine++;
                    lastGeneratedCharacter = 0;
                } while (lastGeneratedLine < pendingGeneratedLine);
            }
            else {
                ts.Debug.assertEqual(lastGeneratedLine, pendingGeneratedLine, "generatedLine cannot backtrack");
                // Emit comma to separate the entry
                if (hasLast) {
                    mappings += ",";
                }
            }
            // 1. Relative generated character
            mappings += base64VLQFormatEncode(pendingGeneratedCharacter - lastGeneratedCharacter);
            lastGeneratedCharacter = pendingGeneratedCharacter;
            if (hasPendingSource) {
                // 2. Relative sourceIndex
                mappings += base64VLQFormatEncode(pendingSourceIndex - lastSourceIndex);
                lastSourceIndex = pendingSourceIndex;
                // 3. Relative source line
                mappings += base64VLQFormatEncode(pendingSourceLine - lastSourceLine);
                lastSourceLine = pendingSourceLine;
                // 4. Relative source character
                mappings += base64VLQFormatEncode(pendingSourceCharacter - lastSourceCharacter);
                lastSourceCharacter = pendingSourceCharacter;
                if (hasPendingName) {
                    // 5. Relative nameIndex
                    mappings += base64VLQFormatEncode(pendingNameIndex - lastNameIndex);
                    lastNameIndex = pendingNameIndex;
                }
            }
            hasLast = true;
            exit();
        }
        function toJSON() {
            commitPendingMapping();
            return {
                version: 3,
                file: file,
                sourceRoot: sourceRoot,
                sources: sources,
                names: names,
                mappings: mappings,
                sourcesContent: sourcesContent,
            };
        }
    }
    ts.createSourceMapGenerator = createSourceMapGenerator;
    // Sometimes tools can see the following line as a source mapping url comment, so we mangle it a bit (the [M])
    var sourceMapCommentRegExp = /^\/\/[@#] source[M]appingURL=(.+)\s*$/;
    var whitespaceOrMapCommentRegExp = /^\s*(\/\/[@#] .*)?$/;
    function getLineInfo(text, lineStarts) {
        return {
            getLineCount: function () { return lineStarts.length; },
            getLineText: function (line) { return text.substring(lineStarts[line], lineStarts[line + 1]); }
        };
    }
    ts.getLineInfo = getLineInfo;
    /**
     * Tries to find the sourceMappingURL comment at the end of a file.
     */
    function tryGetSourceMappingURL(lineInfo) {
        for (var index = lineInfo.getLineCount() - 1; index >= 0; index--) {
            var line = lineInfo.getLineText(index);
            var comment = sourceMapCommentRegExp.exec(line);
            if (comment) {
                return comment[1];
            }
            // If we see a non-whitespace/map comment-like line, break, to avoid scanning up the entire file
            else if (!line.match(whitespaceOrMapCommentRegExp)) {
                break;
            }
        }
    }
    ts.tryGetSourceMappingURL = tryGetSourceMappingURL;
    function isStringOrNull(x) {
        // tslint:disable-next-line:no-null-keyword
        return typeof x === "string" || x === null;
    }
    function isRawSourceMap(x) {
        // tslint:disable-next-line:no-null-keyword
        return x !== null
            && typeof x === "object"
            && x.version === 3
            && typeof x.file === "string"
            && typeof x.mappings === "string"
            && ts.isArray(x.sources) && ts.every(x.sources, ts.isString)
            && (x.sourceRoot === undefined || x.sourceRoot === null || typeof x.sourceRoot === "string")
            && (x.sourcesContent === undefined || x.sourcesContent === null || ts.isArray(x.sourcesContent) && ts.every(x.sourcesContent, isStringOrNull))
            && (x.names === undefined || x.names === null || ts.isArray(x.names) && ts.every(x.names, ts.isString));
    }
    ts.isRawSourceMap = isRawSourceMap;
    function tryParseRawSourceMap(text) {
        try {
            var parsed = JSON.parse(text);
            if (isRawSourceMap(parsed)) {
                return parsed;
            }
        }
        catch (_a) {
            // empty
        }
        return undefined;
    }
    ts.tryParseRawSourceMap = tryParseRawSourceMap;
    function decodeMappings(mappings) {
        var done = false;
        var pos = 0;
        var generatedLine = 0;
        var generatedCharacter = 0;
        var sourceIndex = 0;
        var sourceLine = 0;
        var sourceCharacter = 0;
        var nameIndex = 0;
        var error;
        return {
            get pos() { return pos; },
            get error() { return error; },
            get state() { return captureMapping(/*hasSource*/ true, /*hasName*/ true); },
            next: function () {
                while (!done && pos < mappings.length) {
                    var ch = mappings.charCodeAt(pos);
                    if (ch === 59 /* semicolon */) {
                        // new line
                        generatedLine++;
                        generatedCharacter = 0;
                        pos++;
                        continue;
                    }
                    if (ch === 44 /* comma */) {
                        // Next entry is on same line - no action needed
                        pos++;
                        continue;
                    }
                    var hasSource = false;
                    var hasName = false;
                    generatedCharacter += base64VLQFormatDecode();
                    if (hasReportedError())
                        return stopIterating();
                    if (generatedCharacter < 0)
                        return setErrorAndStopIterating("Invalid generatedCharacter found");
                    if (!isSourceMappingSegmentEnd()) {
                        hasSource = true;
                        sourceIndex += base64VLQFormatDecode();
                        if (hasReportedError())
                            return stopIterating();
                        if (sourceIndex < 0)
                            return setErrorAndStopIterating("Invalid sourceIndex found");
                        if (isSourceMappingSegmentEnd())
                            return setErrorAndStopIterating("Unsupported Format: No entries after sourceIndex");
                        sourceLine += base64VLQFormatDecode();
                        if (hasReportedError())
                            return stopIterating();
                        if (sourceLine < 0)
                            return setErrorAndStopIterating("Invalid sourceLine found");
                        if (isSourceMappingSegmentEnd())
                            return setErrorAndStopIterating("Unsupported Format: No entries after sourceLine");
                        sourceCharacter += base64VLQFormatDecode();
                        if (hasReportedError())
                            return stopIterating();
                        if (sourceCharacter < 0)
                            return setErrorAndStopIterating("Invalid sourceCharacter found");
                        if (!isSourceMappingSegmentEnd()) {
                            hasName = true;
                            nameIndex += base64VLQFormatDecode();
                            if (hasReportedError())
                                return stopIterating();
                            if (nameIndex < 0)
                                return setErrorAndStopIterating("Invalid nameIndex found");
                            if (!isSourceMappingSegmentEnd())
                                return setErrorAndStopIterating("Unsupported Error Format: Entries after nameIndex");
                        }
                    }
                    return { value: captureMapping(hasSource, hasName), done: done };
                }
                return stopIterating();
            }
        };
        function captureMapping(hasSource, hasName) {
            return {
                generatedLine: generatedLine,
                generatedCharacter: generatedCharacter,
                sourceIndex: hasSource ? sourceIndex : undefined,
                sourceLine: hasSource ? sourceLine : undefined,
                sourceCharacter: hasSource ? sourceCharacter : undefined,
                nameIndex: hasName ? nameIndex : undefined
            };
        }
        function stopIterating() {
            done = true;
            return { value: undefined, done: true };
        }
        function setError(message) {
            if (error === undefined) {
                error = message;
            }
        }
        function setErrorAndStopIterating(message) {
            setError(message);
            return stopIterating();
        }
        function hasReportedError() {
            return error !== undefined;
        }
        function isSourceMappingSegmentEnd() {
            return (pos === mappings.length ||
                mappings.charCodeAt(pos) === 44 /* comma */ ||
                mappings.charCodeAt(pos) === 59 /* semicolon */);
        }
        function base64VLQFormatDecode() {
            var moreDigits = true;
            var shiftCount = 0;
            var value = 0;
            for (; moreDigits; pos++) {
                if (pos >= mappings.length)
                    return setError("Error in decoding base64VLQFormatDecode, past the mapping string"), -1;
                // 6 digit number
                var currentByte = base64FormatDecode(mappings.charCodeAt(pos));
                if (currentByte === -1)
                    return setError("Invalid character in VLQ"), -1;
                // If msb is set, we still have more bits to continue
                moreDigits = (currentByte & 32) !== 0;
                // least significant 5 bits are the next msbs in the final value.
                value = value | ((currentByte & 31) << shiftCount);
                shiftCount += 5;
            }
            // Least significant bit if 1 represents negative and rest of the msb is actual absolute value
            if ((value & 1) === 0) {
                // + number
                value = value >> 1;
            }
            else {
                // - number
                value = value >> 1;
                value = -value;
            }
            return value;
        }
    }
    ts.decodeMappings = decodeMappings;
    function sameMapping(left, right) {
        return left === right
            || left.generatedLine === right.generatedLine
                && left.generatedCharacter === right.generatedCharacter
                && left.sourceIndex === right.sourceIndex
                && left.sourceLine === right.sourceLine
                && left.sourceCharacter === right.sourceCharacter
                && left.nameIndex === right.nameIndex;
    }
    ts.sameMapping = sameMapping;
    function isSourceMapping(mapping) {
        return mapping.sourceIndex !== undefined
            && mapping.sourceLine !== undefined
            && mapping.sourceCharacter !== undefined;
    }
    ts.isSourceMapping = isSourceMapping;
    function base64FormatEncode(value) {
        return value >= 0 && value < 26 ? 65 /* A */ + value :
            value >= 26 && value < 52 ? 97 /* a */ + value - 26 :
                value >= 52 && value < 62 ? 48 /* _0 */ + value - 52 :
                    value === 62 ? 43 /* plus */ :
                        value === 63 ? 47 /* slash */ :
                            ts.Debug.fail(value + ": not a base64 value");
    }
    function base64FormatDecode(ch) {
        return ch >= 65 /* A */ && ch <= 90 /* Z */ ? ch - 65 /* A */ :
            ch >= 97 /* a */ && ch <= 122 /* z */ ? ch - 97 /* a */ + 26 :
                ch >= 48 /* _0 */ && ch <= 57 /* _9 */ ? ch - 48 /* _0 */ + 52 :
                    ch === 43 /* plus */ ? 62 :
                        ch === 47 /* slash */ ? 63 :
                            -1;
    }
    function base64VLQFormatEncode(inValue) {
        // Add a new least significant bit that has the sign of the value.
        // if negative number the least significant bit that gets added to the number has value 1
        // else least significant bit value that gets added is 0
        // eg. -1 changes to binary : 01 [1] => 3
        //     +1 changes to binary : 01 [0] => 2
        if (inValue < 0) {
            inValue = ((-inValue) << 1) + 1;
        }
        else {
            inValue = inValue << 1;
        }
        // Encode 5 bits at a time starting from least significant bits
        var encodedStr = "";
        do {
            var currentDigit = inValue & 31; // 11111
            inValue = inValue >> 5;
            if (inValue > 0) {
                // There are still more digits to decode, set the msb (6th bit)
                currentDigit = currentDigit | 32;
            }
            encodedStr = encodedStr + String.fromCharCode(base64FormatEncode(currentDigit));
        } while (inValue > 0);
        return encodedStr;
    }
    function isSourceMappedPosition(value) {
        return value.sourceIndex !== undefined
            && value.sourcePosition !== undefined;
    }
    function sameMappedPosition(left, right) {
        return left.generatedPosition === right.generatedPosition
            && left.sourceIndex === right.sourceIndex
            && left.sourcePosition === right.sourcePosition;
    }
    function compareSourcePositions(left, right) {
        // Compares sourcePosition without comparing sourceIndex
        // since the mappings are grouped by sourceIndex
        ts.Debug.assert(left.sourceIndex === right.sourceIndex);
        return ts.compareValues(left.sourcePosition, right.sourcePosition);
    }
    function compareGeneratedPositions(left, right) {
        return ts.compareValues(left.generatedPosition, right.generatedPosition);
    }
    function getSourcePositionOfMapping(value) {
        return value.sourcePosition;
    }
    function getGeneratedPositionOfMapping(value) {
        return value.generatedPosition;
    }
    function createDocumentPositionMapper(host, map, mapPath) {
        var mapDirectory = ts.getDirectoryPath(mapPath);
        var sourceRoot = map.sourceRoot ? ts.getNormalizedAbsolutePath(map.sourceRoot, mapDirectory) : mapDirectory;
        var generatedAbsoluteFilePath = ts.getNormalizedAbsolutePath(map.file, mapDirectory);
        var generatedFile = host.getSourceFileLike(generatedAbsoluteFilePath);
        var sourceFileAbsolutePaths = map.sources.map(function (source) { return ts.getNormalizedAbsolutePath(source, sourceRoot); });
        var sourceToSourceIndexMap = ts.createMapFromEntries(sourceFileAbsolutePaths.map(function (source, i) { return [host.getCanonicalFileName(source), i]; }));
        var decodedMappings;
        var generatedMappings;
        var sourceMappings;
        return {
            getSourcePosition: getSourcePosition,
            getGeneratedPosition: getGeneratedPosition
        };
        function processMapping(mapping) {
            var generatedPosition = generatedFile !== undefined
                ? ts.getPositionOfLineAndCharacter(generatedFile, mapping.generatedLine, mapping.generatedCharacter, /*allowEdits*/ true)
                : -1;
            var source;
            var sourcePosition;
            if (isSourceMapping(mapping)) {
                var sourceFile = host.getSourceFileLike(sourceFileAbsolutePaths[mapping.sourceIndex]);
                source = map.sources[mapping.sourceIndex];
                sourcePosition = sourceFile !== undefined
                    ? ts.getPositionOfLineAndCharacter(sourceFile, mapping.sourceLine, mapping.sourceCharacter, /*allowEdits*/ true)
                    : -1;
            }
            return {
                generatedPosition: generatedPosition,
                source: source,
                sourceIndex: mapping.sourceIndex,
                sourcePosition: sourcePosition,
                nameIndex: mapping.nameIndex
            };
        }
        function getDecodedMappings() {
            if (decodedMappings === undefined) {
                var decoder = decodeMappings(map.mappings);
                var mappings = ts.arrayFrom(decoder, processMapping);
                if (decoder.error !== undefined) {
                    if (host.log) {
                        host.log("Encountered error while decoding sourcemap: " + decoder.error);
                    }
                    decodedMappings = ts.emptyArray;
                }
                else {
                    decodedMappings = mappings;
                }
            }
            return decodedMappings;
        }
        function getSourceMappings(sourceIndex) {
            if (sourceMappings === undefined) {
                var lists = [];
                for (var _i = 0, _a = getDecodedMappings(); _i < _a.length; _i++) {
                    var mapping = _a[_i];
                    if (!isSourceMappedPosition(mapping))
                        continue;
                    var list = lists[mapping.sourceIndex];
                    if (!list)
                        lists[mapping.sourceIndex] = list = [];
                    list.push(mapping);
                }
                sourceMappings = lists.map(function (list) { return ts.sortAndDeduplicate(list, compareSourcePositions, sameMappedPosition); });
            }
            return sourceMappings[sourceIndex];
        }
        function getGeneratedMappings() {
            if (generatedMappings === undefined) {
                var list = [];
                for (var _i = 0, _a = getDecodedMappings(); _i < _a.length; _i++) {
                    var mapping = _a[_i];
                    list.push(mapping);
                }
                generatedMappings = ts.sortAndDeduplicate(list, compareGeneratedPositions, sameMappedPosition);
            }
            return generatedMappings;
        }
        function getGeneratedPosition(loc) {
            var sourceIndex = sourceToSourceIndexMap.get(host.getCanonicalFileName(loc.fileName));
            if (sourceIndex === undefined)
                return loc;
            var sourceMappings = getSourceMappings(sourceIndex);
            if (!ts.some(sourceMappings))
                return loc;
            var targetIndex = ts.binarySearchKey(sourceMappings, loc.pos, getSourcePositionOfMapping, ts.compareValues);
            if (targetIndex < 0) {
                // if no exact match, closest is 2's complement of result
                targetIndex = ~targetIndex;
            }
            var mapping = sourceMappings[targetIndex];
            if (mapping === undefined || mapping.sourceIndex !== sourceIndex) {
                return loc;
            }
            return { fileName: generatedAbsoluteFilePath, pos: mapping.generatedPosition }; // Closest pos
        }
        function getSourcePosition(loc) {
            var generatedMappings = getGeneratedMappings();
            if (!ts.some(generatedMappings))
                return loc;
            var targetIndex = ts.binarySearchKey(generatedMappings, loc.pos, getGeneratedPositionOfMapping, ts.compareValues);
            if (targetIndex < 0) {
                // if no exact match, closest is 2's complement of result
                targetIndex = ~targetIndex;
            }
            var mapping = generatedMappings[targetIndex];
            if (mapping === undefined || !isSourceMappedPosition(mapping)) {
                return loc;
            }
            return { fileName: sourceFileAbsolutePaths[mapping.sourceIndex], pos: mapping.sourcePosition }; // Closest pos
        }
    }
    ts.createDocumentPositionMapper = createDocumentPositionMapper;
    ts.identitySourceMapConsumer = {
        getSourcePosition: ts.identity,
        getGeneratedPosition: ts.identity
    };
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function getOriginalNodeId(node) {
        node = ts.getOriginalNode(node);
        return node ? ts.getNodeId(node) : 0;
    }
    ts.getOriginalNodeId = getOriginalNodeId;
    function containsDefaultReference(node) {
        if (!node)
            return false;
        if (!ts.isNamedImports(node))
            return false;
        return ts.some(node.elements, isNamedDefaultReference);
    }
    function isNamedDefaultReference(e) {
        return e.propertyName !== undefined && e.propertyName.escapedText === "default" /* Default */;
    }
    function chainBundle(transformSourceFile) {
        return transformSourceFileOrBundle;
        function transformSourceFileOrBundle(node) {
            return node.kind === 285 /* SourceFile */ ? transformSourceFile(node) : transformBundle(node);
        }
        function transformBundle(node) {
            return ts.createBundle(ts.map(node.sourceFiles, transformSourceFile), node.prepends);
        }
    }
    ts.chainBundle = chainBundle;
    function getImportNeedsImportStarHelper(node) {
        if (!!ts.getNamespaceDeclarationNode(node)) {
            return true;
        }
        var bindings = node.importClause && node.importClause.namedBindings;
        if (!bindings) {
            return false;
        }
        if (!ts.isNamedImports(bindings))
            return false;
        var defaultRefCount = 0;
        for (var _i = 0, _a = bindings.elements; _i < _a.length; _i++) {
            var binding = _a[_i];
            if (isNamedDefaultReference(binding)) {
                defaultRefCount++;
            }
        }
        // Import star is required if there's default named refs mixed with non-default refs, or if theres non-default refs and it has a default import
        return (defaultRefCount > 0 && defaultRefCount !== bindings.elements.length) || (!!(bindings.elements.length - defaultRefCount) && ts.isDefaultImport(node));
    }
    ts.getImportNeedsImportStarHelper = getImportNeedsImportStarHelper;
    function getImportNeedsImportDefaultHelper(node) {
        // Import default is needed if there's a default import or a default ref and no other refs (meaning an import star helper wasn't requested)
        return !getImportNeedsImportStarHelper(node) && (ts.isDefaultImport(node) || (!!node.importClause && ts.isNamedImports(node.importClause.namedBindings) && containsDefaultReference(node.importClause.namedBindings))); // TODO: GH#18217
    }
    ts.getImportNeedsImportDefaultHelper = getImportNeedsImportDefaultHelper;
    function collectExternalModuleInfo(sourceFile, resolver, compilerOptions) {
        var externalImports = [];
        var exportSpecifiers = ts.createMultiMap();
        var exportedBindings = [];
        var uniqueExports = ts.createMap();
        var exportedNames;
        var hasExportDefault = false;
        var exportEquals;
        var hasExportStarsToExportValues = false;
        var hasImportStarOrImportDefault = false;
        for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
            var node = _a[_i];
            switch (node.kind) {
                case 250 /* ImportDeclaration */:
                    // import "mod"
                    // import x from "mod"
                    // import * as x from "mod"
                    // import { x, y } from "mod"
                    externalImports.push(node);
                    hasImportStarOrImportDefault = hasImportStarOrImportDefault || getImportNeedsImportStarHelper(node) || getImportNeedsImportDefaultHelper(node);
                    break;
                case 249 /* ImportEqualsDeclaration */:
                    if (node.moduleReference.kind === 260 /* ExternalModuleReference */) {
                        // import x = require("mod")
                        externalImports.push(node);
                    }
                    break;
                case 256 /* ExportDeclaration */:
                    if (node.moduleSpecifier) {
                        if (!node.exportClause) {
                            // export * from "mod"
                            externalImports.push(node);
                            hasExportStarsToExportValues = true;
                        }
                        else {
                            // export { x, y } from "mod"
                            externalImports.push(node);
                        }
                    }
                    else {
                        // export { x, y }
                        for (var _b = 0, _c = node.exportClause.elements; _b < _c.length; _b++) {
                            var specifier = _c[_b];
                            if (!uniqueExports.get(ts.idText(specifier.name))) {
                                var name = specifier.propertyName || specifier.name;
                                exportSpecifiers.add(ts.idText(name), specifier);
                                var decl = resolver.getReferencedImportDeclaration(name)
                                    || resolver.getReferencedValueDeclaration(name);
                                if (decl) {
                                    multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
                                }
                                uniqueExports.set(ts.idText(specifier.name), true);
                                exportedNames = ts.append(exportedNames, specifier.name);
                            }
                        }
                    }
                    break;
                case 255 /* ExportAssignment */:
                    if (node.isExportEquals && !exportEquals) {
                        // export = x
                        exportEquals = node;
                    }
                    break;
                case 220 /* VariableStatement */:
                    if (ts.hasModifier(node, 1 /* Export */)) {
                        for (var _d = 0, _e = node.declarationList.declarations; _d < _e.length; _d++) {
                            var decl = _e[_d];
                            exportedNames = collectExportedVariableInfo(decl, uniqueExports, exportedNames);
                        }
                    }
                    break;
                case 240 /* FunctionDeclaration */:
                    if (ts.hasModifier(node, 1 /* Export */)) {
                        if (ts.hasModifier(node, 512 /* Default */)) {
                            // export default function() { }
                            if (!hasExportDefault) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), ts.getDeclarationName(node));
                                hasExportDefault = true;
                            }
                        }
                        else {
                            // export function x() { }
                            var name = node.name;
                            if (!uniqueExports.get(ts.idText(name))) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
                                uniqueExports.set(ts.idText(name), true);
                                exportedNames = ts.append(exportedNames, name);
                            }
                        }
                    }
                    break;
                case 241 /* ClassDeclaration */:
                    if (ts.hasModifier(node, 1 /* Export */)) {
                        if (ts.hasModifier(node, 512 /* Default */)) {
                            // export default class { }
                            if (!hasExportDefault) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), ts.getDeclarationName(node));
                                hasExportDefault = true;
                            }
                        }
                        else {
                            // export class x { }
                            var name = node.name;
                            if (name && !uniqueExports.get(ts.idText(name))) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
                                uniqueExports.set(ts.idText(name), true);
                                exportedNames = ts.append(exportedNames, name);
                            }
                        }
                    }
                    break;
            }
        }
        var externalHelpersModuleName = ts.getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStarOrImportDefault);
        var externalHelpersImportDeclaration = externalHelpersModuleName && ts.createImportDeclaration(
        /*decorators*/ undefined, 
        /*modifiers*/ undefined, ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(externalHelpersModuleName)), ts.createLiteral(ts.externalHelpersModuleNameText));
        if (externalHelpersImportDeclaration) {
            ts.addEmitFlags(externalHelpersImportDeclaration, 67108864 /* NeverApplyImportHelper */);
            externalImports.unshift(externalHelpersImportDeclaration);
        }
        return { externalImports: externalImports, exportSpecifiers: exportSpecifiers, exportEquals: exportEquals, hasExportStarsToExportValues: hasExportStarsToExportValues, exportedBindings: exportedBindings, exportedNames: exportedNames, externalHelpersImportDeclaration: externalHelpersImportDeclaration };
    }
    ts.collectExternalModuleInfo = collectExternalModuleInfo;
    function collectExportedVariableInfo(decl, uniqueExports, exportedNames) {
        if (ts.isBindingPattern(decl.name)) {
            for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) {
                var element = _a[_i];
                if (!ts.isOmittedExpression(element)) {
                    exportedNames = collectExportedVariableInfo(element, uniqueExports, exportedNames);
                }
            }
        }
        else if (!ts.isGeneratedIdentifier(decl.name)) {
            var text = ts.idText(decl.name);
            if (!uniqueExports.get(text)) {
                uniqueExports.set(text, true);
                exportedNames = ts.append(exportedNames, decl.name);
            }
        }
        return exportedNames;
    }
    /** Use a sparse array as a multi-map. */
    function multiMapSparseArrayAdd(map, key, value) {
        var values = map[key];
        if (values) {
            values.push(value);
        }
        else {
            map[key] = values = [value];
        }
        return values;
    }
    /**
     * Used in the module transformer to check if an expression is reasonably without sideeffect,
     *  and thus better to copy into multiple places rather than to cache in a temporary variable
     *  - this is mostly subjective beyond the requirement that the expression not be sideeffecting
     */
    function isSimpleCopiableExpression(expression) {
        return ts.isStringLiteralLike(expression) ||
            expression.kind === 8 /* NumericLiteral */ ||
            ts.isKeyword(expression.kind) ||
            ts.isIdentifier(expression);
    }
    ts.isSimpleCopiableExpression = isSimpleCopiableExpression;
    /**
     * @param input Template string input strings
     * @param args Names which need to be made file-level unique
     */
    function helperString(input) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        return function (uniqueName) {
            var result = "";
            for (var i = 0; i < args.length; i++) {
                result += input[i];
                result += uniqueName(args[i]);
            }
            result += input[input.length - 1];
            return result;
        };
    }
    ts.helperString = helperString;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var FlattenLevel;
    (function (FlattenLevel) {
        FlattenLevel[FlattenLevel["All"] = 0] = "All";
        FlattenLevel[FlattenLevel["ObjectRest"] = 1] = "ObjectRest";
    })(FlattenLevel = ts.FlattenLevel || (ts.FlattenLevel = {}));
    /**
     * Flattens a DestructuringAssignment or a VariableDeclaration to an expression.
     *
     * @param node The node to flatten.
     * @param visitor An optional visitor used to visit initializers.
     * @param context The transformation context.
     * @param level Indicates the extent to which flattening should occur.
     * @param needsValue An optional value indicating whether the value from the right-hand-side of
     * the destructuring assignment is needed as part of a larger expression.
     * @param createAssignmentCallback An optional callback used to create the assignment expression.
     */
    function flattenDestructuringAssignment(node, visitor, context, level, needsValue, createAssignmentCallback) {
        var location = node;
        var value;
        if (ts.isDestructuringAssignment(node)) {
            value = node.right;
            while (ts.isEmptyArrayLiteral(node.left) || ts.isEmptyObjectLiteral(node.left)) {
                if (ts.isDestructuringAssignment(value)) {
                    location = node = value;
                    value = node.right;
                }
                else {
                    return ts.visitNode(value, visitor, ts.isExpression);
                }
            }
        }
        var expressions;
        var flattenContext = {
            context: context,
            level: level,
            downlevelIteration: !!context.getCompilerOptions().downlevelIteration,
            hoistTempVariables: true,
            emitExpression: emitExpression,
            emitBindingOrAssignment: emitBindingOrAssignment,
            createArrayBindingOrAssignmentPattern: makeArrayAssignmentPattern,
            createObjectBindingOrAssignmentPattern: makeObjectAssignmentPattern,
            createArrayBindingOrAssignmentElement: makeAssignmentElement,
            visitor: visitor
        };
        if (value) {
            value = ts.visitNode(value, visitor, ts.isExpression);
            if (ts.isIdentifier(value) && bindingOrAssignmentElementAssignsToName(node, value.escapedText)) {
                // If the right-hand value of the assignment is also an assignment target then
                // we need to cache the right-hand value.
                value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ false, location);
            }
            else if (needsValue) {
                // If the right-hand value of the destructuring assignment needs to be preserved (as
                // is the case when the destructuring assignment is part of a larger expression),
                // then we need to cache the right-hand value.
                //
                // The source map location for the assignment should point to the entire binary
                // expression.
                value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location);
            }
            else if (ts.nodeIsSynthesized(node)) {
                // Generally, the source map location for a destructuring assignment is the root
                // expression.
                //
                // However, if the root expression is synthesized (as in the case
                // of the initializer when transforming a ForOfStatement), then the source map
                // location should point to the right-hand value of the expression.
                location = value;
            }
        }
        flattenBindingOrAssignmentElement(flattenContext, node, value, location, /*skipInitializer*/ ts.isDestructuringAssignment(node));
        if (value && needsValue) {
            if (!ts.some(expressions)) {
                return value;
            }
            expressions.push(value);
        }
        return ts.aggregateTransformFlags(ts.inlineExpressions(expressions)) || ts.createOmittedExpression();
        function emitExpression(expression) {
            // NOTE: this completely disables source maps, but aligns with the behavior of
            //       `emitAssignment` in the old emitter.
            ts.setEmitFlags(expression, 64 /* NoNestedSourceMaps */);
            ts.aggregateTransformFlags(expression);
            expressions = ts.append(expressions, expression);
        }
        function emitBindingOrAssignment(target, value, location, original) {
            ts.Debug.assertNode(target, createAssignmentCallback ? ts.isIdentifier : ts.isExpression);
            var expression = createAssignmentCallback
                ? createAssignmentCallback(target, value, location)
                : ts.setTextRange(ts.createAssignment(ts.visitNode(target, visitor, ts.isExpression), value), location);
            expression.original = original;
            emitExpression(expression);
        }
    }
    ts.flattenDestructuringAssignment = flattenDestructuringAssignment;
    function bindingOrAssignmentElementAssignsToName(element, escapedName) {
        var target = ts.getTargetOfBindingOrAssignmentElement(element); // TODO: GH#18217
        if (ts.isBindingOrAssignmentPattern(target)) {
            return bindingOrAssignmentPatternAssignsToName(target, escapedName);
        }
        else if (ts.isIdentifier(target)) {
            return target.escapedText === escapedName;
        }
        return false;
    }
    function bindingOrAssignmentPatternAssignsToName(pattern, escapedName) {
        var elements = ts.getElementsOfBindingOrAssignmentPattern(pattern);
        for (var _i = 0, elements_3 = elements; _i < elements_3.length; _i++) {
            var element = elements_3[_i];
            if (bindingOrAssignmentElementAssignsToName(element, escapedName)) {
                return true;
            }
        }
        return false;
    }
    /**
     * Flattens a VariableDeclaration or ParameterDeclaration to one or more variable declarations.
     *
     * @param node The node to flatten.
     * @param visitor An optional visitor used to visit initializers.
     * @param context The transformation context.
     * @param boundValue The value bound to the declaration.
     * @param skipInitializer A value indicating whether to ignore the initializer of `node`.
     * @param hoistTempVariables Indicates whether temporary variables should not be recorded in-line.
     * @param level Indicates the extent to which flattening should occur.
     */
    function flattenDestructuringBinding(node, visitor, context, level, rval, hoistTempVariables, skipInitializer) {
        if (hoistTempVariables === void 0) { hoistTempVariables = false; }
        var pendingExpressions;
        var pendingDeclarations = [];
        var declarations = [];
        var flattenContext = {
            context: context,
            level: level,
            downlevelIteration: !!context.getCompilerOptions().downlevelIteration,
            hoistTempVariables: hoistTempVariables,
            emitExpression: emitExpression,
            emitBindingOrAssignment: emitBindingOrAssignment,
            createArrayBindingOrAssignmentPattern: makeArrayBindingPattern,
            createObjectBindingOrAssignmentPattern: makeObjectBindingPattern,
            createArrayBindingOrAssignmentElement: makeBindingElement,
            visitor: visitor
        };
        if (ts.isVariableDeclaration(node)) {
            var initializer = ts.getInitializerOfBindingOrAssignmentElement(node);
            if (initializer && ts.isIdentifier(initializer) && bindingOrAssignmentElementAssignsToName(node, initializer.escapedText)) {
                // If the right-hand value of the assignment is also an assignment target then
                // we need to cache the right-hand value.
                initializer = ensureIdentifier(flattenContext, initializer, /*reuseIdentifierExpressions*/ false, initializer);
                node = ts.updateVariableDeclaration(node, node.name, node.type, initializer);
            }
        }
        flattenBindingOrAssignmentElement(flattenContext, node, rval, node, skipInitializer);
        if (pendingExpressions) {
            var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
            if (hoistTempVariables) {
                var value = ts.inlineExpressions(pendingExpressions);
                pendingExpressions = undefined;
                emitBindingOrAssignment(temp, value, /*location*/ undefined, /*original*/ undefined);
            }
            else {
                context.hoistVariableDeclaration(temp);
                var pendingDeclaration = ts.last(pendingDeclarations);
                pendingDeclaration.pendingExpressions = ts.append(pendingDeclaration.pendingExpressions, ts.createAssignment(temp, pendingDeclaration.value));
                ts.addRange(pendingDeclaration.pendingExpressions, pendingExpressions);
                pendingDeclaration.value = temp;
            }
        }
        for (var _i = 0, pendingDeclarations_1 = pendingDeclarations; _i < pendingDeclarations_1.length; _i++) {
            var _a = pendingDeclarations_1[_i], pendingExpressions_1 = _a.pendingExpressions, name = _a.name, value = _a.value, location = _a.location, original = _a.original;
            var variable = ts.createVariableDeclaration(name, 
            /*type*/ undefined, pendingExpressions_1 ? ts.inlineExpressions(ts.append(pendingExpressions_1, value)) : value);
            variable.original = original;
            ts.setTextRange(variable, location);
            if (ts.isIdentifier(name)) {
                ts.setEmitFlags(variable, 64 /* NoNestedSourceMaps */);
            }
            ts.aggregateTransformFlags(variable);
            declarations.push(variable);
        }
        return declarations;
        function emitExpression(value) {
            pendingExpressions = ts.append(pendingExpressions, value);
        }
        function emitBindingOrAssignment(target, value, location, original) {
            ts.Debug.assertNode(target, ts.isBindingName);
            if (pendingExpressions) {
                value = ts.inlineExpressions(ts.append(pendingExpressions, value));
                pendingExpressions = undefined;
            }
            pendingDeclarations.push({ pendingExpressions: pendingExpressions, name: target, value: value, location: location, original: original });
        }
    }
    ts.flattenDestructuringBinding = flattenDestructuringBinding;
    /**
     * Flattens a BindingOrAssignmentElement into zero or more bindings or assignments.
     *
     * @param flattenContext Options used to control flattening.
     * @param element The element to flatten.
     * @param value The current RHS value to assign to the element.
     * @param location The location to use for source maps and comments.
     * @param skipInitializer An optional value indicating whether to include the initializer
     * for the element.
     */
    function flattenBindingOrAssignmentElement(flattenContext, element, value, location, skipInitializer) {
        if (!skipInitializer) {
            var initializer = ts.visitNode(ts.getInitializerOfBindingOrAssignmentElement(element), flattenContext.visitor, ts.isExpression);
            if (initializer) {
                // Combine value and initializer
                value = value ? createDefaultValueCheck(flattenContext, value, initializer, location) : initializer;
            }
            else if (!value) {
                // Use 'void 0' in absence of value and initializer
                value = ts.createVoidZero();
            }
        }
        var bindingTarget = ts.getTargetOfBindingOrAssignmentElement(element); // TODO: GH#18217
        if (ts.isObjectBindingOrAssignmentPattern(bindingTarget)) {
            flattenObjectBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location);
        }
        else if (ts.isArrayBindingOrAssignmentPattern(bindingTarget)) {
            flattenArrayBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location);
        }
        else {
            flattenContext.emitBindingOrAssignment(bindingTarget, value, location, /*original*/ element); // TODO: GH#18217
        }
    }
    /**
     * Flattens an ObjectBindingOrAssignmentPattern into zero or more bindings or assignments.
     *
     * @param flattenContext Options used to control flattening.
     * @param parent The parent element of the pattern.
     * @param pattern The ObjectBindingOrAssignmentPattern to flatten.
     * @param value The current RHS value to assign to the element.
     * @param location The location to use for source maps and comments.
     */
    function flattenObjectBindingOrAssignmentPattern(flattenContext, parent, pattern, value, location) {
        var elements = ts.getElementsOfBindingOrAssignmentPattern(pattern);
        var numElements = elements.length;
        if (numElements !== 1) {
            // For anything other than a single-element destructuring we need to generate a temporary
            // to ensure value is evaluated exactly once. Additionally, if we have zero elements
            // we need to emit *something* to ensure that in case a 'var' keyword was already emitted,
            // so in that case, we'll intentionally create that temporary.
            var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0;
            value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location);
        }
        var bindingElements;
        var computedTempVariables;
        for (var i = 0; i < numElements; i++) {
            var element = elements[i];
            if (!ts.getRestIndicatorOfBindingOrAssignmentElement(element)) {
                var propertyName = ts.getPropertyNameOfBindingOrAssignmentElement(element);
                if (flattenContext.level >= 1 /* ObjectRest */
                    && !(element.transformFlags & (4096 /* ContainsRestOrSpread */ | 8192 /* ContainsObjectRestOrSpread */))
                    && !(ts.getTargetOfBindingOrAssignmentElement(element).transformFlags & (4096 /* ContainsRestOrSpread */ | 8192 /* ContainsObjectRestOrSpread */))
                    && !ts.isComputedPropertyName(propertyName)) {
                    bindingElements = ts.append(bindingElements, element);
                }
                else {
                    if (bindingElements) {
                        flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
                        bindingElements = undefined;
                    }
                    var rhsValue = createDestructuringPropertyAccess(flattenContext, value, propertyName);
                    if (ts.isComputedPropertyName(propertyName)) {
                        computedTempVariables = ts.append(computedTempVariables, rhsValue.argumentExpression);
                    }
                    flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
                }
            }
            else if (i === numElements - 1) {
                if (bindingElements) {
                    flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
                    bindingElements = undefined;
                }
                var rhsValue = createRestCall(flattenContext.context, value, elements, computedTempVariables, pattern); // TODO: GH#18217
                flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, element);
            }
        }
        if (bindingElements) {
            flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
        }
    }
    /**
     * Flattens an ArrayBindingOrAssignmentPattern into zero or more bindings or assignments.
     *
     * @param flattenContext Options used to control flattening.
     * @param parent The parent element of the pattern.
     * @param pattern The ArrayBindingOrAssignmentPattern to flatten.
     * @param value The current RHS value to assign to the element.
     * @param location The location to use for source maps and comments.
     */
    function flattenArrayBindingOrAssignmentPattern(flattenContext, parent, pattern, value, location) {
        var elements = ts.getElementsOfBindingOrAssignmentPattern(pattern);
        var numElements = elements.length;
        if (flattenContext.level < 1 /* ObjectRest */ && flattenContext.downlevelIteration) {
            // Read the elements of the iterable into an array
            value = ensureIdentifier(flattenContext, ts.createReadHelper(flattenContext.context, value, numElements > 0 && ts.getRestIndicatorOfBindingOrAssignmentElement(elements[numElements - 1])
                ? undefined
                : numElements, location), 
            /*reuseIdentifierExpressions*/ false, location);
        }
        else if (numElements !== 1 && (flattenContext.level < 1 /* ObjectRest */ || numElements === 0)
            || ts.every(elements, ts.isOmittedExpression)) {
            // For anything other than a single-element destructuring we need to generate a temporary
            // to ensure value is evaluated exactly once. Additionally, if we have zero elements
            // we need to emit *something* to ensure that in case a 'var' keyword was already emitted,
            // so in that case, we'll intentionally create that temporary.
            // Or all the elements of the binding pattern are omitted expression such as "var [,] = [1,2]",
            // then we will create temporary variable.
            var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0;
            value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location);
        }
        var bindingElements;
        var restContainingElements;
        for (var i = 0; i < numElements; i++) {
            var element = elements[i];
            if (flattenContext.level >= 1 /* ObjectRest */) {
                // If an array pattern contains an ObjectRest, we must cache the result so that we
                // can perform the ObjectRest destructuring in a different declaration
                if (element.transformFlags & 8192 /* ContainsObjectRestOrSpread */) {
                    var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
                    if (flattenContext.hoistTempVariables) {
                        flattenContext.context.hoistVariableDeclaration(temp);
                    }
                    restContainingElements = ts.append(restContainingElements, [temp, element]);
                    bindingElements = ts.append(bindingElements, flattenContext.createArrayBindingOrAssignmentElement(temp));
                }
                else {
                    bindingElements = ts.append(bindingElements, element);
                }
            }
            else if (ts.isOmittedExpression(element)) {
                continue;
            }
            else if (!ts.getRestIndicatorOfBindingOrAssignmentElement(element)) {
                var rhsValue = ts.createElementAccess(value, i);
                flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
            }
            else if (i === numElements - 1) {
                var rhsValue = ts.createArraySlice(value, i);
                flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
            }
        }
        if (bindingElements) {
            flattenContext.emitBindingOrAssignment(flattenContext.createArrayBindingOrAssignmentPattern(bindingElements), value, location, pattern);
        }
        if (restContainingElements) {
            for (var _i = 0, restContainingElements_1 = restContainingElements; _i < restContainingElements_1.length; _i++) {
                var _a = restContainingElements_1[_i], id = _a[0], element = _a[1];
                flattenBindingOrAssignmentElement(flattenContext, element, id, element);
            }
        }
    }
    /**
     * Creates an expression used to provide a default value if a value is `undefined` at runtime.
     *
     * @param flattenContext Options used to control flattening.
     * @param value The RHS value to test.
     * @param defaultValue The default value to use if `value` is `undefined` at runtime.
     * @param location The location to use for source maps and comments.
     */
    function createDefaultValueCheck(flattenContext, value, defaultValue, location) {
        value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location);
        return ts.createConditional(ts.createTypeCheck(value, "undefined"), defaultValue, value);
    }
    /**
     * Creates either a PropertyAccessExpression or an ElementAccessExpression for the
     * right-hand side of a transformed destructuring assignment.
     *
     * @link https://tc39.github.io/ecma262/#sec-runtime-semantics-keyeddestructuringassignmentevaluation
     *
     * @param flattenContext Options used to control flattening.
     * @param value The RHS value that is the source of the property.
     * @param propertyName The destructuring property name.
     */
    function createDestructuringPropertyAccess(flattenContext, value, propertyName) {
        if (ts.isComputedPropertyName(propertyName)) {
            var argumentExpression = ensureIdentifier(flattenContext, ts.visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
            return ts.createElementAccess(value, argumentExpression);
        }
        else if (ts.isStringOrNumericLiteralLike(propertyName)) {
            var argumentExpression = ts.getSynthesizedClone(propertyName);
            argumentExpression.text = argumentExpression.text;
            return ts.createElementAccess(value, argumentExpression);
        }
        else {
            var name = ts.createIdentifier(ts.idText(propertyName));
            return ts.createPropertyAccess(value, name);
        }
    }
    /**
     * Ensures that there exists a declared identifier whose value holds the given expression.
     * This function is useful to ensure that the expression's value can be read from in subsequent expressions.
     * Unless 'reuseIdentifierExpressions' is false, 'value' will be returned if it is just an identifier.
     *
     * @param flattenContext Options used to control flattening.
     * @param value the expression whose value needs to be bound.
     * @param reuseIdentifierExpressions true if identifier expressions can simply be returned;
     * false if it is necessary to always emit an identifier.
     * @param location The location to use for source maps and comments.
     */
    function ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location) {
        if (ts.isIdentifier(value) && reuseIdentifierExpressions) {
            return value;
        }
        else {
            var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
            if (flattenContext.hoistTempVariables) {
                flattenContext.context.hoistVariableDeclaration(temp);
                flattenContext.emitExpression(ts.setTextRange(ts.createAssignment(temp, value), location));
            }
            else {
                flattenContext.emitBindingOrAssignment(temp, value, location, /*original*/ undefined);
            }
            return temp;
        }
    }
    function makeArrayBindingPattern(elements) {
        ts.Debug.assertEachNode(elements, ts.isArrayBindingElement);
        return ts.createArrayBindingPattern(elements);
    }
    function makeArrayAssignmentPattern(elements) {
        return ts.createArrayLiteral(ts.map(elements, ts.convertToArrayAssignmentElement));
    }
    function makeObjectBindingPattern(elements) {
        ts.Debug.assertEachNode(elements, ts.isBindingElement);
        return ts.createObjectBindingPattern(elements);
    }
    function makeObjectAssignmentPattern(elements) {
        return ts.createObjectLiteral(ts.map(elements, ts.convertToObjectAssignmentElement));
    }
    function makeBindingElement(name) {
        return ts.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name);
    }
    function makeAssignmentElement(name) {
        return name;
    }
    ts.restHelper = {
        name: "typescript:rest",
        scoped: false,
        text: "\n            var __rest = (this && this.__rest) || function (s, e) {\n                var t = {};\n                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n                    t[p] = s[p];\n                if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n                    for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n                        if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n                            t[p[i]] = s[p[i]];\n                    }\n                return t;\n            };"
    };
    /** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement
     * `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);`
     */
    function createRestCall(context, value, elements, computedTempVariables, location) {
        context.requestEmitHelper(ts.restHelper);
        var propertyNames = [];
        var computedTempVariableOffset = 0;
        for (var i = 0; i < elements.length - 1; i++) {
            var propertyName = ts.getPropertyNameOfBindingOrAssignmentElement(elements[i]);
            if (propertyName) {
                if (ts.isComputedPropertyName(propertyName)) {
                    var temp = computedTempVariables[computedTempVariableOffset];
                    computedTempVariableOffset++;
                    // typeof _tmp === "symbol" ? _tmp : _tmp + ""
                    propertyNames.push(ts.createConditional(ts.createTypeCheck(temp, "symbol"), temp, ts.createAdd(temp, ts.createLiteral(""))));
                }
                else {
                    propertyNames.push(ts.createLiteral(propertyName));
                }
            }
        }
        return ts.createCall(ts.getHelperName("__rest"), 
        /*typeArguments*/ undefined, [
            value,
            ts.setTextRange(ts.createArrayLiteral(propertyNames), location)
        ]);
    }
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    /**
     * Indicates whether to emit type metadata in the new format.
     */
    var USE_NEW_TYPE_METADATA_FORMAT = false;
    var TypeScriptSubstitutionFlags;
    (function (TypeScriptSubstitutionFlags) {
        /** Enables substitutions for decorated classes. */
        TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["ClassAliases"] = 1] = "ClassAliases";
        /** Enables substitutions for namespace exports. */
        TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["NamespaceExports"] = 2] = "NamespaceExports";
        /* Enables substitutions for unqualified enum members */
        TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["NonQualifiedEnumMembers"] = 8] = "NonQualifiedEnumMembers";
    })(TypeScriptSubstitutionFlags || (TypeScriptSubstitutionFlags = {}));
    var ClassFacts;
    (function (ClassFacts) {
        ClassFacts[ClassFacts["None"] = 0] = "None";
        ClassFacts[ClassFacts["HasStaticInitializedProperties"] = 1] = "HasStaticInitializedProperties";
        ClassFacts[ClassFacts["HasConstructorDecorators"] = 2] = "HasConstructorDecorators";
        ClassFacts[ClassFacts["HasMemberDecorators"] = 4] = "HasMemberDecorators";
        ClassFacts[ClassFacts["IsExportOfNamespace"] = 8] = "IsExportOfNamespace";
        ClassFacts[ClassFacts["IsNamedExternalExport"] = 16] = "IsNamedExternalExport";
        ClassFacts[ClassFacts["IsDefaultExternalExport"] = 32] = "IsDefaultExternalExport";
        ClassFacts[ClassFacts["IsDerivedClass"] = 64] = "IsDerivedClass";
        ClassFacts[ClassFacts["UseImmediatelyInvokedFunctionExpression"] = 128] = "UseImmediatelyInvokedFunctionExpression";
        ClassFacts[ClassFacts["HasAnyDecorators"] = 6] = "HasAnyDecorators";
        ClassFacts[ClassFacts["NeedsName"] = 5] = "NeedsName";
        ClassFacts[ClassFacts["MayNeedImmediatelyInvokedFunctionExpression"] = 7] = "MayNeedImmediatelyInvokedFunctionExpression";
        ClassFacts[ClassFacts["IsExported"] = 56] = "IsExported";
    })(ClassFacts || (ClassFacts = {}));
    function transformTypeScript(context) {
        var startLexicalEnvironment = context.startLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var resolver = context.getEmitResolver();
        var compilerOptions = context.getCompilerOptions();
        var strictNullChecks = ts.getStrictOptionValue(compilerOptions, "strictNullChecks");
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        // Save the previous transformation hooks.
        var previousOnEmitNode = context.onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        // Set new transformation hooks.
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        // Enable substitution for property/element access to emit const enum values.
        context.enableSubstitution(190 /* PropertyAccessExpression */);
        context.enableSubstitution(191 /* ElementAccessExpression */);
        // These variables contain state that changes as we descend into the tree.
        var currentSourceFile;
        var currentNamespace;
        var currentNamespaceContainerName;
        var currentLexicalScope;
        var currentNameScope;
        var currentScopeFirstDeclarationsOfName;
        /**
         * Keeps track of whether expression substitution has been enabled for specific edge cases.
         * They are persisted between each SourceFile transformation and should not be reset.
         */
        var enabledSubstitutions;
        /**
         * A map that keeps track of aliases created for classes with decorators to avoid issues
         * with the double-binding behavior of classes.
         */
        var classAliases;
        /**
         * Keeps track of whether we are within any containing namespaces when performing
         * just-in-time substitution while printing an expression identifier.
         */
        var applicableSubstitutions;
        /**
         * Tracks what computed name expressions originating from elided names must be inlined
         * at the next execution site, in document order
         */
        var pendingExpressions;
        return transformSourceFileOrBundle;
        function transformSourceFileOrBundle(node) {
            if (node.kind === 286 /* Bundle */) {
                return transformBundle(node);
            }
            return transformSourceFile(node);
        }
        function transformBundle(node) {
            return ts.createBundle(node.sourceFiles.map(transformSourceFile), ts.mapDefined(node.prepends, function (prepend) {
                if (prepend.kind === 288 /* InputFiles */) {
                    return ts.createUnparsedSourceFile(prepend, "js");
                }
                return prepend;
            }));
        }
        /**
         * Transform TypeScript-specific syntax in a SourceFile.
         *
         * @param node A SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            currentSourceFile = node;
            var visited = saveStateAndInvoke(node, visitSourceFile);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            currentSourceFile = undefined;
            return visited;
        }
        /**
         * Visits a node, saving and restoring state variables on the stack.
         *
         * @param node The node to visit.
         */
        function saveStateAndInvoke(node, f) {
            // Save state
            var savedCurrentScope = currentLexicalScope;
            var savedCurrentNameScope = currentNameScope;
            var savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
            // Handle state changes before visiting a node.
            onBeforeVisitNode(node);
            var visited = f(node);
            // Restore state
            if (currentLexicalScope !== savedCurrentScope) {
                currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
            }
            currentLexicalScope = savedCurrentScope;
            currentNameScope = savedCurrentNameScope;
            return visited;
        }
        /**
         * Performs actions that should always occur immediately before visiting a node.
         *
         * @param node The node to visit.
         */
        function onBeforeVisitNode(node) {
            switch (node.kind) {
                case 285 /* SourceFile */:
                case 247 /* CaseBlock */:
                case 246 /* ModuleBlock */:
                case 219 /* Block */:
                    currentLexicalScope = node;
                    currentNameScope = undefined;
                    currentScopeFirstDeclarationsOfName = undefined;
                    break;
                case 241 /* ClassDeclaration */:
                case 240 /* FunctionDeclaration */:
                    if (ts.hasModifier(node, 2 /* Ambient */)) {
                        break;
                    }
                    // Record these declarations provided that they have a name.
                    if (node.name) {
                        recordEmittedDeclarationInScope(node);
                    }
                    else {
                        // These nodes should always have names unless they are default-exports;
                        // however, class declaration parsing allows for undefined names, so syntactically invalid
                        // programs may also have an undefined name.
                        ts.Debug.assert(node.kind === 241 /* ClassDeclaration */ || ts.hasModifier(node, 512 /* Default */));
                    }
                    if (ts.isClassDeclaration(node)) {
                        // XXX: should probably also cover interfaces and type aliases that can have type variables?
                        currentNameScope = node;
                    }
                    break;
            }
        }
        /**
         * General-purpose node visitor.
         *
         * @param node The node to visit.
         */
        function visitor(node) {
            return saveStateAndInvoke(node, visitorWorker);
        }
        /**
         * Visits and possibly transforms any node.
         *
         * @param node The node to visit.
         */
        function visitorWorker(node) {
            if (node.transformFlags & 1 /* ContainsTypeScript */) {
                return visitTypeScript(node);
            }
            return node;
        }
        /**
         * Specialized visitor that visits the immediate children of a SourceFile.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitor(node) {
            return saveStateAndInvoke(node, sourceElementVisitorWorker);
        }
        /**
         * Specialized visitor that visits the immediate children of a SourceFile.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitorWorker(node) {
            switch (node.kind) {
                case 250 /* ImportDeclaration */:
                case 249 /* ImportEqualsDeclaration */:
                case 255 /* ExportAssignment */:
                case 256 /* ExportDeclaration */:
                    return visitEllidableStatement(node);
                default:
                    return visitorWorker(node);
            }
        }
        function visitEllidableStatement(node) {
            var parsed = ts.getParseTreeNode(node);
            if (parsed !== node) {
                // If the node has been transformed by a `before` transformer, perform no ellision on it
                // As the type information we would attempt to lookup to perform ellision is potentially unavailable for the synthesized nodes
                // We do not reuse `visitorWorker`, as the ellidable statement syntax kinds are technically unrecognized by the switch-case in `visitTypeScript`,
                // and will trigger debug failures when debug verbosity is turned up
                if (node.transformFlags & 1 /* ContainsTypeScript */) {
                    // This node contains TypeScript, so we should visit its children.
                    return ts.visitEachChild(node, visitor, context);
                }
                // Otherwise, we can just return the node
                return node;
            }
            switch (node.kind) {
                case 250 /* ImportDeclaration */:
                    return visitImportDeclaration(node);
                case 249 /* ImportEqualsDeclaration */:
                    return visitImportEqualsDeclaration(node);
                case 255 /* ExportAssignment */:
                    return visitExportAssignment(node);
                case 256 /* ExportDeclaration */:
                    return visitExportDeclaration(node);
                default:
                    ts.Debug.fail("Unhandled ellided statement");
            }
        }
        /**
         * Specialized visitor that visits the immediate children of a namespace.
         *
         * @param node The node to visit.
         */
        function namespaceElementVisitor(node) {
            return saveStateAndInvoke(node, namespaceElementVisitorWorker);
        }
        /**
         * Specialized visitor that visits the immediate children of a namespace.
         *
         * @param node The node to visit.
         */
        function namespaceElementVisitorWorker(node) {
            if (node.kind === 256 /* ExportDeclaration */ ||
                node.kind === 250 /* ImportDeclaration */ ||
                node.kind === 251 /* ImportClause */ ||
                (node.kind === 249 /* ImportEqualsDeclaration */ &&
                    node.moduleReference.kind === 260 /* ExternalModuleReference */)) {
                // do not emit ES6 imports and exports since they are illegal inside a namespace
                return undefined;
            }
            else if (node.transformFlags & 1 /* ContainsTypeScript */ || ts.hasModifier(node, 1 /* Export */)) {
                return visitTypeScript(node);
            }
            return node;
        }
        /**
         * Specialized visitor that visits the immediate children of a class with TypeScript syntax.
         *
         * @param node The node to visit.
         */
        function classElementVisitor(node) {
            return saveStateAndInvoke(node, classElementVisitorWorker);
        }
        /**
         * Specialized visitor that visits the immediate children of a class with TypeScript syntax.
         *
         * @param node The node to visit.
         */
        function classElementVisitorWorker(node) {
            switch (node.kind) {
                case 158 /* Constructor */:
                    // TypeScript constructors are transformed in `visitClassDeclaration`.
                    // We elide them here as `visitorWorker` checks transform flags, which could
                    // erronously include an ES6 constructor without TypeScript syntax.
                    return undefined;
                case 155 /* PropertyDeclaration */:
                case 163 /* IndexSignature */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                case 157 /* MethodDeclaration */:
                    // Fallback to the default visit behavior.
                    return visitorWorker(node);
                case 218 /* SemicolonClassElement */:
                    return node;
                default:
                    return ts.Debug.failBadSyntaxKind(node);
            }
        }
        function modifierVisitor(node) {
            if (ts.modifierToFlag(node.kind) & 2270 /* TypeScriptModifier */) {
                return undefined;
            }
            else if (currentNamespace && node.kind === 86 /* ExportKeyword */) {
                return undefined;
            }
            return node;
        }
        /**
         * Branching visitor, visits a TypeScript syntax node.
         *
         * @param node The node to visit.
         */
        function visitTypeScript(node) {
            if (ts.isStatement(node) && ts.hasModifier(node, 2 /* Ambient */)) {
                // TypeScript ambient declarations are elided, but some comments may be preserved.
                // See the implementation of `getLeadingComments` in comments.ts for more details.
                return ts.createNotEmittedStatement(node);
            }
            switch (node.kind) {
                case 86 /* ExportKeyword */:
                case 81 /* DefaultKeyword */:
                    // ES6 export and default modifiers are elided when inside a namespace.
                    return currentNamespace ? undefined : node;
                case 116 /* PublicKeyword */:
                case 114 /* PrivateKeyword */:
                case 115 /* ProtectedKeyword */:
                case 119 /* AbstractKeyword */:
                case 78 /* ConstKeyword */:
                case 126 /* DeclareKeyword */:
                case 134 /* ReadonlyKeyword */:
                // TypeScript accessibility and readonly modifiers are elided.
                case 170 /* ArrayType */:
                case 171 /* TupleType */:
                case 172 /* OptionalType */:
                case 173 /* RestType */:
                case 169 /* TypeLiteral */:
                case 164 /* TypePredicate */:
                case 151 /* TypeParameter */:
                case 121 /* AnyKeyword */:
                case 144 /* UnknownKeyword */:
                case 124 /* BooleanKeyword */:
                case 139 /* StringKeyword */:
                case 136 /* NumberKeyword */:
                case 133 /* NeverKeyword */:
                case 107 /* VoidKeyword */:
                case 140 /* SymbolKeyword */:
                case 167 /* ConstructorType */:
                case 166 /* FunctionType */:
                case 168 /* TypeQuery */:
                case 165 /* TypeReference */:
                case 174 /* UnionType */:
                case 175 /* IntersectionType */:
                case 176 /* ConditionalType */:
                case 178 /* ParenthesizedType */:
                case 179 /* ThisType */:
                case 180 /* TypeOperator */:
                case 181 /* IndexedAccessType */:
                case 182 /* MappedType */:
                case 183 /* LiteralType */:
                // TypeScript type nodes are elided.
                case 163 /* IndexSignature */:
                // TypeScript index signatures are elided.
                case 153 /* Decorator */:
                // TypeScript decorators are elided. They will be emitted as part of visitClassDeclaration.
                case 243 /* TypeAliasDeclaration */:
                    // TypeScript type-only declarations are elided.
                    return undefined;
                case 155 /* PropertyDeclaration */:
                    // TypeScript property declarations are elided. However their names are still visited, and can potentially be retained if they could have sideeffects
                    return visitPropertyDeclaration(node);
                case 248 /* NamespaceExportDeclaration */:
                    // TypeScript namespace export declarations are elided.
                    return undefined;
                case 158 /* Constructor */:
                    return visitConstructor(node);
                case 242 /* InterfaceDeclaration */:
                    // TypeScript interfaces are elided, but some comments may be preserved.
                    // See the implementation of `getLeadingComments` in comments.ts for more details.
                    return ts.createNotEmittedStatement(node);
                case 241 /* ClassDeclaration */:
                    // This may be a class declaration with TypeScript syntax extensions.
                    //
                    // TypeScript class syntax extensions include:
                    // - decorators
                    // - optional `implements` heritage clause
                    // - parameter property assignments in the constructor
                    // - property declarations
                    // - index signatures
                    // - method overload signatures
                    return visitClassDeclaration(node);
                case 210 /* ClassExpression */:
                    // This may be a class expression with TypeScript syntax extensions.
                    //
                    // TypeScript class syntax extensions include:
                    // - decorators
                    // - optional `implements` heritage clause
                    // - parameter property assignments in the constructor
                    // - property declarations
                    // - index signatures
                    // - method overload signatures
                    return visitClassExpression(node);
                case 274 /* HeritageClause */:
                    // This may be a heritage clause with TypeScript syntax extensions.
                    //
                    // TypeScript heritage clause extensions include:
                    // - `implements` clause
                    return visitHeritageClause(node);
                case 212 /* ExpressionWithTypeArguments */:
                    // TypeScript supports type arguments on an expression in an `extends` heritage clause.
                    return visitExpressionWithTypeArguments(node);
                case 157 /* MethodDeclaration */:
                    // TypeScript method declarations may have decorators, modifiers
                    // or type annotations.
                    return visitMethodDeclaration(node);
                case 159 /* GetAccessor */:
                    // Get Accessors can have TypeScript modifiers, decorators, and type annotations.
                    return visitGetAccessor(node);
                case 160 /* SetAccessor */:
                    // Set Accessors can have TypeScript modifiers and type annotations.
                    return visitSetAccessor(node);
                case 240 /* FunctionDeclaration */:
                    // Typescript function declarations can have modifiers, decorators, and type annotations.
                    return visitFunctionDeclaration(node);
                case 197 /* FunctionExpression */:
                    // TypeScript function expressions can have modifiers and type annotations.
                    return visitFunctionExpression(node);
                case 198 /* ArrowFunction */:
                    // TypeScript arrow functions can have modifiers and type annotations.
                    return visitArrowFunction(node);
                case 152 /* Parameter */:
                    // This may be a parameter declaration with TypeScript syntax extensions.
                    //
                    // TypeScript parameter declaration syntax extensions include:
                    // - decorators
                    // - accessibility modifiers
                    // - the question mark (?) token for optional parameters
                    // - type annotations
                    // - this parameters
                    return visitParameter(node);
                case 196 /* ParenthesizedExpression */:
                    // ParenthesizedExpressions are TypeScript if their expression is a
                    // TypeAssertion or AsExpression
                    return visitParenthesizedExpression(node);
                case 195 /* TypeAssertionExpression */:
                case 213 /* AsExpression */:
                    // TypeScript type assertions are removed, but their subtrees are preserved.
                    return visitAssertionExpression(node);
                case 192 /* CallExpression */:
                    return visitCallExpression(node);
                case 193 /* NewExpression */:
                    return visitNewExpression(node);
                case 194 /* TaggedTemplateExpression */:
                    return visitTaggedTemplateExpression(node);
                case 214 /* NonNullExpression */:
                    // TypeScript non-null expressions are removed, but their subtrees are preserved.
                    return visitNonNullExpression(node);
                case 244 /* EnumDeclaration */:
                    // TypeScript enum declarations do not exist in ES6 and must be rewritten.
                    return visitEnumDeclaration(node);
                case 220 /* VariableStatement */:
                    // TypeScript namespace exports for variable statements must be transformed.
                    return visitVariableStatement(node);
                case 238 /* VariableDeclaration */:
                    return visitVariableDeclaration(node);
                case 245 /* ModuleDeclaration */:
                    // TypeScript namespace declarations must be transformed.
                    return visitModuleDeclaration(node);
                case 249 /* ImportEqualsDeclaration */:
                    // TypeScript namespace or external module import.
                    return visitImportEqualsDeclaration(node);
                default:
                    // node contains some other TypeScript syntax
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitSourceFile(node) {
            var alwaysStrict = ts.getStrictOptionValue(compilerOptions, "alwaysStrict") &&
                !(ts.isExternalModule(node) && moduleKind >= ts.ModuleKind.ES2015) &&
                !ts.isJsonSourceFile(node);
            return ts.updateSourceFileNode(node, ts.visitLexicalEnvironment(node.statements, sourceElementVisitor, context, /*start*/ 0, alwaysStrict));
        }
        /**
         * Tests whether we should emit a __decorate call for a class declaration.
         */
        function shouldEmitDecorateCallForClass(node) {
            if (node.decorators && node.decorators.length > 0) {
                return true;
            }
            var constructor = ts.getFirstConstructorWithBody(node);
            if (constructor) {
                return ts.forEach(constructor.parameters, shouldEmitDecorateCallForParameter);
            }
            return false;
        }
        /**
         * Tests whether we should emit a __decorate call for a parameter declaration.
         */
        function shouldEmitDecorateCallForParameter(parameter) {
            return parameter.decorators !== undefined && parameter.decorators.length > 0;
        }
        function getClassFacts(node, staticProperties) {
            var facts = 0 /* None */;
            if (ts.some(staticProperties))
                facts |= 1 /* HasStaticInitializedProperties */;
            var extendsClauseElement = ts.getEffectiveBaseTypeNode(node);
            if (extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 97 /* NullKeyword */)
                facts |= 64 /* IsDerivedClass */;
            if (shouldEmitDecorateCallForClass(node))
                facts |= 2 /* HasConstructorDecorators */;
            if (ts.childIsDecorated(node))
                facts |= 4 /* HasMemberDecorators */;
            if (isExportOfNamespace(node))
                facts |= 8 /* IsExportOfNamespace */;
            else if (isDefaultExternalModuleExport(node))
                facts |= 32 /* IsDefaultExternalExport */;
            else if (isNamedExternalModuleExport(node))
                facts |= 16 /* IsNamedExternalExport */;
            if (languageVersion <= 1 /* ES5 */ && (facts & 7 /* MayNeedImmediatelyInvokedFunctionExpression */))
                facts |= 128 /* UseImmediatelyInvokedFunctionExpression */;
            return facts;
        }
        function hasTypeScriptClassSyntax(node) {
            return !!(node.transformFlags & 1024 /* ContainsTypeScriptClassSyntax */);
        }
        function isClassLikeDeclarationWithTypeScriptSyntax(node) {
            return ts.some(node.decorators)
                || ts.some(node.typeParameters)
                || ts.some(node.heritageClauses, hasTypeScriptClassSyntax)
                || ts.some(node.members, hasTypeScriptClassSyntax);
        }
        function visitClassDeclaration(node) {
            if (!isClassLikeDeclarationWithTypeScriptSyntax(node) && !(currentNamespace && ts.hasModifier(node, 1 /* Export */))) {
                return ts.visitEachChild(node, visitor, context);
            }
            var savedPendingExpressions = pendingExpressions;
            pendingExpressions = undefined;
            var staticProperties = getInitializedProperties(node, /*isStatic*/ true);
            var facts = getClassFacts(node, staticProperties);
            if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */) {
                context.startLexicalEnvironment();
            }
            var name = node.name || (facts & 5 /* NeedsName */ ? ts.getGeneratedNameForNode(node) : undefined);
            var classStatement = facts & 2 /* HasConstructorDecorators */
                ? createClassDeclarationHeadWithDecorators(node, name, facts)
                : createClassDeclarationHeadWithoutDecorators(node, name, facts);
            var statements = [classStatement];
            // Write any pending expressions from elided or moved computed property names
            if (ts.some(pendingExpressions)) {
                statements.push(ts.createExpressionStatement(ts.inlineExpressions(pendingExpressions)));
            }
            pendingExpressions = savedPendingExpressions;
            // Emit static property assignment. Because classDeclaration is lexically evaluated,
            // it is safe to emit static property assignment after classDeclaration
            // From ES6 specification:
            //      HasLexicalDeclaration (N) : Determines if the argument identifier has a binding in this environment record that was created using
            //                                  a lexical declaration such as a LexicalDeclaration or a ClassDeclaration.
            if (facts & 1 /* HasStaticInitializedProperties */) {
                addInitializedPropertyStatements(statements, staticProperties, facts & 128 /* UseImmediatelyInvokedFunctionExpression */ ? ts.getInternalName(node) : ts.getLocalName(node));
            }
            // Write any decorators of the node.
            addClassElementDecorationStatements(statements, node, /*isStatic*/ false);
            addClassElementDecorationStatements(statements, node, /*isStatic*/ true);
            addConstructorDecorationStatement(statements, node);
            if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */) {
                // When we emit a TypeScript class down to ES5, we must wrap it in an IIFE so that the
                // 'es2015' transformer can properly nest static initializers and decorators. The result
                // looks something like:
                //
                //  var C = function () {
                //      class C {
                //      }
                //      C.static_prop = 1;
                //      return C;
                //  }();
                //
                var closingBraceLocation = ts.createTokenRange(ts.skipTrivia(currentSourceFile.text, node.members.end), 19 /* CloseBraceToken */);
                var localName = ts.getInternalName(node);
                // The following partially-emitted expression exists purely to align our sourcemap
                // emit with the original emitter.
                var outer = ts.createPartiallyEmittedExpression(localName);
                outer.end = closingBraceLocation.end;
                ts.setEmitFlags(outer, 1536 /* NoComments */);
                var statement = ts.createReturn(outer);
                statement.pos = closingBraceLocation.pos;
                ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */);
                statements.push(statement);
                ts.insertStatementsAfterStandardPrologue(statements, context.endLexicalEnvironment());
                var iife = ts.createImmediatelyInvokedArrowFunction(statements);
                ts.setEmitFlags(iife, 33554432 /* TypeScriptClassWrapper */);
                var varStatement = ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ false), 
                    /*type*/ undefined, iife)
                ]));
                ts.setOriginalNode(varStatement, node);
                ts.setCommentRange(varStatement, node);
                ts.setSourceMapRange(varStatement, ts.moveRangePastDecorators(node));
                ts.startOnNewLine(varStatement);
                statements = [varStatement];
            }
            // If the class is exported as part of a TypeScript namespace, emit the namespace export.
            // Otherwise, if the class was exported at the top level and was decorated, emit an export
            // declaration or export default for the class.
            if (facts & 8 /* IsExportOfNamespace */) {
                addExportMemberAssignment(statements, node);
            }
            else if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */ || facts & 2 /* HasConstructorDecorators */) {
                if (facts & 32 /* IsDefaultExternalExport */) {
                    statements.push(ts.createExportDefault(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)));
                }
                else if (facts & 16 /* IsNamedExternalExport */) {
                    statements.push(ts.createExternalModuleExport(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)));
                }
            }
            if (statements.length > 1) {
                // Add a DeclarationMarker as a marker for the end of the declaration
                statements.push(ts.createEndOfDeclarationMarker(node));
                ts.setEmitFlags(classStatement, ts.getEmitFlags(classStatement) | 4194304 /* HasEndOfDeclarationMarker */);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Transforms a non-decorated class declaration and appends the resulting statements.
         *
         * @param node A ClassDeclaration node.
         * @param name The name of the class.
         * @param facts Precomputed facts about the class.
         */
        function createClassDeclarationHeadWithoutDecorators(node, name, facts) {
            //  ${modifiers} class ${name} ${heritageClauses} {
            //      ${members}
            //  }
            // we do not emit modifiers on the declaration if we are emitting an IIFE
            var modifiers = !(facts & 128 /* UseImmediatelyInvokedFunctionExpression */)
                ? ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier)
                : undefined;
            var classDeclaration = ts.createClassDeclaration(
            /*decorators*/ undefined, modifiers, name, 
            /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause), transformClassMembers(node, (facts & 64 /* IsDerivedClass */) !== 0));
            // To better align with the old emitter, we should not emit a trailing source map
            // entry if the class has static properties.
            var emitFlags = ts.getEmitFlags(node);
            if (facts & 1 /* HasStaticInitializedProperties */) {
                emitFlags |= 32 /* NoTrailingSourceMap */;
            }
            ts.setTextRange(classDeclaration, node);
            ts.setOriginalNode(classDeclaration, node);
            ts.setEmitFlags(classDeclaration, emitFlags);
            return classDeclaration;
        }
        /**
         * Transforms a decorated class declaration and appends the resulting statements. If
         * the class requires an alias to avoid issues with double-binding, the alias is returned.
         */
        function createClassDeclarationHeadWithDecorators(node, name, facts) {
            // When we emit an ES6 class that has a class decorator, we must tailor the
            // emit to certain specific cases.
            //
            // In the simplest case, we emit the class declaration as a let declaration, and
            // evaluate decorators after the close of the class body:
            //
            //  [Example 1]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  class C {                       | }
            //  }                               | C = __decorate([dec], C);
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export class C {                | }
            //  }                               | C = __decorate([dec], C);
            //                                  | export { C };
            //  ---------------------------------------------------------------------
            //
            // If a class declaration contains a reference to itself *inside* of the class body,
            // this introduces two bindings to the class: One outside of the class body, and one
            // inside of the class body. If we apply decorators as in [Example 1] above, there
            // is the possibility that the decorator `dec` will return a new value for the
            // constructor, which would result in the binding inside of the class no longer
            // pointing to the same reference as the binding outside of the class.
            //
            // As a result, we must instead rewrite all references to the class *inside* of the
            // class body to instead point to a local temporary alias for the class:
            //
            //  [Example 2]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = C_1 = class C {
            //  class C {                       |   static x() { return C_1.y; }
            //    static x() { return C.y; }    | }
            //    static y = 1;                 | C.y = 1;
            //  }                               | C = C_1 = __decorate([dec], C);
            //                                  | var C_1;
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export class C {                |   static x() { return C_1.y; }
            //    static x() { return C.y; }    | }
            //    static y = 1;                 | C.y = 1;
            //  }                               | C = C_1 = __decorate([dec], C);
            //                                  | export { C };
            //                                  | var C_1;
            //  ---------------------------------------------------------------------
            //
            // If a class declaration is the default export of a module, we instead emit
            // the export after the decorated declaration:
            //
            //  [Example 3]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let default_1 = class {
            //  export default class {          | }
            //  }                               | default_1 = __decorate([dec], default_1);
            //                                  | export default default_1;
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export default class C {        | }
            //  }                               | C = __decorate([dec], C);
            //                                  | export default C;
            //  ---------------------------------------------------------------------
            //
            // If the class declaration is the default export and a reference to itself
            // inside of the class body, we must emit both an alias for the class *and*
            // move the export after the declaration:
            //
            //  [Example 4]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export default class C {        |   static x() { return C_1.y; }
            //    static x() { return C.y; }    | }
            //    static y = 1;                 | C.y = 1;
            //  }                               | C = C_1 = __decorate([dec], C);
            //                                  | export default C;
            //                                  | var C_1;
            //  ---------------------------------------------------------------------
            //
            var location = ts.moveRangePastDecorators(node);
            var classAlias = getClassAliasIfNeeded(node);
            var declName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            //  ... = class ${name} ${heritageClauses} {
            //      ${members}
            //  }
            var heritageClauses = ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause);
            var members = transformClassMembers(node, (facts & 64 /* IsDerivedClass */) !== 0);
            var classExpression = ts.createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members);
            ts.setOriginalNode(classExpression, node);
            ts.setTextRange(classExpression, location);
            //  let ${name} = ${classExpression} where name is either declaredName if the class doesn't contain self-reference
            //                                         or decoratedClassAlias if the class contain self-reference.
            var statement = ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(declName, 
                /*type*/ undefined, classAlias ? ts.createAssignment(classAlias, classExpression) : classExpression)
            ], 1 /* Let */));
            ts.setOriginalNode(statement, node);
            ts.setTextRange(statement, location);
            ts.setCommentRange(statement, node);
            return statement;
        }
        function visitClassExpression(node) {
            if (!isClassLikeDeclarationWithTypeScriptSyntax(node)) {
                return ts.visitEachChild(node, visitor, context);
            }
            var savedPendingExpressions = pendingExpressions;
            pendingExpressions = undefined;
            var staticProperties = getInitializedProperties(node, /*isStatic*/ true);
            var heritageClauses = ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause);
            var members = transformClassMembers(node, ts.some(heritageClauses, function (c) { return c.token === 87 /* ExtendsKeyword */; }));
            var classExpression = ts.createClassExpression(
            /*modifiers*/ undefined, node.name, 
            /*typeParameters*/ undefined, heritageClauses, members);
            ts.setOriginalNode(classExpression, node);
            ts.setTextRange(classExpression, node);
            if (ts.some(staticProperties) || ts.some(pendingExpressions)) {
                var expressions = [];
                var isClassWithConstructorReference = resolver.getNodeCheckFlags(node) & 16777216 /* ClassWithConstructorReference */;
                var temp = ts.createTempVariable(hoistVariableDeclaration, !!isClassWithConstructorReference);
                if (isClassWithConstructorReference) {
                    // record an alias as the class name is not in scope for statics.
                    enableSubstitutionForClassAliases();
                    var alias = ts.getSynthesizedClone(temp);
                    alias.autoGenerateFlags &= ~8 /* ReservedInNestedScopes */;
                    classAliases[ts.getOriginalNodeId(node)] = alias;
                }
                // To preserve the behavior of the old emitter, we explicitly indent
                // the body of a class with static initializers.
                ts.setEmitFlags(classExpression, 65536 /* Indented */ | ts.getEmitFlags(classExpression));
                expressions.push(ts.startOnNewLine(ts.createAssignment(temp, classExpression)));
                // Add any pending expressions leftover from elided or relocated computed property names
                ts.addRange(expressions, ts.map(pendingExpressions, ts.startOnNewLine));
                pendingExpressions = savedPendingExpressions;
                ts.addRange(expressions, generateInitializedPropertyExpressions(staticProperties, temp));
                expressions.push(ts.startOnNewLine(temp));
                return ts.inlineExpressions(expressions);
            }
            pendingExpressions = savedPendingExpressions;
            return classExpression;
        }
        /**
         * Transforms the members of a class.
         *
         * @param node The current class.
         * @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'.
         */
        function transformClassMembers(node, isDerivedClass) {
            var members = [];
            var constructor = transformConstructor(node, isDerivedClass);
            if (constructor) {
                members.push(constructor);
            }
            ts.addRange(members, ts.visitNodes(node.members, classElementVisitor, ts.isClassElement));
            return ts.setTextRange(ts.createNodeArray(members), /*location*/ node.members);
        }
        /**
         * Transforms (or creates) a constructor for a class.
         *
         * @param node The current class.
         * @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'.
         */
        function transformConstructor(node, isDerivedClass) {
            // Check if we have property assignment inside class declaration.
            // If there is a property assignment, we need to emit constructor whether users define it or not
            // If there is no property assignment, we can omit constructor if users do not define it
            var constructor = ts.getFirstConstructorWithBody(node);
            var hasInstancePropertyWithInitializer = ts.forEach(node.members, isInstanceInitializedProperty);
            var hasParameterPropertyAssignments = constructor &&
                constructor.transformFlags & 1024 /* ContainsTypeScriptClassSyntax */ &&
                ts.forEach(constructor.parameters, isParameterWithPropertyAssignment);
            // If the class does not contain nodes that require a synthesized constructor,
            // accept the current constructor if it exists.
            if (!hasInstancePropertyWithInitializer && !hasParameterPropertyAssignments) {
                return ts.visitEachChild(constructor, visitor, context);
            }
            var parameters = transformConstructorParameters(constructor);
            var body = transformConstructorBody(node, constructor, isDerivedClass);
            //  constructor(${parameters}) {
            //      ${body}
            //  }
            return ts.startOnNewLine(ts.setOriginalNode(ts.setTextRange(ts.createConstructor(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, parameters, body), constructor || node), constructor));
        }
        /**
         * Transforms (or creates) the parameters for the constructor of a class with
         * parameter property assignments or instance property initializers.
         *
         * @param constructor The constructor declaration.
         */
        function transformConstructorParameters(constructor) {
            // The ES2015 spec specifies in 14.5.14. Runtime Semantics: ClassDefinitionEvaluation:
            // If constructor is empty, then
            //     If ClassHeritag_eopt is present and protoParent is not null, then
            //          Let constructor be the result of parsing the source text
            //              constructor(...args) { super (...args);}
            //          using the syntactic grammar with the goal symbol MethodDefinition[~Yield].
            //      Else,
            //           Let constructor be the result of parsing the source text
            //               constructor( ){ }
            //           using the syntactic grammar with the goal symbol MethodDefinition[~Yield].
            //
            // While we could emit the '...args' rest parameter, certain later tools in the pipeline might
            // downlevel the '...args' portion less efficiently by naively copying the contents of 'arguments' to an array.
            // Instead, we'll avoid using a rest parameter and spread into the super call as
            // 'super(...arguments)' instead of 'super(...args)', as you can see in "transformConstructorBody".
            return ts.visitParameterList(constructor && constructor.parameters, visitor, context)
                || [];
        }
        /**
         * Transforms (or creates) a constructor body for a class with parameter property
         * assignments or instance property initializers.
         *
         * @param node The current class.
         * @param constructor The current class constructor.
         * @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'.
         */
        function transformConstructorBody(node, constructor, isDerivedClass) {
            var statements = [];
            var indexOfFirstStatement = 0;
            resumeLexicalEnvironment();
            if (constructor) {
                indexOfFirstStatement = addPrologueDirectivesAndInitialSuperCall(constructor, statements);
                // Add parameters with property assignments. Transforms this:
                //
                //  constructor (public x, public y) {
                //  }
                //
                // Into this:
                //
                //  constructor (x, y) {
                //      this.x = x;
                //      this.y = y;
                //  }
                //
                var propertyAssignments = getParametersWithPropertyAssignments(constructor);
                ts.addRange(statements, ts.map(propertyAssignments, transformParameterWithPropertyAssignment));
            }
            else if (isDerivedClass) {
                // Add a synthetic `super` call:
                //
                //  super(...arguments);
                //
                statements.push(ts.createExpressionStatement(ts.createCall(ts.createSuper(), 
                /*typeArguments*/ undefined, [ts.createSpread(ts.createIdentifier("arguments"))])));
            }
            // Add the property initializers. Transforms this:
            //
            //  public x = 1;
            //
            // Into this:
            //
            //  constructor() {
            //      this.x = 1;
            //  }
            //
            var properties = getInitializedProperties(node, /*isStatic*/ false);
            addInitializedPropertyStatements(statements, properties, ts.createThis());
            if (constructor) {
                // The class already had a constructor, so we should add the existing statements, skipping the initial super call.
                ts.addRange(statements, ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, indexOfFirstStatement));
            }
            // End the lexical environment.
            statements = ts.mergeLexicalEnvironment(statements, endLexicalEnvironment());
            return ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), 
            /*location*/ constructor ? constructor.body.statements : node.members), 
            /*multiLine*/ true), 
            /*location*/ constructor ? constructor.body : undefined);
        }
        /**
         * Adds super call and preceding prologue directives into the list of statements.
         *
         * @param ctor The constructor node.
         * @returns index of the statement that follows super call
         */
        function addPrologueDirectivesAndInitialSuperCall(ctor, result) {
            if (ctor.body) {
                var statements = ctor.body.statements;
                // add prologue directives to the list (if any)
                var index = ts.addPrologue(result, statements, /*ensureUseStrict*/ false, visitor);
                if (index === statements.length) {
                    // list contains nothing but prologue directives (or empty) - exit
                    return index;
                }
                var statement = statements[index];
                if (statement.kind === 222 /* ExpressionStatement */ && ts.isSuperCall(statement.expression)) {
                    result.push(ts.visitNode(statement, visitor, ts.isStatement));
                    return index + 1;
                }
                return index;
            }
            return 0;
        }
        /**
         * Gets all parameters of a constructor that should be transformed into property assignments.
         *
         * @param node The constructor node.
         */
        function getParametersWithPropertyAssignments(node) {
            return ts.filter(node.parameters, isParameterWithPropertyAssignment);
        }
        /**
         * Determines whether a parameter should be transformed into a property assignment.
         *
         * @param parameter The parameter node.
         */
        function isParameterWithPropertyAssignment(parameter) {
            return ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */)
                && ts.isIdentifier(parameter.name);
        }
        /**
         * Transforms a parameter into a property assignment statement.
         *
         * @param node The parameter declaration.
         */
        function transformParameterWithPropertyAssignment(node) {
            ts.Debug.assert(ts.isIdentifier(node.name));
            var name = node.name;
            var propertyName = ts.getMutableClone(name);
            ts.setEmitFlags(propertyName, 1536 /* NoComments */ | 48 /* NoSourceMap */);
            var localName = ts.getMutableClone(name);
            ts.setEmitFlags(localName, 1536 /* NoComments */);
            return ts.startOnNewLine(ts.setEmitFlags(ts.setTextRange(ts.createExpressionStatement(ts.createAssignment(ts.setTextRange(ts.createPropertyAccess(ts.createThis(), propertyName), node.name), localName)), ts.moveRangePos(node, -1)), 1536 /* NoComments */));
        }
        /**
         * Gets all property declarations with initializers on either the static or instance side of a class.
         *
         * @param node The class node.
         * @param isStatic A value indicating whether to get properties from the static or instance side of the class.
         */
        function getInitializedProperties(node, isStatic) {
            return ts.filter(node.members, isStatic ? isStaticInitializedProperty : isInstanceInitializedProperty);
        }
        /**
         * Gets a value indicating whether a class element is a static property declaration with an initializer.
         *
         * @param member The class element node.
         */
        function isStaticInitializedProperty(member) {
            return isInitializedProperty(member, /*isStatic*/ true);
        }
        /**
         * Gets a value indicating whether a class element is an instance property declaration with an initializer.
         *
         * @param member The class element node.
         */
        function isInstanceInitializedProperty(member) {
            return isInitializedProperty(member, /*isStatic*/ false);
        }
        /**
         * Gets a value indicating whether a class element is either a static or an instance property declaration with an initializer.
         *
         * @param member The class element node.
         * @param isStatic A value indicating whether the member should be a static or instance member.
         */
        function isInitializedProperty(member, isStatic) {
            return member.kind === 155 /* PropertyDeclaration */
                && isStatic === ts.hasModifier(member, 32 /* Static */)
                && member.initializer !== undefined;
        }
        /**
         * Generates assignment statements for property initializers.
         *
         * @param properties An array of property declarations to transform.
         * @param receiver The receiver on which each property should be assigned.
         */
        function addInitializedPropertyStatements(statements, properties, receiver) {
            for (var _i = 0, properties_6 = properties; _i < properties_6.length; _i++) {
                var property = properties_6[_i];
                var statement = ts.createExpressionStatement(transformInitializedProperty(property, receiver));
                ts.setSourceMapRange(statement, ts.moveRangePastModifiers(property));
                ts.setCommentRange(statement, property);
                ts.setOriginalNode(statement, property);
                statements.push(statement);
            }
        }
        /**
         * Generates assignment expressions for property initializers.
         *
         * @param properties An array of property declarations to transform.
         * @param receiver The receiver on which each property should be assigned.
         */
        function generateInitializedPropertyExpressions(properties, receiver) {
            var expressions = [];
            for (var _i = 0, properties_7 = properties; _i < properties_7.length; _i++) {
                var property = properties_7[_i];
                var expression = transformInitializedProperty(property, receiver);
                ts.startOnNewLine(expression);
                ts.setSourceMapRange(expression, ts.moveRangePastModifiers(property));
                ts.setCommentRange(expression, property);
                ts.setOriginalNode(expression, property);
                expressions.push(expression);
            }
            return expressions;
        }
        /**
         * Transforms a property initializer into an assignment statement.
         *
         * @param property The property declaration.
         * @param receiver The object receiving the property assignment.
         */
        function transformInitializedProperty(property, receiver) {
            // We generate a name here in order to reuse the value cached by the relocated computed name expression (which uses the same generated name)
            var propertyName = ts.isComputedPropertyName(property.name) && !isSimpleInlineableExpression(property.name.expression)
                ? ts.updateComputedPropertyName(property.name, ts.getGeneratedNameForNode(property.name))
                : property.name;
            var initializer = ts.visitNode(property.initializer, visitor, ts.isExpression);
            var memberAccess = ts.createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName);
            return ts.createAssignment(memberAccess, initializer);
        }
        /**
         * Gets either the static or instance members of a class that are decorated, or have
         * parameters that are decorated.
         *
         * @param node The class containing the member.
         * @param isStatic A value indicating whether to retrieve static or instance members of
         *                 the class.
         */
        function getDecoratedClassElements(node, isStatic) {
            return ts.filter(node.members, isStatic ? function (m) { return isStaticDecoratedClassElement(m, node); } : function (m) { return isInstanceDecoratedClassElement(m, node); });
        }
        /**
         * Determines whether a class member is a static member of a class that is decorated, or
         * has parameters that are decorated.
         *
         * @param member The class member.
         */
        function isStaticDecoratedClassElement(member, parent) {
            return isDecoratedClassElement(member, /*isStatic*/ true, parent);
        }
        /**
         * Determines whether a class member is an instance member of a class that is decorated,
         * or has parameters that are decorated.
         *
         * @param member The class member.
         */
        function isInstanceDecoratedClassElement(member, parent) {
            return isDecoratedClassElement(member, /*isStatic*/ false, parent);
        }
        /**
         * Determines whether a class member is either a static or an instance member of a class
         * that is decorated, or has parameters that are decorated.
         *
         * @param member The class member.
         */
        function isDecoratedClassElement(member, isStatic, parent) {
            return ts.nodeOrChildIsDecorated(member, parent)
                && isStatic === ts.hasModifier(member, 32 /* Static */);
        }
        /**
         * Gets an array of arrays of decorators for the parameters of a function-like node.
         * The offset into the result array should correspond to the offset of the parameter.
         *
         * @param node The function-like node.
         */
        function getDecoratorsOfParameters(node) {
            var decorators;
            if (node) {
                var parameters = node.parameters;
                var firstParameterIsThis = parameters.length > 0 && ts.parameterIsThisKeyword(parameters[0]);
                var firstParameterOffset = firstParameterIsThis ? 1 : 0;
                var numParameters = firstParameterIsThis ? parameters.length - 1 : parameters.length;
                for (var i = 0; i < numParameters; i++) {
                    var parameter = parameters[i + firstParameterOffset];
                    if (decorators || parameter.decorators) {
                        if (!decorators) {
                            decorators = new Array(numParameters);
                        }
                        decorators[i] = parameter.decorators;
                    }
                }
            }
            return decorators;
        }
        /**
         * Gets an AllDecorators object containing the decorators for the class and the decorators for the
         * parameters of the constructor of the class.
         *
         * @param node The class node.
         */
        function getAllDecoratorsOfConstructor(node) {
            var decorators = node.decorators;
            var parameters = getDecoratorsOfParameters(ts.getFirstConstructorWithBody(node));
            if (!decorators && !parameters) {
                return undefined;
            }
            return {
                decorators: decorators,
                parameters: parameters
            };
        }
        /**
         * Gets an AllDecorators object containing the decorators for the member and its parameters.
         *
         * @param node The class node that contains the member.
         * @param member The class member.
         */
        function getAllDecoratorsOfClassElement(node, member) {
            switch (member.kind) {
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    return getAllDecoratorsOfAccessors(node, member);
                case 157 /* MethodDeclaration */:
                    return getAllDecoratorsOfMethod(member);
                case 155 /* PropertyDeclaration */:
                    return getAllDecoratorsOfProperty(member);
                default:
                    return undefined;
            }
        }
        /**
         * Gets an AllDecorators object containing the decorators for the accessor and its parameters.
         *
         * @param node The class node that contains the accessor.
         * @param accessor The class accessor member.
         */
        function getAllDecoratorsOfAccessors(node, accessor) {
            if (!accessor.body) {
                return undefined;
            }
            var _a = ts.getAllAccessorDeclarations(node.members, accessor), firstAccessor = _a.firstAccessor, secondAccessor = _a.secondAccessor, setAccessor = _a.setAccessor;
            var firstAccessorWithDecorators = firstAccessor.decorators ? firstAccessor : secondAccessor && secondAccessor.decorators ? secondAccessor : undefined;
            if (!firstAccessorWithDecorators || accessor !== firstAccessorWithDecorators) {
                return undefined;
            }
            var decorators = firstAccessorWithDecorators.decorators;
            var parameters = getDecoratorsOfParameters(setAccessor);
            if (!decorators && !parameters) {
                return undefined;
            }
            return { decorators: decorators, parameters: parameters };
        }
        /**
         * Gets an AllDecorators object containing the decorators for the method and its parameters.
         *
         * @param method The class method member.
         */
        function getAllDecoratorsOfMethod(method) {
            if (!method.body) {
                return undefined;
            }
            var decorators = method.decorators;
            var parameters = getDecoratorsOfParameters(method);
            if (!decorators && !parameters) {
                return undefined;
            }
            return { decorators: decorators, parameters: parameters };
        }
        /**
         * Gets an AllDecorators object containing the decorators for the property.
         *
         * @param property The class property member.
         */
        function getAllDecoratorsOfProperty(property) {
            var decorators = property.decorators;
            if (!decorators) {
                return undefined;
            }
            return { decorators: decorators };
        }
        /**
         * Transforms all of the decorators for a declaration into an array of expressions.
         *
         * @param node The declaration node.
         * @param allDecorators An object containing all of the decorators for the declaration.
         */
        function transformAllDecoratorsOfDeclaration(node, container, allDecorators) {
            if (!allDecorators) {
                return undefined;
            }
            var decoratorExpressions = [];
            ts.addRange(decoratorExpressions, ts.map(allDecorators.decorators, transformDecorator));
            ts.addRange(decoratorExpressions, ts.flatMap(allDecorators.parameters, transformDecoratorsOfParameter));
            addTypeMetadata(node, container, decoratorExpressions);
            return decoratorExpressions;
        }
        /**
         * Generates statements used to apply decorators to either the static or instance members
         * of a class.
         *
         * @param node The class node.
         * @param isStatic A value indicating whether to generate statements for static or
         *                 instance members.
         */
        function addClassElementDecorationStatements(statements, node, isStatic) {
            ts.addRange(statements, ts.map(generateClassElementDecorationExpressions(node, isStatic), expressionToStatement));
        }
        /**
         * Generates expressions used to apply decorators to either the static or instance members
         * of a class.
         *
         * @param node The class node.
         * @param isStatic A value indicating whether to generate expressions for static or
         *                 instance members.
         */
        function generateClassElementDecorationExpressions(node, isStatic) {
            var members = getDecoratedClassElements(node, isStatic);
            var expressions;
            for (var _i = 0, members_5 = members; _i < members_5.length; _i++) {
                var member = members_5[_i];
                var expression = generateClassElementDecorationExpression(node, member);
                if (expression) {
                    if (!expressions) {
                        expressions = [expression];
                    }
                    else {
                        expressions.push(expression);
                    }
                }
            }
            return expressions;
        }
        /**
         * Generates an expression used to evaluate class element decorators at runtime.
         *
         * @param node The class node that contains the member.
         * @param member The class member.
         */
        function generateClassElementDecorationExpression(node, member) {
            var allDecorators = getAllDecoratorsOfClassElement(node, member);
            var decoratorExpressions = transformAllDecoratorsOfDeclaration(member, node, allDecorators);
            if (!decoratorExpressions) {
                return undefined;
            }
            // Emit the call to __decorate. Given the following:
            //
            //   class C {
            //     @dec method(@dec2 x) {}
            //     @dec get accessor() {}
            //     @dec prop;
            //   }
            //
            // The emit for a method is:
            //
            //   __decorate([
            //       dec,
            //       __param(0, dec2),
            //       __metadata("design:type", Function),
            //       __metadata("design:paramtypes", [Object]),
            //       __metadata("design:returntype", void 0)
            //   ], C.prototype, "method", null);
            //
            // The emit for an accessor is:
            //
            //   __decorate([
            //       dec
            //   ], C.prototype, "accessor", null);
            //
            // The emit for a property is:
            //
            //   __decorate([
            //       dec
            //   ], C.prototype, "prop");
            //
            var prefix = getClassMemberPrefix(node, member);
            var memberName = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ true);
            var descriptor = languageVersion > 0 /* ES3 */
                ? member.kind === 155 /* PropertyDeclaration */
                    // We emit `void 0` here to indicate to `__decorate` that it can invoke `Object.defineProperty` directly, but that it
                    // should not invoke `Object.getOwnPropertyDescriptor`.
                    ? ts.createVoidZero()
                    // We emit `null` here to indicate to `__decorate` that it can invoke `Object.getOwnPropertyDescriptor` directly.
                    // We have this extra argument here so that we can inject an explicit property descriptor at a later date.
                    : ts.createNull()
                : undefined;
            var helper = createDecorateHelper(context, decoratorExpressions, prefix, memberName, descriptor, ts.moveRangePastDecorators(member));
            ts.setEmitFlags(helper, 1536 /* NoComments */);
            return helper;
        }
        /**
         * Generates a __decorate helper call for a class constructor.
         *
         * @param node The class node.
         */
        function addConstructorDecorationStatement(statements, node) {
            var expression = generateConstructorDecorationExpression(node);
            if (expression) {
                statements.push(ts.setOriginalNode(ts.createExpressionStatement(expression), node));
            }
        }
        /**
         * Generates a __decorate helper call for a class constructor.
         *
         * @param node The class node.
         */
        function generateConstructorDecorationExpression(node) {
            var allDecorators = getAllDecoratorsOfConstructor(node);
            var decoratorExpressions = transformAllDecoratorsOfDeclaration(node, node, allDecorators);
            if (!decoratorExpressions) {
                return undefined;
            }
            var classAlias = classAliases && classAliases[ts.getOriginalNodeId(node)];
            var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            var decorate = createDecorateHelper(context, decoratorExpressions, localName);
            var expression = ts.createAssignment(localName, classAlias ? ts.createAssignment(classAlias, decorate) : decorate);
            ts.setEmitFlags(expression, 1536 /* NoComments */);
            ts.setSourceMapRange(expression, ts.moveRangePastDecorators(node));
            return expression;
        }
        /**
         * Transforms a decorator into an expression.
         *
         * @param decorator The decorator node.
         */
        function transformDecorator(decorator) {
            return ts.visitNode(decorator.expression, visitor, ts.isExpression);
        }
        /**
         * Transforms the decorators of a parameter.
         *
         * @param decorators The decorators for the parameter at the provided offset.
         * @param parameterOffset The offset of the parameter.
         */
        function transformDecoratorsOfParameter(decorators, parameterOffset) {
            var expressions;
            if (decorators) {
                expressions = [];
                for (var _i = 0, decorators_1 = decorators; _i < decorators_1.length; _i++) {
                    var decorator = decorators_1[_i];
                    var helper = createParamHelper(context, transformDecorator(decorator), parameterOffset, 
                    /*location*/ decorator.expression);
                    ts.setEmitFlags(helper, 1536 /* NoComments */);
                    expressions.push(helper);
                }
            }
            return expressions;
        }
        /**
         * Adds optional type metadata for a declaration.
         *
         * @param node The declaration node.
         * @param decoratorExpressions The destination array to which to add new decorator expressions.
         */
        function addTypeMetadata(node, container, decoratorExpressions) {
            if (USE_NEW_TYPE_METADATA_FORMAT) {
                addNewTypeMetadata(node, container, decoratorExpressions);
            }
            else {
                addOldTypeMetadata(node, container, decoratorExpressions);
            }
        }
        function addOldTypeMetadata(node, container, decoratorExpressions) {
            if (compilerOptions.emitDecoratorMetadata) {
                if (shouldAddTypeMetadata(node)) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:type", serializeTypeOfNode(node)));
                }
                if (shouldAddParamTypesMetadata(node)) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:paramtypes", serializeParameterTypesOfNode(node, container)));
                }
                if (shouldAddReturnTypeMetadata(node)) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:returntype", serializeReturnTypeOfNode(node)));
                }
            }
        }
        function addNewTypeMetadata(node, container, decoratorExpressions) {
            if (compilerOptions.emitDecoratorMetadata) {
                var properties = void 0;
                if (shouldAddTypeMetadata(node)) {
                    (properties || (properties = [])).push(ts.createPropertyAssignment("type", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(37 /* EqualsGreaterThanToken */), serializeTypeOfNode(node))));
                }
                if (shouldAddParamTypesMetadata(node)) {
                    (properties || (properties = [])).push(ts.createPropertyAssignment("paramTypes", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(37 /* EqualsGreaterThanToken */), serializeParameterTypesOfNode(node, container))));
                }
                if (shouldAddReturnTypeMetadata(node)) {
                    (properties || (properties = [])).push(ts.createPropertyAssignment("returnType", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(37 /* EqualsGreaterThanToken */), serializeReturnTypeOfNode(node))));
                }
                if (properties) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:typeinfo", ts.createObjectLiteral(properties, /*multiLine*/ true)));
                }
            }
        }
        /**
         * Determines whether to emit the "design:type" metadata based on the node's kind.
         * The caller should have already tested whether the node has decorators and whether the
         * emitDecoratorMetadata compiler option is set.
         *
         * @param node The node to test.
         */
        function shouldAddTypeMetadata(node) {
            var kind = node.kind;
            return kind === 157 /* MethodDeclaration */
                || kind === 159 /* GetAccessor */
                || kind === 160 /* SetAccessor */
                || kind === 155 /* PropertyDeclaration */;
        }
        /**
         * Determines whether to emit the "design:returntype" metadata based on the node's kind.
         * The caller should have already tested whether the node has decorators and whether the
         * emitDecoratorMetadata compiler option is set.
         *
         * @param node The node to test.
         */
        function shouldAddReturnTypeMetadata(node) {
            return node.kind === 157 /* MethodDeclaration */;
        }
        /**
         * Determines whether to emit the "design:paramtypes" metadata based on the node's kind.
         * The caller should have already tested whether the node has decorators and whether the
         * emitDecoratorMetadata compiler option is set.
         *
         * @param node The node to test.
         */
        function shouldAddParamTypesMetadata(node) {
            switch (node.kind) {
                case 241 /* ClassDeclaration */:
                case 210 /* ClassExpression */:
                    return ts.getFirstConstructorWithBody(node) !== undefined;
                case 157 /* MethodDeclaration */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    return true;
            }
            return false;
        }
        function getAccessorTypeNode(node) {
            var accessors = resolver.getAllAccessorDeclarations(node);
            return accessors.setAccessor && ts.getSetAccessorTypeAnnotationNode(accessors.setAccessor)
                || accessors.getAccessor && ts.getEffectiveReturnTypeNode(accessors.getAccessor);
        }
        /**
         * Serializes the type of a node for use with decorator type metadata.
         *
         * @param node The node that should have its type serialized.
         */
        function serializeTypeOfNode(node) {
            switch (node.kind) {
                case 155 /* PropertyDeclaration */:
                case 152 /* Parameter */:
                    return serializeTypeNode(node.type);
                case 160 /* SetAccessor */:
                case 159 /* GetAccessor */:
                    return serializeTypeNode(getAccessorTypeNode(node));
                case 241 /* ClassDeclaration */:
                case 210 /* ClassExpression */:
                case 157 /* MethodDeclaration */:
                    return ts.createIdentifier("Function");
                default:
                    return ts.createVoidZero();
            }
        }
        /**
         * Serializes the types of the parameters of a node for use with decorator type metadata.
         *
         * @param node The node that should have its parameter types serialized.
         */
        function serializeParameterTypesOfNode(node, container) {
            var valueDeclaration = ts.isClassLike(node)
                ? ts.getFirstConstructorWithBody(node)
                : ts.isFunctionLike(node) && ts.nodeIsPresent(node.body)
                    ? node
                    : undefined;
            var expressions = [];
            if (valueDeclaration) {
                var parameters = getParametersOfDecoratedDeclaration(valueDeclaration, container);
                var numParameters = parameters.length;
                for (var i = 0; i < numParameters; i++) {
                    var parameter = parameters[i];
                    if (i === 0 && ts.isIdentifier(parameter.name) && parameter.name.escapedText === "this") {
                        continue;
                    }
                    if (parameter.dotDotDotToken) {
                        expressions.push(serializeTypeNode(ts.getRestParameterElementType(parameter.type)));
                    }
                    else {
                        expressions.push(serializeTypeOfNode(parameter));
                    }
                }
            }
            return ts.createArrayLiteral(expressions);
        }
        function getParametersOfDecoratedDeclaration(node, container) {
            if (container && node.kind === 159 /* GetAccessor */) {
                var setAccessor = ts.getAllAccessorDeclarations(container.members, node).setAccessor;
                if (setAccessor) {
                    return setAccessor.parameters;
                }
            }
            return node.parameters;
        }
        /**
         * Serializes the return type of a node for use with decorator type metadata.
         *
         * @param node The node that should have its return type serialized.
         */
        function serializeReturnTypeOfNode(node) {
            if (ts.isFunctionLike(node) && node.type) {
                return serializeTypeNode(node.type);
            }
            else if (ts.isAsyncFunction(node)) {
                return ts.createIdentifier("Promise");
            }
            return ts.createVoidZero();
        }
        /**
         * Serializes a type node for use with decorator type metadata.
         *
         * Types are serialized in the following fashion:
         * - Void types point to "undefined" (e.g. "void 0")
         * - Function and Constructor types point to the global "Function" constructor.
         * - Interface types with a call or construct signature types point to the global
         *   "Function" constructor.
         * - Array and Tuple types point to the global "Array" constructor.
         * - Type predicates and booleans point to the global "Boolean" constructor.
         * - String literal types and strings point to the global "String" constructor.
         * - Enum and number types point to the global "Number" constructor.
         * - Symbol types point to the global "Symbol" constructor.
         * - Type references to classes (or class-like variables) point to the constructor for the class.
         * - Anything else points to the global "Object" constructor.
         *
         * @param node The type node to serialize.
         */
        function serializeTypeNode(node) {
            if (node === undefined) {
                return ts.createIdentifier("Object");
            }
            switch (node.kind) {
                case 107 /* VoidKeyword */:
                case 142 /* UndefinedKeyword */:
                case 97 /* NullKeyword */:
                case 133 /* NeverKeyword */:
                    return ts.createVoidZero();
                case 178 /* ParenthesizedType */:
                    return serializeTypeNode(node.type);
                case 166 /* FunctionType */:
                case 167 /* ConstructorType */:
                    return ts.createIdentifier("Function");
                case 170 /* ArrayType */:
                case 171 /* TupleType */:
                    return ts.createIdentifier("Array");
                case 164 /* TypePredicate */:
                case 124 /* BooleanKeyword */:
                    return ts.createIdentifier("Boolean");
                case 139 /* StringKeyword */:
                    return ts.createIdentifier("String");
                case 137 /* ObjectKeyword */:
                    return ts.createIdentifier("Object");
                case 183 /* LiteralType */:
                    switch (node.literal.kind) {
                        case 10 /* StringLiteral */:
                            return ts.createIdentifier("String");
                        case 203 /* PrefixUnaryExpression */:
                        case 8 /* NumericLiteral */:
                            return ts.createIdentifier("Number");
                        case 9 /* BigIntLiteral */:
                            return getGlobalBigIntNameWithFallback();
                        case 103 /* TrueKeyword */:
                        case 88 /* FalseKeyword */:
                            return ts.createIdentifier("Boolean");
                        default:
                            return ts.Debug.failBadSyntaxKind(node.literal);
                    }
                case 136 /* NumberKeyword */:
                    return ts.createIdentifier("Number");
                case 147 /* BigIntKeyword */:
                    return getGlobalBigIntNameWithFallback();
                case 140 /* SymbolKeyword */:
                    return languageVersion < 2 /* ES2015 */
                        ? getGlobalSymbolNameWithFallback()
                        : ts.createIdentifier("Symbol");
                case 165 /* TypeReference */:
                    return serializeTypeReferenceNode(node);
                case 175 /* IntersectionType */:
                case 174 /* UnionType */:
                    return serializeTypeList(node.types);
                case 176 /* ConditionalType */:
                    return serializeTypeList([node.trueType, node.falseType]);
                case 180 /* TypeOperator */:
                    if (node.operator === 134 /* ReadonlyKeyword */) {
                        return serializeTypeNode(node.type);
                    }
                    break;
                case 168 /* TypeQuery */:
                case 181 /* IndexedAccessType */:
                case 182 /* MappedType */:
                case 169 /* TypeLiteral */:
                case 121 /* AnyKeyword */:
                case 144 /* UnknownKeyword */:
                case 179 /* ThisType */:
                case 184 /* ImportType */:
                    break;
                default:
                    return ts.Debug.failBadSyntaxKind(node);
            }
            return ts.createIdentifier("Object");
        }
        function serializeTypeList(types) {
            // Note when updating logic here also update getEntityNameForDecoratorMetadata
            // so that aliases can be marked as referenced
            var serializedUnion;
            for (var _i = 0, types_17 = types; _i < types_17.length; _i++) {
                var typeNode = types_17[_i];
                while (typeNode.kind === 178 /* ParenthesizedType */) {
                    typeNode = typeNode.type; // Skip parens if need be
                }
                if (typeNode.kind === 133 /* NeverKeyword */) {
                    continue; // Always elide `never` from the union/intersection if possible
                }
                if (!strictNullChecks && (typeNode.kind === 97 /* NullKeyword */ || typeNode.kind === 142 /* UndefinedKeyword */)) {
                    continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks
                }
                var serializedIndividual = serializeTypeNode(typeNode);
                if (ts.isIdentifier(serializedIndividual) && serializedIndividual.escapedText === "Object") {
                    // One of the individual is global object, return immediately
                    return serializedIndividual;
                }
                // If there exists union that is not void 0 expression, check if the the common type is identifier.
                // anything more complex and we will just default to Object
                else if (serializedUnion) {
                    // Different types
                    if (!ts.isIdentifier(serializedUnion) ||
                        !ts.isIdentifier(serializedIndividual) ||
                        serializedUnion.escapedText !== serializedIndividual.escapedText) {
                        return ts.createIdentifier("Object");
                    }
                }
                else {
                    // Initialize the union type
                    serializedUnion = serializedIndividual;
                }
            }
            // If we were able to find common type, use it
            return serializedUnion || ts.createVoidZero(); // Fallback is only hit if all union constituients are null/undefined/never
        }
        /**
         * Serializes a TypeReferenceNode to an appropriate JS constructor value for use with
         * decorator type metadata.
         *
         * @param node The type reference node.
         */
        function serializeTypeReferenceNode(node) {
            var kind = resolver.getTypeReferenceSerializationKind(node.typeName, currentNameScope || currentLexicalScope);
            switch (kind) {
                case ts.TypeReferenceSerializationKind.Unknown:
                    // From conditional type type reference that cannot be resolved is Similar to any or unknown
                    if (ts.findAncestor(node, function (n) { return n.parent && ts.isConditionalTypeNode(n.parent) && (n.parent.trueType === n || n.parent.falseType === n); })) {
                        return ts.createIdentifier("Object");
                    }
                    var serialized = serializeEntityNameAsExpressionFallback(node.typeName);
                    var temp = ts.createTempVariable(hoistVariableDeclaration);
                    return ts.createConditional(ts.createTypeCheck(ts.createAssignment(temp, serialized), "function"), temp, ts.createIdentifier("Object"));
                case ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue:
                    return serializeEntityNameAsExpression(node.typeName);
                case ts.TypeReferenceSerializationKind.VoidNullableOrNeverType:
                    return ts.createVoidZero();
                case ts.TypeReferenceSerializationKind.BigIntLikeType:
                    return getGlobalBigIntNameWithFallback();
                case ts.TypeReferenceSerializationKind.BooleanType:
                    return ts.createIdentifier("Boolean");
                case ts.TypeReferenceSerializationKind.NumberLikeType:
                    return ts.createIdentifier("Number");
                case ts.TypeReferenceSerializationKind.StringLikeType:
                    return ts.createIdentifier("String");
                case ts.TypeReferenceSerializationKind.ArrayLikeType:
                    return ts.createIdentifier("Array");
                case ts.TypeReferenceSerializationKind.ESSymbolType:
                    return languageVersion < 2 /* ES2015 */
                        ? getGlobalSymbolNameWithFallback()
                        : ts.createIdentifier("Symbol");
                case ts.TypeReferenceSerializationKind.TypeWithCallSignature:
                    return ts.createIdentifier("Function");
                case ts.TypeReferenceSerializationKind.Promise:
                    return ts.createIdentifier("Promise");
                case ts.TypeReferenceSerializationKind.ObjectType:
                    return ts.createIdentifier("Object");
                default:
                    return ts.Debug.assertNever(kind);
            }
        }
        function createCheckedValue(left, right) {
            return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(left), ts.createLiteral("undefined")), right);
        }
        /**
         * Serializes an entity name which may not exist at runtime, but whose access shouldn't throw
         *
         * @param node The entity name to serialize.
         */
        function serializeEntityNameAsExpressionFallback(node) {
            if (node.kind === 73 /* Identifier */) {
                // A -> typeof A !== undefined && A
                var copied = serializeEntityNameAsExpression(node);
                return createCheckedValue(copied, copied);
            }
            if (node.left.kind === 73 /* Identifier */) {
                // A.B -> typeof A !== undefined && A.B
                return createCheckedValue(serializeEntityNameAsExpression(node.left), serializeEntityNameAsExpression(node));
            }
            // A.B.C -> typeof A !== undefined && (_a = A.B) !== void 0 && _a.C
            var left = serializeEntityNameAsExpressionFallback(node.left);
            var temp = ts.createTempVariable(hoistVariableDeclaration);
            return ts.createLogicalAnd(ts.createLogicalAnd(left.left, ts.createStrictInequality(ts.createAssignment(temp, left.right), ts.createVoidZero())), ts.createPropertyAccess(temp, node.right));
        }
        /**
         * Serializes an entity name as an expression for decorator type metadata.
         *
         * @param node The entity name to serialize.
         */
        function serializeEntityNameAsExpression(node) {
            switch (node.kind) {
                case 73 /* Identifier */:
                    // Create a clone of the name with a new parent, and treat it as if it were
                    // a source tree node for the purposes of the checker.
                    var name = ts.getMutableClone(node);
                    name.flags &= ~8 /* Synthesized */;
                    name.original = undefined;
                    name.parent = ts.getParseTreeNode(currentLexicalScope); // ensure the parent is set to a parse tree node.
                    return name;
                case 149 /* QualifiedName */:
                    return serializeQualifiedNameAsExpression(node);
            }
        }
        /**
         * Serializes an qualified name as an expression for decorator type metadata.
         *
         * @param node The qualified name to serialize.
         * @param useFallback A value indicating whether to use logical operators to test for the
         *                    qualified name at runtime.
         */
        function serializeQualifiedNameAsExpression(node) {
            return ts.createPropertyAccess(serializeEntityNameAsExpression(node.left), node.right);
        }
        /**
         * Gets an expression that points to the global "Symbol" constructor at runtime if it is
         * available.
         */
        function getGlobalSymbolNameWithFallback() {
            return ts.createConditional(ts.createTypeCheck(ts.createIdentifier("Symbol"), "function"), ts.createIdentifier("Symbol"), ts.createIdentifier("Object"));
        }
        /**
         * Gets an expression that points to the global "BigInt" constructor at runtime if it is
         * available.
         */
        function getGlobalBigIntNameWithFallback() {
            return languageVersion < 8 /* ESNext */
                ? ts.createConditional(ts.createTypeCheck(ts.createIdentifier("BigInt"), "function"), ts.createIdentifier("BigInt"), ts.createIdentifier("Object"))
                : ts.createIdentifier("BigInt");
        }
        /**
         * A simple inlinable expression is an expression which can be copied into multiple locations
         * without risk of repeating any sideeffects and whose value could not possibly change between
         * any such locations
         */
        function isSimpleInlineableExpression(expression) {
            return !ts.isIdentifier(expression) && ts.isSimpleCopiableExpression(expression) ||
                ts.isWellKnownSymbolSyntactically(expression);
        }
        /**
         * Gets an expression that represents a property name. For a computed property, a
         * name is generated for the node.
         *
         * @param member The member whose name should be converted into an expression.
         */
        function getExpressionForPropertyName(member, generateNameForComputedPropertyName) {
            var name = member.name;
            if (ts.isComputedPropertyName(name)) {
                return generateNameForComputedPropertyName && !isSimpleInlineableExpression(name.expression)
                    ? ts.getGeneratedNameForNode(name)
                    : name.expression;
            }
            else if (ts.isIdentifier(name)) {
                return ts.createLiteral(ts.idText(name));
            }
            else {
                return ts.getSynthesizedClone(name);
            }
        }
        /**
         * If the name is a computed property, this function transforms it, then either returns an expression which caches the
         * value of the result or the expression itself if the value is either unused or safe to inline into multiple locations
         * @param shouldHoist Does the expression need to be reused? (ie, for an initializer or a decorator)
         * @param omitSimple Should expressions with no observable side-effects be elided? (ie, the expression is not hoisted for a decorator or initializer and is a literal)
         */
        function getPropertyNameExpressionIfNeeded(name, shouldHoist, omitSimple) {
            if (ts.isComputedPropertyName(name)) {
                var expression = ts.visitNode(name.expression, visitor, ts.isExpression);
                var innerExpression = ts.skipPartiallyEmittedExpressions(expression);
                var inlinable = isSimpleInlineableExpression(innerExpression);
                if (!inlinable && shouldHoist) {
                    var generatedName = ts.getGeneratedNameForNode(name);
                    hoistVariableDeclaration(generatedName);
                    return ts.createAssignment(generatedName, expression);
                }
                return (omitSimple && (inlinable || ts.isIdentifier(innerExpression))) ? undefined : expression;
            }
        }
        /**
         * Visits the property name of a class element, for use when emitting property
         * initializers. For a computed property on a node with decorators, a temporary
         * value is stored for later use.
         *
         * @param member The member whose name should be visited.
         */
        function visitPropertyNameOfClassElement(member) {
            var name = member.name;
            var expr = getPropertyNameExpressionIfNeeded(name, ts.some(member.decorators), /*omitSimple*/ false);
            if (expr) { // expr only exists if `name` is a computed property name
                // Inline any pending expressions from previous elided or relocated computed property name expressions in order to preserve execution order
                if (ts.some(pendingExpressions)) {
                    expr = ts.inlineExpressions(pendingExpressions.concat([expr]));
                    pendingExpressions.length = 0;
                }
                return ts.updateComputedPropertyName(name, expr);
            }
            else {
                return name;
            }
        }
        /**
         * Transforms a HeritageClause with TypeScript syntax.
         *
         * This function will only be called when one of the following conditions are met:
         * - The node is a non-`extends` heritage clause that should be elided.
         * - The node is an `extends` heritage clause that should be visited, but only allow a single type.
         *
         * @param node The HeritageClause to transform.
         */
        function visitHeritageClause(node) {
            if (node.token === 110 /* ImplementsKeyword */) {
                // implements clauses are elided
                return undefined;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Transforms an ExpressionWithTypeArguments with TypeScript syntax.
         *
         * This function will only be called when one of the following conditions are met:
         * - The node contains type arguments that should be elided.
         *
         * @param node The ExpressionWithTypeArguments to transform.
         */
        function visitExpressionWithTypeArguments(node) {
            return ts.updateExpressionWithTypeArguments(node, 
            /*typeArguments*/ undefined, ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression));
        }
        /**
         * Determines whether to emit a function-like declaration. We should not emit the
         * declaration if it does not have a body.
         *
         * @param node The declaration node.
         */
        function shouldEmitFunctionLikeDeclaration(node) {
            return !ts.nodeIsMissing(node.body);
        }
        function visitPropertyDeclaration(node) {
            var expr = getPropertyNameExpressionIfNeeded(node.name, ts.some(node.decorators) || !!node.initializer, /*omitSimple*/ true);
            if (expr && !isSimpleInlineableExpression(expr)) {
                (pendingExpressions || (pendingExpressions = [])).push(expr);
            }
            return undefined;
        }
        function visitConstructor(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return undefined;
            }
            return ts.updateConstructor(node, ts.visitNodes(node.decorators, visitor, ts.isDecorator), ts.visitNodes(node.modifiers, visitor, ts.isModifier), ts.visitParameterList(node.parameters, visitor, context), ts.visitFunctionBody(node.body, visitor, context));
        }
        function visitMethodDeclaration(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return undefined;
            }
            var updated = ts.updateMethod(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, visitPropertyNameOfClassElement(node), 
            /*questionToken*/ undefined, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
            }
            return updated;
        }
        /**
         * Determines whether to emit an accessor declaration. We should not emit the
         * declaration if it does not have a body and is abstract.
         *
         * @param node The declaration node.
         */
        function shouldEmitAccessorDeclaration(node) {
            return !(ts.nodeIsMissing(node.body) && ts.hasModifier(node, 128 /* Abstract */));
        }
        function visitGetAccessor(node) {
            if (!shouldEmitAccessorDeclaration(node)) {
                return undefined;
            }
            var updated = ts.updateGetAccessor(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), visitPropertyNameOfClassElement(node), ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
            }
            return updated;
        }
        function visitSetAccessor(node) {
            if (!shouldEmitAccessorDeclaration(node)) {
                return undefined;
            }
            var updated = ts.updateSetAccessor(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), visitPropertyNameOfClassElement(node), ts.visitParameterList(node.parameters, visitor, context), ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
            }
            return updated;
        }
        function visitFunctionDeclaration(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return ts.createNotEmittedStatement(node);
            }
            var updated = ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            if (isExportOfNamespace(node)) {
                var statements = [updated];
                addExportMemberAssignment(statements, node);
                return statements;
            }
            return updated;
        }
        function visitFunctionExpression(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return ts.createOmittedExpression();
            }
            var updated = ts.updateFunctionExpression(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            return updated;
        }
        function visitArrowFunction(node) {
            var updated = ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, node.equalsGreaterThanToken, ts.visitFunctionBody(node.body, visitor, context));
            return updated;
        }
        function visitParameter(node) {
            if (ts.parameterIsThisKeyword(node)) {
                return undefined;
            }
            var updated = ts.updateParameter(node, 
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, node.dotDotDotToken, ts.visitNode(node.name, visitor, ts.isBindingName), 
            /*questionToken*/ undefined, 
            /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setTextRange(updated, ts.moveRangePastModifiers(node));
                ts.setSourceMapRange(updated, ts.moveRangePastModifiers(node));
                ts.setEmitFlags(updated.name, 32 /* NoTrailingSourceMap */);
            }
            return updated;
        }
        function visitVariableStatement(node) {
            if (isExportOfNamespace(node)) {
                var variables = ts.getInitializedVariables(node.declarationList);
                if (variables.length === 0) {
                    // elide statement if there are no initialized variables.
                    return undefined;
                }
                return ts.setTextRange(ts.createExpressionStatement(ts.inlineExpressions(ts.map(variables, transformInitializedVariable))), node);
            }
            else {
                return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformInitializedVariable(node) {
            var name = node.name;
            if (ts.isBindingPattern(name)) {
                return ts.flattenDestructuringAssignment(node, visitor, context, 0 /* All */, 
                /*needsValue*/ false, createNamespaceExportExpression);
            }
            else {
                return ts.setTextRange(ts.createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(name), ts.visitNode(node.initializer, visitor, ts.isExpression)), 
                /*location*/ node);
            }
        }
        function visitVariableDeclaration(node) {
            return ts.updateVariableDeclaration(node, ts.visitNode(node.name, visitor, ts.isBindingName), 
            /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
        }
        function visitParenthesizedExpression(node) {
            var innerExpression = ts.skipOuterExpressions(node.expression, ~2 /* Assertions */);
            if (ts.isAssertionExpression(innerExpression)) {
                // Make sure we consider all nested cast expressions, e.g.:
                // (<any><number><any>-A).x;
                var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
                // We have an expression of the form: (<Type>SubExpr). Emitting this as (SubExpr)
                // is really not desirable. We would like to emit the subexpression as-is. Omitting
                // the parentheses, however, could cause change in the semantics of the generated
                // code if the casted expression has a lower precedence than the rest of the
                // expression.
                //
                // To preserve comments, we return a "PartiallyEmittedExpression" here which will
                // preserve the position information of the original expression.
                //
                // Due to the auto-parenthesization rules used by the visitor and factory functions
                // we can safely elide the parentheses here, as a new synthetic
                // ParenthesizedExpression will be inserted if we remove parentheses too
                // aggressively.
                // HOWEVER - if there are leading comments on the expression itself, to handle ASI
                // correctly for return and throw, we must keep the parenthesis
                if (ts.length(ts.getLeadingCommentRangesOfNode(expression, currentSourceFile))) {
                    return ts.updateParen(node, expression);
                }
                return ts.createPartiallyEmittedExpression(expression, node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitAssertionExpression(node) {
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            return ts.createPartiallyEmittedExpression(expression, node);
        }
        function visitNonNullExpression(node) {
            var expression = ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression);
            return ts.createPartiallyEmittedExpression(expression, node);
        }
        function visitCallExpression(node) {
            return ts.updateCall(node, ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
        }
        function visitNewExpression(node) {
            return ts.updateNew(node, ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
        }
        function visitTaggedTemplateExpression(node) {
            return ts.updateTaggedTemplate(node, ts.visitNode(node.tag, visitor, ts.isExpression), 
            /*typeArguments*/ undefined, ts.visitNode(node.template, visitor, ts.isExpression));
        }
        /**
         * Determines whether to emit an enum declaration.
         *
         * @param node The enum declaration node.
         */
        function shouldEmitEnumDeclaration(node) {
            return !ts.isEnumConst(node)
                || compilerOptions.preserveConstEnums
                || compilerOptions.isolatedModules;
        }
        /**
         * Visits an enum declaration.
         *
         * This function will be called any time a TypeScript enum is encountered.
         *
         * @param node The enum declaration node.
         */
        function visitEnumDeclaration(node) {
            if (!shouldEmitEnumDeclaration(node)) {
                return ts.createNotEmittedStatement(node);
            }
            var statements = [];
            // We request to be advised when the printer is about to print this node. This allows
            // us to set up the correct state for later substitutions.
            var emitFlags = 2 /* AdviseOnEmitNode */;
            // If needed, we should emit a variable declaration for the enum. If we emit
            // a leading variable declaration, we should not emit leading comments for the
            // enum body.
            var varAdded = addVarForEnumOrModuleDeclaration(statements, node);
            if (varAdded) {
                // We should still emit the comments if we are emitting a system module.
                if (moduleKind !== ts.ModuleKind.System || currentLexicalScope !== currentSourceFile) {
                    emitFlags |= 512 /* NoLeadingComments */;
                }
            }
            // `parameterName` is the declaration name used inside of the enum.
            var parameterName = getNamespaceParameterName(node);
            // `containerName` is the expression used inside of the enum for assignments.
            var containerName = getNamespaceContainerName(node);
            // `exportName` is the expression used within this node's container for any exported references.
            var exportName = ts.hasModifier(node, 1 /* Export */)
                ? ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true)
                : ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            //  x || (x = {})
            //  exports.x || (exports.x = {})
            var moduleArg = ts.createLogicalOr(exportName, ts.createAssignment(exportName, ts.createObjectLiteral()));
            if (hasNamespaceQualifiedExportName(node)) {
                // `localName` is the expression used within this node's containing scope for any local references.
                var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
                //  x = (exports.x || (exports.x = {}))
                moduleArg = ts.createAssignment(localName, moduleArg);
            }
            //  (function (x) {
            //      x[x["y"] = 0] = "y";
            //      ...
            //  })(x || (x = {}));
            var enumStatement = ts.createExpressionStatement(ts.createCall(ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], 
            /*type*/ undefined, transformEnumBody(node, containerName)), 
            /*typeArguments*/ undefined, [moduleArg]));
            ts.setOriginalNode(enumStatement, node);
            if (varAdded) {
                // If a variable was added, synthetic comments are emitted on it, not on the moduleStatement.
                ts.setSyntheticLeadingComments(enumStatement, undefined);
                ts.setSyntheticTrailingComments(enumStatement, undefined);
            }
            ts.setTextRange(enumStatement, node);
            ts.addEmitFlags(enumStatement, emitFlags);
            statements.push(enumStatement);
            // Add a DeclarationMarker for the enum to preserve trailing comments and mark
            // the end of the declaration.
            statements.push(ts.createEndOfDeclarationMarker(node));
            return statements;
        }
        /**
         * Transforms the body of an enum declaration.
         *
         * @param node The enum declaration node.
         */
        function transformEnumBody(node, localName) {
            var savedCurrentNamespaceLocalName = currentNamespaceContainerName;
            currentNamespaceContainerName = localName;
            var statements = [];
            startLexicalEnvironment();
            var members = ts.map(node.members, transformEnumMember);
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            ts.addRange(statements, members);
            currentNamespaceContainerName = savedCurrentNamespaceLocalName;
            return ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), /*location*/ node.members), 
            /*multiLine*/ true);
        }
        /**
         * Transforms an enum member into a statement.
         *
         * @param member The enum member node.
         */
        function transformEnumMember(member) {
            // enums don't support computed properties
            // we pass false as 'generateNameForComputedPropertyName' for a backward compatibility purposes
            // old emitter always generate 'expression' part of the name as-is.
            var name = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ false);
            var valueExpression = transformEnumMemberDeclarationValue(member);
            var innerAssignment = ts.createAssignment(ts.createElementAccess(currentNamespaceContainerName, name), valueExpression);
            var outerAssignment = valueExpression.kind === 10 /* StringLiteral */ ?
                innerAssignment :
                ts.createAssignment(ts.createElementAccess(currentNamespaceContainerName, innerAssignment), name);
            return ts.setTextRange(ts.createExpressionStatement(ts.setTextRange(outerAssignment, member)), member);
        }
        /**
         * Transforms the value of an enum member.
         *
         * @param member The enum member node.
         */
        function transformEnumMemberDeclarationValue(member) {
            var value = resolver.getConstantValue(member);
            if (value !== undefined) {
                return ts.createLiteral(value);
            }
            else {
                enableSubstitutionForNonQualifiedEnumMembers();
                if (member.initializer) {
                    return ts.visitNode(member.initializer, visitor, ts.isExpression);
                }
                else {
                    return ts.createVoidZero();
                }
            }
        }
        /**
         * Determines whether to elide a module declaration.
         *
         * @param node The module declaration node.
         */
        function shouldEmitModuleDeclaration(node) {
            return ts.isInstantiatedModule(node, !!compilerOptions.preserveConstEnums || !!compilerOptions.isolatedModules);
        }
        /**
         * Determines whether an exported declaration will have a qualified export name (e.g. `f.x`
         * or `exports.x`).
         */
        function hasNamespaceQualifiedExportName(node) {
            return isExportOfNamespace(node)
                || (isExternalModuleExport(node)
                    && moduleKind !== ts.ModuleKind.ES2015
                    && moduleKind !== ts.ModuleKind.ESNext
                    && moduleKind !== ts.ModuleKind.System);
        }
        /**
         * Records that a declaration was emitted in the current scope, if it was the first
         * declaration for the provided symbol.
         */
        function recordEmittedDeclarationInScope(node) {
            if (!currentScopeFirstDeclarationsOfName) {
                currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap();
            }
            var name = declaredNameInScope(node);
            if (!currentScopeFirstDeclarationsOfName.has(name)) {
                currentScopeFirstDeclarationsOfName.set(name, node);
            }
        }
        /**
         * Determines whether a declaration is the first declaration with
         * the same name emitted in the current scope.
         */
        function isFirstEmittedDeclarationInScope(node) {
            if (currentScopeFirstDeclarationsOfName) {
                var name = declaredNameInScope(node);
                return currentScopeFirstDeclarationsOfName.get(name) === node;
            }
            return true;
        }
        function declaredNameInScope(node) {
            ts.Debug.assertNode(node.name, ts.isIdentifier);
            return node.name.escapedText;
        }
        /**
         * Adds a leading VariableStatement for a enum or module declaration.
         */
        function addVarForEnumOrModuleDeclaration(statements, node) {
            // Emit a variable statement for the module. We emit top-level enums as a `var`
            // declaration to avoid static errors in global scripts scripts due to redeclaration.
            // enums in any other scope are emitted as a `let` declaration.
            var statement = ts.createVariableStatement(ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.createVariableDeclarationList([
                ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true))
            ], currentLexicalScope.kind === 285 /* SourceFile */ ? 0 /* None */ : 1 /* Let */));
            ts.setOriginalNode(statement, node);
            recordEmittedDeclarationInScope(node);
            if (isFirstEmittedDeclarationInScope(node)) {
                // Adjust the source map emit to match the old emitter.
                if (node.kind === 244 /* EnumDeclaration */) {
                    ts.setSourceMapRange(statement.declarationList, node);
                }
                else {
                    ts.setSourceMapRange(statement, node);
                }
                // Trailing comments for module declaration should be emitted after the function closure
                // instead of the variable statement:
                //
                //     /** Module comment*/
                //     module m1 {
                //         function foo4Export() {
                //         }
                //     } // trailing comment module
                //
                // Should emit:
                //
                //     /** Module comment*/
                //     var m1;
                //     (function (m1) {
                //         function foo4Export() {
                //         }
                //     })(m1 || (m1 = {})); // trailing comment module
                //
                ts.setCommentRange(statement, node);
                ts.addEmitFlags(statement, 1024 /* NoTrailingComments */ | 4194304 /* HasEndOfDeclarationMarker */);
                statements.push(statement);
                return true;
            }
            else {
                // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
                // declaration we do not emit a leading variable declaration. To preserve the
                // begin/end semantics of the declararation and to properly handle exports
                // we wrap the leading variable declaration in a `MergeDeclarationMarker`.
                var mergeMarker = ts.createMergeDeclarationMarker(statement);
                ts.setEmitFlags(mergeMarker, 1536 /* NoComments */ | 4194304 /* HasEndOfDeclarationMarker */);
                statements.push(mergeMarker);
                return false;
            }
        }
        /**
         * Visits a module declaration node.
         *
         * This function will be called any time a TypeScript namespace (ModuleDeclaration) is encountered.
         *
         * @param node The module declaration node.
         */
        function visitModuleDeclaration(node) {
            if (!shouldEmitModuleDeclaration(node)) {
                return ts.createNotEmittedStatement(node);
            }
            ts.Debug.assertNode(node.name, ts.isIdentifier, "A TypeScript namespace should have an Identifier name.");
            enableSubstitutionForNamespaceExports();
            var statements = [];
            // We request to be advised when the printer is about to print this node. This allows
            // us to set up the correct state for later substitutions.
            var emitFlags = 2 /* AdviseOnEmitNode */;
            // If needed, we should emit a variable declaration for the module. If we emit
            // a leading variable declaration, we should not emit leading comments for the
            // module body.
            var varAdded = addVarForEnumOrModuleDeclaration(statements, node);
            if (varAdded) {
                // We should still emit the comments if we are emitting a system module.
                if (moduleKind !== ts.ModuleKind.System || currentLexicalScope !== currentSourceFile) {
                    emitFlags |= 512 /* NoLeadingComments */;
                }
            }
            // `parameterName` is the declaration name used inside of the namespace.
            var parameterName = getNamespaceParameterName(node);
            // `containerName` is the expression used inside of the namespace for exports.
            var containerName = getNamespaceContainerName(node);
            // `exportName` is the expression used within this node's container for any exported references.
            var exportName = ts.hasModifier(node, 1 /* Export */)
                ? ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true)
                : ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            //  x || (x = {})
            //  exports.x || (exports.x = {})
            var moduleArg = ts.createLogicalOr(exportName, ts.createAssignment(exportName, ts.createObjectLiteral()));
            if (hasNamespaceQualifiedExportName(node)) {
                // `localName` is the expression used within this node's containing scope for any local references.
                var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
                //  x = (exports.x || (exports.x = {}))
                moduleArg = ts.createAssignment(localName, moduleArg);
            }
            //  (function (x_1) {
            //      x_1.y = ...;
            //  })(x || (x = {}));
            var moduleStatement = ts.createExpressionStatement(ts.createCall(ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], 
            /*type*/ undefined, transformModuleBody(node, containerName)), 
            /*typeArguments*/ undefined, [moduleArg]));
            ts.setOriginalNode(moduleStatement, node);
            if (varAdded) {
                // If a variable was added, synthetic comments are emitted on it, not on the moduleStatement.
                ts.setSyntheticLeadingComments(moduleStatement, undefined);
                ts.setSyntheticTrailingComments(moduleStatement, undefined);
            }
            ts.setTextRange(moduleStatement, node);
            ts.addEmitFlags(moduleStatement, emitFlags);
            statements.push(moduleStatement);
            // Add a DeclarationMarker for the namespace to preserve trailing comments and mark
            // the end of the declaration.
            statements.push(ts.createEndOfDeclarationMarker(node));
            return statements;
        }
        /**
         * Transforms the body of a module declaration.
         *
         * @param node The module declaration node.
         */
        function transformModuleBody(node, namespaceLocalName) {
            var savedCurrentNamespaceContainerName = currentNamespaceContainerName;
            var savedCurrentNamespace = currentNamespace;
            var savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
            currentNamespaceContainerName = namespaceLocalName;
            currentNamespace = node;
            currentScopeFirstDeclarationsOfName = undefined;
            var statements = [];
            startLexicalEnvironment();
            var statementsLocation;
            var blockLocation;
            var body = node.body;
            if (body.kind === 246 /* ModuleBlock */) {
                saveStateAndInvoke(body, function (body) { return ts.addRange(statements, ts.visitNodes(body.statements, namespaceElementVisitor, ts.isStatement)); });
                statementsLocation = body.statements;
                blockLocation = body;
            }
            else {
                var result = visitModuleDeclaration(body);
                if (result) {
                    if (ts.isArray(result)) {
                        ts.addRange(statements, result);
                    }
                    else {
                        statements.push(result);
                    }
                }
                var moduleBlock = getInnerMostModuleDeclarationFromDottedModule(node).body;
                statementsLocation = ts.moveRangePos(moduleBlock.statements, -1);
            }
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            currentNamespaceContainerName = savedCurrentNamespaceContainerName;
            currentNamespace = savedCurrentNamespace;
            currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), 
            /*location*/ statementsLocation), 
            /*multiLine*/ true);
            ts.setTextRange(block, blockLocation);
            // namespace hello.hi.world {
            //      function foo() {}
            //
            //      // TODO, blah
            // }
            //
            // should be emitted as
            //
            // var hello;
            // (function (hello) {
            //     var hi;
            //     (function (hi) {
            //         var world;
            //         (function (world) {
            //             function foo() { }
            //             // TODO, blah
            //         })(world = hi.world || (hi.world = {}));
            //     })(hi = hello.hi || (hello.hi = {}));
            // })(hello || (hello = {}));
            // We only want to emit comment on the namespace which contains block body itself, not the containing namespaces.
            if (body.kind !== 246 /* ModuleBlock */) {
                ts.setEmitFlags(block, ts.getEmitFlags(block) | 1536 /* NoComments */);
            }
            return block;
        }
        function getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration) {
            if (moduleDeclaration.body.kind === 245 /* ModuleDeclaration */) {
                var recursiveInnerModule = getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration.body);
                return recursiveInnerModule || moduleDeclaration.body;
            }
        }
        /**
         * Visits an import declaration, eliding it if it is not referenced.
         *
         * @param node The import declaration node.
         */
        function visitImportDeclaration(node) {
            if (!node.importClause) {
                // Do not elide a side-effect only import declaration.
                //  import "foo";
                return node;
            }
            // Elide the declaration if the import clause was elided.
            var importClause = ts.visitNode(node.importClause, visitImportClause, ts.isImportClause);
            return importClause
                ? ts.updateImportDeclaration(node, 
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, importClause, node.moduleSpecifier)
                : undefined;
        }
        /**
         * Visits an import clause, eliding it if it is not referenced.
         *
         * @param node The import clause node.
         */
        function visitImportClause(node) {
            // Elide the import clause if we elide both its name and its named bindings.
            var name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined;
            var namedBindings = ts.visitNode(node.namedBindings, visitNamedImportBindings, ts.isNamedImportBindings);
            return (name || namedBindings) ? ts.updateImportClause(node, name, namedBindings) : undefined;
        }
        /**
         * Visits named import bindings, eliding it if it is not referenced.
         *
         * @param node The named import bindings node.
         */
        function visitNamedImportBindings(node) {
            if (node.kind === 252 /* NamespaceImport */) {
                // Elide a namespace import if it is not referenced.
                return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
            }
            else {
                // Elide named imports if all of its import specifiers are elided.
                var elements = ts.visitNodes(node.elements, visitImportSpecifier, ts.isImportSpecifier);
                return ts.some(elements) ? ts.updateNamedImports(node, elements) : undefined;
            }
        }
        /**
         * Visits an import specifier, eliding it if it is not referenced.
         *
         * @param node The import specifier node.
         */
        function visitImportSpecifier(node) {
            // Elide an import specifier if it is not referenced.
            return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
        }
        /**
         * Visits an export assignment, eliding it if it does not contain a clause that resolves
         * to a value.
         *
         * @param node The export assignment node.
         */
        function visitExportAssignment(node) {
            // Elide the export assignment if it does not reference a value.
            return resolver.isValueAliasDeclaration(node)
                ? ts.visitEachChild(node, visitor, context)
                : undefined;
        }
        /**
         * Visits an export declaration, eliding it if it does not contain a clause that resolves
         * to a value.
         *
         * @param node The export declaration node.
         */
        function visitExportDeclaration(node) {
            if (!node.exportClause) {
                // Elide a star export if the module it references does not export a value.
                return compilerOptions.isolatedModules || resolver.moduleExportsSomeValue(node.moduleSpecifier) ? node : undefined;
            }
            if (!resolver.isValueAliasDeclaration(node)) {
                // Elide the export declaration if it does not export a value.
                return undefined;
            }
            // Elide the export declaration if all of its named exports are elided.
            var exportClause = ts.visitNode(node.exportClause, visitNamedExports, ts.isNamedExports);
            return exportClause
                ? ts.updateExportDeclaration(node, 
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, exportClause, node.moduleSpecifier)
                : undefined;
        }
        /**
         * Visits named exports, eliding it if it does not contain an export specifier that
         * resolves to a value.
         *
         * @param node The named exports node.
         */
        function visitNamedExports(node) {
            // Elide the named exports if all of its export specifiers were elided.
            var elements = ts.visitNodes(node.elements, visitExportSpecifier, ts.isExportSpecifier);
            return ts.some(elements) ? ts.updateNamedExports(node, elements) : undefined;
        }
        /**
         * Visits an export specifier, eliding it if it does not resolve to a value.
         *
         * @param node The export specifier node.
         */
        function visitExportSpecifier(node) {
            // Elide an export specifier if it does not reference a value.
            return resolver.isValueAliasDeclaration(node) ? node : undefined;
        }
        /**
         * Determines whether to emit an import equals declaration.
         *
         * @param node The import equals declaration node.
         */
        function shouldEmitImportEqualsDeclaration(node) {
            // preserve old compiler's behavior: emit 'var' for import declaration (even if we do not consider them referenced) when
            // - current file is not external module
            // - import declaration is top level and target is value imported by entity name
            return resolver.isReferencedAliasDeclaration(node)
                || (!ts.isExternalModule(currentSourceFile)
                    && resolver.isTopLevelValueImportEqualsWithEntityName(node));
        }
        /**
         * Visits an import equals declaration.
         *
         * @param node The import equals declaration node.
         */
        function visitImportEqualsDeclaration(node) {
            if (ts.isExternalModuleImportEqualsDeclaration(node)) {
                // Elide external module `import=` if it is not referenced.
                return resolver.isReferencedAliasDeclaration(node)
                    ? ts.visitEachChild(node, visitor, context)
                    : undefined;
            }
            if (!shouldEmitImportEqualsDeclaration(node)) {
                return undefined;
            }
            var moduleReference = ts.createExpressionFromEntityName(node.moduleReference);
            ts.setEmitFlags(moduleReference, 1536 /* NoComments */ | 2048 /* NoNestedComments */);
            if (isNamedExternalModuleExport(node) || !isExportOfNamespace(node)) {
                //  export var ${name} = ${moduleReference};
                //  var ${name} = ${moduleReference};
                return ts.setOriginalNode(ts.setTextRange(ts.createVariableStatement(ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.createVariableDeclarationList([
                    ts.setOriginalNode(ts.createVariableDeclaration(node.name, 
                    /*type*/ undefined, moduleReference), node)
                ])), node), node);
            }
            else {
                // exports.${name} = ${moduleReference};
                return ts.setOriginalNode(createNamespaceExport(node.name, moduleReference, node), node);
            }
        }
        /**
         * Gets a value indicating whether the node is exported from a namespace.
         *
         * @param node The node to test.
         */
        function isExportOfNamespace(node) {
            return currentNamespace !== undefined && ts.hasModifier(node, 1 /* Export */);
        }
        /**
         * Gets a value indicating whether the node is exported from an external module.
         *
         * @param node The node to test.
         */
        function isExternalModuleExport(node) {
            return currentNamespace === undefined && ts.hasModifier(node, 1 /* Export */);
        }
        /**
         * Gets a value indicating whether the node is a named export from an external module.
         *
         * @param node The node to test.
         */
        function isNamedExternalModuleExport(node) {
            return isExternalModuleExport(node)
                && !ts.hasModifier(node, 512 /* Default */);
        }
        /**
         * Gets a value indicating whether the node is the default export of an external module.
         *
         * @param node The node to test.
         */
        function isDefaultExternalModuleExport(node) {
            return isExternalModuleExport(node)
                && ts.hasModifier(node, 512 /* Default */);
        }
        /**
         * Creates a statement for the provided expression. This is used in calls to `map`.
         */
        function expressionToStatement(expression) {
            return ts.createExpressionStatement(expression);
        }
        function addExportMemberAssignment(statements, node) {
            var expression = ts.createAssignment(ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true), ts.getLocalName(node));
            ts.setSourceMapRange(expression, ts.createRange(node.name ? node.name.pos : node.pos, node.end));
            var statement = ts.createExpressionStatement(expression);
            ts.setSourceMapRange(statement, ts.createRange(-1, node.end));
            statements.push(statement);
        }
        function createNamespaceExport(exportName, exportValue, location) {
            return ts.setTextRange(ts.createExpressionStatement(ts.createAssignment(ts.getNamespaceMemberName(currentNamespaceContainerName, exportName, /*allowComments*/ false, /*allowSourceMaps*/ true), exportValue)), location);
        }
        function createNamespaceExportExpression(exportName, exportValue, location) {
            return ts.setTextRange(ts.createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue), location);
        }
        function getNamespaceMemberNameWithSourceMapsAndWithoutComments(name) {
            return ts.getNamespaceMemberName(currentNamespaceContainerName, name, /*allowComments*/ false, /*allowSourceMaps*/ true);
        }
        /**
         * Gets the declaration name used inside of a namespace or enum.
         */
        function getNamespaceParameterName(node) {
            var name = ts.getGeneratedNameForNode(node);
            ts.setSourceMapRange(name, node.name);
            return name;
        }
        /**
         * Gets the expression used to refer to a namespace or enum within the body
         * of its declaration.
         */
        function getNamespaceContainerName(node) {
            return ts.getGeneratedNameForNode(node);
        }
        /**
         * Gets a local alias for a class declaration if it is a decorated class with an internal
         * reference to the static side of the class. This is necessary to avoid issues with
         * double-binding semantics for the class name.
         */
        function getClassAliasIfNeeded(node) {
            if (resolver.getNodeCheckFlags(node) & 16777216 /* ClassWithConstructorReference */) {
                enableSubstitutionForClassAliases();
                var classAlias = ts.createUniqueName(node.name && !ts.isGeneratedIdentifier(node.name) ? ts.idText(node.name) : "default");
                classAliases[ts.getOriginalNodeId(node)] = classAlias;
                hoistVariableDeclaration(classAlias);
                return classAlias;
            }
        }
        function getClassPrototype(node) {
            return ts.createPropertyAccess(ts.getDeclarationName(node), "prototype");
        }
        function getClassMemberPrefix(node, member) {
            return ts.hasModifier(member, 32 /* Static */)
                ? ts.getDeclarationName(node)
                : getClassPrototype(node);
        }
        function enableSubstitutionForNonQualifiedEnumMembers() {
            if ((enabledSubstitutions & 8 /* NonQualifiedEnumMembers */) === 0) {
                enabledSubstitutions |= 8 /* NonQualifiedEnumMembers */;
                context.enableSubstitution(73 /* Identifier */);
            }
        }
        function enableSubstitutionForClassAliases() {
            if ((enabledSubstitutions & 1 /* ClassAliases */) === 0) {
                enabledSubstitutions |= 1 /* ClassAliases */;
                // We need to enable substitutions for identifiers. This allows us to
                // substitute class names inside of a class declaration.
                context.enableSubstitution(73 /* Identifier */);
                // Keep track of class aliases.
                classAliases = [];
            }
        }
        function enableSubstitutionForNamespaceExports() {
            if ((enabledSubstitutions & 2 /* NamespaceExports */) === 0) {
                enabledSubstitutions |= 2 /* NamespaceExports */;
                // We need to enable substitutions for identifiers and shorthand property assignments. This allows us to
                // substitute the names of exported members of a namespace.
                context.enableSubstitution(73 /* Identifier */);
                context.enableSubstitution(277 /* ShorthandPropertyAssignment */);
                // We need to be notified when entering and exiting namespaces.
                context.enableEmitNotification(245 /* ModuleDeclaration */);
            }
        }
        function isTransformedModuleDeclaration(node) {
            return ts.getOriginalNode(node).kind === 245 /* ModuleDeclaration */;
        }
        function isTransformedEnumDeclaration(node) {
            return ts.getOriginalNode(node).kind === 244 /* EnumDeclaration */;
        }
        /**
         * Hook for node emit.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            var savedApplicableSubstitutions = applicableSubstitutions;
            var savedCurrentSourceFile = currentSourceFile;
            if (ts.isSourceFile(node)) {
                currentSourceFile = node;
            }
            if (enabledSubstitutions & 2 /* NamespaceExports */ && isTransformedModuleDeclaration(node)) {
                applicableSubstitutions |= 2 /* NamespaceExports */;
            }
            if (enabledSubstitutions & 8 /* NonQualifiedEnumMembers */ && isTransformedEnumDeclaration(node)) {
                applicableSubstitutions |= 8 /* NonQualifiedEnumMembers */;
            }
            previousOnEmitNode(hint, node, emitCallback);
            applicableSubstitutions = savedApplicableSubstitutions;
            currentSourceFile = savedCurrentSourceFile;
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            else if (ts.isShorthandPropertyAssignment(node)) {
                return substituteShorthandPropertyAssignment(node);
            }
            return node;
        }
        function substituteShorthandPropertyAssignment(node) {
            if (enabledSubstitutions & 2 /* NamespaceExports */) {
                var name = node.name;
                var exportedName = trySubstituteNamespaceExportedName(name);
                if (exportedName) {
                    // A shorthand property with an assignment initializer is probably part of a
                    // destructuring assignment
                    if (node.objectAssignmentInitializer) {
                        var initializer = ts.createAssignment(exportedName, node.objectAssignmentInitializer);
                        return ts.setTextRange(ts.createPropertyAssignment(name, initializer), node);
                    }
                    return ts.setTextRange(ts.createPropertyAssignment(name, exportedName), node);
                }
            }
            return node;
        }
        function substituteExpression(node) {
            switch (node.kind) {
                case 73 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 190 /* PropertyAccessExpression */:
                    return substitutePropertyAccessExpression(node);
                case 191 /* ElementAccessExpression */:
                    return substituteElementAccessExpression(node);
            }
            return node;
        }
        function substituteExpressionIdentifier(node) {
            return trySubstituteClassAlias(node)
                || trySubstituteNamespaceExportedName(node)
                || node;
        }
        function trySubstituteClassAlias(node) {
            if (enabledSubstitutions & 1 /* ClassAliases */) {
                if (resolver.getNodeCheckFlags(node) & 33554432 /* ConstructorReferenceInClass */) {
                    // Due to the emit for class decorators, any reference to the class from inside of the class body
                    // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
                    // behavior of class names in ES6.
                    // Also, when emitting statics for class expressions, we must substitute a class alias for
                    // constructor references in static property initializers.
                    var declaration = resolver.getReferencedValueDeclaration(node);
                    if (declaration) {
                        var classAlias = classAliases[declaration.id]; // TODO: GH#18217
                        if (classAlias) {
                            var clone_1 = ts.getSynthesizedClone(classAlias);
                            ts.setSourceMapRange(clone_1, node);
                            ts.setCommentRange(clone_1, node);
                            return clone_1;
                        }
                    }
                }
            }
            return undefined;
        }
        function trySubstituteNamespaceExportedName(node) {
            // If this is explicitly a local name, do not substitute.
            if (enabledSubstitutions & applicableSubstitutions && !ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) {
                // If we are nested within a namespace declaration, we may need to qualifiy
                // an identifier that is exported from a merged namespace.
                var container = resolver.getReferencedExportContainer(node, /*prefixLocals*/ false);
                if (container && container.kind !== 285 /* SourceFile */) {
                    var substitute = (applicableSubstitutions & 2 /* NamespaceExports */ && container.kind === 245 /* ModuleDeclaration */) ||
                        (applicableSubstitutions & 8 /* NonQualifiedEnumMembers */ && container.kind === 244 /* EnumDeclaration */);
                    if (substitute) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(container), node), 
                        /*location*/ node);
                    }
                }
            }
            return undefined;
        }
        function substitutePropertyAccessExpression(node) {
            return substituteConstantValue(node);
        }
        function substituteElementAccessExpression(node) {
            return substituteConstantValue(node);
        }
        function substituteConstantValue(node) {
            var constantValue = tryGetConstEnumValue(node);
            if (constantValue !== undefined) {
                // track the constant value on the node for the printer in needsDotDotForPropertyAccess
                ts.setConstantValue(node, constantValue);
                var substitute = ts.createLiteral(constantValue);
                if (!compilerOptions.removeComments) {
                    var propertyName = ts.isPropertyAccessExpression(node)
                        ? ts.declarationNameToString(node.name)
                        : ts.getTextOfNode(node.argumentExpression);
                    ts.addSyntheticTrailingComment(substitute, 3 /* MultiLineCommentTrivia */, " " + propertyName + " ");
                }
                return substitute;
            }
            return node;
        }
        function tryGetConstEnumValue(node) {
            if (compilerOptions.isolatedModules) {
                return undefined;
            }
            return ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node) ? resolver.getConstantValue(node) : undefined;
        }
    }
    ts.transformTypeScript = transformTypeScript;
    function createDecorateHelper(context, decoratorExpressions, target, memberName, descriptor, location) {
        var argumentsArray = [];
        argumentsArray.push(ts.createArrayLiteral(decoratorExpressions, /*multiLine*/ true));
        argumentsArray.push(target);
        if (memberName) {
            argumentsArray.push(memberName);
            if (descriptor) {
                argumentsArray.push(descriptor);
            }
        }
        context.requestEmitHelper(ts.decorateHelper);
        return ts.setTextRange(ts.createCall(ts.getHelperName("__decorate"), 
        /*typeArguments*/ undefined, argumentsArray), location);
    }
    ts.decorateHelper = {
        name: "typescript:decorate",
        scoped: false,
        priority: 2,
        text: "\n            var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {\n                var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n                if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n                else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n                return c > 3 && r && Object.defineProperty(target, key, r), r;\n            };"
    };
    function createMetadataHelper(context, metadataKey, metadataValue) {
        context.requestEmitHelper(ts.metadataHelper);
        return ts.createCall(ts.getHelperName("__metadata"), 
        /*typeArguments*/ undefined, [
            ts.createLiteral(metadataKey),
            metadataValue
        ]);
    }
    ts.metadataHelper = {
        name: "typescript:metadata",
        scoped: false,
        priority: 3,
        text: "\n            var __metadata = (this && this.__metadata) || function (k, v) {\n                if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(k, v);\n            };"
    };
    function createParamHelper(context, expression, parameterOffset, location) {
        context.requestEmitHelper(ts.paramHelper);
        return ts.setTextRange(ts.createCall(ts.getHelperName("__param"), 
        /*typeArguments*/ undefined, [
            ts.createLiteral(parameterOffset),
            expression
        ]), location);
    }
    ts.paramHelper = {
        name: "typescript:param",
        scoped: false,
        priority: 4,
        text: "\n            var __param = (this && this.__param) || function (paramIndex, decorator) {\n                return function (target, key) { decorator(target, key, paramIndex); }\n            };"
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var ES2017SubstitutionFlags;
    (function (ES2017SubstitutionFlags) {
        /** Enables substitutions for async methods with `super` calls. */
        ES2017SubstitutionFlags[ES2017SubstitutionFlags["AsyncMethodsWithSuper"] = 1] = "AsyncMethodsWithSuper";
    })(ES2017SubstitutionFlags || (ES2017SubstitutionFlags = {}));
    function transformES2017(context) {
        var resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var resolver = context.getEmitResolver();
        var compilerOptions = context.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        /**
         * Keeps track of whether expression substitution has been enabled for specific edge cases.
         * They are persisted between each SourceFile transformation and should not be reset.
         */
        var enabledSubstitutions;
        /**
         * This keeps track of containers where `super` is valid, for use with
         * just-in-time substitution for `super` expressions inside of async methods.
         */
        var enclosingSuperContainerFlags = 0;
        var enclosingFunctionParameterNames;
        /**
         * Keeps track of property names accessed on super (`super.x`) within async functions.
         */
        var capturedSuperProperties;
        /** Whether the async function contains an element access on super (`super[x]`). */
        var hasSuperElementAccess;
        /** A set of node IDs for generated super accessors (variable statements). */
        var substitutedSuperAccessors = [];
        // Save the previous transformation hooks.
        var previousOnEmitNode = context.onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        // Set new transformation hooks.
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        function visitor(node) {
            if ((node.transformFlags & 32 /* ContainsES2017 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 122 /* AsyncKeyword */:
                    // ES2017 async modifier should be elided for targets < ES2017
                    return undefined;
                case 202 /* AwaitExpression */:
                    return visitAwaitExpression(node);
                case 157 /* MethodDeclaration */:
                    return visitMethodDeclaration(node);
                case 240 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 197 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                case 198 /* ArrowFunction */:
                    return visitArrowFunction(node);
                case 190 /* PropertyAccessExpression */:
                    if (capturedSuperProperties && ts.isPropertyAccessExpression(node) && node.expression.kind === 99 /* SuperKeyword */) {
                        capturedSuperProperties.set(node.name.escapedText, true);
                    }
                    return ts.visitEachChild(node, visitor, context);
                case 191 /* ElementAccessExpression */:
                    if (capturedSuperProperties && node.expression.kind === 99 /* SuperKeyword */) {
                        hasSuperElementAccess = true;
                    }
                    return ts.visitEachChild(node, visitor, context);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function asyncBodyVisitor(node) {
            if (ts.isNodeWithPossibleHoistedDeclaration(node)) {
                switch (node.kind) {
                    case 220 /* VariableStatement */:
                        return visitVariableStatementInAsyncBody(node);
                    case 226 /* ForStatement */:
                        return visitForStatementInAsyncBody(node);
                    case 227 /* ForInStatement */:
                        return visitForInStatementInAsyncBody(node);
                    case 228 /* ForOfStatement */:
                        return visitForOfStatementInAsyncBody(node);
                    case 275 /* CatchClause */:
                        return visitCatchClauseInAsyncBody(node);
                    case 219 /* Block */:
                    case 233 /* SwitchStatement */:
                    case 247 /* CaseBlock */:
                    case 272 /* CaseClause */:
                    case 273 /* DefaultClause */:
                    case 236 /* TryStatement */:
                    case 224 /* DoStatement */:
                    case 225 /* WhileStatement */:
                    case 223 /* IfStatement */:
                    case 232 /* WithStatement */:
                    case 234 /* LabeledStatement */:
                        return ts.visitEachChild(node, asyncBodyVisitor, context);
                    default:
                        return ts.Debug.assertNever(node, "Unhandled node.");
                }
            }
            return visitor(node);
        }
        function visitCatchClauseInAsyncBody(node) {
            var catchClauseNames = ts.createUnderscoreEscapedMap();
            recordDeclarationName(node.variableDeclaration, catchClauseNames); // TODO: GH#18217
            // names declared in a catch variable are block scoped
            var catchClauseUnshadowedNames;
            catchClauseNames.forEach(function (_, escapedName) {
                if (enclosingFunctionParameterNames.has(escapedName)) {
                    if (!catchClauseUnshadowedNames) {
                        catchClauseUnshadowedNames = ts.cloneMap(enclosingFunctionParameterNames);
                    }
                    catchClauseUnshadowedNames.delete(escapedName);
                }
            });
            if (catchClauseUnshadowedNames) {
                var savedEnclosingFunctionParameterNames = enclosingFunctionParameterNames;
                enclosingFunctionParameterNames = catchClauseUnshadowedNames;
                var result = ts.visitEachChild(node, asyncBodyVisitor, context);
                enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames;
                return result;
            }
            else {
                return ts.visitEachChild(node, asyncBodyVisitor, context);
            }
        }
        function visitVariableStatementInAsyncBody(node) {
            if (isVariableDeclarationListWithCollidingName(node.declarationList)) {
                var expression = visitVariableDeclarationListWithCollidingNames(node.declarationList, /*hasReceiver*/ false);
                return expression ? ts.createExpressionStatement(expression) : undefined;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitForInStatementInAsyncBody(node) {
            return ts.updateForIn(node, isVariableDeclarationListWithCollidingName(node.initializer)
                ? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)
                : ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.expression, visitor, ts.isExpression), ts.visitNode(node.statement, asyncBodyVisitor, ts.isStatement, ts.liftToBlock));
        }
        function visitForOfStatementInAsyncBody(node) {
            return ts.updateForOf(node, ts.visitNode(node.awaitModifier, visitor, ts.isToken), isVariableDeclarationListWithCollidingName(node.initializer)
                ? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)
                : ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.expression, visitor, ts.isExpression), ts.visitNode(node.statement, asyncBodyVisitor, ts.isStatement, ts.liftToBlock));
        }
        function visitForStatementInAsyncBody(node) {
            var initializer = node.initializer; // TODO: GH#18217
            return ts.updateFor(node, isVariableDeclarationListWithCollidingName(initializer)
                ? visitVariableDeclarationListWithCollidingNames(initializer, /*hasReceiver*/ false)
                : ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, visitor, ts.isExpression), ts.visitNode(node.statement, asyncBodyVisitor, ts.isStatement, ts.liftToBlock));
        }
        /**
         * Visits an AwaitExpression node.
         *
         * This function will be called any time a ES2017 await expression is encountered.
         *
         * @param node The node to visit.
         */
        function visitAwaitExpression(node) {
            return ts.setOriginalNode(ts.setTextRange(ts.createYield(
            /*asteriskToken*/ undefined, ts.visitNode(node.expression, visitor, ts.isExpression)), node), node);
        }
        /**
         * Visits a MethodDeclaration node.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked as async
         *
         * @param node The node to visit.
         */
        function visitMethodDeclaration(node) {
            return ts.updateMethod(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, 
            /*questionToken*/ undefined, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        /**
         * Visits a FunctionDeclaration node.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked async
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            return ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        /**
         * Visits a FunctionExpression node.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked async
         *
         * @param node The node to visit.
         */
        function visitFunctionExpression(node) {
            return ts.updateFunctionExpression(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        /**
         * Visits an ArrowFunction.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked async
         *
         * @param node The node to visit.
         */
        function visitArrowFunction(node) {
            return ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, node.equalsGreaterThanToken, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        function recordDeclarationName(_a, names) {
            var name = _a.name;
            if (ts.isIdentifier(name)) {
                names.set(name.escapedText, true);
            }
            else {
                for (var _i = 0, _b = name.elements; _i < _b.length; _i++) {
                    var element = _b[_i];
                    if (!ts.isOmittedExpression(element)) {
                        recordDeclarationName(element, names);
                    }
                }
            }
        }
        function isVariableDeclarationListWithCollidingName(node) {
            return !!node
                && ts.isVariableDeclarationList(node)
                && !(node.flags & 3 /* BlockScoped */)
                && node.declarations.some(collidesWithParameterName);
        }
        function visitVariableDeclarationListWithCollidingNames(node, hasReceiver) {
            hoistVariableDeclarationList(node);
            var variables = ts.getInitializedVariables(node);
            if (variables.length === 0) {
                if (hasReceiver) {
                    return ts.visitNode(ts.convertToAssignmentElementTarget(node.declarations[0].name), visitor, ts.isExpression);
                }
                return undefined;
            }
            return ts.inlineExpressions(ts.map(variables, transformInitializedVariable));
        }
        function hoistVariableDeclarationList(node) {
            ts.forEach(node.declarations, hoistVariable);
        }
        function hoistVariable(_a) {
            var name = _a.name;
            if (ts.isIdentifier(name)) {
                hoistVariableDeclaration(name);
            }
            else {
                for (var _i = 0, _b = name.elements; _i < _b.length; _i++) {
                    var element = _b[_i];
                    if (!ts.isOmittedExpression(element)) {
                        hoistVariable(element);
                    }
                }
            }
        }
        function transformInitializedVariable(node) {
            var converted = ts.setSourceMapRange(ts.createAssignment(ts.convertToAssignmentElementTarget(node.name), node.initializer), node);
            return ts.visitNode(converted, visitor, ts.isExpression);
        }
        function collidesWithParameterName(_a) {
            var name = _a.name;
            if (ts.isIdentifier(name)) {
                return enclosingFunctionParameterNames.has(name.escapedText);
            }
            else {
                for (var _i = 0, _b = name.elements; _i < _b.length; _i++) {
                    var element = _b[_i];
                    if (!ts.isOmittedExpression(element) && collidesWithParameterName(element)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function transformAsyncFunctionBody(node) {
            resumeLexicalEnvironment();
            var original = ts.getOriginalNode(node, ts.isFunctionLike);
            var nodeType = original.type;
            var promiseConstructor = languageVersion < 2 /* ES2015 */ ? getPromiseConstructor(nodeType) : undefined;
            var isArrowFunction = node.kind === 198 /* ArrowFunction */;
            var hasLexicalArguments = (resolver.getNodeCheckFlags(node) & 8192 /* CaptureArguments */) !== 0;
            // An async function is emit as an outer function that calls an inner
            // generator function. To preserve lexical bindings, we pass the current
            // `this` and `arguments` objects to `__awaiter`. The generator function
            // passed to `__awaiter` is executed inside of the callback to the
            // promise constructor.
            var savedEnclosingFunctionParameterNames = enclosingFunctionParameterNames;
            enclosingFunctionParameterNames = ts.createUnderscoreEscapedMap();
            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
                var parameter = _a[_i];
                recordDeclarationName(parameter, enclosingFunctionParameterNames);
            }
            var savedCapturedSuperProperties = capturedSuperProperties;
            var savedHasSuperElementAccess = hasSuperElementAccess;
            if (!isArrowFunction) {
                capturedSuperProperties = ts.createUnderscoreEscapedMap();
                hasSuperElementAccess = false;
            }
            var result;
            if (!isArrowFunction) {
                var statements = [];
                var statementOffset = ts.addPrologue(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
                statements.push(ts.createReturn(createAwaiterHelper(context, hasLexicalArguments, promiseConstructor, transformAsyncFunctionBodyWorker(node.body, statementOffset))));
                ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
                // Minor optimization, emit `_super` helper to capture `super` access in an arrow.
                // This step isn't needed if we eventually transform this to ES5.
                var emitSuperHelpers = languageVersion >= 2 /* ES2015 */ && resolver.getNodeCheckFlags(node) & (4096 /* AsyncMethodWithSuperBinding */ | 2048 /* AsyncMethodWithSuper */);
                if (emitSuperHelpers) {
                    enableSubstitutionForAsyncMethodsWithSuper();
                    if (ts.hasEntries(capturedSuperProperties)) {
                        var variableStatement = createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
                        substitutedSuperAccessors[ts.getNodeId(variableStatement)] = true;
                        ts.insertStatementsAfterStandardPrologue(statements, [variableStatement]);
                    }
                }
                var block = ts.createBlock(statements, /*multiLine*/ true);
                ts.setTextRange(block, node.body);
                if (emitSuperHelpers && hasSuperElementAccess) {
                    // Emit helpers for super element access expressions (`super[x]`).
                    if (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) {
                        ts.addEmitHelper(block, ts.advancedAsyncSuperHelper);
                    }
                    else if (resolver.getNodeCheckFlags(node) & 2048 /* AsyncMethodWithSuper */) {
                        ts.addEmitHelper(block, ts.asyncSuperHelper);
                    }
                }
                result = block;
            }
            else {
                var expression = createAwaiterHelper(context, hasLexicalArguments, promiseConstructor, transformAsyncFunctionBodyWorker(node.body));
                var declarations = endLexicalEnvironment();
                if (ts.some(declarations)) {
                    var block = ts.convertToFunctionBody(expression);
                    result = ts.updateBlock(block, ts.setTextRange(ts.createNodeArray(ts.concatenate(declarations, block.statements)), block.statements));
                }
                else {
                    result = expression;
                }
            }
            enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames;
            if (!isArrowFunction) {
                capturedSuperProperties = savedCapturedSuperProperties;
                hasSuperElementAccess = savedHasSuperElementAccess;
            }
            return result;
        }
        function transformAsyncFunctionBodyWorker(body, start) {
            if (ts.isBlock(body)) {
                return ts.updateBlock(body, ts.visitNodes(body.statements, asyncBodyVisitor, ts.isStatement, start));
            }
            else {
                return ts.convertToFunctionBody(ts.visitNode(body, asyncBodyVisitor, ts.isConciseBody));
            }
        }
        function getPromiseConstructor(type) {
            var typeName = type && ts.getEntityNameFromTypeNode(type);
            if (typeName && ts.isEntityName(typeName)) {
                var serializationKind = resolver.getTypeReferenceSerializationKind(typeName);
                if (serializationKind === ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue
                    || serializationKind === ts.TypeReferenceSerializationKind.Unknown) {
                    return typeName;
                }
            }
            return undefined;
        }
        function enableSubstitutionForAsyncMethodsWithSuper() {
            if ((enabledSubstitutions & 1 /* AsyncMethodsWithSuper */) === 0) {
                enabledSubstitutions |= 1 /* AsyncMethodsWithSuper */;
                // We need to enable substitutions for call, property access, and element access
                // if we need to rewrite super calls.
                context.enableSubstitution(192 /* CallExpression */);
                context.enableSubstitution(190 /* PropertyAccessExpression */);
                context.enableSubstitution(191 /* ElementAccessExpression */);
                // We need to be notified when entering and exiting declarations that bind super.
                context.enableEmitNotification(241 /* ClassDeclaration */);
                context.enableEmitNotification(157 /* MethodDeclaration */);
                context.enableEmitNotification(159 /* GetAccessor */);
                context.enableEmitNotification(160 /* SetAccessor */);
                context.enableEmitNotification(158 /* Constructor */);
                // We need to be notified when entering the generated accessor arrow functions.
                context.enableEmitNotification(220 /* VariableStatement */);
            }
        }
        /**
         * Hook for node emit.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            // If we need to support substitutions for `super` in an async method,
            // we should track it here.
            if (enabledSubstitutions & 1 /* AsyncMethodsWithSuper */ && isSuperContainer(node)) {
                var superContainerFlags = resolver.getNodeCheckFlags(node) & (2048 /* AsyncMethodWithSuper */ | 4096 /* AsyncMethodWithSuperBinding */);
                if (superContainerFlags !== enclosingSuperContainerFlags) {
                    var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
                    enclosingSuperContainerFlags = superContainerFlags;
                    previousOnEmitNode(hint, node, emitCallback);
                    enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
                    return;
                }
            }
            // Disable substitution in the generated super accessor itself.
            else if (enabledSubstitutions && substitutedSuperAccessors[ts.getNodeId(node)]) {
                var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
                enclosingSuperContainerFlags = 0;
                previousOnEmitNode(hint, node, emitCallback);
                enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
                return;
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */ && enclosingSuperContainerFlags) {
                return substituteExpression(node);
            }
            return node;
        }
        function substituteExpression(node) {
            switch (node.kind) {
                case 190 /* PropertyAccessExpression */:
                    return substitutePropertyAccessExpression(node);
                case 191 /* ElementAccessExpression */:
                    return substituteElementAccessExpression(node);
                case 192 /* CallExpression */:
                    return substituteCallExpression(node);
            }
            return node;
        }
        function substitutePropertyAccessExpression(node) {
            if (node.expression.kind === 99 /* SuperKeyword */) {
                return ts.setTextRange(ts.createPropertyAccess(ts.createFileLevelUniqueName("_super"), node.name), node);
            }
            return node;
        }
        function substituteElementAccessExpression(node) {
            if (node.expression.kind === 99 /* SuperKeyword */) {
                return createSuperElementAccessInAsyncMethod(node.argumentExpression, node);
            }
            return node;
        }
        function substituteCallExpression(node) {
            var expression = node.expression;
            if (ts.isSuperProperty(expression)) {
                var argumentExpression = ts.isPropertyAccessExpression(expression)
                    ? substitutePropertyAccessExpression(expression)
                    : substituteElementAccessExpression(expression);
                return ts.createCall(ts.createPropertyAccess(argumentExpression, "call"), 
                /*typeArguments*/ undefined, [
                    ts.createThis()
                ].concat(node.arguments));
            }
            return node;
        }
        function isSuperContainer(node) {
            var kind = node.kind;
            return kind === 241 /* ClassDeclaration */
                || kind === 158 /* Constructor */
                || kind === 157 /* MethodDeclaration */
                || kind === 159 /* GetAccessor */
                || kind === 160 /* SetAccessor */;
        }
        function createSuperElementAccessInAsyncMethod(argumentExpression, location) {
            if (enclosingSuperContainerFlags & 4096 /* AsyncMethodWithSuperBinding */) {
                return ts.setTextRange(ts.createPropertyAccess(ts.createCall(ts.createFileLevelUniqueName("_superIndex"), 
                /*typeArguments*/ undefined, [argumentExpression]), "value"), location);
            }
            else {
                return ts.setTextRange(ts.createCall(ts.createFileLevelUniqueName("_superIndex"), 
                /*typeArguments*/ undefined, [argumentExpression]), location);
            }
        }
    }
    ts.transformES2017 = transformES2017;
    /** Creates a variable named `_super` with accessor properties for the given property names. */
    function createSuperAccessVariableStatement(resolver, node, names) {
        // Create a variable declaration with a getter/setter (if binding) definition for each name:
        //   const _super = Object.create(null, { x: { get: () => super.x, set: (v) => super.x = v }, ... });
        var hasBinding = (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) !== 0;
        var accessors = [];
        names.forEach(function (_, key) {
            var name = ts.unescapeLeadingUnderscores(key);
            var getterAndSetter = [];
            getterAndSetter.push(ts.createPropertyAssignment("get", ts.createArrowFunction(
            /* modifiers */ undefined, 
            /* typeParameters */ undefined, 
            /* parameters */ [], 
            /* type */ undefined, 
            /* equalsGreaterThanToken */ undefined, ts.setEmitFlags(ts.createPropertyAccess(ts.setEmitFlags(ts.createSuper(), 4 /* NoSubstitution */), name), 4 /* NoSubstitution */))));
            if (hasBinding) {
                getterAndSetter.push(ts.createPropertyAssignment("set", ts.createArrowFunction(
                /* modifiers */ undefined, 
                /* typeParameters */ undefined, 
                /* parameters */ [
                    ts.createParameter(
                    /* decorators */ undefined, 
                    /* modifiers */ undefined, 
                    /* dotDotDotToken */ undefined, "v", 
                    /* questionToken */ undefined, 
                    /* type */ undefined, 
                    /* initializer */ undefined)
                ], 
                /* type */ undefined, 
                /* equalsGreaterThanToken */ undefined, ts.createAssignment(ts.setEmitFlags(ts.createPropertyAccess(ts.setEmitFlags(ts.createSuper(), 4 /* NoSubstitution */), name), 4 /* NoSubstitution */), ts.createIdentifier("v")))));
            }
            accessors.push(ts.createPropertyAssignment(name, ts.createObjectLiteral(getterAndSetter)));
        });
        return ts.createVariableStatement(
        /* modifiers */ undefined, ts.createVariableDeclarationList([
            ts.createVariableDeclaration(ts.createFileLevelUniqueName("_super"), 
            /* type */ undefined, ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "create"), 
            /* typeArguments */ undefined, [
                ts.createNull(),
                ts.createObjectLiteral(accessors, /* multiline */ true)
            ]))
        ], 2 /* Const */));
    }
    ts.createSuperAccessVariableStatement = createSuperAccessVariableStatement;
    ts.awaiterHelper = {
        name: "typescript:awaiter",
        scoped: false,
        priority: 5,
        text: "\n            var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n                return new (P || (P = Promise))(function (resolve, reject) {\n                    function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n                    function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n                    function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\n                    step((generator = generator.apply(thisArg, _arguments || [])).next());\n                });\n            };"
    };
    function createAwaiterHelper(context, hasLexicalArguments, promiseConstructor, body) {
        context.requestEmitHelper(ts.awaiterHelper);
        var generatorFunc = ts.createFunctionExpression(
        /*modifiers*/ undefined, ts.createToken(40 /* AsteriskToken */), 
        /*name*/ undefined, 
        /*typeParameters*/ undefined, 
        /*parameters*/ [], 
        /*type*/ undefined, body);
        // Mark this node as originally an async function
        (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= 262144 /* AsyncFunctionBody */ | 524288 /* ReuseTempVariableScope */;
        return ts.createCall(ts.getHelperName("__awaiter"), 
        /*typeArguments*/ undefined, [
            ts.createThis(),
            hasLexicalArguments ? ts.createIdentifier("arguments") : ts.createVoidZero(),
            promiseConstructor ? ts.createExpressionFromEntityName(promiseConstructor) : ts.createVoidZero(),
            generatorFunc
        ]);
    }
    ts.asyncSuperHelper = {
        name: "typescript:async-super",
        scoped: true,
        text: ts.helperString(__makeTemplateObject(["\n            const ", " = name => super[name];"], ["\n            const ", " = name => super[name];"]), "_superIndex")
    };
    ts.advancedAsyncSuperHelper = {
        name: "typescript:advanced-async-super",
        scoped: true,
        text: ts.helperString(__makeTemplateObject(["\n            const ", " = (function (geti, seti) {\n                const cache = Object.create(null);\n                return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });\n            })(name => super[name], (name, value) => super[name] = value);"], ["\n            const ", " = (function (geti, seti) {\n                const cache = Object.create(null);\n                return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });\n            })(name => super[name], (name, value) => super[name] = value);"]), "_superIndex")
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var ESNextSubstitutionFlags;
    (function (ESNextSubstitutionFlags) {
        /** Enables substitutions for async methods with `super` calls. */
        ESNextSubstitutionFlags[ESNextSubstitutionFlags["AsyncMethodsWithSuper"] = 1] = "AsyncMethodsWithSuper";
    })(ESNextSubstitutionFlags || (ESNextSubstitutionFlags = {}));
    function transformES2018(context) {
        var resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var resolver = context.getEmitResolver();
        var compilerOptions = context.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var previousOnEmitNode = context.onEmitNode;
        context.onEmitNode = onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onSubstituteNode = onSubstituteNode;
        var enabledSubstitutions;
        var enclosingFunctionFlags;
        var enclosingSuperContainerFlags = 0;
        /** Keeps track of property names accessed on super (`super.x`) within async functions. */
        var capturedSuperProperties;
        /** Whether the async function contains an element access on super (`super[x]`). */
        var hasSuperElementAccess;
        /** A set of node IDs for generated super accessors. */
        var substitutedSuperAccessors = [];
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        function visitor(node) {
            return visitorWorker(node, /*noDestructuringValue*/ false);
        }
        function visitorNoDestructuringValue(node) {
            return visitorWorker(node, /*noDestructuringValue*/ true);
        }
        function visitorNoAsyncModifier(node) {
            if (node.kind === 122 /* AsyncKeyword */) {
                return undefined;
            }
            return node;
        }
        function visitorWorker(node, noDestructuringValue) {
            if ((node.transformFlags & 16 /* ContainsES2018 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 202 /* AwaitExpression */:
                    return visitAwaitExpression(node);
                case 208 /* YieldExpression */:
                    return visitYieldExpression(node);
                case 231 /* ReturnStatement */:
                    return visitReturnStatement(node);
                case 234 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                case 189 /* ObjectLiteralExpression */:
                    return visitObjectLiteralExpression(node);
                case 205 /* BinaryExpression */:
                    return visitBinaryExpression(node, noDestructuringValue);
                case 275 /* CatchClause */:
                    return visitCatchClause(node);
                case 238 /* VariableDeclaration */:
                    return visitVariableDeclaration(node);
                case 228 /* ForOfStatement */:
                    return visitForOfStatement(node, /*outermostLabeledStatement*/ undefined);
                case 226 /* ForStatement */:
                    return visitForStatement(node);
                case 201 /* VoidExpression */:
                    return visitVoidExpression(node);
                case 158 /* Constructor */:
                    return visitConstructorDeclaration(node);
                case 157 /* MethodDeclaration */:
                    return visitMethodDeclaration(node);
                case 159 /* GetAccessor */:
                    return visitGetAccessorDeclaration(node);
                case 160 /* SetAccessor */:
                    return visitSetAccessorDeclaration(node);
                case 240 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 197 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                case 198 /* ArrowFunction */:
                    return visitArrowFunction(node);
                case 152 /* Parameter */:
                    return visitParameter(node);
                case 222 /* ExpressionStatement */:
                    return visitExpressionStatement(node);
                case 196 /* ParenthesizedExpression */:
                    return visitParenthesizedExpression(node, noDestructuringValue);
                case 190 /* PropertyAccessExpression */:
                    if (capturedSuperProperties && ts.isPropertyAccessExpression(node) && node.expression.kind === 99 /* SuperKeyword */) {
                        capturedSuperProperties.set(node.name.escapedText, true);
                    }
                    return ts.visitEachChild(node, visitor, context);
                case 191 /* ElementAccessExpression */:
                    if (capturedSuperProperties && node.expression.kind === 99 /* SuperKeyword */) {
                        hasSuperElementAccess = true;
                    }
                    return ts.visitEachChild(node, visitor, context);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitAwaitExpression(node) {
            if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
                return ts.setOriginalNode(ts.setTextRange(ts.createYield(createAwaitHelper(context, ts.visitNode(node.expression, visitor, ts.isExpression))), 
                /*location*/ node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitYieldExpression(node) {
            if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
                if (node.asteriskToken) {
                    var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
                    return ts.setOriginalNode(ts.setTextRange(ts.createYield(createAwaitHelper(context, ts.updateYield(node, node.asteriskToken, createAsyncDelegatorHelper(context, createAsyncValuesHelper(context, expression, expression), expression)))), node), node);
                }
                return ts.setOriginalNode(ts.setTextRange(ts.createYield(createDownlevelAwait(node.expression
                    ? ts.visitNode(node.expression, visitor, ts.isExpression)
                    : ts.createVoidZero())), node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitReturnStatement(node) {
            if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
                return ts.updateReturn(node, createDownlevelAwait(node.expression ? ts.visitNode(node.expression, visitor, ts.isExpression) : ts.createVoidZero()));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitLabeledStatement(node) {
            if (enclosingFunctionFlags & 2 /* Async */) {
                var statement = ts.unwrapInnermostStatementOfLabel(node);
                if (statement.kind === 228 /* ForOfStatement */ && statement.awaitModifier) {
                    return visitForOfStatement(statement, node);
                }
                return ts.restoreEnclosingLabel(ts.visitEachChild(statement, visitor, context), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function chunkObjectLiteralElements(elements) {
            var chunkObject;
            var objects = [];
            for (var _i = 0, elements_4 = elements; _i < elements_4.length; _i++) {
                var e = elements_4[_i];
                if (e.kind === 278 /* SpreadAssignment */) {
                    if (chunkObject) {
                        objects.push(ts.createObjectLiteral(chunkObject));
                        chunkObject = undefined;
                    }
                    var target = e.expression;
                    objects.push(ts.visitNode(target, visitor, ts.isExpression));
                }
                else {
                    chunkObject = ts.append(chunkObject, e.kind === 276 /* PropertyAssignment */
                        ? ts.createPropertyAssignment(e.name, ts.visitNode(e.initializer, visitor, ts.isExpression))
                        : ts.visitNode(e, visitor, ts.isObjectLiteralElementLike));
                }
            }
            if (chunkObject) {
                objects.push(ts.createObjectLiteral(chunkObject));
            }
            return objects;
        }
        function visitObjectLiteralExpression(node) {
            if (node.transformFlags & 8192 /* ContainsObjectRestOrSpread */) {
                // spread elements emit like so:
                // non-spread elements are chunked together into object literals, and then all are passed to __assign:
                //     { a, ...o, b } => __assign({a}, o, {b});
                // If the first element is a spread element, then the first argument to __assign is {}:
                //     { ...o, a, b, ...o2 } => __assign({}, o, {a, b}, o2)
                var objects = chunkObjectLiteralElements(node.properties);
                if (objects.length && objects[0].kind !== 189 /* ObjectLiteralExpression */) {
                    objects.unshift(ts.createObjectLiteral());
                }
                return createAssignHelper(context, objects);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitExpressionStatement(node) {
            return ts.visitEachChild(node, visitorNoDestructuringValue, context);
        }
        function visitParenthesizedExpression(node, noDestructuringValue) {
            return ts.visitEachChild(node, noDestructuringValue ? visitorNoDestructuringValue : visitor, context);
        }
        /**
         * Visits a BinaryExpression that contains a destructuring assignment.
         *
         * @param node A BinaryExpression node.
         */
        function visitBinaryExpression(node, noDestructuringValue) {
            if (ts.isDestructuringAssignment(node) && node.left.transformFlags & 8192 /* ContainsObjectRestOrSpread */) {
                return ts.flattenDestructuringAssignment(node, visitor, context, 1 /* ObjectRest */, !noDestructuringValue);
            }
            else if (node.operatorToken.kind === 27 /* CommaToken */) {
                return ts.updateBinary(node, ts.visitNode(node.left, visitorNoDestructuringValue, ts.isExpression), ts.visitNode(node.right, noDestructuringValue ? visitorNoDestructuringValue : visitor, ts.isExpression));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitCatchClause(node) {
            if (node.variableDeclaration &&
                ts.isBindingPattern(node.variableDeclaration.name) &&
                node.variableDeclaration.name.transformFlags & 8192 /* ContainsObjectRestOrSpread */) {
                var name = ts.getGeneratedNameForNode(node.variableDeclaration.name);
                var updatedDecl = ts.updateVariableDeclaration(node.variableDeclaration, node.variableDeclaration.name, /*type*/ undefined, name);
                var visitedBindings = ts.flattenDestructuringBinding(updatedDecl, visitor, context, 1 /* ObjectRest */);
                var block = ts.visitNode(node.block, visitor, ts.isBlock);
                if (ts.some(visitedBindings)) {
                    block = ts.updateBlock(block, [
                        ts.createVariableStatement(/*modifiers*/ undefined, visitedBindings)
                    ].concat(block.statements));
                }
                return ts.updateCatchClause(node, ts.updateVariableDeclaration(node.variableDeclaration, name, /*type*/ undefined, /*initializer*/ undefined), block);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a VariableDeclaration node with a binding pattern.
         *
         * @param node A VariableDeclaration node.
         */
        function visitVariableDeclaration(node) {
            // If we are here it is because the name contains a binding pattern with a rest somewhere in it.
            if (ts.isBindingPattern(node.name) && node.name.transformFlags & 8192 /* ContainsObjectRestOrSpread */) {
                return ts.flattenDestructuringBinding(node, visitor, context, 1 /* ObjectRest */);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitForStatement(node) {
            return ts.updateFor(node, ts.visitNode(node.initializer, visitorNoDestructuringValue, ts.isForInitializer), ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement));
        }
        function visitVoidExpression(node) {
            return ts.visitEachChild(node, visitorNoDestructuringValue, context);
        }
        /**
         * Visits a ForOfStatement and converts it into a ES2015-compatible ForOfStatement.
         *
         * @param node A ForOfStatement.
         */
        function visitForOfStatement(node, outermostLabeledStatement) {
            if (node.initializer.transformFlags & 8192 /* ContainsObjectRestOrSpread */) {
                node = transformForOfStatementWithObjectRest(node);
            }
            if (node.awaitModifier) {
                return transformForAwaitOfStatement(node, outermostLabeledStatement);
            }
            else {
                return ts.restoreEnclosingLabel(ts.visitEachChild(node, visitor, context), outermostLabeledStatement);
            }
        }
        function transformForOfStatementWithObjectRest(node) {
            var initializerWithoutParens = ts.skipParentheses(node.initializer);
            if (ts.isVariableDeclarationList(initializerWithoutParens) || ts.isAssignmentPattern(initializerWithoutParens)) {
                var bodyLocation = void 0;
                var statementsLocation = void 0;
                var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
                var statements = [ts.createForOfBindingStatement(initializerWithoutParens, temp)];
                if (ts.isBlock(node.statement)) {
                    ts.addRange(statements, node.statement.statements);
                    bodyLocation = node.statement;
                    statementsLocation = node.statement.statements;
                }
                else if (node.statement) {
                    ts.append(statements, node.statement);
                    bodyLocation = node.statement;
                    statementsLocation = node.statement;
                }
                return ts.updateForOf(node, node.awaitModifier, ts.setTextRange(ts.createVariableDeclarationList([
                    ts.setTextRange(ts.createVariableDeclaration(temp), node.initializer)
                ], 1 /* Let */), node.initializer), node.expression, ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), 
                /*multiLine*/ true), bodyLocation));
            }
            return node;
        }
        function convertForOfStatementHead(node, boundValue) {
            var binding = ts.createForOfBindingStatement(node.initializer, boundValue);
            var bodyLocation;
            var statementsLocation;
            var statements = [ts.visitNode(binding, visitor, ts.isStatement)];
            var statement = ts.visitNode(node.statement, visitor, ts.isStatement);
            if (ts.isBlock(statement)) {
                ts.addRange(statements, statement.statements);
                bodyLocation = statement;
                statementsLocation = statement.statements;
            }
            else {
                statements.push(statement);
            }
            return ts.setEmitFlags(ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), 
            /*multiLine*/ true), bodyLocation), 48 /* NoSourceMap */ | 384 /* NoTokenSourceMaps */);
        }
        function createDownlevelAwait(expression) {
            return enclosingFunctionFlags & 1 /* Generator */
                ? ts.createYield(/*asteriskToken*/ undefined, createAwaitHelper(context, expression))
                : ts.createAwait(expression);
        }
        function transformForAwaitOfStatement(node, outermostLabeledStatement) {
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            var iterator = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var result = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(iterator) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var errorRecord = ts.createUniqueName("e");
            var catchVariable = ts.getGeneratedNameForNode(errorRecord);
            var returnMethod = ts.createTempVariable(/*recordTempVariable*/ undefined);
            var callValues = createAsyncValuesHelper(context, expression, /*location*/ node.expression);
            var callNext = ts.createCall(ts.createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []);
            var getDone = ts.createPropertyAccess(result, "done");
            var getValue = ts.createPropertyAccess(result, "value");
            var callReturn = ts.createFunctionCall(returnMethod, iterator, []);
            hoistVariableDeclaration(errorRecord);
            hoistVariableDeclaration(returnMethod);
            var forStatement = ts.setEmitFlags(ts.setTextRange(ts.createFor(
            /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([
                ts.setTextRange(ts.createVariableDeclaration(iterator, /*type*/ undefined, callValues), node.expression),
                ts.createVariableDeclaration(result)
            ]), node.expression), 2097152 /* NoHoisting */), 
            /*condition*/ ts.createComma(ts.createAssignment(result, createDownlevelAwait(callNext)), ts.createLogicalNot(getDone)), 
            /*incrementor*/ undefined, 
            /*statement*/ convertForOfStatementHead(node, getValue)), 
            /*location*/ node), 256 /* NoTokenTrailingSourceMaps */);
            return ts.createTry(ts.createBlock([
                ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement)
            ]), ts.createCatchClause(ts.createVariableDeclaration(catchVariable), ts.setEmitFlags(ts.createBlock([
                ts.createExpressionStatement(ts.createAssignment(errorRecord, ts.createObjectLiteral([
                    ts.createPropertyAssignment("error", catchVariable)
                ])))
            ]), 1 /* SingleLine */)), ts.createBlock([
                ts.createTry(
                /*tryBlock*/ ts.createBlock([
                    ts.setEmitFlags(ts.createIf(ts.createLogicalAnd(ts.createLogicalAnd(result, ts.createLogicalNot(getDone)), ts.createAssignment(returnMethod, ts.createPropertyAccess(iterator, "return"))), ts.createExpressionStatement(createDownlevelAwait(callReturn))), 1 /* SingleLine */)
                ]), 
                /*catchClause*/ undefined, 
                /*finallyBlock*/ ts.setEmitFlags(ts.createBlock([
                    ts.setEmitFlags(ts.createIf(errorRecord, ts.createThrow(ts.createPropertyAccess(errorRecord, "error"))), 1 /* SingleLine */)
                ]), 1 /* SingleLine */))
            ]));
        }
        function visitParameter(node) {
            if (node.transformFlags & 8192 /* ContainsObjectRestOrSpread */) {
                // Binding patterns are converted into a generated name and are
                // evaluated inside the function body.
                return ts.updateParameter(node, 
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, node.dotDotDotToken, ts.getGeneratedNameForNode(node), 
                /*questionToken*/ undefined, 
                /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitConstructorDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = 0 /* Normal */;
            var updated = ts.updateConstructor(node, 
            /*decorators*/ undefined, node.modifiers, ts.visitParameterList(node.parameters, visitor, context), transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitGetAccessorDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = 0 /* Normal */;
            var updated = ts.updateGetAccessor(node, 
            /*decorators*/ undefined, node.modifiers, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitSetAccessorDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = 0 /* Normal */;
            var updated = ts.updateSetAccessor(node, 
            /*decorators*/ undefined, node.modifiers, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitParameterList(node.parameters, visitor, context), transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitMethodDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateMethod(node, 
            /*decorators*/ undefined, enclosingFunctionFlags & 1 /* Generator */
                ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier)
                : node.modifiers, enclosingFunctionFlags & 2 /* Async */
                ? undefined
                : node.asteriskToken, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitNode(/*questionToken*/ undefined, visitor, ts.isToken), 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */
                ? transformAsyncGeneratorFunctionBody(node)
                : transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitFunctionDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, enclosingFunctionFlags & 1 /* Generator */
                ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier)
                : node.modifiers, enclosingFunctionFlags & 2 /* Async */
                ? undefined
                : node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */
                ? transformAsyncGeneratorFunctionBody(node)
                : transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitArrowFunction(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateArrowFunction(node, node.modifiers, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, node.equalsGreaterThanToken, transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitFunctionExpression(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateFunctionExpression(node, enclosingFunctionFlags & 1 /* Generator */
                ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier)
                : node.modifiers, enclosingFunctionFlags & 2 /* Async */
                ? undefined
                : node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */
                ? transformAsyncGeneratorFunctionBody(node)
                : transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function transformAsyncGeneratorFunctionBody(node) {
            resumeLexicalEnvironment();
            var statements = [];
            var statementOffset = ts.addPrologue(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
            appendObjectRestAssignmentsIfNeeded(statements, node);
            var savedCapturedSuperProperties = capturedSuperProperties;
            var savedHasSuperElementAccess = hasSuperElementAccess;
            capturedSuperProperties = ts.createUnderscoreEscapedMap();
            hasSuperElementAccess = false;
            var returnStatement = ts.createReturn(createAsyncGeneratorHelper(context, ts.createFunctionExpression(
            /*modifiers*/ undefined, ts.createToken(40 /* AsteriskToken */), node.name && ts.getGeneratedNameForNode(node.name), 
            /*typeParameters*/ undefined, 
            /*parameters*/ [], 
            /*type*/ undefined, ts.updateBlock(node.body, ts.visitLexicalEnvironment(node.body.statements, visitor, context, statementOffset)))));
            // Minor optimization, emit `_super` helper to capture `super` access in an arrow.
            // This step isn't needed if we eventually transform this to ES5.
            var emitSuperHelpers = languageVersion >= 2 /* ES2015 */ && resolver.getNodeCheckFlags(node) & (4096 /* AsyncMethodWithSuperBinding */ | 2048 /* AsyncMethodWithSuper */);
            if (emitSuperHelpers) {
                enableSubstitutionForAsyncMethodsWithSuper();
                var variableStatement = ts.createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
                substitutedSuperAccessors[ts.getNodeId(variableStatement)] = true;
                ts.insertStatementsAfterStandardPrologue(statements, [variableStatement]);
            }
            statements.push(returnStatement);
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            var block = ts.updateBlock(node.body, statements);
            if (emitSuperHelpers && hasSuperElementAccess) {
                if (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) {
                    ts.addEmitHelper(block, ts.advancedAsyncSuperHelper);
                }
                else if (resolver.getNodeCheckFlags(node) & 2048 /* AsyncMethodWithSuper */) {
                    ts.addEmitHelper(block, ts.asyncSuperHelper);
                }
            }
            capturedSuperProperties = savedCapturedSuperProperties;
            hasSuperElementAccess = savedHasSuperElementAccess;
            return block;
        }
        function transformFunctionBody(node) {
            resumeLexicalEnvironment();
            var statementOffset = 0;
            var statements = [];
            var body = ts.visitNode(node.body, visitor, ts.isConciseBody);
            if (ts.isBlock(body)) {
                statementOffset = ts.addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor);
            }
            ts.addRange(statements, appendObjectRestAssignmentsIfNeeded(/*statements*/ undefined, node));
            var leadingStatements = endLexicalEnvironment();
            if (statementOffset > 0 || ts.some(statements) || ts.some(leadingStatements)) {
                var block = ts.convertToFunctionBody(body, /*multiLine*/ true);
                ts.insertStatementsAfterStandardPrologue(statements, leadingStatements);
                ts.addRange(statements, block.statements.slice(statementOffset));
                return ts.updateBlock(block, ts.setTextRange(ts.createNodeArray(statements), block.statements));
            }
            return body;
        }
        function appendObjectRestAssignmentsIfNeeded(statements, node) {
            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
                var parameter = _a[_i];
                if (parameter.transformFlags & 8192 /* ContainsObjectRestOrSpread */) {
                    var temp = ts.getGeneratedNameForNode(parameter);
                    var declarations = ts.flattenDestructuringBinding(parameter, visitor, context, 1 /* ObjectRest */, temp, 
                    /*doNotRecordTempVariablesInLine*/ false, 
                    /*skipInitializer*/ true);
                    if (ts.some(declarations)) {
                        var statement = ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList(declarations));
                        ts.setEmitFlags(statement, 1048576 /* CustomPrologue */);
                        statements = ts.append(statements, statement);
                    }
                }
            }
            return statements;
        }
        function enableSubstitutionForAsyncMethodsWithSuper() {
            if ((enabledSubstitutions & 1 /* AsyncMethodsWithSuper */) === 0) {
                enabledSubstitutions |= 1 /* AsyncMethodsWithSuper */;
                // We need to enable substitutions for call, property access, and element access
                // if we need to rewrite super calls.
                context.enableSubstitution(192 /* CallExpression */);
                context.enableSubstitution(190 /* PropertyAccessExpression */);
                context.enableSubstitution(191 /* ElementAccessExpression */);
                // We need to be notified when entering and exiting declarations that bind super.
                context.enableEmitNotification(241 /* ClassDeclaration */);
                context.enableEmitNotification(157 /* MethodDeclaration */);
                context.enableEmitNotification(159 /* GetAccessor */);
                context.enableEmitNotification(160 /* SetAccessor */);
                context.enableEmitNotification(158 /* Constructor */);
                // We need to be notified when entering the generated accessor arrow functions.
                context.enableEmitNotification(220 /* VariableStatement */);
            }
        }
        /**
         * Called by the printer just before a node is printed.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to be printed.
         * @param emitCallback The callback used to emit the node.
         */
        function onEmitNode(hint, node, emitCallback) {
            // If we need to support substitutions for `super` in an async method,
            // we should track it here.
            if (enabledSubstitutions & 1 /* AsyncMethodsWithSuper */ && isSuperContainer(node)) {
                var superContainerFlags = resolver.getNodeCheckFlags(node) & (2048 /* AsyncMethodWithSuper */ | 4096 /* AsyncMethodWithSuperBinding */);
                if (superContainerFlags !== enclosingSuperContainerFlags) {
                    var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
                    enclosingSuperContainerFlags = superContainerFlags;
                    previousOnEmitNode(hint, node, emitCallback);
                    enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
                    return;
                }
            }
            // Disable substitution in the generated super accessor itself.
            else if (enabledSubstitutions && substitutedSuperAccessors[ts.getNodeId(node)]) {
                var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
                enclosingSuperContainerFlags = 0;
                previousOnEmitNode(hint, node, emitCallback);
                enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
                return;
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint The context for the emitter.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */ && enclosingSuperContainerFlags) {
                return substituteExpression(node);
            }
            return node;
        }
        function substituteExpression(node) {
            switch (node.kind) {
                case 190 /* PropertyAccessExpression */:
                    return substitutePropertyAccessExpression(node);
                case 191 /* ElementAccessExpression */:
                    return substituteElementAccessExpression(node);
                case 192 /* CallExpression */:
                    return substituteCallExpression(node);
            }
            return node;
        }
        function substitutePropertyAccessExpression(node) {
            if (node.expression.kind === 99 /* SuperKeyword */) {
                return ts.setTextRange(ts.createPropertyAccess(ts.createFileLevelUniqueName("_super"), node.name), node);
            }
            return node;
        }
        function substituteElementAccessExpression(node) {
            if (node.expression.kind === 99 /* SuperKeyword */) {
                return createSuperElementAccessInAsyncMethod(node.argumentExpression, node);
            }
            return node;
        }
        function substituteCallExpression(node) {
            var expression = node.expression;
            if (ts.isSuperProperty(expression)) {
                var argumentExpression = ts.isPropertyAccessExpression(expression)
                    ? substitutePropertyAccessExpression(expression)
                    : substituteElementAccessExpression(expression);
                return ts.createCall(ts.createPropertyAccess(argumentExpression, "call"), 
                /*typeArguments*/ undefined, [
                    ts.createThis()
                ].concat(node.arguments));
            }
            return node;
        }
        function isSuperContainer(node) {
            var kind = node.kind;
            return kind === 241 /* ClassDeclaration */
                || kind === 158 /* Constructor */
                || kind === 157 /* MethodDeclaration */
                || kind === 159 /* GetAccessor */
                || kind === 160 /* SetAccessor */;
        }
        function createSuperElementAccessInAsyncMethod(argumentExpression, location) {
            if (enclosingSuperContainerFlags & 4096 /* AsyncMethodWithSuperBinding */) {
                return ts.setTextRange(ts.createPropertyAccess(ts.createCall(ts.createIdentifier("_superIndex"), 
                /*typeArguments*/ undefined, [argumentExpression]), "value"), location);
            }
            else {
                return ts.setTextRange(ts.createCall(ts.createIdentifier("_superIndex"), 
                /*typeArguments*/ undefined, [argumentExpression]), location);
            }
        }
    }
    ts.transformES2018 = transformES2018;
    ts.assignHelper = {
        name: "typescript:assign",
        scoped: false,
        priority: 1,
        text: "\n            var __assign = (this && this.__assign) || function () {\n                __assign = Object.assign || function(t) {\n                    for (var s, i = 1, n = arguments.length; i < n; i++) {\n                        s = arguments[i];\n                        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n                            t[p] = s[p];\n                    }\n                    return t;\n                };\n                return __assign.apply(this, arguments);\n            };"
    };
    function createAssignHelper(context, attributesSegments) {
        if (context.getCompilerOptions().target >= 2 /* ES2015 */) {
            return ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "assign"), 
            /*typeArguments*/ undefined, attributesSegments);
        }
        context.requestEmitHelper(ts.assignHelper);
        return ts.createCall(ts.getHelperName("__assign"), 
        /*typeArguments*/ undefined, attributesSegments);
    }
    ts.createAssignHelper = createAssignHelper;
    ts.awaitHelper = {
        name: "typescript:await",
        scoped: false,
        text: "\n            var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }"
    };
    function createAwaitHelper(context, expression) {
        context.requestEmitHelper(ts.awaitHelper);
        return ts.createCall(ts.getHelperName("__await"), /*typeArguments*/ undefined, [expression]);
    }
    ts.asyncGeneratorHelper = {
        name: "typescript:asyncGenerator",
        scoped: false,
        text: "\n            var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {\n                if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n                var g = generator.apply(thisArg, _arguments || []), i, q = [];\n                return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\n                function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\n                function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n                function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n                function fulfill(value) { resume(\"next\", value); }\n                function reject(value) { resume(\"throw\", value); }\n                function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n            };"
    };
    function createAsyncGeneratorHelper(context, generatorFunc) {
        context.requestEmitHelper(ts.awaitHelper);
        context.requestEmitHelper(ts.asyncGeneratorHelper);
        // Mark this node as originally an async function
        (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= 262144 /* AsyncFunctionBody */;
        return ts.createCall(ts.getHelperName("__asyncGenerator"), 
        /*typeArguments*/ undefined, [
            ts.createThis(),
            ts.createIdentifier("arguments"),
            generatorFunc
        ]);
    }
    ts.asyncDelegator = {
        name: "typescript:asyncDelegator",
        scoped: false,
        text: "\n            var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {\n                var i, p;\n                return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n                function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\n            };"
    };
    function createAsyncDelegatorHelper(context, expression, location) {
        context.requestEmitHelper(ts.awaitHelper);
        context.requestEmitHelper(ts.asyncDelegator);
        return ts.setTextRange(ts.createCall(ts.getHelperName("__asyncDelegator"), 
        /*typeArguments*/ undefined, [expression]), location);
    }
    ts.asyncValues = {
        name: "typescript:asyncValues",
        scoped: false,
        text: "\n            var __asyncValues = (this && this.__asyncValues) || function (o) {\n                if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n                var m = o[Symbol.asyncIterator], i;\n                return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n                function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n                function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n            };"
    };
    function createAsyncValuesHelper(context, expression, location) {
        context.requestEmitHelper(ts.asyncValues);
        return ts.setTextRange(ts.createCall(ts.getHelperName("__asyncValues"), 
        /*typeArguments*/ undefined, [expression]), location);
    }
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformES2019(context) {
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitor(node) {
            if ((node.transformFlags & 8 /* ContainsES2019 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 275 /* CatchClause */:
                    return visitCatchClause(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitCatchClause(node) {
            if (!node.variableDeclaration) {
                return ts.updateCatchClause(node, ts.createVariableDeclaration(ts.createTempVariable(/*recordTempVariable*/ undefined)), ts.visitNode(node.block, visitor, ts.isBlock));
            }
            return ts.visitEachChild(node, visitor, context);
        }
    }
    ts.transformES2019 = transformES2019;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformESNext(context) {
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitor(node) {
            if ((node.transformFlags & 4 /* ContainsESNext */) === 0) {
                return node;
            }
            switch (node.kind) {
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
    }
    ts.transformESNext = transformESNext;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformJsx(context) {
        var compilerOptions = context.getCompilerOptions();
        var currentSourceFile;
        return ts.chainBundle(transformSourceFile);
        /**
         * Transform JSX-specific syntax in a SourceFile.
         *
         * @param node A SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            currentSourceFile = node;
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        function visitor(node) {
            if (node.transformFlags & 2 /* ContainsJsx */) {
                return visitorWorker(node);
            }
            else {
                return node;
            }
        }
        function visitorWorker(node) {
            switch (node.kind) {
                case 261 /* JsxElement */:
                    return visitJsxElement(node, /*isChild*/ false);
                case 262 /* JsxSelfClosingElement */:
                    return visitJsxSelfClosingElement(node, /*isChild*/ false);
                case 265 /* JsxFragment */:
                    return visitJsxFragment(node, /*isChild*/ false);
                case 271 /* JsxExpression */:
                    return visitJsxExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformJsxChildToExpression(node) {
            switch (node.kind) {
                case 11 /* JsxText */:
                    return visitJsxText(node);
                case 271 /* JsxExpression */:
                    return visitJsxExpression(node);
                case 261 /* JsxElement */:
                    return visitJsxElement(node, /*isChild*/ true);
                case 262 /* JsxSelfClosingElement */:
                    return visitJsxSelfClosingElement(node, /*isChild*/ true);
                case 265 /* JsxFragment */:
                    return visitJsxFragment(node, /*isChild*/ true);
                default:
                    return ts.Debug.failBadSyntaxKind(node);
            }
        }
        function visitJsxElement(node, isChild) {
            return visitJsxOpeningLikeElement(node.openingElement, node.children, isChild, /*location*/ node);
        }
        function visitJsxSelfClosingElement(node, isChild) {
            return visitJsxOpeningLikeElement(node, /*children*/ undefined, isChild, /*location*/ node);
        }
        function visitJsxFragment(node, isChild) {
            return visitJsxOpeningFragment(node.openingFragment, node.children, isChild, /*location*/ node);
        }
        function visitJsxOpeningLikeElement(node, children, isChild, location) {
            var tagName = getTagName(node);
            var objectProperties;
            var attrs = node.attributes.properties;
            if (attrs.length === 0) {
                // When there are no attributes, React wants "null"
                objectProperties = ts.createNull();
            }
            else {
                // Map spans of JsxAttribute nodes into object literals and spans
                // of JsxSpreadAttribute nodes into expressions.
                var segments = ts.flatten(ts.spanMap(attrs, ts.isJsxSpreadAttribute, function (attrs, isSpread) { return isSpread
                    ? ts.map(attrs, transformJsxSpreadAttributeToExpression)
                    : ts.createObjectLiteral(ts.map(attrs, transformJsxAttributeToObjectLiteralElement)); }));
                if (ts.isJsxSpreadAttribute(attrs[0])) {
                    // We must always emit at least one object literal before a spread
                    // argument.
                    segments.unshift(ts.createObjectLiteral());
                }
                // Either emit one big object literal (no spread attribs), or
                // a call to the __assign helper.
                objectProperties = ts.singleOrUndefined(segments);
                if (!objectProperties) {
                    objectProperties = ts.createAssignHelper(context, segments);
                }
            }
            var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(currentSourceFile), compilerOptions.reactNamespace, // TODO: GH#18217
            tagName, objectProperties, ts.mapDefined(children, transformJsxChildToExpression), node, location);
            if (isChild) {
                ts.startOnNewLine(element);
            }
            return element;
        }
        function visitJsxOpeningFragment(node, children, isChild, location) {
            var element = ts.createExpressionForJsxFragment(context.getEmitResolver().getJsxFactoryEntity(currentSourceFile), compilerOptions.reactNamespace, // TODO: GH#18217
            ts.mapDefined(children, transformJsxChildToExpression), node, location);
            if (isChild) {
                ts.startOnNewLine(element);
            }
            return element;
        }
        function transformJsxSpreadAttributeToExpression(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
        function transformJsxAttributeToObjectLiteralElement(node) {
            var name = getAttributeName(node);
            var expression = transformJsxAttributeInitializer(node.initializer);
            return ts.createPropertyAssignment(name, expression);
        }
        function transformJsxAttributeInitializer(node) {
            if (node === undefined) {
                return ts.createTrue();
            }
            else if (node.kind === 10 /* StringLiteral */) {
                // Always recreate the literal to escape any escape sequences or newlines which may be in the original jsx string and which
                // Need to be escaped to be handled correctly in a normal string
                var literal = ts.createLiteral(tryDecodeEntities(node.text) || node.text);
                literal.singleQuote = node.singleQuote !== undefined ? node.singleQuote : !ts.isStringDoubleQuoted(node, currentSourceFile);
                return ts.setTextRange(literal, node);
            }
            else if (node.kind === 271 /* JsxExpression */) {
                if (node.expression === undefined) {
                    return ts.createTrue();
                }
                return visitJsxExpression(node);
            }
            else {
                return ts.Debug.failBadSyntaxKind(node);
            }
        }
        function visitJsxText(node) {
            var fixed = fixupWhitespaceAndDecodeEntities(node.text);
            return fixed === undefined ? undefined : ts.createLiteral(fixed);
        }
        /**
         * JSX trims whitespace at the end and beginning of lines, except that the
         * start/end of a tag is considered a start/end of a line only if that line is
         * on the same line as the closing tag. See examples in
         * tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx
         * See also https://www.w3.org/TR/html4/struct/text.html#h-9.1 and https://www.w3.org/TR/CSS2/text.html#white-space-model
         *
         * An equivalent algorithm would be:
         * - If there is only one line, return it.
         * - If there is only whitespace (but multiple lines), return `undefined`.
         * - Split the text into lines.
         * - 'trimRight' the first line, 'trimLeft' the last line, 'trim' middle lines.
         * - Decode entities on each line (individually).
         * - Remove empty lines and join the rest with " ".
         */
        function fixupWhitespaceAndDecodeEntities(text) {
            var acc;
            // First non-whitespace character on this line.
            var firstNonWhitespace = 0;
            // Last non-whitespace character on this line.
            var lastNonWhitespace = -1;
            // These initial values are special because the first line is:
            // firstNonWhitespace = 0 to indicate that we want leading whitsepace,
            // but lastNonWhitespace = -1 as a special flag to indicate that we *don't* include the line if it's all whitespace.
            for (var i = 0; i < text.length; i++) {
                var c = text.charCodeAt(i);
                if (ts.isLineBreak(c)) {
                    // If we've seen any non-whitespace characters on this line, add the 'trim' of the line.
                    // (lastNonWhitespace === -1 is a special flag to detect whether the first line is all whitespace.)
                    if (firstNonWhitespace !== -1 && lastNonWhitespace !== -1) {
                        acc = addLineOfJsxText(acc, text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1));
                    }
                    // Reset firstNonWhitespace for the next line.
                    // Don't bother to reset lastNonWhitespace because we ignore it if firstNonWhitespace = -1.
                    firstNonWhitespace = -1;
                }
                else if (!ts.isWhiteSpaceSingleLine(c)) {
                    lastNonWhitespace = i;
                    if (firstNonWhitespace === -1) {
                        firstNonWhitespace = i;
                    }
                }
            }
            return firstNonWhitespace !== -1
                // Last line had a non-whitespace character. Emit the 'trimLeft', meaning keep trailing whitespace.
                ? addLineOfJsxText(acc, text.substr(firstNonWhitespace))
                // Last line was all whitespace, so ignore it
                : acc;
        }
        function addLineOfJsxText(acc, trimmedLine) {
            // We do not escape the string here as that is handled by the printer
            // when it emits the literal. We do, however, need to decode JSX entities.
            var decoded = decodeEntities(trimmedLine);
            return acc === undefined ? decoded : acc + " " + decoded;
        }
        /**
         * Replace entities like "&nbsp;", "&#123;", and "&#xDEADBEEF;" with the characters they encode.
         * See https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
         */
        function decodeEntities(text) {
            return text.replace(/&((#((\d+)|x([\da-fA-F]+)))|(\w+));/g, function (match, _all, _number, _digits, decimal, hex, word) {
                if (decimal) {
                    return String.fromCharCode(parseInt(decimal, 10));
                }
                else if (hex) {
                    return String.fromCharCode(parseInt(hex, 16));
                }
                else {
                    var ch = entities.get(word);
                    // If this is not a valid entity, then just use `match` (replace it with itself, i.e. don't replace)
                    return ch ? String.fromCharCode(ch) : match;
                }
            });
        }
        /** Like `decodeEntities` but returns `undefined` if there were no entities to decode. */
        function tryDecodeEntities(text) {
            var decoded = decodeEntities(text);
            return decoded === text ? undefined : decoded;
        }
        function getTagName(node) {
            if (node.kind === 261 /* JsxElement */) {
                return getTagName(node.openingElement);
            }
            else {
                var name = node.tagName;
                if (ts.isIdentifier(name) && ts.isIntrinsicJsxName(name.escapedText)) {
                    return ts.createLiteral(ts.idText(name));
                }
                else {
                    return ts.createExpressionFromEntityName(name);
                }
            }
        }
        /**
         * Emit an attribute name, which is quoted if it needs to be quoted. Because
         * these emit into an object literal property name, we don't need to be worried
         * about keywords, just non-identifier characters
         */
        function getAttributeName(node) {
            var name = node.name;
            var text = ts.idText(name);
            if (/^[A-Za-z_]\w*$/.test(text)) {
                return name;
            }
            else {
                return ts.createLiteral(text);
            }
        }
        function visitJsxExpression(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
    }
    ts.transformJsx = transformJsx;
    var entities = ts.createMapFromTemplate({
        quot: 0x0022,
        amp: 0x0026,
        apos: 0x0027,
        lt: 0x003C,
        gt: 0x003E,
        nbsp: 0x00A0,
        iexcl: 0x00A1,
        cent: 0x00A2,
        pound: 0x00A3,
        curren: 0x00A4,
        yen: 0x00A5,
        brvbar: 0x00A6,
        sect: 0x00A7,
        uml: 0x00A8,
        copy: 0x00A9,
        ordf: 0x00AA,
        laquo: 0x00AB,
        not: 0x00AC,
        shy: 0x00AD,
        reg: 0x00AE,
        macr: 0x00AF,
        deg: 0x00B0,
        plusmn: 0x00B1,
        sup2: 0x00B2,
        sup3: 0x00B3,
        acute: 0x00B4,
        micro: 0x00B5,
        para: 0x00B6,
        middot: 0x00B7,
        cedil: 0x00B8,
        sup1: 0x00B9,
        ordm: 0x00BA,
        raquo: 0x00BB,
        frac14: 0x00BC,
        frac12: 0x00BD,
        frac34: 0x00BE,
        iquest: 0x00BF,
        Agrave: 0x00C0,
        Aacute: 0x00C1,
        Acirc: 0x00C2,
        Atilde: 0x00C3,
        Auml: 0x00C4,
        Aring: 0x00C5,
        AElig: 0x00C6,
        Ccedil: 0x00C7,
        Egrave: 0x00C8,
        Eacute: 0x00C9,
        Ecirc: 0x00CA,
        Euml: 0x00CB,
        Igrave: 0x00CC,
        Iacute: 0x00CD,
        Icirc: 0x00CE,
        Iuml: 0x00CF,
        ETH: 0x00D0,
        Ntilde: 0x00D1,
        Ograve: 0x00D2,
        Oacute: 0x00D3,
        Ocirc: 0x00D4,
        Otilde: 0x00D5,
        Ouml: 0x00D6,
        times: 0x00D7,
        Oslash: 0x00D8,
        Ugrave: 0x00D9,
        Uacute: 0x00DA,
        Ucirc: 0x00DB,
        Uuml: 0x00DC,
        Yacute: 0x00DD,
        THORN: 0x00DE,
        szlig: 0x00DF,
        agrave: 0x00E0,
        aacute: 0x00E1,
        acirc: 0x00E2,
        atilde: 0x00E3,
        auml: 0x00E4,
        aring: 0x00E5,
        aelig: 0x00E6,
        ccedil: 0x00E7,
        egrave: 0x00E8,
        eacute: 0x00E9,
        ecirc: 0x00EA,
        euml: 0x00EB,
        igrave: 0x00EC,
        iacute: 0x00ED,
        icirc: 0x00EE,
        iuml: 0x00EF,
        eth: 0x00F0,
        ntilde: 0x00F1,
        ograve: 0x00F2,
        oacute: 0x00F3,
        ocirc: 0x00F4,
        otilde: 0x00F5,
        ouml: 0x00F6,
        divide: 0x00F7,
        oslash: 0x00F8,
        ugrave: 0x00F9,
        uacute: 0x00FA,
        ucirc: 0x00FB,
        uuml: 0x00FC,
        yacute: 0x00FD,
        thorn: 0x00FE,
        yuml: 0x00FF,
        OElig: 0x0152,
        oelig: 0x0153,
        Scaron: 0x0160,
        scaron: 0x0161,
        Yuml: 0x0178,
        fnof: 0x0192,
        circ: 0x02C6,
        tilde: 0x02DC,
        Alpha: 0x0391,
        Beta: 0x0392,
        Gamma: 0x0393,
        Delta: 0x0394,
        Epsilon: 0x0395,
        Zeta: 0x0396,
        Eta: 0x0397,
        Theta: 0x0398,
        Iota: 0x0399,
        Kappa: 0x039A,
        Lambda: 0x039B,
        Mu: 0x039C,
        Nu: 0x039D,
        Xi: 0x039E,
        Omicron: 0x039F,
        Pi: 0x03A0,
        Rho: 0x03A1,
        Sigma: 0x03A3,
        Tau: 0x03A4,
        Upsilon: 0x03A5,
        Phi: 0x03A6,
        Chi: 0x03A7,
        Psi: 0x03A8,
        Omega: 0x03A9,
        alpha: 0x03B1,
        beta: 0x03B2,
        gamma: 0x03B3,
        delta: 0x03B4,
        epsilon: 0x03B5,
        zeta: 0x03B6,
        eta: 0x03B7,
        theta: 0x03B8,
        iota: 0x03B9,
        kappa: 0x03BA,
        lambda: 0x03BB,
        mu: 0x03BC,
        nu: 0x03BD,
        xi: 0x03BE,
        omicron: 0x03BF,
        pi: 0x03C0,
        rho: 0x03C1,
        sigmaf: 0x03C2,
        sigma: 0x03C3,
        tau: 0x03C4,
        upsilon: 0x03C5,
        phi: 0x03C6,
        chi: 0x03C7,
        psi: 0x03C8,
        omega: 0x03C9,
        thetasym: 0x03D1,
        upsih: 0x03D2,
        piv: 0x03D6,
        ensp: 0x2002,
        emsp: 0x2003,
        thinsp: 0x2009,
        zwnj: 0x200C,
        zwj: 0x200D,
        lrm: 0x200E,
        rlm: 0x200F,
        ndash: 0x2013,
        mdash: 0x2014,
        lsquo: 0x2018,
        rsquo: 0x2019,
        sbquo: 0x201A,
        ldquo: 0x201C,
        rdquo: 0x201D,
        bdquo: 0x201E,
        dagger: 0x2020,
        Dagger: 0x2021,
        bull: 0x2022,
        hellip: 0x2026,
        permil: 0x2030,
        prime: 0x2032,
        Prime: 0x2033,
        lsaquo: 0x2039,
        rsaquo: 0x203A,
        oline: 0x203E,
        frasl: 0x2044,
        euro: 0x20AC,
        image: 0x2111,
        weierp: 0x2118,
        real: 0x211C,
        trade: 0x2122,
        alefsym: 0x2135,
        larr: 0x2190,
        uarr: 0x2191,
        rarr: 0x2192,
        darr: 0x2193,
        harr: 0x2194,
        crarr: 0x21B5,
        lArr: 0x21D0,
        uArr: 0x21D1,
        rArr: 0x21D2,
        dArr: 0x21D3,
        hArr: 0x21D4,
        forall: 0x2200,
        part: 0x2202,
        exist: 0x2203,
        empty: 0x2205,
        nabla: 0x2207,
        isin: 0x2208,
        notin: 0x2209,
        ni: 0x220B,
        prod: 0x220F,
        sum: 0x2211,
        minus: 0x2212,
        lowast: 0x2217,
        radic: 0x221A,
        prop: 0x221D,
        infin: 0x221E,
        ang: 0x2220,
        and: 0x2227,
        or: 0x2228,
        cap: 0x2229,
        cup: 0x222A,
        int: 0x222B,
        there4: 0x2234,
        sim: 0x223C,
        cong: 0x2245,
        asymp: 0x2248,
        ne: 0x2260,
        equiv: 0x2261,
        le: 0x2264,
        ge: 0x2265,
        sub: 0x2282,
        sup: 0x2283,
        nsub: 0x2284,
        sube: 0x2286,
        supe: 0x2287,
        oplus: 0x2295,
        otimes: 0x2297,
        perp: 0x22A5,
        sdot: 0x22C5,
        lceil: 0x2308,
        rceil: 0x2309,
        lfloor: 0x230A,
        rfloor: 0x230B,
        lang: 0x2329,
        rang: 0x232A,
        loz: 0x25CA,
        spades: 0x2660,
        clubs: 0x2663,
        hearts: 0x2665,
        diams: 0x2666
    });
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformES2016(context) {
        var hoistVariableDeclaration = context.hoistVariableDeclaration;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitor(node) {
            if ((node.transformFlags & 64 /* ContainsES2016 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 205 /* BinaryExpression */:
                    return visitBinaryExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitBinaryExpression(node) {
            switch (node.operatorToken.kind) {
                case 64 /* AsteriskAsteriskEqualsToken */:
                    return visitExponentiationAssignmentExpression(node);
                case 41 /* AsteriskAsteriskToken */:
                    return visitExponentiationExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitExponentiationAssignmentExpression(node) {
            var target;
            var value;
            var left = ts.visitNode(node.left, visitor, ts.isExpression);
            var right = ts.visitNode(node.right, visitor, ts.isExpression);
            if (ts.isElementAccessExpression(left)) {
                // Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)`
                var expressionTemp = ts.createTempVariable(hoistVariableDeclaration);
                var argumentExpressionTemp = ts.createTempVariable(hoistVariableDeclaration);
                target = ts.setTextRange(ts.createElementAccess(ts.setTextRange(ts.createAssignment(expressionTemp, left.expression), left.expression), ts.setTextRange(ts.createAssignment(argumentExpressionTemp, left.argumentExpression), left.argumentExpression)), left);
                value = ts.setTextRange(ts.createElementAccess(expressionTemp, argumentExpressionTemp), left);
            }
            else if (ts.isPropertyAccessExpression(left)) {
                // Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)`
                var expressionTemp = ts.createTempVariable(hoistVariableDeclaration);
                target = ts.setTextRange(ts.createPropertyAccess(ts.setTextRange(ts.createAssignment(expressionTemp, left.expression), left.expression), left.name), left);
                value = ts.setTextRange(ts.createPropertyAccess(expressionTemp, left.name), left);
            }
            else {
                // Transforms `a **= b` into `a = Math.pow(a, b)`
                target = left;
                value = left;
            }
            return ts.setTextRange(ts.createAssignment(target, ts.createMathPow(value, right, /*location*/ node)), node);
        }
        function visitExponentiationExpression(node) {
            // Transforms `a ** b` into `Math.pow(a, b)`
            var left = ts.visitNode(node.left, visitor, ts.isExpression);
            var right = ts.visitNode(node.right, visitor, ts.isExpression);
            return ts.createMathPow(left, right, /*location*/ node);
        }
    }
    ts.transformES2016 = transformES2016;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var ES2015SubstitutionFlags;
    (function (ES2015SubstitutionFlags) {
        /** Enables substitutions for captured `this` */
        ES2015SubstitutionFlags[ES2015SubstitutionFlags["CapturedThis"] = 1] = "CapturedThis";
        /** Enables substitutions for block-scoped bindings. */
        ES2015SubstitutionFlags[ES2015SubstitutionFlags["BlockScopedBindings"] = 2] = "BlockScopedBindings";
    })(ES2015SubstitutionFlags || (ES2015SubstitutionFlags = {}));
    var LoopOutParameterFlags;
    (function (LoopOutParameterFlags) {
        LoopOutParameterFlags[LoopOutParameterFlags["Body"] = 1] = "Body";
        LoopOutParameterFlags[LoopOutParameterFlags["Initializer"] = 2] = "Initializer";
    })(LoopOutParameterFlags || (LoopOutParameterFlags = {}));
    var CopyDirection;
    (function (CopyDirection) {
        CopyDirection[CopyDirection["ToOriginal"] = 0] = "ToOriginal";
        CopyDirection[CopyDirection["ToOutParameter"] = 1] = "ToOutParameter";
    })(CopyDirection || (CopyDirection = {}));
    var Jump;
    (function (Jump) {
        Jump[Jump["Break"] = 2] = "Break";
        Jump[Jump["Continue"] = 4] = "Continue";
        Jump[Jump["Return"] = 8] = "Return";
    })(Jump || (Jump = {}));
    // Facts we track as we traverse the tree
    var HierarchyFacts;
    (function (HierarchyFacts) {
        HierarchyFacts[HierarchyFacts["None"] = 0] = "None";
        //
        // Ancestor facts
        //
        HierarchyFacts[HierarchyFacts["Function"] = 1] = "Function";
        HierarchyFacts[HierarchyFacts["ArrowFunction"] = 2] = "ArrowFunction";
        HierarchyFacts[HierarchyFacts["AsyncFunctionBody"] = 4] = "AsyncFunctionBody";
        HierarchyFacts[HierarchyFacts["NonStaticClassElement"] = 8] = "NonStaticClassElement";
        HierarchyFacts[HierarchyFacts["CapturesThis"] = 16] = "CapturesThis";
        HierarchyFacts[HierarchyFacts["ExportedVariableStatement"] = 32] = "ExportedVariableStatement";
        HierarchyFacts[HierarchyFacts["TopLevel"] = 64] = "TopLevel";
        HierarchyFacts[HierarchyFacts["Block"] = 128] = "Block";
        HierarchyFacts[HierarchyFacts["IterationStatement"] = 256] = "IterationStatement";
        HierarchyFacts[HierarchyFacts["IterationStatementBlock"] = 512] = "IterationStatementBlock";
        HierarchyFacts[HierarchyFacts["IterationContainer"] = 1024] = "IterationContainer";
        HierarchyFacts[HierarchyFacts["ForStatement"] = 2048] = "ForStatement";
        HierarchyFacts[HierarchyFacts["ForInOrForOfStatement"] = 4096] = "ForInOrForOfStatement";
        HierarchyFacts[HierarchyFacts["ConstructorWithCapturedSuper"] = 8192] = "ConstructorWithCapturedSuper";
        // NOTE: do not add more ancestor flags without also updating AncestorFactsMask below.
        // NOTE: when adding a new ancestor flag, be sure to update the subtree flags below.
        //
        // Ancestor masks
        //
        HierarchyFacts[HierarchyFacts["AncestorFactsMask"] = 16383] = "AncestorFactsMask";
        // We are always in *some* kind of block scope, but only specific block-scope containers are
        // top-level or Blocks.
        HierarchyFacts[HierarchyFacts["BlockScopeIncludes"] = 0] = "BlockScopeIncludes";
        HierarchyFacts[HierarchyFacts["BlockScopeExcludes"] = 7104] = "BlockScopeExcludes";
        // A source file is a top-level block scope.
        HierarchyFacts[HierarchyFacts["SourceFileIncludes"] = 64] = "SourceFileIncludes";
        HierarchyFacts[HierarchyFacts["SourceFileExcludes"] = 8064] = "SourceFileExcludes";
        // Functions, methods, and accessors are both new lexical scopes and new block scopes.
        HierarchyFacts[HierarchyFacts["FunctionIncludes"] = 65] = "FunctionIncludes";
        HierarchyFacts[HierarchyFacts["FunctionExcludes"] = 16286] = "FunctionExcludes";
        HierarchyFacts[HierarchyFacts["AsyncFunctionBodyIncludes"] = 69] = "AsyncFunctionBodyIncludes";
        HierarchyFacts[HierarchyFacts["AsyncFunctionBodyExcludes"] = 16278] = "AsyncFunctionBodyExcludes";
        // Arrow functions are lexically scoped to their container, but are new block scopes.
        HierarchyFacts[HierarchyFacts["ArrowFunctionIncludes"] = 66] = "ArrowFunctionIncludes";
        HierarchyFacts[HierarchyFacts["ArrowFunctionExcludes"] = 15232] = "ArrowFunctionExcludes";
        // Constructors are both new lexical scopes and new block scopes. Constructors are also
        // always considered non-static members of a class.
        HierarchyFacts[HierarchyFacts["ConstructorIncludes"] = 73] = "ConstructorIncludes";
        HierarchyFacts[HierarchyFacts["ConstructorExcludes"] = 16278] = "ConstructorExcludes";
        // 'do' and 'while' statements are not block scopes. We track that the subtree is contained
        // within an IterationStatement to indicate whether the embedded statement is an
        // IterationStatementBlock.
        HierarchyFacts[HierarchyFacts["DoOrWhileStatementIncludes"] = 1280] = "DoOrWhileStatementIncludes";
        HierarchyFacts[HierarchyFacts["DoOrWhileStatementExcludes"] = 0] = "DoOrWhileStatementExcludes";
        // 'for' statements are new block scopes and have special handling for 'let' declarations.
        HierarchyFacts[HierarchyFacts["ForStatementIncludes"] = 3328] = "ForStatementIncludes";
        HierarchyFacts[HierarchyFacts["ForStatementExcludes"] = 5056] = "ForStatementExcludes";
        // 'for-in' and 'for-of' statements are new block scopes and have special handling for
        // 'let' declarations.
        HierarchyFacts[HierarchyFacts["ForInOrForOfStatementIncludes"] = 5376] = "ForInOrForOfStatementIncludes";
        HierarchyFacts[HierarchyFacts["ForInOrForOfStatementExcludes"] = 3008] = "ForInOrForOfStatementExcludes";
        // Blocks (other than function bodies) are new block scopes.
        HierarchyFacts[HierarchyFacts["BlockIncludes"] = 128] = "BlockIncludes";
        HierarchyFacts[HierarchyFacts["BlockExcludes"] = 6976] = "BlockExcludes";
        HierarchyFacts[HierarchyFacts["IterationStatementBlockIncludes"] = 512] = "IterationStatementBlockIncludes";
        HierarchyFacts[HierarchyFacts["IterationStatementBlockExcludes"] = 7104] = "IterationStatementBlockExcludes";
        //
        // Subtree facts
        //
        HierarchyFacts[HierarchyFacts["NewTarget"] = 16384] = "NewTarget";
        HierarchyFacts[HierarchyFacts["CapturedLexicalThis"] = 32768] = "CapturedLexicalThis";
        //
        // Subtree masks
        //
        HierarchyFacts[HierarchyFacts["SubtreeFactsMask"] = -16384] = "SubtreeFactsMask";
        HierarchyFacts[HierarchyFacts["ArrowFunctionSubtreeExcludes"] = 0] = "ArrowFunctionSubtreeExcludes";
        HierarchyFacts[HierarchyFacts["FunctionSubtreeExcludes"] = 49152] = "FunctionSubtreeExcludes";
    })(HierarchyFacts || (HierarchyFacts = {}));
    function transformES2015(context) {
        var startLexicalEnvironment = context.startLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var resolver = context.getEmitResolver();
        var previousOnSubstituteNode = context.onSubstituteNode;
        var previousOnEmitNode = context.onEmitNode;
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        var currentSourceFile;
        var currentText;
        var hierarchyFacts;
        var taggedTemplateStringDeclarations;
        function recordTaggedTemplateString(temp) {
            taggedTemplateStringDeclarations = ts.append(taggedTemplateStringDeclarations, ts.createVariableDeclaration(temp));
        }
        /**
         * Used to track if we are emitting body of the converted loop
         */
        var convertedLoopState;
        /**
         * Keeps track of whether substitutions have been enabled for specific cases.
         * They are persisted between each SourceFile transformation and should not
         * be reset.
         */
        var enabledSubstitutions;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            currentSourceFile = node;
            currentText = node.text;
            var visited = visitSourceFile(node);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            currentSourceFile = undefined;
            currentText = undefined;
            taggedTemplateStringDeclarations = undefined;
            hierarchyFacts = 0 /* None */;
            return visited;
        }
        /**
         * Sets the `HierarchyFacts` for this node prior to visiting this node's subtree, returning the facts set prior to modification.
         * @param excludeFacts The existing `HierarchyFacts` to reset before visiting the subtree.
         * @param includeFacts The new `HierarchyFacts` to set before visiting the subtree.
         */
        function enterSubtree(excludeFacts, includeFacts) {
            var ancestorFacts = hierarchyFacts;
            hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & 16383 /* AncestorFactsMask */;
            return ancestorFacts;
        }
        /**
         * Restores the `HierarchyFacts` for this node's ancestor after visiting this node's
         * subtree, propagating specific facts from the subtree.
         * @param ancestorFacts The `HierarchyFacts` of the ancestor to restore after visiting the subtree.
         * @param excludeFacts The existing `HierarchyFacts` of the subtree that should not be propagated.
         * @param includeFacts The new `HierarchyFacts` of the subtree that should be propagated.
         */
        function exitSubtree(ancestorFacts, excludeFacts, includeFacts) {
            hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & -16384 /* SubtreeFactsMask */ | ancestorFacts;
        }
        function isReturnVoidStatementInConstructorWithCapturedSuper(node) {
            return (hierarchyFacts & 8192 /* ConstructorWithCapturedSuper */) !== 0
                && node.kind === 231 /* ReturnStatement */
                && !node.expression;
        }
        function shouldVisitNode(node) {
            return (node.transformFlags & 128 /* ContainsES2015 */) !== 0
                || convertedLoopState !== undefined
                || (hierarchyFacts & 8192 /* ConstructorWithCapturedSuper */ && (ts.isStatement(node) || (node.kind === 219 /* Block */)))
                || (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatement(node))
                || (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) !== 0;
        }
        function visitor(node) {
            if (shouldVisitNode(node)) {
                return visitJavaScript(node);
            }
            else {
                return node;
            }
        }
        function callExpressionVisitor(node) {
            if (node.kind === 99 /* SuperKeyword */) {
                return visitSuperKeyword(/*isExpressionOfCall*/ true);
            }
            return visitor(node);
        }
        function visitJavaScript(node) {
            switch (node.kind) {
                case 117 /* StaticKeyword */:
                    return undefined; // elide static keyword
                case 241 /* ClassDeclaration */:
                    return visitClassDeclaration(node);
                case 210 /* ClassExpression */:
                    return visitClassExpression(node);
                case 152 /* Parameter */:
                    return visitParameter(node);
                case 240 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 198 /* ArrowFunction */:
                    return visitArrowFunction(node);
                case 197 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                case 238 /* VariableDeclaration */:
                    return visitVariableDeclaration(node);
                case 73 /* Identifier */:
                    return visitIdentifier(node);
                case 239 /* VariableDeclarationList */:
                    return visitVariableDeclarationList(node);
                case 233 /* SwitchStatement */:
                    return visitSwitchStatement(node);
                case 247 /* CaseBlock */:
                    return visitCaseBlock(node);
                case 219 /* Block */:
                    return visitBlock(node, /*isFunctionBody*/ false);
                case 230 /* BreakStatement */:
                case 229 /* ContinueStatement */:
                    return visitBreakOrContinueStatement(node);
                case 234 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                case 224 /* DoStatement */:
                case 225 /* WhileStatement */:
                    return visitDoOrWhileStatement(node, /*outermostLabeledStatement*/ undefined);
                case 226 /* ForStatement */:
                    return visitForStatement(node, /*outermostLabeledStatement*/ undefined);
                case 227 /* ForInStatement */:
                    return visitForInStatement(node, /*outermostLabeledStatement*/ undefined);
                case 228 /* ForOfStatement */:
                    return visitForOfStatement(node, /*outermostLabeledStatement*/ undefined);
                case 222 /* ExpressionStatement */:
                    return visitExpressionStatement(node);
                case 189 /* ObjectLiteralExpression */:
                    return visitObjectLiteralExpression(node);
                case 275 /* CatchClause */:
                    return visitCatchClause(node);
                case 277 /* ShorthandPropertyAssignment */:
                    return visitShorthandPropertyAssignment(node);
                case 150 /* ComputedPropertyName */:
                    return visitComputedPropertyName(node);
                case 188 /* ArrayLiteralExpression */:
                    return visitArrayLiteralExpression(node);
                case 192 /* CallExpression */:
                    return visitCallExpression(node);
                case 193 /* NewExpression */:
                    return visitNewExpression(node);
                case 196 /* ParenthesizedExpression */:
                    return visitParenthesizedExpression(node, /*needsDestructuringValue*/ true);
                case 205 /* BinaryExpression */:
                    return visitBinaryExpression(node, /*needsDestructuringValue*/ true);
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 15 /* TemplateHead */:
                case 16 /* TemplateMiddle */:
                case 17 /* TemplateTail */:
                    return visitTemplateLiteral(node);
                case 10 /* StringLiteral */:
                    return visitStringLiteral(node);
                case 8 /* NumericLiteral */:
                    return visitNumericLiteral(node);
                case 194 /* TaggedTemplateExpression */:
                    return visitTaggedTemplateExpression(node);
                case 207 /* TemplateExpression */:
                    return visitTemplateExpression(node);
                case 208 /* YieldExpression */:
                    return visitYieldExpression(node);
                case 209 /* SpreadElement */:
                    return visitSpreadElement(node);
                case 99 /* SuperKeyword */:
                    return visitSuperKeyword(/*isExpressionOfCall*/ false);
                case 101 /* ThisKeyword */:
                    return visitThisKeyword(node);
                case 215 /* MetaProperty */:
                    return visitMetaProperty(node);
                case 157 /* MethodDeclaration */:
                    return visitMethodDeclaration(node);
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    return visitAccessorDeclaration(node);
                case 220 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 231 /* ReturnStatement */:
                    return visitReturnStatement(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitSourceFile(node) {
            var ancestorFacts = enterSubtree(8064 /* SourceFileExcludes */, 64 /* SourceFileIncludes */);
            var prologue = [];
            var statements = [];
            startLexicalEnvironment();
            var statementOffset = ts.addStandardPrologue(prologue, node.statements, /*ensureUseStrict*/ false);
            statementOffset = ts.addCustomPrologue(prologue, node.statements, statementOffset, visitor);
            ts.addRange(statements, ts.visitNodes(node.statements, visitor, ts.isStatement, statementOffset));
            if (taggedTemplateStringDeclarations) {
                statements.push(ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList(taggedTemplateStringDeclarations)));
            }
            ts.mergeLexicalEnvironment(prologue, endLexicalEnvironment());
            insertCaptureThisForNodeIfNeeded(prologue, node);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(ts.concatenate(prologue, statements)), node.statements));
        }
        function visitSwitchStatement(node) {
            if (convertedLoopState !== undefined) {
                var savedAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
                // for switch statement allow only non-labeled break
                convertedLoopState.allowedNonLabeledJumps |= 2 /* Break */;
                var result = ts.visitEachChild(node, visitor, context);
                convertedLoopState.allowedNonLabeledJumps = savedAllowedNonLabeledJumps;
                return result;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitCaseBlock(node) {
            var ancestorFacts = enterSubtree(7104 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */);
            var updated = ts.visitEachChild(node, visitor, context);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function returnCapturedThis(node) {
            return ts.setOriginalNode(ts.createReturn(ts.createFileLevelUniqueName("_this")), node);
        }
        function visitReturnStatement(node) {
            if (convertedLoopState) {
                convertedLoopState.nonLocalJumps |= 8 /* Return */;
                if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
                    node = returnCapturedThis(node);
                }
                return ts.createReturn(ts.createObjectLiteral([
                    ts.createPropertyAssignment(ts.createIdentifier("value"), node.expression
                        ? ts.visitNode(node.expression, visitor, ts.isExpression)
                        : ts.createVoidZero())
                ]));
            }
            else if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
                return returnCapturedThis(node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitThisKeyword(node) {
            if (hierarchyFacts & 2 /* ArrowFunction */) {
                hierarchyFacts |= 32768 /* CapturedLexicalThis */;
            }
            if (convertedLoopState) {
                if (hierarchyFacts & 2 /* ArrowFunction */) {
                    // if the enclosing function is an ArrowFunction then we use the captured 'this' keyword.
                    convertedLoopState.containsLexicalThis = true;
                    return node;
                }
                return convertedLoopState.thisName || (convertedLoopState.thisName = ts.createUniqueName("this"));
            }
            return node;
        }
        function visitIdentifier(node) {
            if (!convertedLoopState) {
                return node;
            }
            if (ts.isGeneratedIdentifier(node)) {
                return node;
            }
            if (node.escapedText !== "arguments" || !resolver.isArgumentsLocalBinding(node)) {
                return node;
            }
            return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = ts.createUniqueName("arguments"));
        }
        function visitBreakOrContinueStatement(node) {
            if (convertedLoopState) {
                // check if we can emit break/continue as is
                // it is possible if either
                //   - break/continue is labeled and label is located inside the converted loop
                //   - break/continue is non-labeled and located in non-converted loop/switch statement
                var jump = node.kind === 230 /* BreakStatement */ ? 2 /* Break */ : 4 /* Continue */;
                var canUseBreakOrContinue = (node.label && convertedLoopState.labels && convertedLoopState.labels.get(ts.idText(node.label))) ||
                    (!node.label && (convertedLoopState.allowedNonLabeledJumps & jump));
                if (!canUseBreakOrContinue) {
                    var labelMarker = void 0;
                    var label = node.label;
                    if (!label) {
                        if (node.kind === 230 /* BreakStatement */) {
                            convertedLoopState.nonLocalJumps |= 2 /* Break */;
                            labelMarker = "break";
                        }
                        else {
                            convertedLoopState.nonLocalJumps |= 4 /* Continue */;
                            // note: return value is emitted only to simplify debugging, call to converted loop body does not do any dispatching on it.
                            labelMarker = "continue";
                        }
                    }
                    else {
                        if (node.kind === 230 /* BreakStatement */) {
                            labelMarker = "break-" + label.escapedText;
                            setLabeledJump(convertedLoopState, /*isBreak*/ true, ts.idText(label), labelMarker);
                        }
                        else {
                            labelMarker = "continue-" + label.escapedText;
                            setLabeledJump(convertedLoopState, /*isBreak*/ false, ts.idText(label), labelMarker);
                        }
                    }
                    var returnExpression = ts.createLiteral(labelMarker);
                    if (convertedLoopState.loopOutParameters.length) {
                        var outParams = convertedLoopState.loopOutParameters;
                        var expr = void 0;
                        for (var i = 0; i < outParams.length; i++) {
                            var copyExpr = copyOutParameter(outParams[i], 1 /* ToOutParameter */);
                            if (i === 0) {
                                expr = copyExpr;
                            }
                            else {
                                expr = ts.createBinary(expr, 27 /* CommaToken */, copyExpr);
                            }
                        }
                        returnExpression = ts.createBinary(expr, 27 /* CommaToken */, returnExpression);
                    }
                    return ts.createReturn(returnExpression);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a ClassDeclaration and transforms it into a variable statement.
         *
         * @param node A ClassDeclaration node.
         */
        function visitClassDeclaration(node) {
            // [source]
            //      class C { }
            //
            // [output]
            //      var C = (function () {
            //          function C() {
            //          }
            //          return C;
            //      }());
            var variable = ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ true), 
            /*type*/ undefined, transformClassLikeDeclarationToExpression(node));
            ts.setOriginalNode(variable, node);
            var statements = [];
            var statement = ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([variable]));
            ts.setOriginalNode(statement, node);
            ts.setTextRange(statement, node);
            ts.startOnNewLine(statement);
            statements.push(statement);
            // Add an `export default` statement for default exports (for `--target es5 --module es6`)
            if (ts.hasModifier(node, 1 /* Export */)) {
                var exportStatement = ts.hasModifier(node, 512 /* Default */)
                    ? ts.createExportDefault(ts.getLocalName(node))
                    : ts.createExternalModuleExport(ts.getLocalName(node));
                ts.setOriginalNode(exportStatement, statement);
                statements.push(exportStatement);
            }
            var emitFlags = ts.getEmitFlags(node);
            if ((emitFlags & 4194304 /* HasEndOfDeclarationMarker */) === 0) {
                // Add a DeclarationMarker as a marker for the end of the declaration
                statements.push(ts.createEndOfDeclarationMarker(node));
                ts.setEmitFlags(statement, emitFlags | 4194304 /* HasEndOfDeclarationMarker */);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a ClassExpression and transforms it into an expression.
         *
         * @param node A ClassExpression node.
         */
        function visitClassExpression(node) {
            // [source]
            //      C = class { }
            //
            // [output]
            //      C = (function () {
            //          function class_1() {
            //          }
            //          return class_1;
            //      }())
            return transformClassLikeDeclarationToExpression(node);
        }
        /**
         * Transforms a ClassExpression or ClassDeclaration into an expression.
         *
         * @param node A ClassExpression or ClassDeclaration node.
         */
        function transformClassLikeDeclarationToExpression(node) {
            // [source]
            //      class C extends D {
            //          constructor() {}
            //          method() {}
            //          get prop() {}
            //          set prop(v) {}
            //      }
            //
            // [output]
            //      (function (_super) {
            //          __extends(C, _super);
            //          function C() {
            //          }
            //          C.prototype.method = function () {}
            //          Object.defineProperty(C.prototype, "prop", {
            //              get: function() {},
            //              set: function() {},
            //              enumerable: true,
            //              configurable: true
            //          });
            //          return C;
            //      }(D))
            if (node.name) {
                enableSubstitutionsForBlockScopedBindings();
            }
            var extendsClauseElement = ts.getClassExtendsHeritageElement(node);
            var classFunction = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, extendsClauseElement ? [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, ts.createFileLevelUniqueName("_super"))] : [], 
            /*type*/ undefined, transformClassBody(node, extendsClauseElement));
            // To preserve the behavior of the old emitter, we explicitly indent
            // the body of the function here if it was requested in an earlier
            // transformation.
            ts.setEmitFlags(classFunction, (ts.getEmitFlags(node) & 65536 /* Indented */) | 524288 /* ReuseTempVariableScope */);
            // "inner" and "outer" below are added purely to preserve source map locations from
            // the old emitter
            var inner = ts.createPartiallyEmittedExpression(classFunction);
            inner.end = node.end;
            ts.setEmitFlags(inner, 1536 /* NoComments */);
            var outer = ts.createPartiallyEmittedExpression(inner);
            outer.end = ts.skipTrivia(currentText, node.pos);
            ts.setEmitFlags(outer, 1536 /* NoComments */);
            var result = ts.createParen(ts.createCall(outer, 
            /*typeArguments*/ undefined, extendsClauseElement
                ? [ts.visitNode(extendsClauseElement.expression, visitor, ts.isExpression)]
                : []));
            ts.addSyntheticLeadingComment(result, 3 /* MultiLineCommentTrivia */, "* @class ");
            return result;
        }
        /**
         * Transforms a ClassExpression or ClassDeclaration into a function body.
         *
         * @param node A ClassExpression or ClassDeclaration node.
         * @param extendsClauseElement The expression for the class `extends` clause.
         */
        function transformClassBody(node, extendsClauseElement) {
            var statements = [];
            startLexicalEnvironment();
            addExtendsHelperIfNeeded(statements, node, extendsClauseElement);
            addConstructor(statements, node, extendsClauseElement);
            addClassMembers(statements, node);
            // Create a synthetic text range for the return statement.
            var closingBraceLocation = ts.createTokenRange(ts.skipTrivia(currentText, node.members.end), 19 /* CloseBraceToken */);
            var localName = ts.getInternalName(node);
            // The following partially-emitted expression exists purely to align our sourcemap
            // emit with the original emitter.
            var outer = ts.createPartiallyEmittedExpression(localName);
            outer.end = closingBraceLocation.end;
            ts.setEmitFlags(outer, 1536 /* NoComments */);
            var statement = ts.createReturn(outer);
            statement.pos = closingBraceLocation.pos;
            ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */);
            statements.push(statement);
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true);
            ts.setEmitFlags(block, 1536 /* NoComments */);
            return block;
        }
        /**
         * Adds a call to the `__extends` helper if needed for a class.
         *
         * @param statements The statements of the class body function.
         * @param node The ClassExpression or ClassDeclaration node.
         * @param extendsClauseElement The expression for the class `extends` clause.
         */
        function addExtendsHelperIfNeeded(statements, node, extendsClauseElement) {
            if (extendsClauseElement) {
                statements.push(ts.setTextRange(ts.createExpressionStatement(createExtendsHelper(context, ts.getInternalName(node))), 
                /*location*/ extendsClauseElement));
            }
        }
        /**
         * Adds the constructor of the class to a class body function.
         *
         * @param statements The statements of the class body function.
         * @param node The ClassExpression or ClassDeclaration node.
         * @param extendsClauseElement The expression for the class `extends` clause.
         */
        function addConstructor(statements, node, extendsClauseElement) {
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(16278 /* ConstructorExcludes */, 73 /* ConstructorIncludes */);
            var constructor = ts.getFirstConstructorWithBody(node);
            var hasSynthesizedSuper = hasSynthesizedDefaultSuperCall(constructor, extendsClauseElement !== undefined);
            var constructorFunction = ts.createFunctionDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, ts.getInternalName(node), 
            /*typeParameters*/ undefined, transformConstructorParameters(constructor, hasSynthesizedSuper), 
            /*type*/ undefined, transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper));
            ts.setTextRange(constructorFunction, constructor || node);
            if (extendsClauseElement) {
                ts.setEmitFlags(constructorFunction, 8 /* CapturesThis */);
            }
            statements.push(constructorFunction);
            exitSubtree(ancestorFacts, 49152 /* FunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
        }
        /**
         * Transforms the parameters of the constructor declaration of a class.
         *
         * @param constructor The constructor for the class.
         * @param hasSynthesizedSuper A value indicating whether the constructor starts with a
         *                            synthesized `super` call.
         */
        function transformConstructorParameters(constructor, hasSynthesizedSuper) {
            // If the TypeScript transformer needed to synthesize a constructor for property
            // initializers, it would have also added a synthetic `...args` parameter and
            // `super` call.
            // If this is the case, we do not include the synthetic `...args` parameter and
            // will instead use the `arguments` object in ES5/3.
            return ts.visitParameterList(constructor && !hasSynthesizedSuper ? constructor.parameters : undefined, visitor, context)
                || [];
        }
        function createDefaultConstructorBody(node, isDerivedClass) {
            // We must be here because the user didn't write a constructor
            // but we needed to call 'super(...args)' anyway as per 14.5.14 of the ES2016 spec.
            // If that's the case we can just immediately return the result of a 'super()' call.
            var statements = [];
            resumeLexicalEnvironment();
            ts.mergeLexicalEnvironment(statements, endLexicalEnvironment());
            if (isDerivedClass) {
                // return _super !== null && _super.apply(this, arguments) || this;
                statements.push(ts.createReturn(createDefaultSuperCallOrThis()));
            }
            var statementsArray = ts.createNodeArray(statements);
            ts.setTextRange(statementsArray, node.members);
            var block = ts.createBlock(statementsArray, /*multiLine*/ true);
            ts.setTextRange(block, node);
            ts.setEmitFlags(block, 1536 /* NoComments */);
            return block;
        }
        /**
         * Transforms the body of a constructor declaration of a class.
         *
         * @param constructor The constructor for the class.
         * @param node The node which contains the constructor.
         * @param extendsClauseElement The expression for the class `extends` clause.
         * @param hasSynthesizedSuper A value indicating whether the constructor starts with a
         *                            synthesized `super` call.
         */
        function transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper) {
            // determine whether the class is known syntactically to be a derived class (e.g. a
            // class that extends a value that is not syntactically known to be `null`).
            var isDerivedClass = !!extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 97 /* NullKeyword */;
            // When the subclass does not have a constructor, we synthesize a *default* constructor using the following
            // representation:
            //
            // ```
            // // es2015 (source)
            // class C extends Base { }
            //
            // // es5 (transformed)
            // var C = (function (_super) {
            //     function C() {
            //         return _super.apply(this, arguments) || this;
            //     }
            //     return C;
            // })(Base);
            // ```
            if (!constructor)
                return createDefaultConstructorBody(node, isDerivedClass);
            // The prologue will contain all leading standard and custom prologue statements added by this transform
            var prologue = [];
            var statements = [];
            resumeLexicalEnvironment();
            // If a super call has already been synthesized,
            // we're going to assume that we should just transform everything after that.
            // The assumption is that no prior step in the pipeline has added any prologue directives.
            var statementOffset = 0;
            if (!hasSynthesizedSuper)
                statementOffset = ts.addStandardPrologue(prologue, constructor.body.statements, /*ensureUseStrict*/ false);
            addDefaultValueAssignmentsIfNeeded(statements, constructor);
            addRestParameterIfNeeded(statements, constructor, hasSynthesizedSuper);
            if (!hasSynthesizedSuper)
                statementOffset = ts.addCustomPrologue(statements, constructor.body.statements, statementOffset, visitor);
            // If the first statement is a call to `super()`, visit the statement directly
            var superCallExpression;
            if (hasSynthesizedSuper) {
                superCallExpression = createDefaultSuperCallOrThis();
            }
            else if (isDerivedClass && statementOffset < constructor.body.statements.length) {
                var firstStatement = constructor.body.statements[statementOffset];
                if (ts.isExpressionStatement(firstStatement) && ts.isSuperCall(firstStatement.expression)) {
                    superCallExpression = visitImmediateSuperCallInBody(firstStatement.expression);
                }
            }
            if (superCallExpression) {
                hierarchyFacts |= 8192 /* ConstructorWithCapturedSuper */;
                statementOffset++; // skip this statement, we will add it after visiting the rest of the body.
            }
            // visit the remaining statements
            ts.addRange(statements, ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, /*start*/ statementOffset));
            ts.mergeLexicalEnvironment(prologue, endLexicalEnvironment());
            insertCaptureNewTargetIfNeeded(prologue, constructor, /*copyOnWrite*/ false);
            if (isDerivedClass) {
                if (superCallExpression && statementOffset === constructor.body.statements.length && !(constructor.body.transformFlags & 2048 /* ContainsLexicalThis */)) {
                    // If the subclass constructor does *not* contain `this` and *ends* with a `super()` call, we will use the
                    // following representation:
                    //
                    // ```
                    // // es2015 (source)
                    // class C extends Base {
                    //     constructor() {
                    //         super("foo");
                    //     }
                    // }
                    //
                    // // es5 (transformed)
                    // var C = (function (_super) {
                    //     function C() {
                    //         return _super.call(this, "foo") || this;
                    //     }
                    //     return C;
                    // })(Base);
                    // ```
                    var superCall = ts.cast(ts.cast(superCallExpression, ts.isBinaryExpression).left, ts.isCallExpression);
                    var returnStatement = ts.createReturn(superCallExpression);
                    ts.setCommentRange(returnStatement, ts.getCommentRange(superCall));
                    ts.setEmitFlags(superCall, 1536 /* NoComments */);
                    statements.push(returnStatement);
                }
                else {
                    // Otherwise, we will use the following transformed representation for calls to `super()` in a constructor:
                    //
                    // ```
                    // // es2015 (source)
                    // class C extends Base {
                    //     constructor() {
                    //         super("foo");
                    //         this.x = 1;
                    //     }
                    // }
                    //
                    // // es5 (transformed)
                    // var C = (function (_super) {
                    //     function C() {
                    //         var _this = _super.call(this, "foo") || this;
                    //         _this.x = 1;
                    //         return _this;
                    //     }
                    //     return C;
                    // })(Base);
                    // ```
                    // Since the `super()` call was the first statement, we insert the `this` capturing call to
                    // `super()` at the top of the list of `statements` (after any pre-existing custom prologues).
                    insertCaptureThisForNode(statements, constructor, superCallExpression || createActualThis());
                    if (!isSufficientlyCoveredByReturnStatements(constructor.body)) {
                        statements.push(ts.createReturn(ts.createFileLevelUniqueName("_this")));
                    }
                }
            }
            else {
                // If a class is not derived from a base class or does not have a call to `super()`, `this` is only
                // captured when necessitated by an arrow function capturing the lexical `this`:
                //
                // ```
                // // es2015
                // class C {}
                //
                // // es5
                // var C = (function () {
                //     function C() {
                //     }
                //     return C;
                // })();
                // ```
                insertCaptureThisForNodeIfNeeded(prologue, constructor);
            }
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(ts.concatenate(prologue, statements)), 
            /*location*/ constructor.body.statements), 
            /*multiLine*/ true);
            ts.setTextRange(block, constructor.body);
            return block;
        }
        /**
         * We want to try to avoid emitting a return statement in certain cases if a user already returned something.
         * It would generate obviously dead code, so we'll try to make things a little bit prettier
         * by doing a minimal check on whether some common patterns always explicitly return.
         */
        function isSufficientlyCoveredByReturnStatements(statement) {
            // A return statement is considered covered.
            if (statement.kind === 231 /* ReturnStatement */) {
                return true;
            }
            // An if-statement with two covered branches is covered.
            else if (statement.kind === 223 /* IfStatement */) {
                var ifStatement = statement;
                if (ifStatement.elseStatement) {
                    return isSufficientlyCoveredByReturnStatements(ifStatement.thenStatement) &&
                        isSufficientlyCoveredByReturnStatements(ifStatement.elseStatement);
                }
            }
            // A block is covered if it has a last statement which is covered.
            else if (statement.kind === 219 /* Block */) {
                var lastStatement = ts.lastOrUndefined(statement.statements);
                if (lastStatement && isSufficientlyCoveredByReturnStatements(lastStatement)) {
                    return true;
                }
            }
            return false;
        }
        function createActualThis() {
            return ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */);
        }
        function createDefaultSuperCallOrThis() {
            return ts.createLogicalOr(ts.createLogicalAnd(ts.createStrictInequality(ts.createFileLevelUniqueName("_super"), ts.createNull()), ts.createFunctionApply(ts.createFileLevelUniqueName("_super"), createActualThis(), ts.createIdentifier("arguments"))), createActualThis());
        }
        /**
         * Visits a parameter declaration.
         *
         * @param node A ParameterDeclaration node.
         */
        function visitParameter(node) {
            if (node.dotDotDotToken) {
                // rest parameters are elided
                return undefined;
            }
            else if (ts.isBindingPattern(node.name)) {
                // Binding patterns are converted into a generated name and are
                // evaluated inside the function body.
                return ts.setOriginalNode(ts.setTextRange(ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, ts.getGeneratedNameForNode(node), 
                /*questionToken*/ undefined, 
                /*type*/ undefined, 
                /*initializer*/ undefined), 
                /*location*/ node), 
                /*original*/ node);
            }
            else if (node.initializer) {
                // Initializers are elided
                return ts.setOriginalNode(ts.setTextRange(ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, node.name, 
                /*questionToken*/ undefined, 
                /*type*/ undefined, 
                /*initializer*/ undefined), 
                /*location*/ node), 
                /*original*/ node);
            }
            else {
                return node;
            }
        }
        function hasDefaultValueOrBindingPattern(node) {
            return node.initializer !== undefined
                || ts.isBindingPattern(node.name);
        }
        /**
         * Adds statements to the body of a function-like node if it contains parameters with
         * binding patterns or initializers.
         *
         * @param statements The statements for the new function body.
         * @param node A function-like node.
         */
        function addDefaultValueAssignmentsIfNeeded(statements, node) {
            if (!ts.some(node.parameters, hasDefaultValueOrBindingPattern)) {
                return false;
            }
            var added = false;
            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
                var parameter = _a[_i];
                var name = parameter.name, initializer = parameter.initializer, dotDotDotToken = parameter.dotDotDotToken;
                // A rest parameter cannot have a binding pattern or an initializer,
                // so let's just ignore it.
                if (dotDotDotToken) {
                    continue;
                }
                if (ts.isBindingPattern(name)) {
                    added = insertDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer) || added;
                }
                else if (initializer) {
                    insertDefaultValueAssignmentForInitializer(statements, parameter, name, initializer);
                    added = true;
                }
            }
            return added;
        }
        /**
         * Adds statements to the body of a function-like node for parameters with binding patterns
         *
         * @param statements The statements for the new function body.
         * @param parameter The parameter for the function.
         * @param name The name of the parameter.
         * @param initializer The initializer for the parameter.
         */
        function insertDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer) {
            // In cases where a binding pattern is simply '[]' or '{}',
            // we usually don't want to emit a var declaration; however, in the presence
            // of an initializer, we must emit that expression to preserve side effects.
            if (name.elements.length > 0) {
                ts.insertStatementAfterCustomPrologue(statements, ts.setEmitFlags(ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList(ts.flattenDestructuringBinding(parameter, visitor, context, 0 /* All */, ts.getGeneratedNameForNode(parameter)))), 1048576 /* CustomPrologue */));
                return true;
            }
            else if (initializer) {
                ts.insertStatementAfterCustomPrologue(statements, ts.setEmitFlags(ts.createExpressionStatement(ts.createAssignment(ts.getGeneratedNameForNode(parameter), ts.visitNode(initializer, visitor, ts.isExpression))), 1048576 /* CustomPrologue */));
                return true;
            }
            return false;
        }
        /**
         * Adds statements to the body of a function-like node for parameters with initializers.
         *
         * @param statements The statements for the new function body.
         * @param parameter The parameter for the function.
         * @param name The name of the parameter.
         * @param initializer The initializer for the parameter.
         */
        function insertDefaultValueAssignmentForInitializer(statements, parameter, name, initializer) {
            initializer = ts.visitNode(initializer, visitor, ts.isExpression);
            var statement = ts.createIf(ts.createTypeCheck(ts.getSynthesizedClone(name), "undefined"), ts.setEmitFlags(ts.setTextRange(ts.createBlock([
                ts.createExpressionStatement(ts.setEmitFlags(ts.setTextRange(ts.createAssignment(ts.setEmitFlags(ts.getMutableClone(name), 48 /* NoSourceMap */), ts.setEmitFlags(initializer, 48 /* NoSourceMap */ | ts.getEmitFlags(initializer) | 1536 /* NoComments */)), parameter), 1536 /* NoComments */))
            ]), parameter), 1 /* SingleLine */ | 32 /* NoTrailingSourceMap */ | 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */));
            ts.startOnNewLine(statement);
            ts.setTextRange(statement, parameter);
            ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 32 /* NoTrailingSourceMap */ | 1048576 /* CustomPrologue */ | 1536 /* NoComments */);
            ts.insertStatementAfterCustomPrologue(statements, statement);
        }
        /**
         * Gets a value indicating whether we need to add statements to handle a rest parameter.
         *
         * @param node A ParameterDeclaration node.
         * @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is
         *                                          part of a constructor declaration with a
         *                                          synthesized call to `super`
         */
        function shouldAddRestParameter(node, inConstructorWithSynthesizedSuper) {
            return !!(node && node.dotDotDotToken && !inConstructorWithSynthesizedSuper);
        }
        /**
         * Adds statements to the body of a function-like node if it contains a rest parameter.
         *
         * @param statements The statements for the new function body.
         * @param node A function-like node.
         * @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is
         *                                          part of a constructor declaration with a
         *                                          synthesized call to `super`
         */
        function addRestParameterIfNeeded(statements, node, inConstructorWithSynthesizedSuper) {
            var prologueStatements = [];
            var parameter = ts.lastOrUndefined(node.parameters);
            if (!shouldAddRestParameter(parameter, inConstructorWithSynthesizedSuper)) {
                return false;
            }
            // `declarationName` is the name of the local declaration for the parameter.
            var declarationName = parameter.name.kind === 73 /* Identifier */ ? ts.getMutableClone(parameter.name) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            ts.setEmitFlags(declarationName, 48 /* NoSourceMap */);
            // `expressionName` is the name of the parameter used in expressions.
            var expressionName = parameter.name.kind === 73 /* Identifier */ ? ts.getSynthesizedClone(parameter.name) : declarationName;
            var restIndex = node.parameters.length - 1;
            var temp = ts.createLoopVariable();
            // var param = [];
            prologueStatements.push(ts.setEmitFlags(ts.setTextRange(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(declarationName, 
                /*type*/ undefined, ts.createArrayLiteral([]))
            ])), 
            /*location*/ parameter), 1048576 /* CustomPrologue */));
            // for (var _i = restIndex; _i < arguments.length; _i++) {
            //   param[_i - restIndex] = arguments[_i];
            // }
            var forStatement = ts.createFor(ts.setTextRange(ts.createVariableDeclarationList([
                ts.createVariableDeclaration(temp, /*type*/ undefined, ts.createLiteral(restIndex))
            ]), parameter), ts.setTextRange(ts.createLessThan(temp, ts.createPropertyAccess(ts.createIdentifier("arguments"), "length")), parameter), ts.setTextRange(ts.createPostfixIncrement(temp), parameter), ts.createBlock([
                ts.startOnNewLine(ts.setTextRange(ts.createExpressionStatement(ts.createAssignment(ts.createElementAccess(expressionName, restIndex === 0
                    ? temp
                    : ts.createSubtract(temp, ts.createLiteral(restIndex))), ts.createElementAccess(ts.createIdentifier("arguments"), temp))), 
                /*location*/ parameter))
            ]));
            ts.setEmitFlags(forStatement, 1048576 /* CustomPrologue */);
            ts.startOnNewLine(forStatement);
            prologueStatements.push(forStatement);
            if (parameter.name.kind !== 73 /* Identifier */) {
                // do the actual destructuring of the rest parameter if necessary
                prologueStatements.push(ts.setEmitFlags(ts.setTextRange(ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList(ts.flattenDestructuringBinding(parameter, visitor, context, 0 /* All */, expressionName))), parameter), 1048576 /* CustomPrologue */));
            }
            ts.insertStatementsAfterCustomPrologue(statements, prologueStatements);
            return true;
        }
        /**
         * Adds a statement to capture the `this` of a function declaration if it is needed.
         * NOTE: This must be executed *after* the subtree has been visited.
         *
         * @param statements The statements for the new function body.
         * @param node A node.
         */
        function insertCaptureThisForNodeIfNeeded(statements, node) {
            if (hierarchyFacts & 32768 /* CapturedLexicalThis */ && node.kind !== 198 /* ArrowFunction */) {
                insertCaptureThisForNode(statements, node, ts.createThis());
                return true;
            }
            return false;
        }
        function insertCaptureThisForNode(statements, node, initializer) {
            enableSubstitutionsForCapturedThis();
            var captureThisStatement = ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(ts.createFileLevelUniqueName("_this"), 
                /*type*/ undefined, initializer)
            ]));
            ts.setEmitFlags(captureThisStatement, 1536 /* NoComments */ | 1048576 /* CustomPrologue */);
            ts.setSourceMapRange(captureThisStatement, node);
            ts.insertStatementAfterCustomPrologue(statements, captureThisStatement);
        }
        function insertCaptureNewTargetIfNeeded(statements, node, copyOnWrite) {
            if (hierarchyFacts & 16384 /* NewTarget */) {
                var newTarget = void 0;
                switch (node.kind) {
                    case 198 /* ArrowFunction */:
                        return statements;
                    case 157 /* MethodDeclaration */:
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                        // Methods and accessors cannot be constructors, so 'new.target' will
                        // always return 'undefined'.
                        newTarget = ts.createVoidZero();
                        break;
                    case 158 /* Constructor */:
                        // Class constructors can only be called with `new`, so `this.constructor`
                        // should be relatively safe to use.
                        newTarget = ts.createPropertyAccess(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), "constructor");
                        break;
                    case 240 /* FunctionDeclaration */:
                    case 197 /* FunctionExpression */:
                        // Functions can be called or constructed, and may have a `this` due to
                        // being a member or when calling an imported function via `other_1.f()`.
                        newTarget = ts.createConditional(ts.createLogicalAnd(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), ts.createBinary(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), 95 /* InstanceOfKeyword */, ts.getLocalName(node))), ts.createPropertyAccess(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), "constructor"), ts.createVoidZero());
                        break;
                    default:
                        return ts.Debug.failBadSyntaxKind(node);
                }
                var captureNewTargetStatement = ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(ts.createFileLevelUniqueName("_newTarget"), 
                    /*type*/ undefined, newTarget)
                ]));
                ts.setEmitFlags(captureNewTargetStatement, 1536 /* NoComments */ | 1048576 /* CustomPrologue */);
                if (copyOnWrite) {
                    statements = statements.slice();
                }
                ts.insertStatementAfterCustomPrologue(statements, captureNewTargetStatement);
            }
            return statements;
        }
        /**
         * Adds statements to the class body function for a class to define the members of the
         * class.
         *
         * @param statements The statements for the class body function.
         * @param node The ClassExpression or ClassDeclaration node.
         */
        function addClassMembers(statements, node) {
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                switch (member.kind) {
                    case 218 /* SemicolonClassElement */:
                        statements.push(transformSemicolonClassElementToStatement(member));
                        break;
                    case 157 /* MethodDeclaration */:
                        statements.push(transformClassMethodDeclarationToStatement(getClassMemberPrefix(node, member), member, node));
                        break;
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                        var accessors = ts.getAllAccessorDeclarations(node.members, member);
                        if (member === accessors.firstAccessor) {
                            statements.push(transformAccessorsToStatement(getClassMemberPrefix(node, member), accessors, node));
                        }
                        break;
                    case 158 /* Constructor */:
                        // Constructors are handled in visitClassExpression/visitClassDeclaration
                        break;
                    default:
                        ts.Debug.failBadSyntaxKind(node);
                        break;
                }
            }
        }
        /**
         * Transforms a SemicolonClassElement into a statement for a class body function.
         *
         * @param member The SemicolonClassElement node.
         */
        function transformSemicolonClassElementToStatement(member) {
            return ts.setTextRange(ts.createEmptyStatement(), member);
        }
        /**
         * Transforms a MethodDeclaration into a statement for a class body function.
         *
         * @param receiver The receiver for the member.
         * @param member The MethodDeclaration node.
         */
        function transformClassMethodDeclarationToStatement(receiver, member, container) {
            var commentRange = ts.getCommentRange(member);
            var sourceMapRange = ts.getSourceMapRange(member);
            var memberName = ts.createMemberAccessForPropertyName(receiver, ts.visitNode(member.name, visitor, ts.isPropertyName), /*location*/ member.name);
            var memberFunction = transformFunctionLikeToExpression(member, /*location*/ member, /*name*/ undefined, container);
            ts.setEmitFlags(memberFunction, 1536 /* NoComments */);
            ts.setSourceMapRange(memberFunction, sourceMapRange);
            var statement = ts.setTextRange(ts.createExpressionStatement(ts.createAssignment(memberName, memberFunction)), 
            /*location*/ member);
            ts.setOriginalNode(statement, member);
            ts.setCommentRange(statement, commentRange);
            // The location for the statement is used to emit comments only.
            // No source map should be emitted for this statement to align with the
            // old emitter.
            ts.setEmitFlags(statement, 48 /* NoSourceMap */);
            return statement;
        }
        /**
         * Transforms a set of related of get/set accessors into a statement for a class body function.
         *
         * @param receiver The receiver for the member.
         * @param accessors The set of related get/set accessors.
         */
        function transformAccessorsToStatement(receiver, accessors, container) {
            var statement = ts.createExpressionStatement(transformAccessorsToExpression(receiver, accessors, container, /*startsOnNewLine*/ false));
            // The location for the statement is used to emit source maps only.
            // No comments should be emitted for this statement to align with the
            // old emitter.
            ts.setEmitFlags(statement, 1536 /* NoComments */);
            ts.setSourceMapRange(statement, ts.getSourceMapRange(accessors.firstAccessor));
            return statement;
        }
        /**
         * Transforms a set of related get/set accessors into an expression for either a class
         * body function or an ObjectLiteralExpression with computed properties.
         *
         * @param receiver The receiver for the member.
         */
        function transformAccessorsToExpression(receiver, _a, container, startsOnNewLine) {
            var firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor;
            // To align with source maps in the old emitter, the receiver and property name
            // arguments are both mapped contiguously to the accessor name.
            var target = ts.getMutableClone(receiver);
            ts.setEmitFlags(target, 1536 /* NoComments */ | 32 /* NoTrailingSourceMap */);
            ts.setSourceMapRange(target, firstAccessor.name);
            var propertyName = ts.createExpressionForPropertyName(ts.visitNode(firstAccessor.name, visitor, ts.isPropertyName));
            ts.setEmitFlags(propertyName, 1536 /* NoComments */ | 16 /* NoLeadingSourceMap */);
            ts.setSourceMapRange(propertyName, firstAccessor.name);
            var properties = [];
            if (getAccessor) {
                var getterFunction = transformFunctionLikeToExpression(getAccessor, /*location*/ undefined, /*name*/ undefined, container);
                ts.setSourceMapRange(getterFunction, ts.getSourceMapRange(getAccessor));
                ts.setEmitFlags(getterFunction, 512 /* NoLeadingComments */);
                var getter = ts.createPropertyAssignment("get", getterFunction);
                ts.setCommentRange(getter, ts.getCommentRange(getAccessor));
                properties.push(getter);
            }
            if (setAccessor) {
                var setterFunction = transformFunctionLikeToExpression(setAccessor, /*location*/ undefined, /*name*/ undefined, container);
                ts.setSourceMapRange(setterFunction, ts.getSourceMapRange(setAccessor));
                ts.setEmitFlags(setterFunction, 512 /* NoLeadingComments */);
                var setter = ts.createPropertyAssignment("set", setterFunction);
                ts.setCommentRange(setter, ts.getCommentRange(setAccessor));
                properties.push(setter);
            }
            properties.push(ts.createPropertyAssignment("enumerable", ts.createTrue()), ts.createPropertyAssignment("configurable", ts.createTrue()));
            var call = ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
            /*typeArguments*/ undefined, [
                target,
                propertyName,
                ts.createObjectLiteral(properties, /*multiLine*/ true)
            ]);
            if (startsOnNewLine) {
                ts.startOnNewLine(call);
            }
            return call;
        }
        /**
         * Visits an ArrowFunction and transforms it into a FunctionExpression.
         *
         * @param node An ArrowFunction node.
         */
        function visitArrowFunction(node) {
            if (node.transformFlags & 2048 /* ContainsLexicalThis */) {
                hierarchyFacts |= 32768 /* CapturedLexicalThis */;
            }
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(15232 /* ArrowFunctionExcludes */, 66 /* ArrowFunctionIncludes */);
            var func = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, transformFunctionBody(node));
            ts.setTextRange(func, node);
            ts.setOriginalNode(func, node);
            ts.setEmitFlags(func, 8 /* CapturesThis */);
            if (hierarchyFacts & 32768 /* CapturedLexicalThis */) {
                enableSubstitutionsForCapturedThis();
            }
            // If an arrow function contains
            exitSubtree(ancestorFacts, 0 /* ArrowFunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return func;
        }
        /**
         * Visits a FunctionExpression node.
         *
         * @param node a FunctionExpression node.
         */
        function visitFunctionExpression(node) {
            var ancestorFacts = ts.getEmitFlags(node) & 262144 /* AsyncFunctionBody */
                ? enterSubtree(16278 /* AsyncFunctionBodyExcludes */, 69 /* AsyncFunctionBodyIncludes */)
                : enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var parameters = ts.visitParameterList(node.parameters, visitor, context);
            var body = transformFunctionBody(node);
            var name = hierarchyFacts & 16384 /* NewTarget */
                ? ts.getLocalName(node)
                : node.name;
            exitSubtree(ancestorFacts, 49152 /* FunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return ts.updateFunctionExpression(node, 
            /*modifiers*/ undefined, node.asteriskToken, name, 
            /*typeParameters*/ undefined, parameters, 
            /*type*/ undefined, body);
        }
        /**
         * Visits a FunctionDeclaration node.
         *
         * @param node a FunctionDeclaration node.
         */
        function visitFunctionDeclaration(node) {
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var parameters = ts.visitParameterList(node.parameters, visitor, context);
            var body = transformFunctionBody(node);
            var name = hierarchyFacts & 16384 /* NewTarget */
                ? ts.getLocalName(node)
                : node.name;
            exitSubtree(ancestorFacts, 49152 /* FunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, name, 
            /*typeParameters*/ undefined, parameters, 
            /*type*/ undefined, body);
        }
        /**
         * Transforms a function-like node into a FunctionExpression.
         *
         * @param node The function-like node to transform.
         * @param location The source-map location for the new FunctionExpression.
         * @param name The name of the new FunctionExpression.
         */
        function transformFunctionLikeToExpression(node, location, name, container) {
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = container && ts.isClassLike(container) && !ts.hasModifier(node, 32 /* Static */)
                ? enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */ | 8 /* NonStaticClassElement */)
                : enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var parameters = ts.visitParameterList(node.parameters, visitor, context);
            var body = transformFunctionBody(node);
            if (hierarchyFacts & 16384 /* NewTarget */ && !name && (node.kind === 240 /* FunctionDeclaration */ || node.kind === 197 /* FunctionExpression */)) {
                name = ts.getGeneratedNameForNode(node);
            }
            exitSubtree(ancestorFacts, 49152 /* FunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(
            /*modifiers*/ undefined, node.asteriskToken, name, 
            /*typeParameters*/ undefined, parameters, 
            /*type*/ undefined, body), location), 
            /*original*/ node);
        }
        /**
         * Transforms the body of a function-like node.
         *
         * @param node A function-like node.
         */
        function transformFunctionBody(node) {
            var multiLine = false; // indicates whether the block *must* be emitted as multiple lines
            var singleLine = false; // indicates whether the block *may* be emitted as a single line
            var statementsLocation;
            var closeBraceLocation;
            var prologue = [];
            var statements = [];
            var body = node.body;
            var statementOffset;
            resumeLexicalEnvironment();
            if (ts.isBlock(body)) {
                // ensureUseStrict is false because no new prologue-directive should be added.
                // addStandardPrologue will put already-existing directives at the beginning of the target statement-array
                statementOffset = ts.addStandardPrologue(prologue, body.statements, /*ensureUseStrict*/ false);
            }
            multiLine = addDefaultValueAssignmentsIfNeeded(statements, node) || multiLine;
            multiLine = addRestParameterIfNeeded(statements, node, /*inConstructorWithSynthesizedSuper*/ false) || multiLine;
            if (ts.isBlock(body)) {
                // addCustomPrologue puts already-existing directives at the beginning of the target statement-array
                statementOffset = ts.addCustomPrologue(statements, body.statements, statementOffset, visitor);
                statementsLocation = body.statements;
                ts.addRange(statements, ts.visitNodes(body.statements, visitor, ts.isStatement, statementOffset));
                // If the original body was a multi-line block, this must be a multi-line block.
                if (!multiLine && body.multiLine) {
                    multiLine = true;
                }
            }
            else {
                ts.Debug.assert(node.kind === 198 /* ArrowFunction */);
                // To align with the old emitter, we use a synthetic end position on the location
                // for the statement list we synthesize when we down-level an arrow function with
                // an expression function body. This prevents both comments and source maps from
                // being emitted for the end position only.
                statementsLocation = ts.moveRangeEnd(body, -1);
                var equalsGreaterThanToken = node.equalsGreaterThanToken;
                if (!ts.nodeIsSynthesized(equalsGreaterThanToken) && !ts.nodeIsSynthesized(body)) {
                    if (ts.rangeEndIsOnSameLineAsRangeStart(equalsGreaterThanToken, body, currentSourceFile)) {
                        singleLine = true;
                    }
                    else {
                        multiLine = true;
                    }
                }
                var expression = ts.visitNode(body, visitor, ts.isExpression);
                var returnStatement = ts.createReturn(expression);
                ts.setTextRange(returnStatement, body);
                ts.moveSyntheticComments(returnStatement, body);
                ts.setEmitFlags(returnStatement, 384 /* NoTokenSourceMaps */ | 32 /* NoTrailingSourceMap */ | 1024 /* NoTrailingComments */);
                statements.push(returnStatement);
                // To align with the source map emit for the old emitter, we set a custom
                // source map location for the close brace.
                closeBraceLocation = body;
            }
            ts.mergeLexicalEnvironment(prologue, endLexicalEnvironment());
            insertCaptureNewTargetIfNeeded(prologue, node, /*copyOnWrite*/ false);
            insertCaptureThisForNodeIfNeeded(prologue, node);
            // If we added any final generated statements, this must be a multi-line block
            if (ts.some(prologue)) {
                multiLine = true;
            }
            statements.unshift.apply(statements, prologue);
            if (ts.isBlock(body) && ts.arrayIsEqualTo(statements, body.statements)) {
                // no changes were made, preserve the tree
                return body;
            }
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), multiLine);
            ts.setTextRange(block, node.body);
            if (!multiLine && singleLine) {
                ts.setEmitFlags(block, 1 /* SingleLine */);
            }
            if (closeBraceLocation) {
                ts.setTokenSourceMapRange(block, 19 /* CloseBraceToken */, closeBraceLocation);
            }
            ts.setOriginalNode(block, node.body);
            return block;
        }
        function visitBlock(node, isFunctionBody) {
            if (isFunctionBody) {
                // A function body is not a block scope.
                return ts.visitEachChild(node, visitor, context);
            }
            var ancestorFacts = hierarchyFacts & 256 /* IterationStatement */
                ? enterSubtree(7104 /* IterationStatementBlockExcludes */, 512 /* IterationStatementBlockIncludes */)
                : enterSubtree(6976 /* BlockExcludes */, 128 /* BlockIncludes */);
            var updated = ts.visitEachChild(node, visitor, context);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        /**
         * Visits an ExpressionStatement that contains a destructuring assignment.
         *
         * @param node An ExpressionStatement node.
         */
        function visitExpressionStatement(node) {
            // If we are here it is most likely because our expression is a destructuring assignment.
            switch (node.expression.kind) {
                case 196 /* ParenthesizedExpression */:
                    return ts.updateExpressionStatement(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false));
                case 205 /* BinaryExpression */:
                    return ts.updateExpressionStatement(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a ParenthesizedExpression that may contain a destructuring assignment.
         *
         * @param node A ParenthesizedExpression node.
         * @param needsDestructuringValue A value indicating whether we need to hold onto the rhs
         *                                of a destructuring assignment.
         */
        function visitParenthesizedExpression(node, needsDestructuringValue) {
            // If we are here it is most likely because our expression is a destructuring assignment.
            if (!needsDestructuringValue) {
                // By default we always emit the RHS at the end of a flattened destructuring
                // expression. If we are in a state where we do not need the destructuring value,
                // we pass that information along to the children that care about it.
                switch (node.expression.kind) {
                    case 196 /* ParenthesizedExpression */:
                        return ts.updateParen(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false));
                    case 205 /* BinaryExpression */:
                        return ts.updateParen(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false));
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a BinaryExpression that contains a destructuring assignment.
         *
         * @param node A BinaryExpression node.
         * @param needsDestructuringValue A value indicating whether we need to hold onto the rhs
         *                                of a destructuring assignment.
         */
        function visitBinaryExpression(node, needsDestructuringValue) {
            // If we are here it is because this is a destructuring assignment.
            if (ts.isDestructuringAssignment(node)) {
                return ts.flattenDestructuringAssignment(node, visitor, context, 0 /* All */, needsDestructuringValue);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitVariableStatement(node) {
            var ancestorFacts = enterSubtree(0 /* None */, ts.hasModifier(node, 1 /* Export */) ? 32 /* ExportedVariableStatement */ : 0 /* None */);
            var updated;
            if (convertedLoopState && (node.declarationList.flags & 3 /* BlockScoped */) === 0) {
                // we are inside a converted loop - hoist variable declarations
                var assignments = void 0;
                for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    hoistVariableDeclarationDeclaredInConvertedLoop(convertedLoopState, decl);
                    if (decl.initializer) {
                        var assignment = void 0;
                        if (ts.isBindingPattern(decl.name)) {
                            assignment = ts.flattenDestructuringAssignment(decl, visitor, context, 0 /* All */);
                        }
                        else {
                            assignment = ts.createBinary(decl.name, 60 /* EqualsToken */, ts.visitNode(decl.initializer, visitor, ts.isExpression));
                            ts.setTextRange(assignment, decl);
                        }
                        assignments = ts.append(assignments, assignment);
                    }
                }
                if (assignments) {
                    updated = ts.setTextRange(ts.createExpressionStatement(ts.inlineExpressions(assignments)), node);
                }
                else {
                    // none of declarations has initializer - the entire variable statement can be deleted
                    updated = undefined;
                }
            }
            else {
                updated = ts.visitEachChild(node, visitor, context);
            }
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        /**
         * Visits a VariableDeclarationList that is block scoped (e.g. `let` or `const`).
         *
         * @param node A VariableDeclarationList node.
         */
        function visitVariableDeclarationList(node) {
            if (node.flags & 3 /* BlockScoped */ || node.transformFlags & 65536 /* ContainsBindingPattern */) {
                if (node.flags & 3 /* BlockScoped */) {
                    enableSubstitutionsForBlockScopedBindings();
                }
                var declarations = ts.flatMap(node.declarations, node.flags & 1 /* Let */
                    ? visitVariableDeclarationInLetDeclarationList
                    : visitVariableDeclaration);
                var declarationList = ts.createVariableDeclarationList(declarations);
                ts.setOriginalNode(declarationList, node);
                ts.setTextRange(declarationList, node);
                ts.setCommentRange(declarationList, node);
                // If the first or last declaration is a binding pattern, we need to modify
                // the source map range for the declaration list.
                if (node.transformFlags & 65536 /* ContainsBindingPattern */
                    && (ts.isBindingPattern(node.declarations[0].name) || ts.isBindingPattern(ts.last(node.declarations).name))) {
                    ts.setSourceMapRange(declarationList, getRangeUnion(declarations));
                }
                return declarationList;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function getRangeUnion(declarations) {
            // declarations may not be sorted by position.
            // pos should be the minimum* position over all nodes (that's not -1), end should be the maximum end over all nodes.
            var pos = -1, end = -1;
            for (var _i = 0, declarations_10 = declarations; _i < declarations_10.length; _i++) {
                var node = declarations_10[_i];
                pos = pos === -1 ? node.pos : node.pos === -1 ? pos : Math.min(pos, node.pos);
                end = Math.max(end, node.end);
            }
            return ts.createRange(pos, end);
        }
        /**
         * Gets a value indicating whether we should emit an explicit initializer for a variable
         * declaration in a `let` declaration list.
         *
         * @param node A VariableDeclaration node.
         */
        function shouldEmitExplicitInitializerForLetDeclaration(node) {
            // Nested let bindings might need to be initialized explicitly to preserve
            // ES6 semantic:
            //
            //  { let x = 1; }
            //  { let x; } // x here should be undefined. not 1
            //
            // Top level bindings never collide with anything and thus don't require
            // explicit initialization. As for nested let bindings there are two cases:
            //
            // - Nested let bindings that were not renamed definitely should be
            //   initialized explicitly:
            //
            //    { let x = 1; }
            //    { let x; if (some-condition) { x = 1}; if (x) { /*1*/ } }
            //
            //   Without explicit initialization code in /*1*/ can be executed even if
            //   some-condition is evaluated to false.
            //
            // - Renaming introduces fresh name that should not collide with any
            //   existing names, however renamed bindings sometimes also should be
            //   explicitly initialized. One particular case: non-captured binding
            //   declared inside loop body (but not in loop initializer):
            //
            //    let x;
            //    for (;;) {
            //        let x;
            //    }
            //
            //   In downlevel codegen inner 'x' will be renamed so it won't collide
            //   with outer 'x' however it will should be reset on every iteration as
            //   if it was declared anew.
            //
            //   * Why non-captured binding?
            //     - Because if loop contains block scoped binding captured in some
            //       function then loop body will be rewritten to have a fresh scope
            //       on every iteration so everything will just work.
            //
            //   * Why loop initializer is excluded?
            //     - Since we've introduced a fresh name it already will be undefined.
            var flags = resolver.getNodeCheckFlags(node);
            var isCapturedInFunction = flags & 262144 /* CapturedBlockScopedBinding */;
            var isDeclaredInLoop = flags & 524288 /* BlockScopedBindingInLoop */;
            var emittedAsTopLevel = (hierarchyFacts & 64 /* TopLevel */) !== 0
                || (isCapturedInFunction
                    && isDeclaredInLoop
                    && (hierarchyFacts & 512 /* IterationStatementBlock */) !== 0);
            var emitExplicitInitializer = !emittedAsTopLevel
                && (hierarchyFacts & 4096 /* ForInOrForOfStatement */) === 0
                && (!resolver.isDeclarationWithCollidingName(node)
                    || (isDeclaredInLoop
                        && !isCapturedInFunction
                        && (hierarchyFacts & (2048 /* ForStatement */ | 4096 /* ForInOrForOfStatement */)) === 0));
            return emitExplicitInitializer;
        }
        /**
         * Visits a VariableDeclaration in a `let` declaration list.
         *
         * @param node A VariableDeclaration node.
         */
        function visitVariableDeclarationInLetDeclarationList(node) {
            // For binding pattern names that lack initializers there is no point to emit
            // explicit initializer since downlevel codegen for destructuring will fail
            // in the absence of initializer so all binding elements will say uninitialized
            var name = node.name;
            if (ts.isBindingPattern(name)) {
                return visitVariableDeclaration(node);
            }
            if (!node.initializer && shouldEmitExplicitInitializerForLetDeclaration(node)) {
                var clone_2 = ts.getMutableClone(node);
                clone_2.initializer = ts.createVoidZero();
                return clone_2;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a VariableDeclaration node with a binding pattern.
         *
         * @param node A VariableDeclaration node.
         */
        function visitVariableDeclaration(node) {
            var ancestorFacts = enterSubtree(32 /* ExportedVariableStatement */, 0 /* None */);
            var updated;
            if (ts.isBindingPattern(node.name)) {
                updated = ts.flattenDestructuringBinding(node, visitor, context, 0 /* All */, 
                /*value*/ undefined, (ancestorFacts & 32 /* ExportedVariableStatement */) !== 0);
            }
            else {
                updated = ts.visitEachChild(node, visitor, context);
            }
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function recordLabel(node) {
            convertedLoopState.labels.set(ts.idText(node.label), true);
        }
        function resetLabel(node) {
            convertedLoopState.labels.set(ts.idText(node.label), false);
        }
        function visitLabeledStatement(node) {
            if (convertedLoopState && !convertedLoopState.labels) {
                convertedLoopState.labels = ts.createMap();
            }
            var statement = ts.unwrapInnermostStatementOfLabel(node, convertedLoopState && recordLabel);
            return ts.isIterationStatement(statement, /*lookInLabeledStatements*/ false)
                ? visitIterationStatement(statement, /*outermostLabeledStatement*/ node)
                : ts.restoreEnclosingLabel(ts.visitNode(statement, visitor, ts.isStatement, ts.liftToBlock), node, convertedLoopState && resetLabel);
        }
        function visitIterationStatement(node, outermostLabeledStatement) {
            switch (node.kind) {
                case 224 /* DoStatement */:
                case 225 /* WhileStatement */:
                    return visitDoOrWhileStatement(node, outermostLabeledStatement);
                case 226 /* ForStatement */:
                    return visitForStatement(node, outermostLabeledStatement);
                case 227 /* ForInStatement */:
                    return visitForInStatement(node, outermostLabeledStatement);
                case 228 /* ForOfStatement */:
                    return visitForOfStatement(node, outermostLabeledStatement);
            }
        }
        function visitIterationStatementWithFacts(excludeFacts, includeFacts, node, outermostLabeledStatement, convert) {
            var ancestorFacts = enterSubtree(excludeFacts, includeFacts);
            var updated = convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, ancestorFacts, convert);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function visitDoOrWhileStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(0 /* DoOrWhileStatementExcludes */, 1280 /* DoOrWhileStatementIncludes */, node, outermostLabeledStatement);
        }
        function visitForStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(5056 /* ForStatementExcludes */, 3328 /* ForStatementIncludes */, node, outermostLabeledStatement);
        }
        function visitForInStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(3008 /* ForInOrForOfStatementExcludes */, 5376 /* ForInOrForOfStatementIncludes */, node, outermostLabeledStatement);
        }
        function visitForOfStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(3008 /* ForInOrForOfStatementExcludes */, 5376 /* ForInOrForOfStatementIncludes */, node, outermostLabeledStatement, compilerOptions.downlevelIteration ? convertForOfStatementForIterable : convertForOfStatementForArray);
        }
        function convertForOfStatementHead(node, boundValue, convertedLoopBodyStatements) {
            var statements = [];
            var initializer = node.initializer;
            if (ts.isVariableDeclarationList(initializer)) {
                if (node.initializer.flags & 3 /* BlockScoped */) {
                    enableSubstitutionsForBlockScopedBindings();
                }
                var firstOriginalDeclaration = ts.firstOrUndefined(initializer.declarations);
                if (firstOriginalDeclaration && ts.isBindingPattern(firstOriginalDeclaration.name)) {
                    // This works whether the declaration is a var, let, or const.
                    // It will use rhsIterationValue _a[_i] as the initializer.
                    var declarations = ts.flattenDestructuringBinding(firstOriginalDeclaration, visitor, context, 0 /* All */, boundValue);
                    var declarationList = ts.setTextRange(ts.createVariableDeclarationList(declarations), node.initializer);
                    ts.setOriginalNode(declarationList, node.initializer);
                    // Adjust the source map range for the first declaration to align with the old
                    // emitter.
                    ts.setSourceMapRange(declarationList, ts.createRange(declarations[0].pos, ts.last(declarations).end));
                    statements.push(ts.createVariableStatement(
                    /*modifiers*/ undefined, declarationList));
                }
                else {
                    // The following call does not include the initializer, so we have
                    // to emit it separately.
                    statements.push(ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.setOriginalNode(ts.setTextRange(ts.createVariableDeclarationList([
                        ts.createVariableDeclaration(firstOriginalDeclaration ? firstOriginalDeclaration.name : ts.createTempVariable(/*recordTempVariable*/ undefined), 
                        /*type*/ undefined, boundValue)
                    ]), ts.moveRangePos(initializer, -1)), initializer)), ts.moveRangeEnd(initializer, -1)));
                }
            }
            else {
                // Initializer is an expression. Emit the expression in the body, so that it's
                // evaluated on every iteration.
                var assignment = ts.createAssignment(initializer, boundValue);
                if (ts.isDestructuringAssignment(assignment)) {
                    ts.aggregateTransformFlags(assignment);
                    statements.push(ts.createExpressionStatement(visitBinaryExpression(assignment, /*needsDestructuringValue*/ false)));
                }
                else {
                    assignment.end = initializer.end;
                    statements.push(ts.setTextRange(ts.createExpressionStatement(ts.visitNode(assignment, visitor, ts.isExpression)), ts.moveRangeEnd(initializer, -1)));
                }
            }
            if (convertedLoopBodyStatements) {
                return createSyntheticBlockForConvertedStatements(ts.addRange(statements, convertedLoopBodyStatements));
            }
            else {
                var statement = ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock);
                if (ts.isBlock(statement)) {
                    return ts.updateBlock(statement, ts.setTextRange(ts.createNodeArray(ts.concatenate(statements, statement.statements)), statement.statements));
                }
                else {
                    statements.push(statement);
                    return createSyntheticBlockForConvertedStatements(statements);
                }
            }
        }
        function createSyntheticBlockForConvertedStatements(statements) {
            return ts.setEmitFlags(ts.createBlock(ts.createNodeArray(statements), 
            /*multiLine*/ true), 48 /* NoSourceMap */ | 384 /* NoTokenSourceMaps */);
        }
        function convertForOfStatementForArray(node, outermostLabeledStatement, convertedLoopBodyStatements) {
            // The following ES6 code:
            //
            //    for (let v of expr) { }
            //
            // should be emitted as
            //
            //    for (var _i = 0, _a = expr; _i < _a.length; _i++) {
            //        var v = _a[_i];
            //    }
            //
            // where _a and _i are temps emitted to capture the RHS and the counter,
            // respectively.
            // When the left hand side is an expression instead of a let declaration,
            // the "let v" is not emitted.
            // When the left hand side is a let/const, the v is renamed if there is
            // another v in scope.
            // Note that all assignments to the LHS are emitted in the body, including
            // all destructuring.
            // Note also that because an extra statement is needed to assign to the LHS,
            // for-of bodies are always emitted as blocks.
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            // In the case where the user wrote an identifier as the RHS, like this:
            //
            //     for (let v of arr) { }
            //
            // we don't want to emit a temporary variable for the RHS, just use it directly.
            var counter = ts.createLoopVariable();
            var rhsReference = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            // The old emitter does not emit source maps for the expression
            ts.setEmitFlags(expression, 48 /* NoSourceMap */ | ts.getEmitFlags(expression));
            var forStatement = ts.setTextRange(ts.createFor(
            /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([
                ts.setTextRange(ts.createVariableDeclaration(counter, /*type*/ undefined, ts.createLiteral(0)), ts.moveRangePos(node.expression, -1)),
                ts.setTextRange(ts.createVariableDeclaration(rhsReference, /*type*/ undefined, expression), node.expression)
            ]), node.expression), 2097152 /* NoHoisting */), 
            /*condition*/ ts.setTextRange(ts.createLessThan(counter, ts.createPropertyAccess(rhsReference, "length")), node.expression), 
            /*incrementor*/ ts.setTextRange(ts.createPostfixIncrement(counter), node.expression), 
            /*statement*/ convertForOfStatementHead(node, ts.createElementAccess(rhsReference, counter), convertedLoopBodyStatements)), 
            /*location*/ node);
            // Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter.
            ts.setEmitFlags(forStatement, 256 /* NoTokenTrailingSourceMaps */);
            ts.setTextRange(forStatement, node);
            return ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel);
        }
        function convertForOfStatementForIterable(node, outermostLabeledStatement, convertedLoopBodyStatements, ancestorFacts) {
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            var iterator = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var result = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(iterator) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var errorRecord = ts.createUniqueName("e");
            var catchVariable = ts.getGeneratedNameForNode(errorRecord);
            var returnMethod = ts.createTempVariable(/*recordTempVariable*/ undefined);
            var values = ts.createValuesHelper(context, expression, node.expression);
            var next = ts.createCall(ts.createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []);
            hoistVariableDeclaration(errorRecord);
            hoistVariableDeclaration(returnMethod);
            // if we are enclosed in an outer loop ensure we reset 'errorRecord' per each iteration
            var initializer = ancestorFacts & 1024 /* IterationContainer */
                ? ts.inlineExpressions([ts.createAssignment(errorRecord, ts.createVoidZero()), values])
                : values;
            var forStatement = ts.setEmitFlags(ts.setTextRange(ts.createFor(
            /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([
                ts.setTextRange(ts.createVariableDeclaration(iterator, /*type*/ undefined, initializer), node.expression),
                ts.createVariableDeclaration(result, /*type*/ undefined, next)
            ]), node.expression), 2097152 /* NoHoisting */), 
            /*condition*/ ts.createLogicalNot(ts.createPropertyAccess(result, "done")), 
            /*incrementor*/ ts.createAssignment(result, next), 
            /*statement*/ convertForOfStatementHead(node, ts.createPropertyAccess(result, "value"), convertedLoopBodyStatements)), 
            /*location*/ node), 256 /* NoTokenTrailingSourceMaps */);
            return ts.createTry(ts.createBlock([
                ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel)
            ]), ts.createCatchClause(ts.createVariableDeclaration(catchVariable), ts.setEmitFlags(ts.createBlock([
                ts.createExpressionStatement(ts.createAssignment(errorRecord, ts.createObjectLiteral([
                    ts.createPropertyAssignment("error", catchVariable)
                ])))
            ]), 1 /* SingleLine */)), ts.createBlock([
                ts.createTry(
                /*tryBlock*/ ts.createBlock([
                    ts.setEmitFlags(ts.createIf(ts.createLogicalAnd(ts.createLogicalAnd(result, ts.createLogicalNot(ts.createPropertyAccess(result, "done"))), ts.createAssignment(returnMethod, ts.createPropertyAccess(iterator, "return"))), ts.createExpressionStatement(ts.createFunctionCall(returnMethod, iterator, []))), 1 /* SingleLine */),
                ]), 
                /*catchClause*/ undefined, 
                /*finallyBlock*/ ts.setEmitFlags(ts.createBlock([
                    ts.setEmitFlags(ts.createIf(errorRecord, ts.createThrow(ts.createPropertyAccess(errorRecord, "error"))), 1 /* SingleLine */)
                ]), 1 /* SingleLine */))
            ]));
        }
        /**
         * Visits an ObjectLiteralExpression with computed property names.
         *
         * @param node An ObjectLiteralExpression node.
         */
        function visitObjectLiteralExpression(node) {
            // We are here because a ComputedPropertyName was used somewhere in the expression.
            var properties = node.properties;
            var numProperties = properties.length;
            // Find the first computed property.
            // Everything until that point can be emitted as part of the initial object literal.
            var numInitialProperties = numProperties;
            var numInitialPropertiesWithoutYield = numProperties;
            for (var i = 0; i < numProperties; i++) {
                var property = properties[i];
                if ((property.transformFlags & 131072 /* ContainsYield */ && hierarchyFacts & 4 /* AsyncFunctionBody */)
                    && i < numInitialPropertiesWithoutYield) {
                    numInitialPropertiesWithoutYield = i;
                }
                if (property.name.kind === 150 /* ComputedPropertyName */) {
                    numInitialProperties = i;
                    break;
                }
            }
            if (numInitialProperties !== numProperties) {
                if (numInitialPropertiesWithoutYield < numInitialProperties) {
                    numInitialProperties = numInitialPropertiesWithoutYield;
                }
                // For computed properties, we need to create a unique handle to the object
                // literal so we can modify it without risking internal assignments tainting the object.
                var temp = ts.createTempVariable(hoistVariableDeclaration);
                // Write out the first non-computed properties, then emit the rest through indexing on the temp variable.
                var expressions = [];
                var assignment = ts.createAssignment(temp, ts.setEmitFlags(ts.createObjectLiteral(ts.visitNodes(properties, visitor, ts.isObjectLiteralElementLike, 0, numInitialProperties), node.multiLine), 65536 /* Indented */));
                if (node.multiLine) {
                    ts.startOnNewLine(assignment);
                }
                expressions.push(assignment);
                addObjectLiteralMembers(expressions, node, temp, numInitialProperties);
                // We need to clone the temporary identifier so that we can write it on a
                // new line
                expressions.push(node.multiLine ? ts.startOnNewLine(ts.getMutableClone(temp)) : temp);
                return ts.inlineExpressions(expressions);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function shouldConvertPartOfIterationStatement(node) {
            return (resolver.getNodeCheckFlags(node) & 131072 /* ContainsCapturedBlockScopeBinding */) !== 0;
        }
        function shouldConvertInitializerOfForStatement(node) {
            return ts.isForStatement(node) && !!node.initializer && shouldConvertPartOfIterationStatement(node.initializer);
        }
        function shouldConvertConditionOfForStatement(node) {
            return ts.isForStatement(node) && !!node.condition && shouldConvertPartOfIterationStatement(node.condition);
        }
        function shouldConvertIncrementorOfForStatement(node) {
            return ts.isForStatement(node) && !!node.incrementor && shouldConvertPartOfIterationStatement(node.incrementor);
        }
        function shouldConvertIterationStatement(node) {
            return shouldConvertBodyOfIterationStatement(node)
                || shouldConvertInitializerOfForStatement(node);
        }
        function shouldConvertBodyOfIterationStatement(node) {
            return (resolver.getNodeCheckFlags(node) & 65536 /* LoopWithCapturedBlockScopedBinding */) !== 0;
        }
        /**
         * Records constituents of name for the given variable to be hoisted in the outer scope.
         */
        function hoistVariableDeclarationDeclaredInConvertedLoop(state, node) {
            if (!state.hoistedLocalVariables) {
                state.hoistedLocalVariables = [];
            }
            visit(node.name);
            function visit(node) {
                if (node.kind === 73 /* Identifier */) {
                    state.hoistedLocalVariables.push(node);
                }
                else {
                    for (var _i = 0, _a = node.elements; _i < _a.length; _i++) {
                        var element = _a[_i];
                        if (!ts.isOmittedExpression(element)) {
                            visit(element.name);
                        }
                    }
                }
            }
        }
        function convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, ancestorFacts, convert) {
            if (!shouldConvertIterationStatement(node)) {
                var saveAllowedNonLabeledJumps = void 0;
                if (convertedLoopState) {
                    // we get here if we are trying to emit normal loop loop inside converted loop
                    // set allowedNonLabeledJumps to Break | Continue to mark that break\continue inside the loop should be emitted as is
                    saveAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
                    convertedLoopState.allowedNonLabeledJumps = 2 /* Break */ | 4 /* Continue */;
                }
                var result = convert
                    ? convert(node, outermostLabeledStatement, /*convertedLoopBodyStatements*/ undefined, ancestorFacts)
                    : ts.restoreEnclosingLabel(ts.visitEachChild(node, visitor, context), outermostLabeledStatement, convertedLoopState && resetLabel);
                if (convertedLoopState) {
                    convertedLoopState.allowedNonLabeledJumps = saveAllowedNonLabeledJumps;
                }
                return result;
            }
            var currentState = createConvertedLoopState(node);
            var statements = [];
            var outerConvertedLoopState = convertedLoopState;
            convertedLoopState = currentState;
            var initializerFunction = shouldConvertInitializerOfForStatement(node) ? createFunctionForInitializerOfForStatement(node, currentState) : undefined;
            var bodyFunction = shouldConvertBodyOfIterationStatement(node) ? createFunctionForBodyOfIterationStatement(node, currentState, outerConvertedLoopState) : undefined;
            convertedLoopState = outerConvertedLoopState;
            if (initializerFunction)
                statements.push(initializerFunction.functionDeclaration);
            if (bodyFunction)
                statements.push(bodyFunction.functionDeclaration);
            addExtraDeclarationsForConvertedLoop(statements, currentState, outerConvertedLoopState);
            if (initializerFunction) {
                statements.push(generateCallToConvertedLoopInitializer(initializerFunction.functionName, initializerFunction.containsYield));
            }
            var loop;
            if (bodyFunction) {
                if (convert) {
                    loop = convert(node, outermostLabeledStatement, bodyFunction.part, ancestorFacts);
                }
                else {
                    var clone_3 = convertIterationStatementCore(node, initializerFunction, ts.createBlock(bodyFunction.part, /*multiLine*/ true));
                    ts.aggregateTransformFlags(clone_3);
                    loop = ts.restoreEnclosingLabel(clone_3, outermostLabeledStatement, convertedLoopState && resetLabel);
                }
            }
            else {
                var clone_4 = convertIterationStatementCore(node, initializerFunction, ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
                ts.aggregateTransformFlags(clone_4);
                loop = ts.restoreEnclosingLabel(clone_4, outermostLabeledStatement, convertedLoopState && resetLabel);
            }
            statements.push(loop);
            return statements;
        }
        function convertIterationStatementCore(node, initializerFunction, convertedLoopBody) {
            switch (node.kind) {
                case 226 /* ForStatement */: return convertForStatement(node, initializerFunction, convertedLoopBody);
                case 227 /* ForInStatement */: return convertForInStatement(node, convertedLoopBody);
                case 228 /* ForOfStatement */: return convertForOfStatement(node, convertedLoopBody);
                case 224 /* DoStatement */: return convertDoStatement(node, convertedLoopBody);
                case 225 /* WhileStatement */: return convertWhileStatement(node, convertedLoopBody);
                default: return ts.Debug.failBadSyntaxKind(node, "IterationStatement expected");
            }
        }
        function convertForStatement(node, initializerFunction, convertedLoopBody) {
            var shouldConvertCondition = node.condition && shouldConvertPartOfIterationStatement(node.condition);
            var shouldConvertIncrementor = shouldConvertCondition || node.incrementor && shouldConvertPartOfIterationStatement(node.incrementor);
            return ts.updateFor(node, ts.visitNode(initializerFunction ? initializerFunction.part : node.initializer, visitor, ts.isForInitializer), ts.visitNode(shouldConvertCondition ? undefined : node.condition, visitor, ts.isExpression), ts.visitNode(shouldConvertIncrementor ? undefined : node.incrementor, visitor, ts.isExpression), convertedLoopBody);
        }
        function convertForOfStatement(node, convertedLoopBody) {
            return ts.updateForOf(node, 
            /*awaitModifier*/ undefined, ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.expression, visitor, ts.isExpression), convertedLoopBody);
        }
        function convertForInStatement(node, convertedLoopBody) {
            return ts.updateForIn(node, ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.expression, visitor, ts.isExpression), convertedLoopBody);
        }
        function convertDoStatement(node, convertedLoopBody) {
            return ts.updateDo(node, convertedLoopBody, ts.visitNode(node.expression, visitor, ts.isExpression));
        }
        function convertWhileStatement(node, convertedLoopBody) {
            return ts.updateWhile(node, ts.visitNode(node.expression, visitor, ts.isExpression), convertedLoopBody);
        }
        function createConvertedLoopState(node) {
            var loopInitializer;
            switch (node.kind) {
                case 226 /* ForStatement */:
                case 227 /* ForInStatement */:
                case 228 /* ForOfStatement */:
                    var initializer = node.initializer;
                    if (initializer && initializer.kind === 239 /* VariableDeclarationList */) {
                        loopInitializer = initializer;
                    }
                    break;
            }
            // variables that will be passed to the loop as parameters
            var loopParameters = [];
            // variables declared in the loop initializer that will be changed inside the loop
            var loopOutParameters = [];
            if (loopInitializer && (ts.getCombinedNodeFlags(loopInitializer) & 3 /* BlockScoped */)) {
                var hasCapturedBindingsInForInitializer = shouldConvertInitializerOfForStatement(node);
                for (var _i = 0, _a = loopInitializer.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    processLoopVariableDeclaration(node, decl, loopParameters, loopOutParameters, hasCapturedBindingsInForInitializer);
                }
            }
            var currentState = { loopParameters: loopParameters, loopOutParameters: loopOutParameters };
            if (convertedLoopState) {
                // convertedOuterLoopState !== undefined means that this converted loop is nested in another converted loop.
                // if outer converted loop has already accumulated some state - pass it through
                if (convertedLoopState.argumentsName) {
                    // outer loop has already used 'arguments' so we've already have some name to alias it
                    // use the same name in all nested loops
                    currentState.argumentsName = convertedLoopState.argumentsName;
                }
                if (convertedLoopState.thisName) {
                    // outer loop has already used 'this' so we've already have some name to alias it
                    // use the same name in all nested loops
                    currentState.thisName = convertedLoopState.thisName;
                }
                if (convertedLoopState.hoistedLocalVariables) {
                    // we've already collected some non-block scoped variable declarations in enclosing loop
                    // use the same storage in nested loop
                    currentState.hoistedLocalVariables = convertedLoopState.hoistedLocalVariables;
                }
            }
            return currentState;
        }
        function addExtraDeclarationsForConvertedLoop(statements, state, outerState) {
            var extraVariableDeclarations;
            // propagate state from the inner loop to the outer loop if necessary
            if (state.argumentsName) {
                // if alias for arguments is set
                if (outerState) {
                    // pass it to outer converted loop
                    outerState.argumentsName = state.argumentsName;
                }
                else {
                    // this is top level converted loop and we need to create an alias for 'arguments' object
                    (extraVariableDeclarations || (extraVariableDeclarations = [])).push(ts.createVariableDeclaration(state.argumentsName, 
                    /*type*/ undefined, ts.createIdentifier("arguments")));
                }
            }
            if (state.thisName) {
                // if alias for this is set
                if (outerState) {
                    // pass it to outer converted loop
                    outerState.thisName = state.thisName;
                }
                else {
                    // this is top level converted loop so we need to create an alias for 'this' here
                    // NOTE:
                    // if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set.
                    // If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'.
                    (extraVariableDeclarations || (extraVariableDeclarations = [])).push(ts.createVariableDeclaration(state.thisName, 
                    /*type*/ undefined, ts.createIdentifier("this")));
                }
            }
            if (state.hoistedLocalVariables) {
                // if hoistedLocalVariables !== undefined this means that we've possibly collected some variable declarations to be hoisted later
                if (outerState) {
                    // pass them to outer converted loop
                    outerState.hoistedLocalVariables = state.hoistedLocalVariables;
                }
                else {
                    if (!extraVariableDeclarations) {
                        extraVariableDeclarations = [];
                    }
                    // hoist collected variable declarations
                    for (var _i = 0, _a = state.hoistedLocalVariables; _i < _a.length; _i++) {
                        var identifier = _a[_i];
                        extraVariableDeclarations.push(ts.createVariableDeclaration(identifier));
                    }
                }
            }
            // add extra variables to hold out parameters if necessary
            if (state.loopOutParameters.length) {
                if (!extraVariableDeclarations) {
                    extraVariableDeclarations = [];
                }
                for (var _b = 0, _c = state.loopOutParameters; _b < _c.length; _b++) {
                    var outParam = _c[_b];
                    extraVariableDeclarations.push(ts.createVariableDeclaration(outParam.outParamName));
                }
            }
            if (state.conditionVariable) {
                if (!extraVariableDeclarations) {
                    extraVariableDeclarations = [];
                }
                extraVariableDeclarations.push(ts.createVariableDeclaration(state.conditionVariable, /*type*/ undefined, ts.createFalse()));
            }
            // create variable statement to hold all introduced variable declarations
            if (extraVariableDeclarations) {
                statements.push(ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList(extraVariableDeclarations)));
            }
        }
        function createOutVariable(p) {
            return ts.createVariableDeclaration(p.originalName, /*type*/ undefined, p.outParamName);
        }
        /**
         * Creates a `_loop_init` function for a `ForStatement` with a block-scoped initializer
         * that is captured in a closure inside of the initializer. The `_loop_init` function is
         * used to preserve the per-iteration environment semantics of
         * [13.7.4.8 RS: ForBodyEvaluation](https://tc39.github.io/ecma262/#sec-forbodyevaluation).
         */
        function createFunctionForInitializerOfForStatement(node, currentState) {
            var functionName = ts.createUniqueName("_loop_init");
            var containsYield = (node.initializer.transformFlags & 131072 /* ContainsYield */) !== 0;
            var emitFlags = 0 /* None */;
            if (currentState.containsLexicalThis)
                emitFlags |= 8 /* CapturesThis */;
            if (containsYield && hierarchyFacts & 4 /* AsyncFunctionBody */)
                emitFlags |= 262144 /* AsyncFunctionBody */;
            var statements = [];
            statements.push(ts.createVariableStatement(/*modifiers*/ undefined, node.initializer));
            copyOutParameters(currentState.loopOutParameters, 2 /* Initializer */, 1 /* ToOutParameter */, statements);
            // This transforms the following ES2015 syntax:
            //
            //  for (let i = (setImmediate(() => console.log(i)), 0); i < 2; i++) {
            //      // loop body
            //  }
            //
            // Into the following ES5 syntax:
            //
            //  var _loop_init_1 = function () {
            //      var i = (setImmediate(() => console.log(i)), 0);
            //      out_i_1 = i;
            //  };
            //  var out_i_1;
            //  _loop_init_1();
            //  for (var i = out_i_1; i < 2; i++) {
            //      // loop body
            //  }
            //
            // Which prevents mutations to `i` in the per-iteration environment of the body
            // from affecting the initial value for `i` outside of the per-iteration environment.
            var functionDeclaration = ts.createVariableStatement(
            /*modifiers*/ undefined, ts.setEmitFlags(ts.createVariableDeclarationList([
                ts.createVariableDeclaration(functionName, 
                /*type*/ undefined, ts.setEmitFlags(ts.createFunctionExpression(
                /*modifiers*/ undefined, containsYield ? ts.createToken(40 /* AsteriskToken */) : undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, 
                /*parameters*/ undefined, 
                /*type*/ undefined, ts.visitNode(ts.createBlock(statements, /*multiLine*/ true), visitor, ts.isBlock)), emitFlags))
            ]), 2097152 /* NoHoisting */));
            var part = ts.createVariableDeclarationList(ts.map(currentState.loopOutParameters, createOutVariable));
            return { functionName: functionName, containsYield: containsYield, functionDeclaration: functionDeclaration, part: part };
        }
        /**
         * Creates a `_loop` function for an `IterationStatement` with a block-scoped initializer
         * that is captured in a closure inside of the loop body. The `_loop` function is used to
         * preserve the per-iteration environment semantics of
         * [13.7.4.8 RS: ForBodyEvaluation](https://tc39.github.io/ecma262/#sec-forbodyevaluation).
         */
        function createFunctionForBodyOfIterationStatement(node, currentState, outerState) {
            var functionName = ts.createUniqueName("_loop");
            startLexicalEnvironment();
            var statement = ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock);
            var lexicalEnvironment = endLexicalEnvironment();
            var statements = [];
            if (shouldConvertConditionOfForStatement(node) || shouldConvertIncrementorOfForStatement(node)) {
                // If a block-scoped variable declared in the initializer of `node` is captured in
                // the condition or incrementor, we must move the condition and incrementor into
                // the body of the for loop.
                //
                // This transforms the following ES2015 syntax:
                //
                //  for (let i = 0; setImmediate(() => console.log(i)), i < 2; setImmediate(() => console.log(i)), i++) {
                //      // loop body
                //  }
                //
                // Into the following ES5 syntax:
                //
                //  var _loop_1 = function (i) {
                //      if (inc_1)
                //          setImmediate(() => console.log(i)), i++;
                //      else
                //          inc_1 = true;
                //      if (!(setImmediate(() => console.log(i)), i < 2))
                //          return out_i_1 = i, "break";
                //      // loop body
                //      out_i_1 = i;
                //  }
                //  var out_i_1, inc_1 = false;
                //  for (var i = 0;;) {
                //      var state_1 = _loop_1(i);
                //      i = out_i_1;
                //      if (state_1 === "break")
                //          break;
                //  }
                //
                // Which prevents mutations to `i` in the per-iteration environment of the body
                // from affecting the value of `i` in the previous per-iteration environment.
                //
                // Note that the incrementor of a `for` loop is evaluated in a *new* per-iteration
                // environment that is carried over to the next iteration of the loop. As a result,
                // we must indicate whether this is the first evaluation of the loop body so that
                // we only evaluate the incrementor on subsequent evaluations.
                currentState.conditionVariable = ts.createUniqueName("inc");
                statements.push(ts.createIf(currentState.conditionVariable, ts.createStatement(ts.visitNode(node.incrementor, visitor, ts.isExpression)), ts.createStatement(ts.createAssignment(currentState.conditionVariable, ts.createTrue()))));
                if (shouldConvertConditionOfForStatement(node)) {
                    statements.push(ts.createIf(ts.createPrefix(52 /* ExclamationToken */, ts.visitNode(node.condition, visitor, ts.isExpression)), ts.visitNode(ts.createBreak(), visitor, ts.isStatement)));
                }
            }
            if (ts.isBlock(statement)) {
                ts.addRange(statements, statement.statements);
            }
            else {
                statements.push(statement);
            }
            copyOutParameters(currentState.loopOutParameters, 1 /* Body */, 1 /* ToOutParameter */, statements);
            ts.insertStatementsAfterStandardPrologue(statements, lexicalEnvironment);
            var loopBody = ts.createBlock(statements, /*multiLine*/ true);
            if (ts.isBlock(statement))
                ts.setOriginalNode(loopBody, statement);
            var containsYield = (node.statement.transformFlags & 131072 /* ContainsYield */) !== 0;
            var emitFlags = 0;
            if (currentState.containsLexicalThis)
                emitFlags |= 8 /* CapturesThis */;
            if (containsYield && (hierarchyFacts & 4 /* AsyncFunctionBody */) !== 0)
                emitFlags |= 262144 /* AsyncFunctionBody */;
            // This transforms the following ES2015 syntax (in addition to other variations):
            //
            //  for (let i = 0; i < 2; i++) {
            //      setImmediate(() => console.log(i));
            //  }
            //
            // Into the following ES5 syntax:
            //
            //  var _loop_1 = function (i) {
            //      setImmediate(() => console.log(i));
            //  };
            //  for (var i = 0; i < 2; i++) {
            //      _loop_1(i);
            //  }
            var functionDeclaration = ts.createVariableStatement(
            /*modifiers*/ undefined, ts.setEmitFlags(ts.createVariableDeclarationList([
                ts.createVariableDeclaration(functionName, 
                /*type*/ undefined, ts.setEmitFlags(ts.createFunctionExpression(
                /*modifiers*/ undefined, containsYield ? ts.createToken(40 /* AsteriskToken */) : undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, currentState.loopParameters, 
                /*type*/ undefined, loopBody), emitFlags))
            ]), 2097152 /* NoHoisting */));
            var part = generateCallToConvertedLoop(functionName, currentState, outerState, containsYield);
            return { functionName: functionName, containsYield: containsYield, functionDeclaration: functionDeclaration, part: part };
        }
        function copyOutParameter(outParam, copyDirection) {
            var source = copyDirection === 0 /* ToOriginal */ ? outParam.outParamName : outParam.originalName;
            var target = copyDirection === 0 /* ToOriginal */ ? outParam.originalName : outParam.outParamName;
            return ts.createBinary(target, 60 /* EqualsToken */, source);
        }
        function copyOutParameters(outParams, partFlags, copyDirection, statements) {
            for (var _i = 0, outParams_1 = outParams; _i < outParams_1.length; _i++) {
                var outParam = outParams_1[_i];
                if (outParam.flags & partFlags) {
                    statements.push(ts.createExpressionStatement(copyOutParameter(outParam, copyDirection)));
                }
            }
        }
        function generateCallToConvertedLoopInitializer(initFunctionExpressionName, containsYield) {
            var call = ts.createCall(initFunctionExpressionName, /*typeArguments*/ undefined, []);
            var callResult = containsYield
                ? ts.createYield(ts.createToken(40 /* AsteriskToken */), ts.setEmitFlags(call, 8388608 /* Iterator */))
                : call;
            return ts.createStatement(callResult);
        }
        function generateCallToConvertedLoop(loopFunctionExpressionName, state, outerState, containsYield) {
            var statements = [];
            // loop is considered simple if it does not have any return statements or break\continue that transfer control outside of the loop
            // simple loops are emitted as just 'loop()';
            // NOTE: if loop uses only 'continue' it still will be emitted as simple loop
            var isSimpleLoop = !(state.nonLocalJumps & ~4 /* Continue */) &&
                !state.labeledNonLocalBreaks &&
                !state.labeledNonLocalContinues;
            var call = ts.createCall(loopFunctionExpressionName, /*typeArguments*/ undefined, ts.map(state.loopParameters, function (p) { return p.name; }));
            var callResult = containsYield
                ? ts.createYield(ts.createToken(40 /* AsteriskToken */), ts.setEmitFlags(call, 8388608 /* Iterator */))
                : call;
            if (isSimpleLoop) {
                statements.push(ts.createExpressionStatement(callResult));
                copyOutParameters(state.loopOutParameters, 1 /* Body */, 0 /* ToOriginal */, statements);
            }
            else {
                var loopResultName = ts.createUniqueName("state");
                var stateVariable = ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(loopResultName, /*type*/ undefined, callResult)]));
                statements.push(stateVariable);
                copyOutParameters(state.loopOutParameters, 1 /* Body */, 0 /* ToOriginal */, statements);
                if (state.nonLocalJumps & 8 /* Return */) {
                    var returnStatement = void 0;
                    if (outerState) {
                        outerState.nonLocalJumps |= 8 /* Return */;
                        returnStatement = ts.createReturn(loopResultName);
                    }
                    else {
                        returnStatement = ts.createReturn(ts.createPropertyAccess(loopResultName, "value"));
                    }
                    statements.push(ts.createIf(ts.createBinary(ts.createTypeOf(loopResultName), 35 /* EqualsEqualsEqualsToken */, ts.createLiteral("object")), returnStatement));
                }
                if (state.nonLocalJumps & 2 /* Break */) {
                    statements.push(ts.createIf(ts.createBinary(loopResultName, 35 /* EqualsEqualsEqualsToken */, ts.createLiteral("break")), ts.createBreak()));
                }
                if (state.labeledNonLocalBreaks || state.labeledNonLocalContinues) {
                    var caseClauses = [];
                    processLabeledJumps(state.labeledNonLocalBreaks, /*isBreak*/ true, loopResultName, outerState, caseClauses);
                    processLabeledJumps(state.labeledNonLocalContinues, /*isBreak*/ false, loopResultName, outerState, caseClauses);
                    statements.push(ts.createSwitch(loopResultName, ts.createCaseBlock(caseClauses)));
                }
            }
            return statements;
        }
        function setLabeledJump(state, isBreak, labelText, labelMarker) {
            if (isBreak) {
                if (!state.labeledNonLocalBreaks) {
                    state.labeledNonLocalBreaks = ts.createMap();
                }
                state.labeledNonLocalBreaks.set(labelText, labelMarker);
            }
            else {
                if (!state.labeledNonLocalContinues) {
                    state.labeledNonLocalContinues = ts.createMap();
                }
                state.labeledNonLocalContinues.set(labelText, labelMarker);
            }
        }
        function processLabeledJumps(table, isBreak, loopResultName, outerLoop, caseClauses) {
            if (!table) {
                return;
            }
            table.forEach(function (labelMarker, labelText) {
                var statements = [];
                // if there are no outer converted loop or outer label in question is located inside outer converted loop
                // then emit labeled break\continue
                // otherwise propagate pair 'label -> marker' to outer converted loop and emit 'return labelMarker' so outer loop can later decide what to do
                if (!outerLoop || (outerLoop.labels && outerLoop.labels.get(labelText))) {
                    var label = ts.createIdentifier(labelText);
                    statements.push(isBreak ? ts.createBreak(label) : ts.createContinue(label));
                }
                else {
                    setLabeledJump(outerLoop, isBreak, labelText, labelMarker);
                    statements.push(ts.createReturn(loopResultName));
                }
                caseClauses.push(ts.createCaseClause(ts.createLiteral(labelMarker), statements));
            });
        }
        function processLoopVariableDeclaration(container, decl, loopParameters, loopOutParameters, hasCapturedBindingsInForInitializer) {
            var name = decl.name;
            if (ts.isBindingPattern(name)) {
                for (var _i = 0, _a = name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        processLoopVariableDeclaration(container, element, loopParameters, loopOutParameters, hasCapturedBindingsInForInitializer);
                    }
                }
            }
            else {
                loopParameters.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
                var checkFlags = resolver.getNodeCheckFlags(decl);
                if (checkFlags & 4194304 /* NeedsLoopOutParameter */ || hasCapturedBindingsInForInitializer) {
                    var outParamName = ts.createUniqueName("out_" + ts.idText(name));
                    var flags = 0;
                    if (checkFlags & 4194304 /* NeedsLoopOutParameter */) {
                        flags |= 1 /* Body */;
                    }
                    if (ts.isForStatement(container) && container.initializer && resolver.isBindingCapturedByNode(container.initializer, decl)) {
                        flags |= 2 /* Initializer */;
                    }
                    loopOutParameters.push({ flags: flags, originalName: name, outParamName: outParamName });
                }
            }
        }
        /**
         * Adds the members of an object literal to an array of expressions.
         *
         * @param expressions An array of expressions.
         * @param node An ObjectLiteralExpression node.
         * @param receiver The receiver for members of the ObjectLiteralExpression.
         * @param numInitialNonComputedProperties The number of initial properties without
         *                                        computed property names.
         */
        function addObjectLiteralMembers(expressions, node, receiver, start) {
            var properties = node.properties;
            var numProperties = properties.length;
            for (var i = start; i < numProperties; i++) {
                var property = properties[i];
                switch (property.kind) {
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                        var accessors = ts.getAllAccessorDeclarations(node.properties, property);
                        if (property === accessors.firstAccessor) {
                            expressions.push(transformAccessorsToExpression(receiver, accessors, node, !!node.multiLine));
                        }
                        break;
                    case 157 /* MethodDeclaration */:
                        expressions.push(transformObjectLiteralMethodDeclarationToExpression(property, receiver, node, node.multiLine));
                        break;
                    case 276 /* PropertyAssignment */:
                        expressions.push(transformPropertyAssignmentToExpression(property, receiver, node.multiLine));
                        break;
                    case 277 /* ShorthandPropertyAssignment */:
                        expressions.push(transformShorthandPropertyAssignmentToExpression(property, receiver, node.multiLine));
                        break;
                    default:
                        ts.Debug.failBadSyntaxKind(node);
                        break;
                }
            }
        }
        /**
         * Transforms a PropertyAssignment node into an expression.
         *
         * @param node The ObjectLiteralExpression that contains the PropertyAssignment.
         * @param property The PropertyAssignment node.
         * @param receiver The receiver for the assignment.
         */
        function transformPropertyAssignmentToExpression(property, receiver, startsOnNewLine) {
            var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(property.name, visitor, ts.isPropertyName)), ts.visitNode(property.initializer, visitor, ts.isExpression));
            ts.setTextRange(expression, property);
            if (startsOnNewLine) {
                ts.startOnNewLine(expression);
            }
            return expression;
        }
        /**
         * Transforms a ShorthandPropertyAssignment node into an expression.
         *
         * @param node The ObjectLiteralExpression that contains the ShorthandPropertyAssignment.
         * @param property The ShorthandPropertyAssignment node.
         * @param receiver The receiver for the assignment.
         */
        function transformShorthandPropertyAssignmentToExpression(property, receiver, startsOnNewLine) {
            var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(property.name, visitor, ts.isPropertyName)), ts.getSynthesizedClone(property.name));
            ts.setTextRange(expression, property);
            if (startsOnNewLine) {
                ts.startOnNewLine(expression);
            }
            return expression;
        }
        /**
         * Transforms a MethodDeclaration of an ObjectLiteralExpression into an expression.
         *
         * @param node The ObjectLiteralExpression that contains the MethodDeclaration.
         * @param method The MethodDeclaration node.
         * @param receiver The receiver for the assignment.
         */
        function transformObjectLiteralMethodDeclarationToExpression(method, receiver, container, startsOnNewLine) {
            var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(method.name, visitor, ts.isPropertyName)), transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined, container));
            ts.setTextRange(expression, method);
            if (startsOnNewLine) {
                ts.startOnNewLine(expression);
            }
            return expression;
        }
        function visitCatchClause(node) {
            var ancestorFacts = enterSubtree(7104 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */);
            var updated;
            ts.Debug.assert(!!node.variableDeclaration, "Catch clause variable should always be present when downleveling ES2015.");
            if (ts.isBindingPattern(node.variableDeclaration.name)) {
                var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
                var newVariableDeclaration = ts.createVariableDeclaration(temp);
                ts.setTextRange(newVariableDeclaration, node.variableDeclaration);
                var vars = ts.flattenDestructuringBinding(node.variableDeclaration, visitor, context, 0 /* All */, temp);
                var list = ts.createVariableDeclarationList(vars);
                ts.setTextRange(list, node.variableDeclaration);
                var destructure = ts.createVariableStatement(/*modifiers*/ undefined, list);
                updated = ts.updateCatchClause(node, newVariableDeclaration, addStatementToStartOfBlock(node.block, destructure));
            }
            else {
                updated = ts.visitEachChild(node, visitor, context);
            }
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function addStatementToStartOfBlock(block, statement) {
            var transformedStatements = ts.visitNodes(block.statements, visitor, ts.isStatement);
            return ts.updateBlock(block, [statement].concat(transformedStatements));
        }
        /**
         * Visits a MethodDeclaration of an ObjectLiteralExpression and transforms it into a
         * PropertyAssignment.
         *
         * @param node A MethodDeclaration node.
         */
        function visitMethodDeclaration(node) {
            // We should only get here for methods on an object literal with regular identifier names.
            // Methods on classes are handled in visitClassDeclaration/visitClassExpression.
            // Methods with computed property names are handled in visitObjectLiteralExpression.
            ts.Debug.assert(!ts.isComputedPropertyName(node.name));
            var functionExpression = transformFunctionLikeToExpression(node, /*location*/ ts.moveRangePos(node, -1), /*name*/ undefined, /*container*/ undefined);
            ts.setEmitFlags(functionExpression, 512 /* NoLeadingComments */ | ts.getEmitFlags(functionExpression));
            return ts.setTextRange(ts.createPropertyAssignment(node.name, functionExpression), 
            /*location*/ node);
        }
        /**
         * Visits an AccessorDeclaration of an ObjectLiteralExpression.
         *
         * @param node An AccessorDeclaration node.
         */
        function visitAccessorDeclaration(node) {
            ts.Debug.assert(!ts.isComputedPropertyName(node.name));
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var updated;
            var parameters = ts.visitParameterList(node.parameters, visitor, context);
            var body = transformFunctionBody(node);
            if (node.kind === 159 /* GetAccessor */) {
                updated = ts.updateGetAccessor(node, node.decorators, node.modifiers, node.name, parameters, node.type, body);
            }
            else {
                updated = ts.updateSetAccessor(node, node.decorators, node.modifiers, node.name, parameters, body);
            }
            exitSubtree(ancestorFacts, 49152 /* FunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return updated;
        }
        /**
         * Visits a ShorthandPropertyAssignment and transforms it into a PropertyAssignment.
         *
         * @param node A ShorthandPropertyAssignment node.
         */
        function visitShorthandPropertyAssignment(node) {
            return ts.setTextRange(ts.createPropertyAssignment(node.name, ts.getSynthesizedClone(node.name)), 
            /*location*/ node);
        }
        function visitComputedPropertyName(node) {
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a YieldExpression node.
         *
         * @param node A YieldExpression node.
         */
        function visitYieldExpression(node) {
            // `yield` expressions are transformed using the generators transformer.
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits an ArrayLiteralExpression that contains a spread element.
         *
         * @param node An ArrayLiteralExpression node.
         */
        function visitArrayLiteralExpression(node) {
            if (ts.some(node.elements, ts.isSpreadElement)) {
                // We are here because we contain a SpreadElementExpression.
                return transformAndSpreadElements(node.elements, /*needsUniqueCopy*/ true, !!node.multiLine, /*hasTrailingComma*/ !!node.elements.hasTrailingComma);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a CallExpression that contains either a spread element or `super`.
         *
         * @param node a CallExpression.
         */
        function visitCallExpression(node) {
            if (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) {
                return visitTypeScriptClassWrapper(node);
            }
            var expression = ts.skipOuterExpressions(node.expression);
            if (expression.kind === 99 /* SuperKeyword */ ||
                ts.isSuperProperty(expression) ||
                ts.some(node.arguments, ts.isSpreadElement)) {
                return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ true);
            }
            return ts.updateCall(node, ts.visitNode(node.expression, callExpressionVisitor, ts.isExpression), 
            /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
        }
        function visitTypeScriptClassWrapper(node) {
            // This is a call to a class wrapper function (an IIFE) created by the 'ts' transformer.
            // The wrapper has a form similar to:
            //
            //  (function() {
            //      class C { // 1
            //      }
            //      C.x = 1; // 2
            //      return C;
            //  }())
            //
            // When we transform the class, we end up with something like this:
            //
            //  (function () {
            //      var C = (function () { // 3
            //          function C() {
            //          }
            //          return C; // 4
            //      }());
            //      C.x = 1;
            //      return C;
            //  }())
            //
            // We want to simplify the two nested IIFEs to end up with something like this:
            //
            //  (function () {
            //      function C() {
            //      }
            //      C.x = 1;
            //      return C;
            //  }())
            // We skip any outer expressions in a number of places to get to the innermost
            // expression, but we will restore them later to preserve comments and source maps.
            var body = ts.cast(ts.cast(ts.skipOuterExpressions(node.expression), ts.isArrowFunction).body, ts.isBlock);
            // The class statements are the statements generated by visiting the first statement with initializer of the
            // body (1), while all other statements are added to remainingStatements (2)
            var isVariableStatementWithInitializer = function (stmt) { return ts.isVariableStatement(stmt) && !!ts.first(stmt.declarationList.declarations).initializer; };
            var bodyStatements = ts.visitNodes(body.statements, visitor, ts.isStatement);
            var classStatements = ts.filter(bodyStatements, isVariableStatementWithInitializer);
            var remainingStatements = ts.filter(bodyStatements, function (stmt) { return !isVariableStatementWithInitializer(stmt); });
            var varStatement = ts.cast(ts.first(classStatements), ts.isVariableStatement);
            // We know there is only one variable declaration here as we verified this in an
            // earlier call to isTypeScriptClassWrapper
            var variable = varStatement.declarationList.declarations[0];
            var initializer = ts.skipOuterExpressions(variable.initializer);
            // Under certain conditions, the 'ts' transformer may introduce a class alias, which
            // we see as an assignment, for example:
            //
            //  (function () {
            //      var C_1;
            //      var C = C_1 = (function () {
            //          function C() {
            //          }
            //          C.x = function () { return C_1; }
            //          return C;
            //      }());
            //      C = C_1 = __decorate([dec], C);
            //      return C;
            //  }())
            //
            var aliasAssignment = ts.tryCast(initializer, ts.isAssignmentExpression);
            // The underlying call (3) is another IIFE that may contain a '_super' argument.
            var call = ts.cast(aliasAssignment ? ts.skipOuterExpressions(aliasAssignment.right) : initializer, ts.isCallExpression);
            var func = ts.cast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression);
            var funcStatements = func.body.statements;
            var classBodyStart = 0;
            var classBodyEnd = -1;
            var statements = [];
            if (aliasAssignment) {
                // If we have a class alias assignment, we need to move it to the down-level constructor
                // function we generated for the class.
                var extendsCall = ts.tryCast(funcStatements[classBodyStart], ts.isExpressionStatement);
                if (extendsCall) {
                    statements.push(extendsCall);
                    classBodyStart++;
                }
                // The next statement is the function declaration.
                statements.push(funcStatements[classBodyStart]);
                classBodyStart++;
                // Add the class alias following the declaration.
                statements.push(ts.createExpressionStatement(ts.createAssignment(aliasAssignment.left, ts.cast(variable.name, ts.isIdentifier))));
            }
            // Find the trailing 'return' statement (4)
            while (!ts.isReturnStatement(ts.elementAt(funcStatements, classBodyEnd))) {
                classBodyEnd--;
            }
            // When we extract the statements of the inner IIFE, we exclude the 'return' statement (4)
            // as we already have one that has been introduced by the 'ts' transformer.
            ts.addRange(statements, funcStatements, classBodyStart, classBodyEnd);
            if (classBodyEnd < -1) {
                // If there were any hoisted declarations following the return statement, we should
                // append them.
                ts.addRange(statements, funcStatements, classBodyEnd + 1);
            }
            // Add the remaining statements of the outer wrapper.
            ts.addRange(statements, remainingStatements);
            // The 'es2015' class transform may add an end-of-declaration marker. If so we will add it
            // after the remaining statements from the 'ts' transformer.
            ts.addRange(statements, classStatements, /*start*/ 1);
            // Recreate any outer parentheses or partially-emitted expressions to preserve source map
            // and comment locations.
            return ts.recreateOuterExpressions(node.expression, ts.recreateOuterExpressions(variable.initializer, ts.recreateOuterExpressions(aliasAssignment && aliasAssignment.right, ts.updateCall(call, ts.recreateOuterExpressions(call.expression, ts.updateFunctionExpression(func, 
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, func.parameters, 
            /*type*/ undefined, ts.updateBlock(func.body, statements))), 
            /*typeArguments*/ undefined, call.arguments))));
        }
        function visitImmediateSuperCallInBody(node) {
            return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ false);
        }
        function visitCallExpressionWithPotentialCapturedThisAssignment(node, assignToCapturedThis) {
            // We are here either because SuperKeyword was used somewhere in the expression, or
            // because we contain a SpreadElementExpression.
            if (node.transformFlags & 4096 /* ContainsRestOrSpread */ ||
                node.expression.kind === 99 /* SuperKeyword */ ||
                ts.isSuperProperty(ts.skipOuterExpressions(node.expression))) {
                var _a = ts.createCallBinding(node.expression, hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg;
                if (node.expression.kind === 99 /* SuperKeyword */) {
                    ts.setEmitFlags(thisArg, 4 /* NoSubstitution */);
                }
                var resultingCall = void 0;
                if (node.transformFlags & 4096 /* ContainsRestOrSpread */) {
                    // [source]
                    //      f(...a, b)
                    //      x.m(...a, b)
                    //      super(...a, b)
                    //      super.m(...a, b) // in static
                    //      super.m(...a, b) // in instance
                    //
                    // [output]
                    //      f.apply(void 0, a.concat([b]))
                    //      (_a = x).m.apply(_a, a.concat([b]))
                    //      _super.apply(this, a.concat([b]))
                    //      _super.m.apply(this, a.concat([b]))
                    //      _super.prototype.m.apply(this, a.concat([b]))
                    resultingCall = ts.createFunctionApply(ts.visitNode(target, callExpressionVisitor, ts.isExpression), node.expression.kind === 99 /* SuperKeyword */ ? thisArg : ts.visitNode(thisArg, visitor, ts.isExpression), transformAndSpreadElements(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false));
                }
                else {
                    // [source]
                    //      super(a)
                    //      super.m(a) // in static
                    //      super.m(a) // in instance
                    //
                    // [output]
                    //      _super.call(this, a)
                    //      _super.m.call(this, a)
                    //      _super.prototype.m.call(this, a)
                    resultingCall = ts.createFunctionCall(ts.visitNode(target, callExpressionVisitor, ts.isExpression), node.expression.kind === 99 /* SuperKeyword */ ? thisArg : ts.visitNode(thisArg, visitor, ts.isExpression), ts.visitNodes(node.arguments, visitor, ts.isExpression), 
                    /*location*/ node);
                }
                if (node.expression.kind === 99 /* SuperKeyword */) {
                    var initializer = ts.createLogicalOr(resultingCall, createActualThis());
                    resultingCall = assignToCapturedThis
                        ? ts.createAssignment(ts.createFileLevelUniqueName("_this"), initializer)
                        : initializer;
                }
                return ts.setOriginalNode(resultingCall, node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a NewExpression that contains a spread element.
         *
         * @param node A NewExpression node.
         */
        function visitNewExpression(node) {
            if (ts.some(node.arguments, ts.isSpreadElement)) {
                // We are here because we contain a SpreadElementExpression.
                // [source]
                //      new C(...a)
                //
                // [output]
                //      new ((_a = C).bind.apply(_a, [void 0].concat(a)))()
                var _a = ts.createCallBinding(ts.createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg;
                return ts.createNew(ts.createFunctionApply(ts.visitNode(target, visitor, ts.isExpression), thisArg, transformAndSpreadElements(ts.createNodeArray([ts.createVoidZero()].concat(node.arguments)), /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false)), 
                /*typeArguments*/ undefined, []);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Transforms an array of Expression nodes that contains a SpreadExpression.
         *
         * @param elements The array of Expression nodes.
         * @param needsUniqueCopy A value indicating whether to ensure that the result is a fresh array.
         * @param multiLine A value indicating whether the result should be emitted on multiple lines.
         */
        function transformAndSpreadElements(elements, needsUniqueCopy, multiLine, hasTrailingComma) {
            // [source]
            //      [a, ...b, c]
            //
            // [output]
            //      [a].concat(b, [c])
            // Map spans of spread expressions into their expressions and spans of other
            // expressions into an array literal.
            var numElements = elements.length;
            var segments = ts.flatten(ts.spanMap(elements, partitionSpread, function (partition, visitPartition, _start, end) {
                return visitPartition(partition, multiLine, hasTrailingComma && end === numElements);
            }));
            if (compilerOptions.downlevelIteration) {
                if (segments.length === 1) {
                    var firstSegment = segments[0];
                    if (ts.isCallExpression(firstSegment)
                        && ts.isIdentifier(firstSegment.expression)
                        && (ts.getEmitFlags(firstSegment.expression) & 4096 /* HelperName */)
                        && firstSegment.expression.escapedText === "___spread") {
                        return segments[0];
                    }
                }
                return ts.createSpreadHelper(context, segments);
            }
            else {
                if (segments.length === 1) {
                    var firstElement = elements[0];
                    return needsUniqueCopy && ts.isSpreadElement(firstElement) && firstElement.expression.kind !== 188 /* ArrayLiteralExpression */
                        ? ts.createArraySlice(segments[0])
                        : segments[0];
                }
                // Rewrite using the pattern <segment0>.concat(<segment1>, <segment2>, ...)
                return ts.createArrayConcat(segments.shift(), segments);
            }
        }
        function partitionSpread(node) {
            return ts.isSpreadElement(node)
                ? visitSpanOfSpreads
                : visitSpanOfNonSpreads;
        }
        function visitSpanOfSpreads(chunk) {
            return ts.map(chunk, visitExpressionOfSpread);
        }
        function visitSpanOfNonSpreads(chunk, multiLine, hasTrailingComma) {
            return ts.createArrayLiteral(ts.visitNodes(ts.createNodeArray(chunk, hasTrailingComma), visitor, ts.isExpression), multiLine);
        }
        function visitSpreadElement(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
        /**
         * Transforms the expression of a SpreadExpression node.
         *
         * @param node A SpreadExpression node.
         */
        function visitExpressionOfSpread(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
        /**
         * Visits a template literal.
         *
         * @param node A template literal.
         */
        function visitTemplateLiteral(node) {
            return ts.setTextRange(ts.createLiteral(node.text), node);
        }
        /**
         * Visits a string literal with an extended unicode escape.
         *
         * @param node A string literal.
         */
        function visitStringLiteral(node) {
            if (node.hasExtendedUnicodeEscape) {
                return ts.setTextRange(ts.createLiteral(node.text), node);
            }
            return node;
        }
        /**
         * Visits a binary or octal (ES6) numeric literal.
         *
         * @param node A string literal.
         */
        function visitNumericLiteral(node) {
            if (node.numericLiteralFlags & 384 /* BinaryOrOctalSpecifier */) {
                return ts.setTextRange(ts.createNumericLiteral(node.text), node);
            }
            return node;
        }
        /**
         * Visits a TaggedTemplateExpression node.
         *
         * @param node A TaggedTemplateExpression node.
         */
        function visitTaggedTemplateExpression(node) {
            // Visit the tag expression
            var tag = ts.visitNode(node.tag, visitor, ts.isExpression);
            // Build up the template arguments and the raw and cooked strings for the template.
            // We start out with 'undefined' for the first argument and revisit later
            // to avoid walking over the template string twice and shifting all our arguments over after the fact.
            var templateArguments = [undefined];
            var cookedStrings = [];
            var rawStrings = [];
            var template = node.template;
            if (ts.isNoSubstitutionTemplateLiteral(template)) {
                cookedStrings.push(ts.createLiteral(template.text));
                rawStrings.push(getRawLiteral(template));
            }
            else {
                cookedStrings.push(ts.createLiteral(template.head.text));
                rawStrings.push(getRawLiteral(template.head));
                for (var _i = 0, _a = template.templateSpans; _i < _a.length; _i++) {
                    var templateSpan = _a[_i];
                    cookedStrings.push(ts.createLiteral(templateSpan.literal.text));
                    rawStrings.push(getRawLiteral(templateSpan.literal));
                    templateArguments.push(ts.visitNode(templateSpan.expression, visitor, ts.isExpression));
                }
            }
            var helperCall = createTemplateObjectHelper(context, ts.createArrayLiteral(cookedStrings), ts.createArrayLiteral(rawStrings));
            // Create a variable to cache the template object if we're in a module.
            // Do not do this in the global scope, as any variable we currently generate could conflict with
            // variables from outside of the current compilation. In the future, we can revisit this behavior.
            if (ts.isExternalModule(currentSourceFile)) {
                var tempVar = ts.createUniqueName("templateObject");
                recordTaggedTemplateString(tempVar);
                templateArguments[0] = ts.createLogicalOr(tempVar, ts.createAssignment(tempVar, helperCall));
            }
            else {
                templateArguments[0] = helperCall;
            }
            return ts.createCall(tag, /*typeArguments*/ undefined, templateArguments);
        }
        /**
         * Creates an ES5 compatible literal from an ES6 template literal.
         *
         * @param node The ES6 template literal.
         */
        function getRawLiteral(node) {
            // Find original source text, since we need to emit the raw strings of the tagged template.
            // The raw strings contain the (escaped) strings of what the user wrote.
            // Examples: `\n` is converted to "\\n", a template string with a newline to "\n".
            var text = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
            // text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"),
            // thus we need to remove those characters.
            // First template piece starts with "`", others with "}"
            // Last template piece ends with "`", others with "${"
            var isLast = node.kind === 14 /* NoSubstitutionTemplateLiteral */ || node.kind === 17 /* TemplateTail */;
            text = text.substring(1, text.length - (isLast ? 1 : 2));
            // Newline normalization:
            // ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's
            // <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for both TV and TRV.
            text = text.replace(/\r\n?/g, "\n");
            return ts.setTextRange(ts.createLiteral(text), node);
        }
        /**
         * Visits a TemplateExpression node.
         *
         * @param node A TemplateExpression node.
         */
        function visitTemplateExpression(node) {
            var expressions = [];
            addTemplateHead(expressions, node);
            addTemplateSpans(expressions, node);
            // createAdd will check if each expression binds less closely than binary '+'.
            // If it does, it wraps the expression in parentheses. Otherwise, something like
            //    `abc${ 1 << 2 }`
            // becomes
            //    "abc" + 1 << 2 + ""
            // which is really
            //    ("abc" + 1) << (2 + "")
            // rather than
            //    "abc" + (1 << 2) + ""
            var expression = ts.reduceLeft(expressions, ts.createAdd);
            if (ts.nodeIsSynthesized(expression)) {
                expression.pos = node.pos;
                expression.end = node.end;
            }
            return expression;
        }
        /**
         * Gets a value indicating whether we need to include the head of a TemplateExpression.
         *
         * @param node A TemplateExpression node.
         */
        function shouldAddTemplateHead(node) {
            // If this expression has an empty head literal and the first template span has a non-empty
            // literal, then emitting the empty head literal is not necessary.
            //     `${ foo } and ${ bar }`
            // can be emitted as
            //     foo + " and " + bar
            // This is because it is only required that one of the first two operands in the emit
            // output must be a string literal, so that the other operand and all following operands
            // are forced into strings.
            //
            // If the first template span has an empty literal, then the head must still be emitted.
            //     `${ foo }${ bar }`
            // must still be emitted as
            //     "" + foo + bar
            // There is always atleast one templateSpan in this code path, since
            // NoSubstitutionTemplateLiterals are directly emitted via emitLiteral()
            ts.Debug.assert(node.templateSpans.length !== 0);
            return node.head.text.length !== 0 || node.templateSpans[0].literal.text.length === 0;
        }
        /**
         * Adds the head of a TemplateExpression to an array of expressions.
         *
         * @param expressions An array of expressions.
         * @param node A TemplateExpression node.
         */
        function addTemplateHead(expressions, node) {
            if (!shouldAddTemplateHead(node)) {
                return;
            }
            expressions.push(ts.createLiteral(node.head.text));
        }
        /**
         * Visits and adds the template spans of a TemplateExpression to an array of expressions.
         *
         * @param expressions An array of expressions.
         * @param node A TemplateExpression node.
         */
        function addTemplateSpans(expressions, node) {
            for (var _i = 0, _a = node.templateSpans; _i < _a.length; _i++) {
                var span = _a[_i];
                expressions.push(ts.visitNode(span.expression, visitor, ts.isExpression));
                // Only emit if the literal is non-empty.
                // The binary '+' operator is left-associative, so the first string concatenation
                // with the head will force the result up to this point to be a string.
                // Emitting a '+ ""' has no semantic effect for middles and tails.
                if (span.literal.text.length !== 0) {
                    expressions.push(ts.createLiteral(span.literal.text));
                }
            }
        }
        /**
         * Visits the `super` keyword
         */
        function visitSuperKeyword(isExpressionOfCall) {
            return hierarchyFacts & 8 /* NonStaticClassElement */
                && !isExpressionOfCall
                ? ts.createPropertyAccess(ts.createFileLevelUniqueName("_super"), "prototype")
                : ts.createFileLevelUniqueName("_super");
        }
        function visitMetaProperty(node) {
            if (node.keywordToken === 96 /* NewKeyword */ && node.name.escapedText === "target") {
                hierarchyFacts |= 16384 /* NewTarget */;
                return ts.createFileLevelUniqueName("_newTarget");
            }
            return node;
        }
        /**
         * Called by the printer just before a node is printed.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to be printed.
         * @param emitCallback The callback used to emit the node.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (enabledSubstitutions & 1 /* CapturedThis */ && ts.isFunctionLike(node)) {
                // If we are tracking a captured `this`, keep track of the enclosing function.
                var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, ts.getEmitFlags(node) & 8 /* CapturesThis */
                    ? 65 /* FunctionIncludes */ | 16 /* CapturesThis */
                    : 65 /* FunctionIncludes */);
                previousOnEmitNode(hint, node, emitCallback);
                exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
                return;
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Enables a more costly code path for substitutions when we determine a source file
         * contains block-scoped bindings (e.g. `let` or `const`).
         */
        function enableSubstitutionsForBlockScopedBindings() {
            if ((enabledSubstitutions & 2 /* BlockScopedBindings */) === 0) {
                enabledSubstitutions |= 2 /* BlockScopedBindings */;
                context.enableSubstitution(73 /* Identifier */);
            }
        }
        /**
         * Enables a more costly code path for substitutions when we determine a source file
         * contains a captured `this`.
         */
        function enableSubstitutionsForCapturedThis() {
            if ((enabledSubstitutions & 1 /* CapturedThis */) === 0) {
                enabledSubstitutions |= 1 /* CapturedThis */;
                context.enableSubstitution(101 /* ThisKeyword */);
                context.enableEmitNotification(158 /* Constructor */);
                context.enableEmitNotification(157 /* MethodDeclaration */);
                context.enableEmitNotification(159 /* GetAccessor */);
                context.enableEmitNotification(160 /* SetAccessor */);
                context.enableEmitNotification(198 /* ArrowFunction */);
                context.enableEmitNotification(197 /* FunctionExpression */);
                context.enableEmitNotification(240 /* FunctionDeclaration */);
            }
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint The context for the emitter.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            if (ts.isIdentifier(node)) {
                return substituteIdentifier(node);
            }
            return node;
        }
        /**
         * Hooks substitutions for non-expression identifiers.
         */
        function substituteIdentifier(node) {
            // Only substitute the identifier if we have enabled substitutions for block-scoped
            // bindings.
            if (enabledSubstitutions & 2 /* BlockScopedBindings */ && !ts.isInternalName(node)) {
                var original = ts.getParseTreeNode(node, ts.isIdentifier);
                if (original && isNameOfDeclarationWithCollidingName(original)) {
                    return ts.setTextRange(ts.getGeneratedNameForNode(original), node);
                }
            }
            return node;
        }
        /**
         * Determines whether a name is the name of a declaration with a colliding name.
         * NOTE: This function expects to be called with an original source tree node.
         *
         * @param node An original source tree node.
         */
        function isNameOfDeclarationWithCollidingName(node) {
            switch (node.parent.kind) {
                case 187 /* BindingElement */:
                case 241 /* ClassDeclaration */:
                case 244 /* EnumDeclaration */:
                case 238 /* VariableDeclaration */:
                    return node.parent.name === node
                        && resolver.isDeclarationWithCollidingName(node.parent);
            }
            return false;
        }
        /**
         * Substitutes an expression.
         *
         * @param node An Expression node.
         */
        function substituteExpression(node) {
            switch (node.kind) {
                case 73 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 101 /* ThisKeyword */:
                    return substituteThisKeyword(node);
            }
            return node;
        }
        /**
         * Substitutes an expression identifier.
         *
         * @param node An Identifier node.
         */
        function substituteExpressionIdentifier(node) {
            if (enabledSubstitutions & 2 /* BlockScopedBindings */ && !ts.isInternalName(node)) {
                var declaration = resolver.getReferencedDeclarationWithCollidingName(node);
                if (declaration && !(ts.isClassLike(declaration) && isPartOfClassBody(declaration, node))) {
                    return ts.setTextRange(ts.getGeneratedNameForNode(ts.getNameOfDeclaration(declaration)), node);
                }
            }
            return node;
        }
        function isPartOfClassBody(declaration, node) {
            var currentNode = ts.getParseTreeNode(node);
            if (!currentNode || currentNode === declaration || currentNode.end <= declaration.pos || currentNode.pos >= declaration.end) {
                // if the node has no correlation to a parse tree node, its definitely not
                // part of the body.
                // if the node is outside of the document range of the declaration, its
                // definitely not part of the body.
                return false;
            }
            var blockScope = ts.getEnclosingBlockScopeContainer(declaration);
            while (currentNode) {
                if (currentNode === blockScope || currentNode === declaration) {
                    // if we are in the enclosing block scope of the declaration, we are definitely
                    // not inside the class body.
                    return false;
                }
                if (ts.isClassElement(currentNode) && currentNode.parent === declaration) {
                    return true;
                }
                currentNode = currentNode.parent;
            }
            return false;
        }
        /**
         * Substitutes `this` when contained within an arrow function.
         *
         * @param node The ThisKeyword node.
         */
        function substituteThisKeyword(node) {
            if (enabledSubstitutions & 1 /* CapturedThis */
                && hierarchyFacts & 16 /* CapturesThis */) {
                return ts.setTextRange(ts.createFileLevelUniqueName("_this"), node);
            }
            return node;
        }
        function getClassMemberPrefix(node, member) {
            return ts.hasModifier(member, 32 /* Static */)
                ? ts.getInternalName(node)
                : ts.createPropertyAccess(ts.getInternalName(node), "prototype");
        }
        function hasSynthesizedDefaultSuperCall(constructor, hasExtendsClause) {
            if (!constructor || !hasExtendsClause) {
                return false;
            }
            if (ts.some(constructor.parameters)) {
                return false;
            }
            var statement = ts.firstOrUndefined(constructor.body.statements);
            if (!statement || !ts.nodeIsSynthesized(statement) || statement.kind !== 222 /* ExpressionStatement */) {
                return false;
            }
            var statementExpression = statement.expression;
            if (!ts.nodeIsSynthesized(statementExpression) || statementExpression.kind !== 192 /* CallExpression */) {
                return false;
            }
            var callTarget = statementExpression.expression;
            if (!ts.nodeIsSynthesized(callTarget) || callTarget.kind !== 99 /* SuperKeyword */) {
                return false;
            }
            var callArgument = ts.singleOrUndefined(statementExpression.arguments);
            if (!callArgument || !ts.nodeIsSynthesized(callArgument) || callArgument.kind !== 209 /* SpreadElement */) {
                return false;
            }
            var expression = callArgument.expression;
            return ts.isIdentifier(expression) && expression.escapedText === "arguments";
        }
    }
    ts.transformES2015 = transformES2015;
    function createExtendsHelper(context, name) {
        context.requestEmitHelper(ts.extendsHelper);
        return ts.createCall(ts.getHelperName("__extends"), 
        /*typeArguments*/ undefined, [
            name,
            ts.createFileLevelUniqueName("_super")
        ]);
    }
    function createTemplateObjectHelper(context, cooked, raw) {
        context.requestEmitHelper(ts.templateObjectHelper);
        return ts.createCall(ts.getHelperName("__makeTemplateObject"), 
        /*typeArguments*/ undefined, [
            cooked,
            raw
        ]);
    }
    ts.extendsHelper = {
        name: "typescript:extends",
        scoped: false,
        priority: 0,
        text: "\n            var __extends = (this && this.__extends) || (function () {\n                var extendStatics = function (d, b) {\n                    extendStatics = Object.setPrototypeOf ||\n                        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n                        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n                    return extendStatics(d, b);\n                };\n\n                return function (d, b) {\n                    extendStatics(d, b);\n                    function __() { this.constructor = d; }\n                    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n                };\n            })();"
    };
    ts.templateObjectHelper = {
        name: "typescript:makeTemplateObject",
        scoped: false,
        priority: 0,
        text: "\n            var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {\n                if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n                return cooked;\n            };"
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    /**
     * Transforms ES5 syntax into ES3 syntax.
     *
     * @param context Context and state information for the transformation.
     */
    function transformES5(context) {
        var compilerOptions = context.getCompilerOptions();
        // enable emit notification only if using --jsx preserve or react-native
        var previousOnEmitNode;
        var noSubstitution;
        if (compilerOptions.jsx === 1 /* Preserve */ || compilerOptions.jsx === 3 /* ReactNative */) {
            previousOnEmitNode = context.onEmitNode;
            context.onEmitNode = onEmitNode;
            context.enableEmitNotification(263 /* JsxOpeningElement */);
            context.enableEmitNotification(264 /* JsxClosingElement */);
            context.enableEmitNotification(262 /* JsxSelfClosingElement */);
            noSubstitution = [];
        }
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onSubstituteNode = onSubstituteNode;
        context.enableSubstitution(190 /* PropertyAccessExpression */);
        context.enableSubstitution(276 /* PropertyAssignment */);
        return ts.chainBundle(transformSourceFile);
        /**
         * Transforms an ES5 source file to ES3.
         *
         * @param node A SourceFile
         */
        function transformSourceFile(node) {
            return node;
        }
        /**
         * Called by the printer just before a node is printed.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback A callback used to emit the node.
         */
        function onEmitNode(hint, node, emitCallback) {
            switch (node.kind) {
                case 263 /* JsxOpeningElement */:
                case 264 /* JsxClosingElement */:
                case 262 /* JsxSelfClosingElement */:
                    var tagName = node.tagName;
                    noSubstitution[ts.getOriginalNodeId(tagName)] = true;
                    break;
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            if (node.id && noSubstitution && noSubstitution[node.id]) {
                return previousOnSubstituteNode(hint, node);
            }
            node = previousOnSubstituteNode(hint, node);
            if (ts.isPropertyAccessExpression(node)) {
                return substitutePropertyAccessExpression(node);
            }
            else if (ts.isPropertyAssignment(node)) {
                return substitutePropertyAssignment(node);
            }
            return node;
        }
        /**
         * Substitutes a PropertyAccessExpression whose name is a reserved word.
         *
         * @param node A PropertyAccessExpression
         */
        function substitutePropertyAccessExpression(node) {
            var literalName = trySubstituteReservedName(node.name);
            if (literalName) {
                return ts.setTextRange(ts.createElementAccess(node.expression, literalName), node);
            }
            return node;
        }
        /**
         * Substitutes a PropertyAssignment whose name is a reserved word.
         *
         * @param node A PropertyAssignment
         */
        function substitutePropertyAssignment(node) {
            var literalName = ts.isIdentifier(node.name) && trySubstituteReservedName(node.name);
            if (literalName) {
                return ts.updatePropertyAssignment(node, literalName, node.initializer);
            }
            return node;
        }
        /**
         * If an identifier name is a reserved word, returns a string literal for the name.
         *
         * @param name An Identifier
         */
        function trySubstituteReservedName(name) {
            var token = name.originalKeywordKind || (ts.nodeIsSynthesized(name) ? ts.stringToToken(ts.idText(name)) : undefined);
            if (token !== undefined && token >= 74 /* FirstReservedWord */ && token <= 109 /* LastReservedWord */) {
                return ts.setTextRange(ts.createLiteral(name), name);
            }
            return undefined;
        }
    }
    ts.transformES5 = transformES5;
})(ts || (ts = {}));
// Transforms generator functions into a compatible ES5 representation with similar runtime
// semantics. This is accomplished by first transforming the body of each generator
// function into an intermediate representation that is the compiled into a JavaScript
// switch statement.
//
// Many functions in this transformer will contain comments indicating the expected
// intermediate representation. For illustrative purposes, the following intermediate
// language is used to define this intermediate representation:
//
//  .nop                            - Performs no operation.
//  .local NAME, ...                - Define local variable declarations.
//  .mark LABEL                     - Mark the location of a label.
//  .br LABEL                       - Jump to a label. If jumping out of a protected
//                                    region, all .finally blocks are executed.
//  .brtrue LABEL, (x)              - Jump to a label IIF the expression `x` is truthy.
//                                    If jumping out of a protected region, all .finally
//                                    blocks are executed.
//  .brfalse LABEL, (x)             - Jump to a label IIF the expression `x` is falsey.
//                                    If jumping out of a protected region, all .finally
//                                    blocks are executed.
//  .yield (x)                      - Yield the value of the optional expression `x`.
//                                    Resume at the next label.
//  .yieldstar (x)                  - Delegate yield to the value of the optional
//                                    expression `x`. Resume at the next label.
//                                    NOTE: `x` must be an Iterator, not an Iterable.
//  .loop CONTINUE, BREAK           - Marks the beginning of a loop. Any "continue" or
//                                    "break" abrupt completions jump to the CONTINUE or
//                                    BREAK labels, respectively.
//  .endloop                        - Marks the end of a loop.
//  .with (x)                       - Marks the beginning of a WithStatement block, using
//                                    the supplied expression.
//  .endwith                        - Marks the end of a WithStatement.
//  .switch                         - Marks the beginning of a SwitchStatement.
//  .endswitch                      - Marks the end of a SwitchStatement.
//  .labeled NAME                   - Marks the beginning of a LabeledStatement with the
//                                    supplied name.
//  .endlabeled                     - Marks the end of a LabeledStatement.
//  .try TRY, CATCH, FINALLY, END   - Marks the beginning of a protected region, and the
//                                    labels for each block.
//  .catch (x)                      - Marks the beginning of a catch block.
//  .finally                        - Marks the beginning of a finally block.
//  .endfinally                     - Marks the end of a finally block.
//  .endtry                         - Marks the end of a protected region.
//  .throw (x)                      - Throws the value of the expression `x`.
//  .return (x)                     - Returns the value of the expression `x`.
//
// In addition, the illustrative intermediate representation introduces some special
// variables:
//
//  %sent%                          - Either returns the next value sent to the generator,
//                                    returns the result of a delegated yield, or throws
//                                    the exception sent to the generator.
//  %error%                         - Returns the value of the current exception in a
//                                    catch block.
//
// This intermediate representation is then compiled into JavaScript syntax. The resulting
// compilation output looks something like the following:
//
//  function f() {
//      var /*locals*/;
//      /*functions*/
//      return __generator(function (state) {
//          switch (state.label) {
//              /*cases per label*/
//          }
//      });
//  }
//
// Each of the above instructions corresponds to JavaScript emit similar to the following:
//
//  .local NAME                   | var NAME;
// -------------------------------|----------------------------------------------
//  .mark LABEL                   | case LABEL:
// -------------------------------|----------------------------------------------
//  .br LABEL                     |     return [3 /*break*/, LABEL];
// -------------------------------|----------------------------------------------
//  .brtrue LABEL, (x)            |     if (x) return [3 /*break*/, LABEL];
// -------------------------------|----------------------------------------------
//  .brfalse LABEL, (x)           |     if (!(x)) return [3, /*break*/, LABEL];
// -------------------------------|----------------------------------------------
//  .yield (x)                    |     return [4 /*yield*/, x];
//  .mark RESUME                  | case RESUME:
//      a = %sent%;               |     a = state.sent();
// -------------------------------|----------------------------------------------
//  .yieldstar (x)                |     return [5 /*yield**/, x];
//  .mark RESUME                  | case RESUME:
//      a = %sent%;               |     a = state.sent();
// -------------------------------|----------------------------------------------
//  .with (_a)                    |     with (_a) {
//      a();                      |         a();
//                                |     }
//                                |     state.label = LABEL;
//  .mark LABEL                   | case LABEL:
//                                |     with (_a) {
//      b();                      |         b();
//                                |     }
//  .endwith                      |
// -------------------------------|----------------------------------------------
//                                | case 0:
//                                |     state.trys = [];
//                                | ...
//  .try TRY, CATCH, FINALLY, END |
//  .mark TRY                     | case TRY:
//                                |     state.trys.push([TRY, CATCH, FINALLY, END]);
//  .nop                          |
//      a();                      |     a();
//  .br END                       |     return [3 /*break*/, END];
//  .catch (e)                    |
//  .mark CATCH                   | case CATCH:
//                                |     e = state.sent();
//      b();                      |     b();
//  .br END                       |     return [3 /*break*/, END];
//  .finally                      |
//  .mark FINALLY                 | case FINALLY:
//      c();                      |     c();
//  .endfinally                   |     return [7 /*endfinally*/];
//  .endtry                       |
//  .mark END                     | case END:
/*@internal*/
var ts;
(function (ts) {
    var OpCode;
    (function (OpCode) {
        OpCode[OpCode["Nop"] = 0] = "Nop";
        OpCode[OpCode["Statement"] = 1] = "Statement";
        OpCode[OpCode["Assign"] = 2] = "Assign";
        OpCode[OpCode["Break"] = 3] = "Break";
        OpCode[OpCode["BreakWhenTrue"] = 4] = "BreakWhenTrue";
        OpCode[OpCode["BreakWhenFalse"] = 5] = "BreakWhenFalse";
        OpCode[OpCode["Yield"] = 6] = "Yield";
        OpCode[OpCode["YieldStar"] = 7] = "YieldStar";
        OpCode[OpCode["Return"] = 8] = "Return";
        OpCode[OpCode["Throw"] = 9] = "Throw";
        OpCode[OpCode["Endfinally"] = 10] = "Endfinally"; // Marks the end of a `finally` block
    })(OpCode || (OpCode = {}));
    // whether a generated code block is opening or closing at the current operation for a FunctionBuilder
    var BlockAction;
    (function (BlockAction) {
        BlockAction[BlockAction["Open"] = 0] = "Open";
        BlockAction[BlockAction["Close"] = 1] = "Close";
    })(BlockAction || (BlockAction = {}));
    // the kind for a generated code block in a FunctionBuilder
    var CodeBlockKind;
    (function (CodeBlockKind) {
        CodeBlockKind[CodeBlockKind["Exception"] = 0] = "Exception";
        CodeBlockKind[CodeBlockKind["With"] = 1] = "With";
        CodeBlockKind[CodeBlockKind["Switch"] = 2] = "Switch";
        CodeBlockKind[CodeBlockKind["Loop"] = 3] = "Loop";
        CodeBlockKind[CodeBlockKind["Labeled"] = 4] = "Labeled";
    })(CodeBlockKind || (CodeBlockKind = {}));
    // the state for a generated code exception block
    var ExceptionBlockState;
    (function (ExceptionBlockState) {
        ExceptionBlockState[ExceptionBlockState["Try"] = 0] = "Try";
        ExceptionBlockState[ExceptionBlockState["Catch"] = 1] = "Catch";
        ExceptionBlockState[ExceptionBlockState["Finally"] = 2] = "Finally";
        ExceptionBlockState[ExceptionBlockState["Done"] = 3] = "Done";
    })(ExceptionBlockState || (ExceptionBlockState = {}));
    // NOTE: changes to this enum should be reflected in the __generator helper.
    var Instruction;
    (function (Instruction) {
        Instruction[Instruction["Next"] = 0] = "Next";
        Instruction[Instruction["Throw"] = 1] = "Throw";
        Instruction[Instruction["Return"] = 2] = "Return";
        Instruction[Instruction["Break"] = 3] = "Break";
        Instruction[Instruction["Yield"] = 4] = "Yield";
        Instruction[Instruction["YieldStar"] = 5] = "YieldStar";
        Instruction[Instruction["Catch"] = 6] = "Catch";
        Instruction[Instruction["Endfinally"] = 7] = "Endfinally";
    })(Instruction || (Instruction = {}));
    function getInstructionName(instruction) {
        switch (instruction) {
            case 2 /* Return */: return "return";
            case 3 /* Break */: return "break";
            case 4 /* Yield */: return "yield";
            case 5 /* YieldStar */: return "yield*";
            case 7 /* Endfinally */: return "endfinally";
            default: return undefined; // TODO: GH#18217
        }
    }
    function transformGenerators(context) {
        var resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistFunctionDeclaration = context.hoistFunctionDeclaration, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var resolver = context.getEmitResolver();
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onSubstituteNode = onSubstituteNode;
        var renamedCatchVariables;
        var renamedCatchVariableDeclarations;
        var inGeneratorFunctionBody;
        var inStatementContainingYield;
        // The following three arrays store information about generated code blocks.
        // All three arrays are correlated by their index. This approach is used over allocating
        // objects to store the same information to avoid GC overhead.
        //
        var blocks; // Information about the code block
        var blockOffsets; // The operation offset at which a code block begins or ends
        var blockActions; // Whether the code block is opened or closed
        var blockStack; // A stack of currently open code blocks
        // Labels are used to mark locations in the code that can be the target of a Break (jump)
        // operation. These are translated into case clauses in a switch statement.
        // The following two arrays are correlated by their index. This approach is used over
        // allocating objects to store the same information to avoid GC overhead.
        //
        var labelOffsets; // The operation offset at which the label is defined.
        var labelExpressions; // The NumericLiteral nodes bound to each label.
        var nextLabelId = 1; // The next label id to use.
        // Operations store information about generated code for the function body. This
        // Includes things like statements, assignments, breaks (jumps), and yields.
        // The following three arrays are correlated by their index. This approach is used over
        // allocating objects to store the same information to avoid GC overhead.
        //
        var operations; // The operation to perform.
        var operationArguments; // The arguments to the operation.
        var operationLocations; // The source map location for the operation.
        var state; // The name of the state object used by the generator at runtime.
        // The following variables store information used by the `build` function:
        //
        var blockIndex = 0; // The index of the current block.
        var labelNumber = 0; // The current label number.
        var labelNumbers;
        var lastOperationWasAbrupt; // Indicates whether the last operation was abrupt (break/continue).
        var lastOperationWasCompletion; // Indicates whether the last operation was a completion (return/throw).
        var clauses; // The case clauses generated for labels.
        var statements; // The statements for the current label.
        var exceptionBlockStack; // A stack of containing exception blocks.
        var currentExceptionBlock; // The current exception block.
        var withBlockStack; // A stack containing `with` blocks.
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile || (node.transformFlags & 256 /* ContainsGenerator */) === 0) {
                return node;
            }
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        /**
         * Visits a node.
         *
         * @param node The node to visit.
         */
        function visitor(node) {
            var transformFlags = node.transformFlags;
            if (inStatementContainingYield) {
                return visitJavaScriptInStatementContainingYield(node);
            }
            else if (inGeneratorFunctionBody) {
                return visitJavaScriptInGeneratorFunctionBody(node);
            }
            else if (ts.isFunctionLikeDeclaration(node) && node.asteriskToken) {
                return visitGenerator(node);
            }
            else if (transformFlags & 256 /* ContainsGenerator */) {
                return ts.visitEachChild(node, visitor, context);
            }
            else {
                return node;
            }
        }
        /**
         * Visits a node that is contained within a statement that contains yield.
         *
         * @param node The node to visit.
         */
        function visitJavaScriptInStatementContainingYield(node) {
            switch (node.kind) {
                case 224 /* DoStatement */:
                    return visitDoStatement(node);
                case 225 /* WhileStatement */:
                    return visitWhileStatement(node);
                case 233 /* SwitchStatement */:
                    return visitSwitchStatement(node);
                case 234 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                default:
                    return visitJavaScriptInGeneratorFunctionBody(node);
            }
        }
        /**
         * Visits a node that is contained within a generator function.
         *
         * @param node The node to visit.
         */
        function visitJavaScriptInGeneratorFunctionBody(node) {
            switch (node.kind) {
                case 240 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 197 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    return visitAccessorDeclaration(node);
                case 220 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 226 /* ForStatement */:
                    return visitForStatement(node);
                case 227 /* ForInStatement */:
                    return visitForInStatement(node);
                case 230 /* BreakStatement */:
                    return visitBreakStatement(node);
                case 229 /* ContinueStatement */:
                    return visitContinueStatement(node);
                case 231 /* ReturnStatement */:
                    return visitReturnStatement(node);
                default:
                    if (node.transformFlags & 131072 /* ContainsYield */) {
                        return visitJavaScriptContainingYield(node);
                    }
                    else if (node.transformFlags & (256 /* ContainsGenerator */ | 262144 /* ContainsHoistedDeclarationOrCompletion */)) {
                        return ts.visitEachChild(node, visitor, context);
                    }
                    else {
                        return node;
                    }
            }
        }
        /**
         * Visits a node that contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitJavaScriptContainingYield(node) {
            switch (node.kind) {
                case 205 /* BinaryExpression */:
                    return visitBinaryExpression(node);
                case 206 /* ConditionalExpression */:
                    return visitConditionalExpression(node);
                case 208 /* YieldExpression */:
                    return visitYieldExpression(node);
                case 188 /* ArrayLiteralExpression */:
                    return visitArrayLiteralExpression(node);
                case 189 /* ObjectLiteralExpression */:
                    return visitObjectLiteralExpression(node);
                case 191 /* ElementAccessExpression */:
                    return visitElementAccessExpression(node);
                case 192 /* CallExpression */:
                    return visitCallExpression(node);
                case 193 /* NewExpression */:
                    return visitNewExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        /**
         * Visits a generator function.
         *
         * @param node The node to visit.
         */
        function visitGenerator(node) {
            switch (node.kind) {
                case 240 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 197 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                default:
                    return ts.Debug.failBadSyntaxKind(node);
            }
        }
        /**
         * Visits a function declaration.
         *
         * This will be called when one of the following conditions are met:
         * - The function declaration is a generator function.
         * - The function declaration is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            // Currently, we only support generators that were originally async functions.
            if (node.asteriskToken) {
                node = ts.setOriginalNode(ts.setTextRange(ts.createFunctionDeclaration(
                /*decorators*/ undefined, node.modifiers, 
                /*asteriskToken*/ undefined, node.name, 
                /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
                /*type*/ undefined, transformGeneratorFunctionBody(node.body)), 
                /*location*/ node), node);
            }
            else {
                var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
                var savedInStatementContainingYield = inStatementContainingYield;
                inGeneratorFunctionBody = false;
                inStatementContainingYield = false;
                node = ts.visitEachChild(node, visitor, context);
                inGeneratorFunctionBody = savedInGeneratorFunctionBody;
                inStatementContainingYield = savedInStatementContainingYield;
            }
            if (inGeneratorFunctionBody) {
                // Function declarations in a generator function body are hoisted
                // to the top of the lexical scope and elided from the current statement.
                hoistFunctionDeclaration(node);
                return undefined;
            }
            else {
                return node;
            }
        }
        /**
         * Visits a function expression.
         *
         * This will be called when one of the following conditions are met:
         * - The function expression is a generator function.
         * - The function expression is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitFunctionExpression(node) {
            // Currently, we only support generators that were originally async functions.
            if (node.asteriskToken) {
                node = ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, node.name, 
                /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
                /*type*/ undefined, transformGeneratorFunctionBody(node.body)), 
                /*location*/ node), node);
            }
            else {
                var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
                var savedInStatementContainingYield = inStatementContainingYield;
                inGeneratorFunctionBody = false;
                inStatementContainingYield = false;
                node = ts.visitEachChild(node, visitor, context);
                inGeneratorFunctionBody = savedInGeneratorFunctionBody;
                inStatementContainingYield = savedInStatementContainingYield;
            }
            return node;
        }
        /**
         * Visits a get or set accessor declaration.
         *
         * This will be called when one of the following conditions are met:
         * - The accessor is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitAccessorDeclaration(node) {
            var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
            var savedInStatementContainingYield = inStatementContainingYield;
            inGeneratorFunctionBody = false;
            inStatementContainingYield = false;
            node = ts.visitEachChild(node, visitor, context);
            inGeneratorFunctionBody = savedInGeneratorFunctionBody;
            inStatementContainingYield = savedInStatementContainingYield;
            return node;
        }
        /**
         * Transforms the body of a generator function declaration.
         *
         * @param node The function body to transform.
         */
        function transformGeneratorFunctionBody(body) {
            // Save existing generator state
            var statements = [];
            var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
            var savedInStatementContainingYield = inStatementContainingYield;
            var savedBlocks = blocks;
            var savedBlockOffsets = blockOffsets;
            var savedBlockActions = blockActions;
            var savedBlockStack = blockStack;
            var savedLabelOffsets = labelOffsets;
            var savedLabelExpressions = labelExpressions;
            var savedNextLabelId = nextLabelId;
            var savedOperations = operations;
            var savedOperationArguments = operationArguments;
            var savedOperationLocations = operationLocations;
            var savedState = state;
            // Initialize generator state
            inGeneratorFunctionBody = true;
            inStatementContainingYield = false;
            blocks = undefined;
            blockOffsets = undefined;
            blockActions = undefined;
            blockStack = undefined;
            labelOffsets = undefined;
            labelExpressions = undefined;
            nextLabelId = 1;
            operations = undefined;
            operationArguments = undefined;
            operationLocations = undefined;
            state = ts.createTempVariable(/*recordTempVariable*/ undefined);
            // Build the generator
            resumeLexicalEnvironment();
            var statementOffset = ts.addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor);
            transformAndEmitStatements(body.statements, statementOffset);
            var buildResult = build();
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            statements.push(ts.createReturn(buildResult));
            // Restore previous generator state
            inGeneratorFunctionBody = savedInGeneratorFunctionBody;
            inStatementContainingYield = savedInStatementContainingYield;
            blocks = savedBlocks;
            blockOffsets = savedBlockOffsets;
            blockActions = savedBlockActions;
            blockStack = savedBlockStack;
            labelOffsets = savedLabelOffsets;
            labelExpressions = savedLabelExpressions;
            nextLabelId = savedNextLabelId;
            operations = savedOperations;
            operationArguments = savedOperationArguments;
            operationLocations = savedOperationLocations;
            state = savedState;
            return ts.setTextRange(ts.createBlock(statements, body.multiLine), body);
        }
        /**
         * Visits a variable statement.
         *
         * This will be called when one of the following conditions are met:
         * - The variable statement is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitVariableStatement(node) {
            if (node.transformFlags & 131072 /* ContainsYield */) {
                transformAndEmitVariableDeclarationList(node.declarationList);
                return undefined;
            }
            else {
                // Do not hoist custom prologues.
                if (ts.getEmitFlags(node) & 1048576 /* CustomPrologue */) {
                    return node;
                }
                for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    hoistVariableDeclaration(variable.name);
                }
                var variables = ts.getInitializedVariables(node.declarationList);
                if (variables.length === 0) {
                    return undefined;
                }
                return ts.setSourceMapRange(ts.createExpressionStatement(ts.inlineExpressions(ts.map(variables, transformInitializedVariable))), node);
            }
        }
        /**
         * Visits a binary expression.
         *
         * This will be called when one of the following conditions are met:
         * - The node contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitBinaryExpression(node) {
            var assoc = ts.getExpressionAssociativity(node);
            switch (assoc) {
                case 0 /* Left */:
                    return visitLeftAssociativeBinaryExpression(node);
                case 1 /* Right */:
                    return visitRightAssociativeBinaryExpression(node);
                default:
                    return ts.Debug.assertNever(assoc);
            }
        }
        function isCompoundAssignment(kind) {
            return kind >= 61 /* FirstCompoundAssignment */
                && kind <= 72 /* LastCompoundAssignment */;
        }
        function getOperatorForCompoundAssignment(kind) {
            switch (kind) {
                case 61 /* PlusEqualsToken */: return 38 /* PlusToken */;
                case 62 /* MinusEqualsToken */: return 39 /* MinusToken */;
                case 63 /* AsteriskEqualsToken */: return 40 /* AsteriskToken */;
                case 64 /* AsteriskAsteriskEqualsToken */: return 41 /* AsteriskAsteriskToken */;
                case 65 /* SlashEqualsToken */: return 42 /* SlashToken */;
                case 66 /* PercentEqualsToken */: return 43 /* PercentToken */;
                case 67 /* LessThanLessThanEqualsToken */: return 46 /* LessThanLessThanToken */;
                case 68 /* GreaterThanGreaterThanEqualsToken */: return 47 /* GreaterThanGreaterThanToken */;
                case 69 /* GreaterThanGreaterThanGreaterThanEqualsToken */: return 48 /* GreaterThanGreaterThanGreaterThanToken */;
                case 70 /* AmpersandEqualsToken */: return 49 /* AmpersandToken */;
                case 71 /* BarEqualsToken */: return 50 /* BarToken */;
                case 72 /* CaretEqualsToken */: return 51 /* CaretToken */;
            }
        }
        /**
         * Visits a right-associative binary expression containing `yield`.
         *
         * @param node The node to visit.
         */
        function visitRightAssociativeBinaryExpression(node) {
            var left = node.left, right = node.right;
            if (containsYield(right)) {
                var target = void 0;
                switch (left.kind) {
                    case 190 /* PropertyAccessExpression */:
                        // [source]
                        //      a.b = yield;
                        //
                        // [intermediate]
                        //  .local _a
                        //      _a = a;
                        //  .yield resumeLabel
                        //  .mark resumeLabel
                        //      _a.b = %sent%;
                        target = ts.updatePropertyAccess(left, cacheExpression(ts.visitNode(left.expression, visitor, ts.isLeftHandSideExpression)), left.name);
                        break;
                    case 191 /* ElementAccessExpression */:
                        // [source]
                        //      a[b] = yield;
                        //
                        // [intermediate]
                        //  .local _a, _b
                        //      _a = a;
                        //      _b = b;
                        //  .yield resumeLabel
                        //  .mark resumeLabel
                        //      _a[_b] = %sent%;
                        target = ts.updateElementAccess(left, cacheExpression(ts.visitNode(left.expression, visitor, ts.isLeftHandSideExpression)), cacheExpression(ts.visitNode(left.argumentExpression, visitor, ts.isExpression)));
                        break;
                    default:
                        target = ts.visitNode(left, visitor, ts.isExpression);
                        break;
                }
                var operator = node.operatorToken.kind;
                if (isCompoundAssignment(operator)) {
                    return ts.setTextRange(ts.createAssignment(target, ts.setTextRange(ts.createBinary(cacheExpression(target), getOperatorForCompoundAssignment(operator), ts.visitNode(right, visitor, ts.isExpression)), node)), node);
                }
                else {
                    return ts.updateBinary(node, target, ts.visitNode(right, visitor, ts.isExpression));
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitLeftAssociativeBinaryExpression(node) {
            if (containsYield(node.right)) {
                if (ts.isLogicalOperator(node.operatorToken.kind)) {
                    return visitLogicalBinaryExpression(node);
                }
                else if (node.operatorToken.kind === 27 /* CommaToken */) {
                    return visitCommaExpression(node);
                }
                // [source]
                //      a() + (yield) + c()
                //
                // [intermediate]
                //  .local _a
                //      _a = a();
                //  .yield resumeLabel
                //      _a + %sent% + c()
                var clone_5 = ts.getMutableClone(node);
                clone_5.left = cacheExpression(ts.visitNode(node.left, visitor, ts.isExpression));
                clone_5.right = ts.visitNode(node.right, visitor, ts.isExpression);
                return clone_5;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a logical binary expression containing `yield`.
         *
         * @param node A node to visit.
         */
        function visitLogicalBinaryExpression(node) {
            // Logical binary expressions (`&&` and `||`) are shortcutting expressions and need
            // to be transformed as such:
            //
            // [source]
            //      x = a() && yield;
            //
            // [intermediate]
            //  .local _a
            //      _a = a();
            //  .brfalse resultLabel, (_a)
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      _a = %sent%;
            //  .mark resultLabel
            //      x = _a;
            //
            // [source]
            //      x = a() || yield;
            //
            // [intermediate]
            //  .local _a
            //      _a = a();
            //  .brtrue resultLabel, (_a)
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      _a = %sent%;
            //  .mark resultLabel
            //      x = _a;
            var resultLabel = defineLabel();
            var resultLocal = declareLocal();
            emitAssignment(resultLocal, ts.visitNode(node.left, visitor, ts.isExpression), /*location*/ node.left);
            if (node.operatorToken.kind === 54 /* AmpersandAmpersandToken */) {
                // Logical `&&` shortcuts when the left-hand operand is falsey.
                emitBreakWhenFalse(resultLabel, resultLocal, /*location*/ node.left);
            }
            else {
                // Logical `||` shortcuts when the left-hand operand is truthy.
                emitBreakWhenTrue(resultLabel, resultLocal, /*location*/ node.left);
            }
            emitAssignment(resultLocal, ts.visitNode(node.right, visitor, ts.isExpression), /*location*/ node.right);
            markLabel(resultLabel);
            return resultLocal;
        }
        /**
         * Visits a comma expression containing `yield`.
         *
         * @param node The node to visit.
         */
        function visitCommaExpression(node) {
            // [source]
            //      x = a(), yield, b();
            //
            // [intermediate]
            //      a();
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      x = %sent%, b();
            var pendingExpressions = [];
            visit(node.left);
            visit(node.right);
            return ts.inlineExpressions(pendingExpressions);
            function visit(node) {
                if (ts.isBinaryExpression(node) && node.operatorToken.kind === 27 /* CommaToken */) {
                    visit(node.left);
                    visit(node.right);
                }
                else {
                    if (containsYield(node) && pendingExpressions.length > 0) {
                        emitWorker(1 /* Statement */, [ts.createExpressionStatement(ts.inlineExpressions(pendingExpressions))]);
                        pendingExpressions = [];
                    }
                    pendingExpressions.push(ts.visitNode(node, visitor, ts.isExpression));
                }
            }
        }
        /**
         * Visits a conditional expression containing `yield`.
         *
         * @param node The node to visit.
         */
        function visitConditionalExpression(node) {
            // [source]
            //      x = a() ? yield : b();
            //
            // [intermediate]
            //  .local _a
            //  .brfalse whenFalseLabel, (a())
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      _a = %sent%;
            //  .br resultLabel
            //  .mark whenFalseLabel
            //      _a = b();
            //  .mark resultLabel
            //      x = _a;
            // We only need to perform a specific transformation if a `yield` expression exists
            // in either the `whenTrue` or `whenFalse` branches.
            // A `yield` in the condition will be handled by the normal visitor.
            if (containsYield(node.whenTrue) || containsYield(node.whenFalse)) {
                var whenFalseLabel = defineLabel();
                var resultLabel = defineLabel();
                var resultLocal = declareLocal();
                emitBreakWhenFalse(whenFalseLabel, ts.visitNode(node.condition, visitor, ts.isExpression), /*location*/ node.condition);
                emitAssignment(resultLocal, ts.visitNode(node.whenTrue, visitor, ts.isExpression), /*location*/ node.whenTrue);
                emitBreak(resultLabel);
                markLabel(whenFalseLabel);
                emitAssignment(resultLocal, ts.visitNode(node.whenFalse, visitor, ts.isExpression), /*location*/ node.whenFalse);
                markLabel(resultLabel);
                return resultLocal;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a `yield` expression.
         *
         * @param node The node to visit.
         */
        function visitYieldExpression(node) {
            // [source]
            //      x = yield a();
            //
            // [intermediate]
            //  .yield resumeLabel, (a())
            //  .mark resumeLabel
            //      x = %sent%;
            var resumeLabel = defineLabel();
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            if (node.asteriskToken) {
                var iterator = (ts.getEmitFlags(node.expression) & 8388608 /* Iterator */) === 0
                    ? ts.createValuesHelper(context, expression, /*location*/ node)
                    : expression;
                emitYieldStar(iterator, /*location*/ node);
            }
            else {
                emitYield(expression, /*location*/ node);
            }
            markLabel(resumeLabel);
            return createGeneratorResume(/*location*/ node);
        }
        /**
         * Visits an ArrayLiteralExpression that contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitArrayLiteralExpression(node) {
            return visitElements(node.elements, /*leadingElement*/ undefined, /*location*/ undefined, node.multiLine);
        }
        /**
         * Visits an array of expressions containing one or more YieldExpression nodes
         * and returns an expression for the resulting value.
         *
         * @param elements The elements to visit.
         * @param multiLine Whether array literals created should be emitted on multiple lines.
         */
        function visitElements(elements, leadingElement, location, multiLine) {
            // [source]
            //      ar = [1, yield, 2];
            //
            // [intermediate]
            //  .local _a
            //      _a = [1];
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      ar = _a.concat([%sent%, 2]);
            var numInitialElements = countInitialNodesWithoutYield(elements);
            var temp;
            if (numInitialElements > 0) {
                temp = declareLocal();
                var initialElements = ts.visitNodes(elements, visitor, ts.isExpression, 0, numInitialElements);
                emitAssignment(temp, ts.createArrayLiteral(leadingElement
                    ? [leadingElement].concat(initialElements) : initialElements));
                leadingElement = undefined;
            }
            var expressions = ts.reduceLeft(elements, reduceElement, [], numInitialElements);
            return temp
                ? ts.createArrayConcat(temp, [ts.createArrayLiteral(expressions, multiLine)])
                : ts.setTextRange(ts.createArrayLiteral(leadingElement ? [leadingElement].concat(expressions) : expressions, multiLine), location);
            function reduceElement(expressions, element) {
                if (containsYield(element) && expressions.length > 0) {
                    var hasAssignedTemp = temp !== undefined;
                    if (!temp) {
                        temp = declareLocal();
                    }
                    emitAssignment(temp, hasAssignedTemp
                        ? ts.createArrayConcat(temp, [ts.createArrayLiteral(expressions, multiLine)])
                        : ts.createArrayLiteral(leadingElement ? [leadingElement].concat(expressions) : expressions, multiLine));
                    leadingElement = undefined;
                    expressions = [];
                }
                expressions.push(ts.visitNode(element, visitor, ts.isExpression));
                return expressions;
            }
        }
        function visitObjectLiteralExpression(node) {
            // [source]
            //      o = {
            //          a: 1,
            //          b: yield,
            //          c: 2
            //      };
            //
            // [intermediate]
            //  .local _a
            //      _a = {
            //          a: 1
            //      };
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      o = (_a.b = %sent%,
            //          _a.c = 2,
            //          _a);
            var properties = node.properties;
            var multiLine = node.multiLine;
            var numInitialProperties = countInitialNodesWithoutYield(properties);
            var temp = declareLocal();
            emitAssignment(temp, ts.createObjectLiteral(ts.visitNodes(properties, visitor, ts.isObjectLiteralElementLike, 0, numInitialProperties), multiLine));
            var expressions = ts.reduceLeft(properties, reduceProperty, [], numInitialProperties);
            expressions.push(multiLine ? ts.startOnNewLine(ts.getMutableClone(temp)) : temp);
            return ts.inlineExpressions(expressions);
            function reduceProperty(expressions, property) {
                if (containsYield(property) && expressions.length > 0) {
                    emitStatement(ts.createExpressionStatement(ts.inlineExpressions(expressions)));
                    expressions = [];
                }
                var expression = ts.createExpressionForObjectLiteralElementLike(node, property, temp);
                var visited = ts.visitNode(expression, visitor, ts.isExpression);
                if (visited) {
                    if (multiLine) {
                        ts.startOnNewLine(visited);
                    }
                    expressions.push(visited);
                }
                return expressions;
            }
        }
        /**
         * Visits an ElementAccessExpression that contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitElementAccessExpression(node) {
            if (containsYield(node.argumentExpression)) {
                // [source]
                //      a = x[yield];
                //
                // [intermediate]
                //  .local _a
                //      _a = x;
                //  .yield resumeLabel
                //  .mark resumeLabel
                //      a = _a[%sent%]
                var clone_6 = ts.getMutableClone(node);
                clone_6.expression = cacheExpression(ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression));
                clone_6.argumentExpression = ts.visitNode(node.argumentExpression, visitor, ts.isExpression);
                return clone_6;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitCallExpression(node) {
            if (!ts.isImportCall(node) && ts.forEach(node.arguments, containsYield)) {
                // [source]
                //      a.b(1, yield, 2);
                //
                // [intermediate]
                //  .local _a, _b, _c
                //      _b = (_a = a).b;
                //      _c = [1];
                //  .yield resumeLabel
                //  .mark resumeLabel
                //      _b.apply(_a, _c.concat([%sent%, 2]));
                var _a = ts.createCallBinding(node.expression, hoistVariableDeclaration, languageVersion, /*cacheIdentifiers*/ true), target = _a.target, thisArg = _a.thisArg;
                return ts.setOriginalNode(ts.createFunctionApply(cacheExpression(ts.visitNode(target, visitor, ts.isLeftHandSideExpression)), thisArg, visitElements(node.arguments), 
                /*location*/ node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitNewExpression(node) {
            if (ts.forEach(node.arguments, containsYield)) {
                // [source]
                //      new a.b(1, yield, 2);
                //
                // [intermediate]
                //  .local _a, _b, _c
                //      _b = (_a = a.b).bind;
                //      _c = [1];
                //  .yield resumeLabel
                //  .mark resumeLabel
                //      new (_b.apply(_a, _c.concat([%sent%, 2])));
                var _a = ts.createCallBinding(ts.createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg;
                return ts.setOriginalNode(ts.setTextRange(ts.createNew(ts.createFunctionApply(cacheExpression(ts.visitNode(target, visitor, ts.isExpression)), thisArg, visitElements(node.arguments, 
                /*leadingElement*/ ts.createVoidZero())), 
                /*typeArguments*/ undefined, []), node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function transformAndEmitStatements(statements, start) {
            if (start === void 0) { start = 0; }
            var numStatements = statements.length;
            for (var i = start; i < numStatements; i++) {
                transformAndEmitStatement(statements[i]);
            }
        }
        function transformAndEmitEmbeddedStatement(node) {
            if (ts.isBlock(node)) {
                transformAndEmitStatements(node.statements);
            }
            else {
                transformAndEmitStatement(node);
            }
        }
        function transformAndEmitStatement(node) {
            var savedInStatementContainingYield = inStatementContainingYield;
            if (!inStatementContainingYield) {
                inStatementContainingYield = containsYield(node);
            }
            transformAndEmitStatementWorker(node);
            inStatementContainingYield = savedInStatementContainingYield;
        }
        function transformAndEmitStatementWorker(node) {
            switch (node.kind) {
                case 219 /* Block */:
                    return transformAndEmitBlock(node);
                case 222 /* ExpressionStatement */:
                    return transformAndEmitExpressionStatement(node);
                case 223 /* IfStatement */:
                    return transformAndEmitIfStatement(node);
                case 224 /* DoStatement */:
                    return transformAndEmitDoStatement(node);
                case 225 /* WhileStatement */:
                    return transformAndEmitWhileStatement(node);
                case 226 /* ForStatement */:
                    return transformAndEmitForStatement(node);
                case 227 /* ForInStatement */:
                    return transformAndEmitForInStatement(node);
                case 229 /* ContinueStatement */:
                    return transformAndEmitContinueStatement(node);
                case 230 /* BreakStatement */:
                    return transformAndEmitBreakStatement(node);
                case 231 /* ReturnStatement */:
                    return transformAndEmitReturnStatement(node);
                case 232 /* WithStatement */:
                    return transformAndEmitWithStatement(node);
                case 233 /* SwitchStatement */:
                    return transformAndEmitSwitchStatement(node);
                case 234 /* LabeledStatement */:
                    return transformAndEmitLabeledStatement(node);
                case 235 /* ThrowStatement */:
                    return transformAndEmitThrowStatement(node);
                case 236 /* TryStatement */:
                    return transformAndEmitTryStatement(node);
                default:
                    return emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitBlock(node) {
            if (containsYield(node)) {
                transformAndEmitStatements(node.statements);
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitExpressionStatement(node) {
            emitStatement(ts.visitNode(node, visitor, ts.isStatement));
        }
        function transformAndEmitVariableDeclarationList(node) {
            for (var _i = 0, _a = node.declarations; _i < _a.length; _i++) {
                var variable = _a[_i];
                var name = ts.getSynthesizedClone(variable.name);
                ts.setCommentRange(name, variable.name);
                hoistVariableDeclaration(name);
            }
            var variables = ts.getInitializedVariables(node);
            var numVariables = variables.length;
            var variablesWritten = 0;
            var pendingExpressions = [];
            while (variablesWritten < numVariables) {
                for (var i = variablesWritten; i < numVariables; i++) {
                    var variable = variables[i];
                    if (containsYield(variable.initializer) && pendingExpressions.length > 0) {
                        break;
                    }
                    pendingExpressions.push(transformInitializedVariable(variable));
                }
                if (pendingExpressions.length) {
                    emitStatement(ts.createExpressionStatement(ts.inlineExpressions(pendingExpressions)));
                    variablesWritten += pendingExpressions.length;
                    pendingExpressions = [];
                }
            }
            return undefined;
        }
        function transformInitializedVariable(node) {
            return ts.setSourceMapRange(ts.createAssignment(ts.setSourceMapRange(ts.getSynthesizedClone(node.name), node.name), ts.visitNode(node.initializer, visitor, ts.isExpression)), node);
        }
        function transformAndEmitIfStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      if (x)
                //          /*thenStatement*/
                //      else
                //          /*elseStatement*/
                //
                // [intermediate]
                //  .brfalse elseLabel, (x)
                //      /*thenStatement*/
                //  .br endLabel
                //  .mark elseLabel
                //      /*elseStatement*/
                //  .mark endLabel
                if (containsYield(node.thenStatement) || containsYield(node.elseStatement)) {
                    var endLabel = defineLabel();
                    var elseLabel = node.elseStatement ? defineLabel() : undefined;
                    emitBreakWhenFalse(node.elseStatement ? elseLabel : endLabel, ts.visitNode(node.expression, visitor, ts.isExpression), /*location*/ node.expression);
                    transformAndEmitEmbeddedStatement(node.thenStatement);
                    if (node.elseStatement) {
                        emitBreak(endLabel);
                        markLabel(elseLabel);
                        transformAndEmitEmbeddedStatement(node.elseStatement);
                    }
                    markLabel(endLabel);
                }
                else {
                    emitStatement(ts.visitNode(node, visitor, ts.isStatement));
                }
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitDoStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      do {
                //          /*body*/
                //      }
                //      while (i < 10);
                //
                // [intermediate]
                //  .loop conditionLabel, endLabel
                //  .mark loopLabel
                //      /*body*/
                //  .mark conditionLabel
                //  .brtrue loopLabel, (i < 10)
                //  .endloop
                //  .mark endLabel
                var conditionLabel = defineLabel();
                var loopLabel = defineLabel();
                beginLoopBlock(/*continueLabel*/ conditionLabel);
                markLabel(loopLabel);
                transformAndEmitEmbeddedStatement(node.statement);
                markLabel(conditionLabel);
                emitBreakWhenTrue(loopLabel, ts.visitNode(node.expression, visitor, ts.isExpression));
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitDoStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
                node = ts.visitEachChild(node, visitor, context);
                endLoopBlock();
                return node;
            }
            else {
                return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformAndEmitWhileStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      while (i < 10) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .loop loopLabel, endLabel
                //  .mark loopLabel
                //  .brfalse endLabel, (i < 10)
                //      /*body*/
                //  .br loopLabel
                //  .endloop
                //  .mark endLabel
                var loopLabel = defineLabel();
                var endLabel = beginLoopBlock(loopLabel);
                markLabel(loopLabel);
                emitBreakWhenFalse(endLabel, ts.visitNode(node.expression, visitor, ts.isExpression));
                transformAndEmitEmbeddedStatement(node.statement);
                emitBreak(loopLabel);
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitWhileStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
                node = ts.visitEachChild(node, visitor, context);
                endLoopBlock();
                return node;
            }
            else {
                return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformAndEmitForStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      for (var i = 0; i < 10; i++) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .local i
                //      i = 0;
                //  .loop incrementLabel, endLoopLabel
                //  .mark conditionLabel
                //  .brfalse endLoopLabel, (i < 10)
                //      /*body*/
                //  .mark incrementLabel
                //      i++;
                //  .br conditionLabel
                //  .endloop
                //  .mark endLoopLabel
                var conditionLabel = defineLabel();
                var incrementLabel = defineLabel();
                var endLabel = beginLoopBlock(incrementLabel);
                if (node.initializer) {
                    var initializer = node.initializer;
                    if (ts.isVariableDeclarationList(initializer)) {
                        transformAndEmitVariableDeclarationList(initializer);
                    }
                    else {
                        emitStatement(ts.setTextRange(ts.createExpressionStatement(ts.visitNode(initializer, visitor, ts.isExpression)), initializer));
                    }
                }
                markLabel(conditionLabel);
                if (node.condition) {
                    emitBreakWhenFalse(endLabel, ts.visitNode(node.condition, visitor, ts.isExpression));
                }
                transformAndEmitEmbeddedStatement(node.statement);
                markLabel(incrementLabel);
                if (node.incrementor) {
                    emitStatement(ts.setTextRange(ts.createExpressionStatement(ts.visitNode(node.incrementor, visitor, ts.isExpression)), node.incrementor));
                }
                emitBreak(conditionLabel);
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitForStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
            }
            var initializer = node.initializer;
            if (initializer && ts.isVariableDeclarationList(initializer)) {
                for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    hoistVariableDeclaration(variable.name);
                }
                var variables = ts.getInitializedVariables(initializer);
                node = ts.updateFor(node, variables.length > 0
                    ? ts.inlineExpressions(ts.map(variables, transformInitializedVariable))
                    : undefined, ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            }
            else {
                node = ts.visitEachChild(node, visitor, context);
            }
            if (inStatementContainingYield) {
                endLoopBlock();
            }
            return node;
        }
        function transformAndEmitForInStatement(node) {
            // TODO(rbuckton): Source map locations
            if (containsYield(node)) {
                // [source]
                //      for (var p in o) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .local _a, _b, _i
                //      _a = [];
                //      for (_b in o) _a.push(_b);
                //      _i = 0;
                //  .loop incrementLabel, endLoopLabel
                //  .mark conditionLabel
                //  .brfalse endLoopLabel, (_i < _a.length)
                //      p = _a[_i];
                //      /*body*/
                //  .mark incrementLabel
                //      _b++;
                //  .br conditionLabel
                //  .endloop
                //  .mark endLoopLabel
                var keysArray = declareLocal(); // _a
                var key = declareLocal(); // _b
                var keysIndex = ts.createLoopVariable(); // _i
                var initializer = node.initializer;
                hoistVariableDeclaration(keysIndex);
                emitAssignment(keysArray, ts.createArrayLiteral());
                emitStatement(ts.createForIn(key, ts.visitNode(node.expression, visitor, ts.isExpression), ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(keysArray, "push"), 
                /*typeArguments*/ undefined, [key]))));
                emitAssignment(keysIndex, ts.createLiteral(0));
                var conditionLabel = defineLabel();
                var incrementLabel = defineLabel();
                var endLabel = beginLoopBlock(incrementLabel);
                markLabel(conditionLabel);
                emitBreakWhenFalse(endLabel, ts.createLessThan(keysIndex, ts.createPropertyAccess(keysArray, "length")));
                var variable = void 0;
                if (ts.isVariableDeclarationList(initializer)) {
                    for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) {
                        var variable_1 = _a[_i];
                        hoistVariableDeclaration(variable_1.name);
                    }
                    variable = ts.getSynthesizedClone(initializer.declarations[0].name);
                }
                else {
                    variable = ts.visitNode(initializer, visitor, ts.isExpression);
                    ts.Debug.assert(ts.isLeftHandSideExpression(variable));
                }
                emitAssignment(variable, ts.createElementAccess(keysArray, keysIndex));
                transformAndEmitEmbeddedStatement(node.statement);
                markLabel(incrementLabel);
                emitStatement(ts.createExpressionStatement(ts.createPostfixIncrement(keysIndex)));
                emitBreak(conditionLabel);
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitForInStatement(node) {
            // [source]
            //      for (var x in a) {
            //          /*body*/
            //      }
            //
            // [intermediate]
            //  .local x
            //  .loop
            //      for (x in a) {
            //          /*body*/
            //      }
            //  .endloop
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
            }
            var initializer = node.initializer;
            if (ts.isVariableDeclarationList(initializer)) {
                for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    hoistVariableDeclaration(variable.name);
                }
                node = ts.updateForIn(node, initializer.declarations[0].name, ts.visitNode(node.expression, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            }
            else {
                node = ts.visitEachChild(node, visitor, context);
            }
            if (inStatementContainingYield) {
                endLoopBlock();
            }
            return node;
        }
        function transformAndEmitContinueStatement(node) {
            var label = findContinueTarget(node.label ? ts.idText(node.label) : undefined);
            if (label > 0) {
                emitBreak(label, /*location*/ node);
            }
            else {
                // invalid continue without a containing loop. Leave the node as is, per #17875.
                emitStatement(node);
            }
        }
        function visitContinueStatement(node) {
            if (inStatementContainingYield) {
                var label = findContinueTarget(node.label && ts.idText(node.label));
                if (label > 0) {
                    return createInlineBreak(label, /*location*/ node);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function transformAndEmitBreakStatement(node) {
            var label = findBreakTarget(node.label ? ts.idText(node.label) : undefined);
            if (label > 0) {
                emitBreak(label, /*location*/ node);
            }
            else {
                // invalid break without a containing loop, switch, or labeled statement. Leave the node as is, per #17875.
                emitStatement(node);
            }
        }
        function visitBreakStatement(node) {
            if (inStatementContainingYield) {
                var label = findBreakTarget(node.label && ts.idText(node.label));
                if (label > 0) {
                    return createInlineBreak(label, /*location*/ node);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function transformAndEmitReturnStatement(node) {
            emitReturn(ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*location*/ node);
        }
        function visitReturnStatement(node) {
            return createInlineReturn(ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*location*/ node);
        }
        function transformAndEmitWithStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      with (x) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .with (x)
                //      /*body*/
                //  .endwith
                beginWithBlock(cacheExpression(ts.visitNode(node.expression, visitor, ts.isExpression)));
                transformAndEmitEmbeddedStatement(node.statement);
                endWithBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitSwitchStatement(node) {
            if (containsYield(node.caseBlock)) {
                // [source]
                //      switch (x) {
                //          case a:
                //              /*caseStatements*/
                //          case b:
                //              /*caseStatements*/
                //          default:
                //              /*defaultStatements*/
                //      }
                //
                // [intermediate]
                //  .local _a
                //  .switch endLabel
                //      _a = x;
                //      switch (_a) {
                //          case a:
                //  .br clauseLabels[0]
                //      }
                //      switch (_a) {
                //          case b:
                //  .br clauseLabels[1]
                //      }
                //  .br clauseLabels[2]
                //  .mark clauseLabels[0]
                //      /*caseStatements*/
                //  .mark clauseLabels[1]
                //      /*caseStatements*/
                //  .mark clauseLabels[2]
                //      /*caseStatements*/
                //  .endswitch
                //  .mark endLabel
                var caseBlock = node.caseBlock;
                var numClauses = caseBlock.clauses.length;
                var endLabel = beginSwitchBlock();
                var expression = cacheExpression(ts.visitNode(node.expression, visitor, ts.isExpression));
                // Create labels for each clause and find the index of the first default clause.
                var clauseLabels = [];
                var defaultClauseIndex = -1;
                for (var i = 0; i < numClauses; i++) {
                    var clause = caseBlock.clauses[i];
                    clauseLabels.push(defineLabel());
                    if (clause.kind === 273 /* DefaultClause */ && defaultClauseIndex === -1) {
                        defaultClauseIndex = i;
                    }
                }
                // Emit switch statements for each run of case clauses either from the first case
                // clause or the next case clause with a `yield` in its expression, up to the next
                // case clause with a `yield` in its expression.
                var clausesWritten = 0;
                var pendingClauses = [];
                while (clausesWritten < numClauses) {
                    var defaultClausesSkipped = 0;
                    for (var i = clausesWritten; i < numClauses; i++) {
                        var clause = caseBlock.clauses[i];
                        if (clause.kind === 272 /* CaseClause */) {
                            if (containsYield(clause.expression) && pendingClauses.length > 0) {
                                break;
                            }
                            pendingClauses.push(ts.createCaseClause(ts.visitNode(clause.expression, visitor, ts.isExpression), [
                                createInlineBreak(clauseLabels[i], /*location*/ clause.expression)
                            ]));
                        }
                        else {
                            defaultClausesSkipped++;
                        }
                    }
                    if (pendingClauses.length) {
                        emitStatement(ts.createSwitch(expression, ts.createCaseBlock(pendingClauses)));
                        clausesWritten += pendingClauses.length;
                        pendingClauses = [];
                    }
                    if (defaultClausesSkipped > 0) {
                        clausesWritten += defaultClausesSkipped;
                        defaultClausesSkipped = 0;
                    }
                }
                if (defaultClauseIndex >= 0) {
                    emitBreak(clauseLabels[defaultClauseIndex]);
                }
                else {
                    emitBreak(endLabel);
                }
                for (var i = 0; i < numClauses; i++) {
                    markLabel(clauseLabels[i]);
                    transformAndEmitStatements(caseBlock.clauses[i].statements);
                }
                endSwitchBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitSwitchStatement(node) {
            if (inStatementContainingYield) {
                beginScriptSwitchBlock();
            }
            node = ts.visitEachChild(node, visitor, context);
            if (inStatementContainingYield) {
                endSwitchBlock();
            }
            return node;
        }
        function transformAndEmitLabeledStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      x: {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .labeled "x", endLabel
                //      /*body*/
                //  .endlabeled
                //  .mark endLabel
                beginLabeledBlock(ts.idText(node.label));
                transformAndEmitEmbeddedStatement(node.statement);
                endLabeledBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitLabeledStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLabeledBlock(ts.idText(node.label));
            }
            node = ts.visitEachChild(node, visitor, context);
            if (inStatementContainingYield) {
                endLabeledBlock();
            }
            return node;
        }
        function transformAndEmitThrowStatement(node) {
            emitThrow(ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*location*/ node);
        }
        function transformAndEmitTryStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      try {
                //          /*tryBlock*/
                //      }
                //      catch (e) {
                //          /*catchBlock*/
                //      }
                //      finally {
                //          /*finallyBlock*/
                //      }
                //
                // [intermediate]
                //  .local _a
                //  .try tryLabel, catchLabel, finallyLabel, endLabel
                //  .mark tryLabel
                //  .nop
                //      /*tryBlock*/
                //  .br endLabel
                //  .catch
                //  .mark catchLabel
                //      _a = %error%;
                //      /*catchBlock*/
                //  .br endLabel
                //  .finally
                //  .mark finallyLabel
                //      /*finallyBlock*/
                //  .endfinally
                //  .endtry
                //  .mark endLabel
                beginExceptionBlock();
                transformAndEmitEmbeddedStatement(node.tryBlock);
                if (node.catchClause) {
                    beginCatchBlock(node.catchClause.variableDeclaration); // TODO: GH#18217
                    transformAndEmitEmbeddedStatement(node.catchClause.block);
                }
                if (node.finallyBlock) {
                    beginFinallyBlock();
                    transformAndEmitEmbeddedStatement(node.finallyBlock);
                }
                endExceptionBlock();
            }
            else {
                emitStatement(ts.visitEachChild(node, visitor, context));
            }
        }
        function containsYield(node) {
            return !!node && (node.transformFlags & 131072 /* ContainsYield */) !== 0;
        }
        function countInitialNodesWithoutYield(nodes) {
            var numNodes = nodes.length;
            for (var i = 0; i < numNodes; i++) {
                if (containsYield(nodes[i])) {
                    return i;
                }
            }
            return -1;
        }
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            return node;
        }
        function substituteExpression(node) {
            if (ts.isIdentifier(node)) {
                return substituteExpressionIdentifier(node);
            }
            return node;
        }
        function substituteExpressionIdentifier(node) {
            if (!ts.isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(ts.idText(node))) {
                var original = ts.getOriginalNode(node);
                if (ts.isIdentifier(original) && original.parent) {
                    var declaration = resolver.getReferencedValueDeclaration(original);
                    if (declaration) {
                        var name = renamedCatchVariableDeclarations[ts.getOriginalNodeId(declaration)];
                        if (name) {
                            var clone_7 = ts.getMutableClone(name);
                            ts.setSourceMapRange(clone_7, node);
                            ts.setCommentRange(clone_7, node);
                            return clone_7;
                        }
                    }
                }
            }
            return node;
        }
        function cacheExpression(node) {
            var temp;
            if (ts.isGeneratedIdentifier(node) || ts.getEmitFlags(node) & 4096 /* HelperName */) {
                return node;
            }
            temp = ts.createTempVariable(hoistVariableDeclaration);
            emitAssignment(temp, node, /*location*/ node);
            return temp;
        }
        function declareLocal(name) {
            var temp = name
                ? ts.createUniqueName(name)
                : ts.createTempVariable(/*recordTempVariable*/ undefined);
            hoistVariableDeclaration(temp);
            return temp;
        }
        /**
         * Defines a label, uses as the target of a Break operation.
         */
        function defineLabel() {
            if (!labelOffsets) {
                labelOffsets = [];
            }
            var label = nextLabelId;
            nextLabelId++;
            labelOffsets[label] = -1;
            return label;
        }
        /**
         * Marks the current operation with the specified label.
         */
        function markLabel(label) {
            ts.Debug.assert(labelOffsets !== undefined, "No labels were defined.");
            labelOffsets[label] = operations ? operations.length : 0;
        }
        /**
         * Begins a block operation (With, Break/Continue, Try/Catch/Finally)
         *
         * @param block Information about the block.
         */
        function beginBlock(block) {
            if (!blocks) {
                blocks = [];
                blockActions = [];
                blockOffsets = [];
                blockStack = [];
            }
            var index = blockActions.length;
            blockActions[index] = 0 /* Open */;
            blockOffsets[index] = operations ? operations.length : 0;
            blocks[index] = block;
            blockStack.push(block);
            return index;
        }
        /**
         * Ends the current block operation.
         */
        function endBlock() {
            var block = peekBlock();
            if (block === undefined)
                return ts.Debug.fail("beginBlock was never called.");
            var index = blockActions.length;
            blockActions[index] = 1 /* Close */;
            blockOffsets[index] = operations ? operations.length : 0;
            blocks[index] = block;
            blockStack.pop();
            return block;
        }
        /**
         * Gets the current open block.
         */
        function peekBlock() {
            return ts.lastOrUndefined(blockStack);
        }
        /**
         * Gets the kind of the current open block.
         */
        function peekBlockKind() {
            var block = peekBlock();
            return block && block.kind;
        }
        /**
         * Begins a code block for a generated `with` statement.
         *
         * @param expression An identifier representing expression for the `with` block.
         */
        function beginWithBlock(expression) {
            var startLabel = defineLabel();
            var endLabel = defineLabel();
            markLabel(startLabel);
            beginBlock({
                kind: 1 /* With */,
                expression: expression,
                startLabel: startLabel,
                endLabel: endLabel
            });
        }
        /**
         * Ends a code block for a generated `with` statement.
         */
        function endWithBlock() {
            ts.Debug.assert(peekBlockKind() === 1 /* With */);
            var block = endBlock();
            markLabel(block.endLabel);
        }
        /**
         * Begins a code block for a generated `try` statement.
         */
        function beginExceptionBlock() {
            var startLabel = defineLabel();
            var endLabel = defineLabel();
            markLabel(startLabel);
            beginBlock({
                kind: 0 /* Exception */,
                state: 0 /* Try */,
                startLabel: startLabel,
                endLabel: endLabel
            });
            emitNop();
            return endLabel;
        }
        /**
         * Enters the `catch` clause of a generated `try` statement.
         *
         * @param variable The catch variable.
         */
        function beginCatchBlock(variable) {
            ts.Debug.assert(peekBlockKind() === 0 /* Exception */);
            // generated identifiers should already be unique within a file
            var name;
            if (ts.isGeneratedIdentifier(variable.name)) {
                name = variable.name;
                hoistVariableDeclaration(variable.name);
            }
            else {
                var text = ts.idText(variable.name);
                name = declareLocal(text);
                if (!renamedCatchVariables) {
                    renamedCatchVariables = ts.createMap();
                    renamedCatchVariableDeclarations = [];
                    context.enableSubstitution(73 /* Identifier */);
                }
                renamedCatchVariables.set(text, true);
                renamedCatchVariableDeclarations[ts.getOriginalNodeId(variable)] = name;
            }
            var exception = peekBlock();
            ts.Debug.assert(exception.state < 1 /* Catch */);
            var endLabel = exception.endLabel;
            emitBreak(endLabel);
            var catchLabel = defineLabel();
            markLabel(catchLabel);
            exception.state = 1 /* Catch */;
            exception.catchVariable = name;
            exception.catchLabel = catchLabel;
            emitAssignment(name, ts.createCall(ts.createPropertyAccess(state, "sent"), /*typeArguments*/ undefined, []));
            emitNop();
        }
        /**
         * Enters the `finally` block of a generated `try` statement.
         */
        function beginFinallyBlock() {
            ts.Debug.assert(peekBlockKind() === 0 /* Exception */);
            var exception = peekBlock();
            ts.Debug.assert(exception.state < 2 /* Finally */);
            var endLabel = exception.endLabel;
            emitBreak(endLabel);
            var finallyLabel = defineLabel();
            markLabel(finallyLabel);
            exception.state = 2 /* Finally */;
            exception.finallyLabel = finallyLabel;
        }
        /**
         * Ends the code block for a generated `try` statement.
         */
        function endExceptionBlock() {
            ts.Debug.assert(peekBlockKind() === 0 /* Exception */);
            var exception = endBlock();
            var state = exception.state;
            if (state < 2 /* Finally */) {
                emitBreak(exception.endLabel);
            }
            else {
                emitEndfinally();
            }
            markLabel(exception.endLabel);
            emitNop();
            exception.state = 3 /* Done */;
        }
        /**
         * Begins a code block that supports `break` or `continue` statements that are defined in
         * the source tree and not from generated code.
         *
         * @param labelText Names from containing labeled statements.
         */
        function beginScriptLoopBlock() {
            beginBlock({
                kind: 3 /* Loop */,
                isScript: true,
                breakLabel: -1,
                continueLabel: -1
            });
        }
        /**
         * Begins a code block that supports `break` or `continue` statements that are defined in
         * generated code. Returns a label used to mark the operation to which to jump when a
         * `break` statement targets this block.
         *
         * @param continueLabel A Label used to mark the operation to which to jump when a
         *                      `continue` statement targets this block.
         */
        function beginLoopBlock(continueLabel) {
            var breakLabel = defineLabel();
            beginBlock({
                kind: 3 /* Loop */,
                isScript: false,
                breakLabel: breakLabel,
                continueLabel: continueLabel,
            });
            return breakLabel;
        }
        /**
         * Ends a code block that supports `break` or `continue` statements that are defined in
         * generated code or in the source tree.
         */
        function endLoopBlock() {
            ts.Debug.assert(peekBlockKind() === 3 /* Loop */);
            var block = endBlock();
            var breakLabel = block.breakLabel;
            if (!block.isScript) {
                markLabel(breakLabel);
            }
        }
        /**
         * Begins a code block that supports `break` statements that are defined in the source
         * tree and not from generated code.
         *
         */
        function beginScriptSwitchBlock() {
            beginBlock({
                kind: 2 /* Switch */,
                isScript: true,
                breakLabel: -1
            });
        }
        /**
         * Begins a code block that supports `break` statements that are defined in generated code.
         * Returns a label used to mark the operation to which to jump when a `break` statement
         * targets this block.
         */
        function beginSwitchBlock() {
            var breakLabel = defineLabel();
            beginBlock({
                kind: 2 /* Switch */,
                isScript: false,
                breakLabel: breakLabel,
            });
            return breakLabel;
        }
        /**
         * Ends a code block that supports `break` statements that are defined in generated code.
         */
        function endSwitchBlock() {
            ts.Debug.assert(peekBlockKind() === 2 /* Switch */);
            var block = endBlock();
            var breakLabel = block.breakLabel;
            if (!block.isScript) {
                markLabel(breakLabel);
            }
        }
        function beginScriptLabeledBlock(labelText) {
            beginBlock({
                kind: 4 /* Labeled */,
                isScript: true,
                labelText: labelText,
                breakLabel: -1
            });
        }
        function beginLabeledBlock(labelText) {
            var breakLabel = defineLabel();
            beginBlock({
                kind: 4 /* Labeled */,
                isScript: false,
                labelText: labelText,
                breakLabel: breakLabel
            });
        }
        function endLabeledBlock() {
            ts.Debug.assert(peekBlockKind() === 4 /* Labeled */);
            var block = endBlock();
            if (!block.isScript) {
                markLabel(block.breakLabel);
            }
        }
        /**
         * Indicates whether the provided block supports `break` statements.
         *
         * @param block A code block.
         */
        function supportsUnlabeledBreak(block) {
            return block.kind === 2 /* Switch */
                || block.kind === 3 /* Loop */;
        }
        /**
         * Indicates whether the provided block supports `break` statements with labels.
         *
         * @param block A code block.
         */
        function supportsLabeledBreakOrContinue(block) {
            return block.kind === 4 /* Labeled */;
        }
        /**
         * Indicates whether the provided block supports `continue` statements.
         *
         * @param block A code block.
         */
        function supportsUnlabeledContinue(block) {
            return block.kind === 3 /* Loop */;
        }
        function hasImmediateContainingLabeledBlock(labelText, start) {
            for (var j = start; j >= 0; j--) {
                var containingBlock = blockStack[j];
                if (supportsLabeledBreakOrContinue(containingBlock)) {
                    if (containingBlock.labelText === labelText) {
                        return true;
                    }
                }
                else {
                    break;
                }
            }
            return false;
        }
        /**
         * Finds the label that is the target for a `break` statement.
         *
         * @param labelText An optional name of a containing labeled statement.
         */
        function findBreakTarget(labelText) {
            if (blockStack) {
                if (labelText) {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) {
                            return block.breakLabel;
                        }
                        else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
                            return block.breakLabel;
                        }
                    }
                }
                else {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsUnlabeledBreak(block)) {
                            return block.breakLabel;
                        }
                    }
                }
            }
            return 0;
        }
        /**
         * Finds the label that is the target for a `continue` statement.
         *
         * @param labelText An optional name of a containing labeled statement.
         */
        function findContinueTarget(labelText) {
            if (blockStack) {
                if (labelText) {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
                            return block.continueLabel;
                        }
                    }
                }
                else {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsUnlabeledContinue(block)) {
                            return block.continueLabel;
                        }
                    }
                }
            }
            return 0;
        }
        /**
         * Creates an expression that can be used to indicate the value for a label.
         *
         * @param label A label.
         */
        function createLabel(label) {
            if (label !== undefined && label > 0) {
                if (labelExpressions === undefined) {
                    labelExpressions = [];
                }
                var expression = ts.createLiteral(-1);
                if (labelExpressions[label] === undefined) {
                    labelExpressions[label] = [expression];
                }
                else {
                    labelExpressions[label].push(expression);
                }
                return expression;
            }
            return ts.createOmittedExpression();
        }
        /**
         * Creates a numeric literal for the provided instruction.
         */
        function createInstruction(instruction) {
            var literal = ts.createLiteral(instruction);
            ts.addSyntheticTrailingComment(literal, 3 /* MultiLineCommentTrivia */, getInstructionName(instruction));
            return literal;
        }
        /**
         * Creates a statement that can be used indicate a Break operation to the provided label.
         *
         * @param label A label.
         * @param location An optional source map location for the statement.
         */
        function createInlineBreak(label, location) {
            ts.Debug.assertLessThan(0, label, "Invalid label");
            return ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), location);
        }
        /**
         * Creates a statement that can be used indicate a Return operation.
         *
         * @param expression The expression for the return statement.
         * @param location An optional source map location for the statement.
         */
        function createInlineReturn(expression, location) {
            return ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression
                ? [createInstruction(2 /* Return */), expression]
                : [createInstruction(2 /* Return */)])), location);
        }
        /**
         * Creates an expression that can be used to resume from a Yield operation.
         */
        function createGeneratorResume(location) {
            return ts.setTextRange(ts.createCall(ts.createPropertyAccess(state, "sent"), 
            /*typeArguments*/ undefined, []), location);
        }
        /**
         * Emits an empty instruction.
         */
        function emitNop() {
            emitWorker(0 /* Nop */);
        }
        /**
         * Emits a Statement.
         *
         * @param node A statement.
         */
        function emitStatement(node) {
            if (node) {
                emitWorker(1 /* Statement */, [node]);
            }
            else {
                emitNop();
            }
        }
        /**
         * Emits an Assignment operation.
         *
         * @param left The left-hand side of the assignment.
         * @param right The right-hand side of the assignment.
         * @param location An optional source map location for the assignment.
         */
        function emitAssignment(left, right, location) {
            emitWorker(2 /* Assign */, [left, right], location);
        }
        /**
         * Emits a Break operation to the specified label.
         *
         * @param label A label.
         * @param location An optional source map location for the assignment.
         */
        function emitBreak(label, location) {
            emitWorker(3 /* Break */, [label], location);
        }
        /**
         * Emits a Break operation to the specified label when a condition evaluates to a truthy
         * value at runtime.
         *
         * @param label A label.
         * @param condition The condition.
         * @param location An optional source map location for the assignment.
         */
        function emitBreakWhenTrue(label, condition, location) {
            emitWorker(4 /* BreakWhenTrue */, [label, condition], location);
        }
        /**
         * Emits a Break to the specified label when a condition evaluates to a falsey value at
         * runtime.
         *
         * @param label A label.
         * @param condition The condition.
         * @param location An optional source map location for the assignment.
         */
        function emitBreakWhenFalse(label, condition, location) {
            emitWorker(5 /* BreakWhenFalse */, [label, condition], location);
        }
        /**
         * Emits a YieldStar operation for the provided expression.
         *
         * @param expression An optional value for the yield operation.
         * @param location An optional source map location for the assignment.
         */
        function emitYieldStar(expression, location) {
            emitWorker(7 /* YieldStar */, [expression], location);
        }
        /**
         * Emits a Yield operation for the provided expression.
         *
         * @param expression An optional value for the yield operation.
         * @param location An optional source map location for the assignment.
         */
        function emitYield(expression, location) {
            emitWorker(6 /* Yield */, [expression], location);
        }
        /**
         * Emits a Return operation for the provided expression.
         *
         * @param expression An optional value for the operation.
         * @param location An optional source map location for the assignment.
         */
        function emitReturn(expression, location) {
            emitWorker(8 /* Return */, [expression], location);
        }
        /**
         * Emits a Throw operation for the provided expression.
         *
         * @param expression A value for the operation.
         * @param location An optional source map location for the assignment.
         */
        function emitThrow(expression, location) {
            emitWorker(9 /* Throw */, [expression], location);
        }
        /**
         * Emits an Endfinally operation. This is used to handle `finally` block semantics.
         */
        function emitEndfinally() {
            emitWorker(10 /* Endfinally */);
        }
        /**
         * Emits an operation.
         *
         * @param code The OpCode for the operation.
         * @param args The optional arguments for the operation.
         */
        function emitWorker(code, args, location) {
            if (operations === undefined) {
                operations = [];
                operationArguments = [];
                operationLocations = [];
            }
            if (labelOffsets === undefined) {
                // mark entry point
                markLabel(defineLabel());
            }
            var operationIndex = operations.length;
            operations[operationIndex] = code;
            operationArguments[operationIndex] = args;
            operationLocations[operationIndex] = location;
        }
        /**
         * Builds the generator function body.
         */
        function build() {
            blockIndex = 0;
            labelNumber = 0;
            labelNumbers = undefined;
            lastOperationWasAbrupt = false;
            lastOperationWasCompletion = false;
            clauses = undefined;
            statements = undefined;
            exceptionBlockStack = undefined;
            currentExceptionBlock = undefined;
            withBlockStack = undefined;
            var buildResult = buildStatements();
            return createGeneratorHelper(context, ts.setEmitFlags(ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, state)], 
            /*type*/ undefined, ts.createBlock(buildResult, 
            /*multiLine*/ buildResult.length > 0)), 524288 /* ReuseTempVariableScope */));
        }
        /**
         * Builds the statements for the generator function body.
         */
        function buildStatements() {
            if (operations) {
                for (var operationIndex = 0; operationIndex < operations.length; operationIndex++) {
                    writeOperation(operationIndex);
                }
                flushFinalLabel(operations.length);
            }
            else {
                flushFinalLabel(0);
            }
            if (clauses) {
                var labelExpression = ts.createPropertyAccess(state, "label");
                var switchStatement = ts.createSwitch(labelExpression, ts.createCaseBlock(clauses));
                return [ts.startOnNewLine(switchStatement)];
            }
            if (statements) {
                return statements;
            }
            return [];
        }
        /**
         * Flush the current label and advance to a new label.
         */
        function flushLabel() {
            if (!statements) {
                return;
            }
            appendLabel(/*markLabelEnd*/ !lastOperationWasAbrupt);
            lastOperationWasAbrupt = false;
            lastOperationWasCompletion = false;
            labelNumber++;
        }
        /**
         * Flush the final label of the generator function body.
         */
        function flushFinalLabel(operationIndex) {
            if (isFinalLabelReachable(operationIndex)) {
                tryEnterLabel(operationIndex);
                withBlockStack = undefined;
                writeReturn(/*expression*/ undefined, /*operationLocation*/ undefined);
            }
            if (statements && clauses) {
                appendLabel(/*markLabelEnd*/ false);
            }
            updateLabelExpressions();
        }
        /**
         * Tests whether the final label of the generator function body
         * is reachable by user code.
         */
        function isFinalLabelReachable(operationIndex) {
            // if the last operation was *not* a completion (return/throw) then
            // the final label is reachable.
            if (!lastOperationWasCompletion) {
                return true;
            }
            // if there are no labels defined or referenced, then the final label is
            // not reachable.
            if (!labelOffsets || !labelExpressions) {
                return false;
            }
            // if the label for this offset is referenced, then the final label
            // is reachable.
            for (var label = 0; label < labelOffsets.length; label++) {
                if (labelOffsets[label] === operationIndex && labelExpressions[label]) {
                    return true;
                }
            }
            return false;
        }
        /**
         * Appends a case clause for the last label and sets the new label.
         *
         * @param markLabelEnd Indicates that the transition between labels was a fall-through
         *                     from a previous case clause and the change in labels should be
         *                     reflected on the `state` object.
         */
        function appendLabel(markLabelEnd) {
            if (!clauses) {
                clauses = [];
            }
            if (statements) {
                if (withBlockStack) {
                    // The previous label was nested inside one or more `with` blocks, so we
                    // surround the statements in generated `with` blocks to create the same environment.
                    for (var i = withBlockStack.length - 1; i >= 0; i--) {
                        var withBlock = withBlockStack[i];
                        statements = [ts.createWith(withBlock.expression, ts.createBlock(statements))];
                    }
                }
                if (currentExceptionBlock) {
                    // The previous label was nested inside of an exception block, so we must
                    // indicate entry into a protected region by pushing the label numbers
                    // for each block in the protected region.
                    var startLabel = currentExceptionBlock.startLabel, catchLabel = currentExceptionBlock.catchLabel, finallyLabel = currentExceptionBlock.finallyLabel, endLabel = currentExceptionBlock.endLabel;
                    statements.unshift(ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(state, "trys"), "push"), 
                    /*typeArguments*/ undefined, [
                        ts.createArrayLiteral([
                            createLabel(startLabel),
                            createLabel(catchLabel),
                            createLabel(finallyLabel),
                            createLabel(endLabel)
                        ])
                    ])));
                    currentExceptionBlock = undefined;
                }
                if (markLabelEnd) {
                    // The case clause for the last label falls through to this label, so we
                    // add an assignment statement to reflect the change in labels.
                    statements.push(ts.createExpressionStatement(ts.createAssignment(ts.createPropertyAccess(state, "label"), ts.createLiteral(labelNumber + 1))));
                }
            }
            clauses.push(ts.createCaseClause(ts.createLiteral(labelNumber), statements || []));
            statements = undefined;
        }
        /**
         * Tries to enter into a new label at the current operation index.
         */
        function tryEnterLabel(operationIndex) {
            if (!labelOffsets) {
                return;
            }
            for (var label = 0; label < labelOffsets.length; label++) {
                if (labelOffsets[label] === operationIndex) {
                    flushLabel();
                    if (labelNumbers === undefined) {
                        labelNumbers = [];
                    }
                    if (labelNumbers[labelNumber] === undefined) {
                        labelNumbers[labelNumber] = [label];
                    }
                    else {
                        labelNumbers[labelNumber].push(label);
                    }
                }
            }
        }
        /**
         * Updates literal expressions for labels with actual label numbers.
         */
        function updateLabelExpressions() {
            if (labelExpressions !== undefined && labelNumbers !== undefined) {
                for (var labelNumber_1 = 0; labelNumber_1 < labelNumbers.length; labelNumber_1++) {
                    var labels = labelNumbers[labelNumber_1];
                    if (labels !== undefined) {
                        for (var _i = 0, labels_1 = labels; _i < labels_1.length; _i++) {
                            var label = labels_1[_i];
                            var expressions = labelExpressions[label];
                            if (expressions !== undefined) {
                                for (var _a = 0, expressions_1 = expressions; _a < expressions_1.length; _a++) {
                                    var expression = expressions_1[_a];
                                    expression.text = String(labelNumber_1);
                                }
                            }
                        }
                    }
                }
            }
        }
        /**
         * Tries to enter or leave a code block.
         */
        function tryEnterOrLeaveBlock(operationIndex) {
            if (blocks) {
                for (; blockIndex < blockActions.length && blockOffsets[blockIndex] <= operationIndex; blockIndex++) {
                    var block = blocks[blockIndex];
                    var blockAction = blockActions[blockIndex];
                    switch (block.kind) {
                        case 0 /* Exception */:
                            if (blockAction === 0 /* Open */) {
                                if (!exceptionBlockStack) {
                                    exceptionBlockStack = [];
                                }
                                if (!statements) {
                                    statements = [];
                                }
                                exceptionBlockStack.push(currentExceptionBlock);
                                currentExceptionBlock = block;
                            }
                            else if (blockAction === 1 /* Close */) {
                                currentExceptionBlock = exceptionBlockStack.pop();
                            }
                            break;
                        case 1 /* With */:
                            if (blockAction === 0 /* Open */) {
                                if (!withBlockStack) {
                                    withBlockStack = [];
                                }
                                withBlockStack.push(block);
                            }
                            else if (blockAction === 1 /* Close */) {
                                withBlockStack.pop();
                            }
                            break;
                        // default: do nothing
                    }
                }
            }
        }
        /**
         * Writes an operation as a statement to the current label's statement list.
         *
         * @param operation The OpCode of the operation
         */
        function writeOperation(operationIndex) {
            tryEnterLabel(operationIndex);
            tryEnterOrLeaveBlock(operationIndex);
            // early termination, nothing else to process in this label
            if (lastOperationWasAbrupt) {
                return;
            }
            lastOperationWasAbrupt = false;
            lastOperationWasCompletion = false;
            var opcode = operations[operationIndex];
            if (opcode === 0 /* Nop */) {
                return;
            }
            else if (opcode === 10 /* Endfinally */) {
                return writeEndfinally();
            }
            var args = operationArguments[operationIndex];
            if (opcode === 1 /* Statement */) {
                return writeStatement(args[0]);
            }
            var location = operationLocations[operationIndex];
            switch (opcode) {
                case 2 /* Assign */:
                    return writeAssign(args[0], args[1], location);
                case 3 /* Break */:
                    return writeBreak(args[0], location);
                case 4 /* BreakWhenTrue */:
                    return writeBreakWhenTrue(args[0], args[1], location);
                case 5 /* BreakWhenFalse */:
                    return writeBreakWhenFalse(args[0], args[1], location);
                case 6 /* Yield */:
                    return writeYield(args[0], location);
                case 7 /* YieldStar */:
                    return writeYieldStar(args[0], location);
                case 8 /* Return */:
                    return writeReturn(args[0], location);
                case 9 /* Throw */:
                    return writeThrow(args[0], location);
            }
        }
        /**
         * Writes a statement to the current label's statement list.
         *
         * @param statement A statement to write.
         */
        function writeStatement(statement) {
            if (statement) {
                if (!statements) {
                    statements = [statement];
                }
                else {
                    statements.push(statement);
                }
            }
        }
        /**
         * Writes an Assign operation to the current label's statement list.
         *
         * @param left The left-hand side of the assignment.
         * @param right The right-hand side of the assignment.
         * @param operationLocation The source map location for the operation.
         */
        function writeAssign(left, right, operationLocation) {
            writeStatement(ts.setTextRange(ts.createExpressionStatement(ts.createAssignment(left, right)), operationLocation));
        }
        /**
         * Writes a Throw operation to the current label's statement list.
         *
         * @param expression The value to throw.
         * @param operationLocation The source map location for the operation.
         */
        function writeThrow(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            lastOperationWasCompletion = true;
            writeStatement(ts.setTextRange(ts.createThrow(expression), operationLocation));
        }
        /**
         * Writes a Return operation to the current label's statement list.
         *
         * @param expression The value to return.
         * @param operationLocation The source map location for the operation.
         */
        function writeReturn(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            lastOperationWasCompletion = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression
                ? [createInstruction(2 /* Return */), expression]
                : [createInstruction(2 /* Return */)])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes a Break operation to the current label's statement list.
         *
         * @param label The label for the Break.
         * @param operationLocation The source map location for the operation.
         */
        function writeBreak(label, operationLocation) {
            lastOperationWasAbrupt = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes a BreakWhenTrue operation to the current label's statement list.
         *
         * @param label The label for the Break.
         * @param condition The condition for the Break.
         * @param operationLocation The source map location for the operation.
         */
        function writeBreakWhenTrue(label, condition, operationLocation) {
            writeStatement(ts.setEmitFlags(ts.createIf(condition, ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), operationLocation), 384 /* NoTokenSourceMaps */)), 1 /* SingleLine */));
        }
        /**
         * Writes a BreakWhenFalse operation to the current label's statement list.
         *
         * @param label The label for the Break.
         * @param condition The condition for the Break.
         * @param operationLocation The source map location for the operation.
         */
        function writeBreakWhenFalse(label, condition, operationLocation) {
            writeStatement(ts.setEmitFlags(ts.createIf(ts.createLogicalNot(condition), ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), operationLocation), 384 /* NoTokenSourceMaps */)), 1 /* SingleLine */));
        }
        /**
         * Writes a Yield operation to the current label's statement list.
         *
         * @param expression The expression to yield.
         * @param operationLocation The source map location for the operation.
         */
        function writeYield(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression
                ? [createInstruction(4 /* Yield */), expression]
                : [createInstruction(4 /* Yield */)])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes a YieldStar instruction to the current label's statement list.
         *
         * @param expression The expression to yield.
         * @param operationLocation The source map location for the operation.
         */
        function writeYieldStar(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(5 /* YieldStar */),
                expression
            ])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes an Endfinally instruction to the current label's statement list.
         */
        function writeEndfinally() {
            lastOperationWasAbrupt = true;
            writeStatement(ts.createReturn(ts.createArrayLiteral([
                createInstruction(7 /* Endfinally */)
            ])));
        }
    }
    ts.transformGenerators = transformGenerators;
    function createGeneratorHelper(context, body) {
        context.requestEmitHelper(ts.generatorHelper);
        return ts.createCall(ts.getHelperName("__generator"), 
        /*typeArguments*/ undefined, [ts.createThis(), body]);
    }
    // The __generator helper is used by down-level transformations to emulate the runtime
    // semantics of an ES2015 generator function. When called, this helper returns an
    // object that implements the Iterator protocol, in that it has `next`, `return`, and
    // `throw` methods that step through the generator when invoked.
    //
    // parameters:
    //  @param thisArg  The value to use as the `this` binding for the transformed generator body.
    //  @param body     A function that acts as the transformed generator body.
    //
    // variables:
    //  _       Persistent state for the generator that is shared between the helper and the
    //          generator body. The state object has the following members:
    //            sent() - A method that returns or throws the current completion value.
    //            label  - The next point at which to resume evaluation of the generator body.
    //            trys   - A stack of protected regions (try/catch/finally blocks).
    //            ops    - A stack of pending instructions when inside of a finally block.
    //  f       A value indicating whether the generator is executing.
    //  y       An iterator to delegate for a yield*.
    //  t       A temporary variable that holds one of the following values (note that these
    //          cases do not overlap):
    //          - The completion value when resuming from a `yield` or `yield*`.
    //          - The error value for a catch block.
    //          - The current protected region (array of try/catch/finally/end labels).
    //          - The verb (`next`, `throw`, or `return` method) to delegate to the expression
    //            of a `yield*`.
    //          - The result of evaluating the verb delegated to the expression of a `yield*`.
    //
    // functions:
    //  verb(n)     Creates a bound callback to the `step` function for opcode `n`.
    //  step(op)    Evaluates opcodes in a generator body until execution is suspended or
    //              completed.
    //
    // The __generator helper understands a limited set of instructions:
    //  0: next(value?)     - Start or resume the generator with the specified value.
    //  1: throw(error)     - Resume the generator with an exception. If the generator is
    //                        suspended inside of one or more protected regions, evaluates
    //                        any intervening finally blocks between the current label and
    //                        the nearest catch block or function boundary. If uncaught, the
    //                        exception is thrown to the caller.
    //  2: return(value?)   - Resume the generator as if with a return. If the generator is
    //                        suspended inside of one or more protected regions, evaluates any
    //                        intervening finally blocks.
    //  3: break(label)     - Jump to the specified label. If the label is outside of the
    //                        current protected region, evaluates any intervening finally
    //                        blocks.
    //  4: yield(value?)    - Yield execution to the caller with an optional value. When
    //                        resumed, the generator will continue at the next label.
    //  5: yield*(value)    - Delegates evaluation to the supplied iterator. When
    //                        delegation completes, the generator will continue at the next
    //                        label.
    //  6: catch(error)     - Handles an exception thrown from within the generator body. If
    //                        the current label is inside of one or more protected regions,
    //                        evaluates any intervening finally blocks between the current
    //                        label and the nearest catch block or function boundary. If
    //                        uncaught, the exception is thrown to the caller.
    //  7: endfinally       - Ends a finally block, resuming the last instruction prior to
    //                        entering a finally block.
    //
    // For examples of how these are used, see the comments in ./transformers/generators.ts
    ts.generatorHelper = {
        name: "typescript:generator",
        scoped: false,
        priority: 6,
        text: "\n            var __generator = (this && this.__generator) || function (thisArg, body) {\n                var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n                return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n                function verb(n) { return function (v) { return step([n, v]); }; }\n                function step(op) {\n                    if (f) throw new TypeError(\"Generator is already executing.\");\n                    while (_) try {\n                        if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n                        if (y = 0, t) op = [op[0] & 2, t.value];\n                        switch (op[0]) {\n                            case 0: case 1: t = op; break;\n                            case 4: _.label++; return { value: op[1], done: false };\n                            case 5: _.label++; y = op[1]; op = [0]; continue;\n                            case 7: op = _.ops.pop(); _.trys.pop(); continue;\n                            default:\n                                if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n                                if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n                                if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n                                if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n                                if (t[2]) _.ops.pop();\n                                _.trys.pop(); continue;\n                        }\n                        op = body.call(thisArg, _);\n                    } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n                    if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n                }\n            };"
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformModule(context) {
        function getTransformModuleDelegate(moduleKind) {
            switch (moduleKind) {
                case ts.ModuleKind.AMD: return transformAMDModule;
                case ts.ModuleKind.UMD: return transformUMDModule;
                default: return transformCommonJSModule;
            }
        }
        var startLexicalEnvironment = context.startLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var resolver = context.getEmitResolver();
        var host = context.getEmitHost();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        var previousOnSubstituteNode = context.onSubstituteNode;
        var previousOnEmitNode = context.onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        context.onEmitNode = onEmitNode;
        context.enableSubstitution(73 /* Identifier */); // Substitutes expression identifiers with imported/exported symbols.
        context.enableSubstitution(205 /* BinaryExpression */); // Substitutes assignments to exported symbols.
        context.enableSubstitution(203 /* PrefixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableSubstitution(204 /* PostfixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableSubstitution(277 /* ShorthandPropertyAssignment */); // Substitutes shorthand property assignments for imported/exported symbols.
        context.enableEmitNotification(285 /* SourceFile */); // Restore state when substituting nodes in a file.
        var moduleInfoMap = []; // The ExternalModuleInfo for each file.
        var deferredExports = []; // Exports to defer until an EndOfDeclarationMarker is found.
        var currentSourceFile; // The current file.
        var currentModuleInfo; // The ExternalModuleInfo for the current file.
        var noSubstitution; // Set of nodes for which substitution rules should be ignored.
        var needUMDDynamicImportHelper;
        return ts.chainBundle(transformSourceFile);
        /**
         * Transforms the module aspects of a SourceFile.
         *
         * @param node The SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile ||
                !(ts.isEffectiveExternalModule(node, compilerOptions) ||
                    node.transformFlags & 524288 /* ContainsDynamicImport */ ||
                    (ts.isJsonSourceFile(node) && ts.hasJsonModuleEmitEnabled(compilerOptions) && (compilerOptions.out || compilerOptions.outFile)))) {
                return node;
            }
            currentSourceFile = node;
            currentModuleInfo = ts.collectExternalModuleInfo(node, resolver, compilerOptions);
            moduleInfoMap[ts.getOriginalNodeId(node)] = currentModuleInfo;
            // Perform the transformation.
            var transformModule = getTransformModuleDelegate(moduleKind);
            var updated = transformModule(node);
            currentSourceFile = undefined;
            currentModuleInfo = undefined;
            needUMDDynamicImportHelper = false;
            return ts.aggregateTransformFlags(updated);
        }
        function shouldEmitUnderscoreUnderscoreESModule() {
            if (!currentModuleInfo.exportEquals && ts.isExternalModule(currentSourceFile)) {
                return true;
            }
            return false;
        }
        /**
         * Transforms a SourceFile into a CommonJS module.
         *
         * @param node The SourceFile node.
         */
        function transformCommonJSModule(node) {
            startLexicalEnvironment();
            var statements = [];
            var ensureUseStrict = ts.getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && ts.isExternalModule(currentSourceFile));
            var statementOffset = ts.addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
            if (shouldEmitUnderscoreUnderscoreESModule()) {
                ts.append(statements, createUnderscoreUnderscoreESModule());
            }
            ts.append(statements, ts.visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement));
            ts.addRange(statements, ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset));
            addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            var updated = ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(statements), node.statements));
            if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
                // If we have any `export * from ...` declarations
                // we need to inform the emitter to add the __export helper.
                ts.addEmitHelper(updated, exportStarHelper);
            }
            ts.addEmitHelpers(updated, context.readEmitHelpers());
            return updated;
        }
        /**
         * Transforms a SourceFile into an AMD module.
         *
         * @param node The SourceFile node.
         */
        function transformAMDModule(node) {
            var define = ts.createIdentifier("define");
            var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions);
            var jsonSourceFile = ts.isJsonSourceFile(node) && node;
            // An AMD define function has the following shape:
            //
            //     define(id?, dependencies?, factory);
            //
            // This has the shape of the following:
            //
            //     define(name, ["module1", "module2"], function (module1Alias) { ... }
            //
            // The location of the alias in the parameter list in the factory function needs to
            // match the position of the module name in the dependency list.
            //
            // To ensure this is true in cases of modules with no aliases, e.g.:
            //
            //     import "module"
            //
            // or
            //
            //     /// <amd-dependency path= "a.css" />
            //
            // we need to add modules without alias names to the end of the dependencies list
            var _a = collectAsynchronousDependencies(node, /*includeNonAmdDependencies*/ true), aliasedModuleNames = _a.aliasedModuleNames, unaliasedModuleNames = _a.unaliasedModuleNames, importAliasNames = _a.importAliasNames;
            // Create an updated SourceFile:
            //
            //     define(moduleName?, ["module1", "module2"], function ...
            var updated = ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([
                ts.createExpressionStatement(ts.createCall(define, 
                /*typeArguments*/ undefined, (moduleName ? [moduleName] : []).concat([
                    // Add the dependency array argument:
                    //
                    //     ["require", "exports", module1", "module2", ...]
                    ts.createArrayLiteral(jsonSourceFile ? ts.emptyArray : [
                        ts.createLiteral("require"),
                        ts.createLiteral("exports")
                    ].concat(aliasedModuleNames, unaliasedModuleNames)),
                    // Add the module body function argument:
                    //
                    //     function (require, exports, module1, module2) ...
                    jsonSourceFile ?
                        jsonSourceFile.statements.length ? jsonSourceFile.statements[0].expression : ts.createObjectLiteral() :
                        ts.createFunctionExpression(
                        /*modifiers*/ undefined, 
                        /*asteriskToken*/ undefined, 
                        /*name*/ undefined, 
                        /*typeParameters*/ undefined, [
                            ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"),
                            ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports")
                        ].concat(importAliasNames), 
                        /*type*/ undefined, transformAsynchronousModuleBody(node))
                ])))
            ]), 
            /*location*/ node.statements));
            ts.addEmitHelpers(updated, context.readEmitHelpers());
            return updated;
        }
        /**
         * Transforms a SourceFile into a UMD module.
         *
         * @param node The SourceFile node.
         */
        function transformUMDModule(node) {
            var _a = collectAsynchronousDependencies(node, /*includeNonAmdDependencies*/ false), aliasedModuleNames = _a.aliasedModuleNames, unaliasedModuleNames = _a.unaliasedModuleNames, importAliasNames = _a.importAliasNames;
            var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions);
            var umdHeader = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "factory")], 
            /*type*/ undefined, ts.setTextRange(ts.createBlock([
                ts.createIf(ts.createLogicalAnd(ts.createTypeCheck(ts.createIdentifier("module"), "object"), ts.createTypeCheck(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), "object")), ts.createBlock([
                    ts.createVariableStatement(
                    /*modifiers*/ undefined, [
                        ts.createVariableDeclaration("v", 
                        /*type*/ undefined, ts.createCall(ts.createIdentifier("factory"), 
                        /*typeArguments*/ undefined, [
                            ts.createIdentifier("require"),
                            ts.createIdentifier("exports")
                        ]))
                    ]),
                    ts.setEmitFlags(ts.createIf(ts.createStrictInequality(ts.createIdentifier("v"), ts.createIdentifier("undefined")), ts.createExpressionStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), ts.createIdentifier("v")))), 1 /* SingleLine */)
                ]), ts.createIf(ts.createLogicalAnd(ts.createTypeCheck(ts.createIdentifier("define"), "function"), ts.createPropertyAccess(ts.createIdentifier("define"), "amd")), ts.createBlock([
                    ts.createExpressionStatement(ts.createCall(ts.createIdentifier("define"), 
                    /*typeArguments*/ undefined, (moduleName ? [moduleName] : []).concat([
                        ts.createArrayLiteral([
                            ts.createLiteral("require"),
                            ts.createLiteral("exports")
                        ].concat(aliasedModuleNames, unaliasedModuleNames)),
                        ts.createIdentifier("factory")
                    ])))
                ])))
            ], 
            /*multiLine*/ true), 
            /*location*/ undefined));
            // Create an updated SourceFile:
            //
            //  (function (factory) {
            //      if (typeof module === "object" && typeof module.exports === "object") {
            //          var v = factory(require, exports);
            //          if (v !== undefined) module.exports = v;
            //      }
            //      else if (typeof define === 'function' && define.amd) {
            //          define(["require", "exports"], factory);
            //      }
            //  })(function ...)
            var updated = ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([
                ts.createExpressionStatement(ts.createCall(umdHeader, 
                /*typeArguments*/ undefined, [
                    // Add the module body function argument:
                    //
                    //     function (require, exports) ...
                    ts.createFunctionExpression(
                    /*modifiers*/ undefined, 
                    /*asteriskToken*/ undefined, 
                    /*name*/ undefined, 
                    /*typeParameters*/ undefined, [
                        ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"),
                        ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports")
                    ].concat(importAliasNames), 
                    /*type*/ undefined, transformAsynchronousModuleBody(node))
                ]))
            ]), 
            /*location*/ node.statements));
            ts.addEmitHelpers(updated, context.readEmitHelpers());
            return updated;
        }
        /**
         * Collect the additional asynchronous dependencies for the module.
         *
         * @param node The source file.
         * @param includeNonAmdDependencies A value indicating whether to include non-AMD dependencies.
         */
        function collectAsynchronousDependencies(node, includeNonAmdDependencies) {
            // names of modules with corresponding parameter in the factory function
            var aliasedModuleNames = [];
            // names of modules with no corresponding parameters in factory function
            var unaliasedModuleNames = [];
            // names of the parameters in the factory function; these
            // parameters need to match the indexes of the corresponding
            // module names in aliasedModuleNames.
            var importAliasNames = [];
            // Fill in amd-dependency tags
            for (var _i = 0, _a = node.amdDependencies; _i < _a.length; _i++) {
                var amdDependency = _a[_i];
                if (amdDependency.name) {
                    aliasedModuleNames.push(ts.createLiteral(amdDependency.path));
                    importAliasNames.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, amdDependency.name));
                }
                else {
                    unaliasedModuleNames.push(ts.createLiteral(amdDependency.path));
                }
            }
            for (var _b = 0, _c = currentModuleInfo.externalImports; _b < _c.length; _b++) {
                var importNode = _c[_b];
                // Find the name of the external module
                var externalModuleName = ts.getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions);
                // Find the name of the module alias, if there is one
                var importAliasName = ts.getLocalNameForExternalImport(importNode, currentSourceFile);
                // It is possible that externalModuleName is undefined if it is not string literal.
                // This can happen in the invalid import syntax.
                // E.g : "import * from alias from 'someLib';"
                if (externalModuleName) {
                    if (includeNonAmdDependencies && importAliasName) {
                        // Set emitFlags on the name of the classDeclaration
                        // This is so that when printer will not substitute the identifier
                        ts.setEmitFlags(importAliasName, 4 /* NoSubstitution */);
                        aliasedModuleNames.push(externalModuleName);
                        importAliasNames.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, importAliasName));
                    }
                    else {
                        unaliasedModuleNames.push(externalModuleName);
                    }
                }
            }
            return { aliasedModuleNames: aliasedModuleNames, unaliasedModuleNames: unaliasedModuleNames, importAliasNames: importAliasNames };
        }
        function getAMDImportExpressionForImport(node) {
            if (ts.isImportEqualsDeclaration(node) || ts.isExportDeclaration(node) || !ts.getExternalModuleNameLiteral(node, currentSourceFile, host, resolver, compilerOptions)) {
                return undefined;
            }
            var name = ts.getLocalNameForExternalImport(node, currentSourceFile); // TODO: GH#18217
            var expr = getHelperExpressionForImport(node, name);
            if (expr === name) {
                return undefined;
            }
            return ts.createExpressionStatement(ts.createAssignment(name, expr));
        }
        /**
         * Transforms a SourceFile into an AMD or UMD module body.
         *
         * @param node The SourceFile node.
         */
        function transformAsynchronousModuleBody(node) {
            startLexicalEnvironment();
            var statements = [];
            var statementOffset = ts.addPrologue(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
            if (shouldEmitUnderscoreUnderscoreESModule()) {
                ts.append(statements, createUnderscoreUnderscoreESModule());
            }
            // Visit each statement of the module body.
            ts.append(statements, ts.visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement));
            if (moduleKind === ts.ModuleKind.AMD) {
                ts.addRange(statements, ts.mapDefined(currentModuleInfo.externalImports, getAMDImportExpressionForImport));
            }
            ts.addRange(statements, ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset));
            // Append the 'export =' statement if provided.
            addExportEqualsIfNeeded(statements, /*emitAsReturn*/ true);
            // End the lexical environment for the module body
            // and merge any new lexical declarations.
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            var body = ts.createBlock(statements, /*multiLine*/ true);
            if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
                // If we have any `export * from ...` declarations
                // we need to inform the emitter to add the __export helper.
                ts.addEmitHelper(body, exportStarHelper);
            }
            if (needUMDDynamicImportHelper) {
                ts.addEmitHelper(body, dynamicImportUMDHelper);
            }
            return body;
        }
        /**
         * Adds the down-level representation of `export=` to the statement list if one exists
         * in the source file.
         *
         * @param statements The Statement list to modify.
         * @param emitAsReturn A value indicating whether to emit the `export=` statement as a
         * return statement.
         */
        function addExportEqualsIfNeeded(statements, emitAsReturn) {
            if (currentModuleInfo.exportEquals) {
                var expressionResult = ts.visitNode(currentModuleInfo.exportEquals.expression, moduleExpressionElementVisitor);
                if (expressionResult) {
                    if (emitAsReturn) {
                        var statement = ts.createReturn(expressionResult);
                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
                        ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */);
                        statements.push(statement);
                    }
                    else {
                        var statement = ts.createExpressionStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult));
                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
                        ts.setEmitFlags(statement, 1536 /* NoComments */);
                        statements.push(statement);
                    }
                }
            }
        }
        //
        // Top-Level Source Element Visitors
        //
        /**
         * Visits a node at the top level of the source file.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitor(node) {
            switch (node.kind) {
                case 250 /* ImportDeclaration */:
                    return visitImportDeclaration(node);
                case 249 /* ImportEqualsDeclaration */:
                    return visitImportEqualsDeclaration(node);
                case 256 /* ExportDeclaration */:
                    return visitExportDeclaration(node);
                case 255 /* ExportAssignment */:
                    return visitExportAssignment(node);
                case 220 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 240 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 241 /* ClassDeclaration */:
                    return visitClassDeclaration(node);
                case 316 /* MergeDeclarationMarker */:
                    return visitMergeDeclarationMarker(node);
                case 317 /* EndOfDeclarationMarker */:
                    return visitEndOfDeclarationMarker(node);
                default:
                    return ts.visitEachChild(node, moduleExpressionElementVisitor, context);
            }
        }
        function moduleExpressionElementVisitor(node) {
            // This visitor does not need to descend into the tree if there is no dynamic import or destructuring assignment,
            // as export/import statements are only transformed at the top level of a file.
            if (!(node.transformFlags & 524288 /* ContainsDynamicImport */) && !(node.transformFlags & 512 /* ContainsDestructuringAssignment */)) {
                return node;
            }
            if (ts.isImportCall(node)) {
                return visitImportCallExpression(node);
            }
            else if (ts.isDestructuringAssignment(node)) {
                return visitDestructuringAssignment(node);
            }
            else {
                return ts.visitEachChild(node, moduleExpressionElementVisitor, context);
            }
        }
        function destructuringNeedsFlattening(node) {
            if (ts.isObjectLiteralExpression(node)) {
                for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                    var elem = _a[_i];
                    switch (elem.kind) {
                        case 276 /* PropertyAssignment */:
                            if (destructuringNeedsFlattening(elem.initializer)) {
                                return true;
                            }
                            break;
                        case 277 /* ShorthandPropertyAssignment */:
                            if (destructuringNeedsFlattening(elem.name)) {
                                return true;
                            }
                            break;
                        case 278 /* SpreadAssignment */:
                            if (destructuringNeedsFlattening(elem.expression)) {
                                return true;
                            }
                            break;
                        case 157 /* MethodDeclaration */:
                        case 159 /* GetAccessor */:
                        case 160 /* SetAccessor */:
                            return false;
                        default: ts.Debug.assertNever(elem, "Unhandled object member kind");
                    }
                }
            }
            else if (ts.isArrayLiteralExpression(node)) {
                for (var _b = 0, _c = node.elements; _b < _c.length; _b++) {
                    var elem = _c[_b];
                    if (ts.isSpreadElement(elem)) {
                        if (destructuringNeedsFlattening(elem.expression)) {
                            return true;
                        }
                    }
                    else if (destructuringNeedsFlattening(elem)) {
                        return true;
                    }
                }
            }
            else if (ts.isIdentifier(node)) {
                return ts.length(getExports(node)) > (ts.isExportName(node) ? 1 : 0);
            }
            return false;
        }
        function visitDestructuringAssignment(node) {
            if (destructuringNeedsFlattening(node.left)) {
                return ts.flattenDestructuringAssignment(node, moduleExpressionElementVisitor, context, 0 /* All */, /*needsValue*/ false, createAllExportExpressions);
            }
            return ts.visitEachChild(node, moduleExpressionElementVisitor, context);
        }
        function visitImportCallExpression(node) {
            var argument = ts.visitNode(ts.firstOrUndefined(node.arguments), moduleExpressionElementVisitor);
            var containsLexicalThis = !!(node.transformFlags & 2048 /* ContainsLexicalThis */);
            switch (compilerOptions.module) {
                case ts.ModuleKind.AMD:
                    return createImportCallExpressionAMD(argument, containsLexicalThis);
                case ts.ModuleKind.UMD:
                    return createImportCallExpressionUMD(argument, containsLexicalThis);
                case ts.ModuleKind.CommonJS:
                default:
                    return createImportCallExpressionCommonJS(argument, containsLexicalThis);
            }
        }
        function createImportCallExpressionUMD(arg, containsLexicalThis) {
            // (function (factory) {
            //      ... (regular UMD)
            // }
            // })(function (require, exports, useSyncRequire) {
            //      "use strict";
            //      Object.defineProperty(exports, "__esModule", { value: true });
            //      var __syncRequire = typeof module === "object" && typeof module.exports === "object";
            //      var __resolved = new Promise(function (resolve) { resolve(); });
            //      .....
            //      __syncRequire
            //          ? __resolved.then(function () { return require(x); }) /*CommonJs Require*/
            //          : new Promise(function (_a, _b) { require([x], _a, _b); }); /*Amd Require*/
            // });
            needUMDDynamicImportHelper = true;
            if (ts.isSimpleCopiableExpression(arg)) {
                var argClone = ts.isGeneratedIdentifier(arg) ? arg : ts.isStringLiteral(arg) ? ts.createLiteral(arg) : ts.setEmitFlags(ts.setTextRange(ts.getSynthesizedClone(arg), arg), 1536 /* NoComments */);
                return ts.createConditional(
                /*condition*/ ts.createIdentifier("__syncRequire"), 
                /*whenTrue*/ createImportCallExpressionCommonJS(arg, containsLexicalThis), 
                /*whenFalse*/ createImportCallExpressionAMD(argClone, containsLexicalThis));
            }
            else {
                var temp = ts.createTempVariable(hoistVariableDeclaration);
                return ts.createComma(ts.createAssignment(temp, arg), ts.createConditional(
                /*condition*/ ts.createIdentifier("__syncRequire"), 
                /*whenTrue*/ createImportCallExpressionCommonJS(temp, containsLexicalThis), 
                /*whenFalse*/ createImportCallExpressionAMD(temp, containsLexicalThis)));
            }
        }
        function createImportCallExpressionAMD(arg, containsLexicalThis) {
            // improt("./blah")
            // emit as
            // define(["require", "exports", "blah"], function (require, exports) {
            //     ...
            //     new Promise(function (_a, _b) { require([x], _a, _b); }); /*Amd Require*/
            // });
            var resolve = ts.createUniqueName("resolve");
            var reject = ts.createUniqueName("reject");
            var parameters = [
                ts.createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ resolve),
                ts.createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ reject)
            ];
            var body = ts.createBlock([
                ts.createExpressionStatement(ts.createCall(ts.createIdentifier("require"), 
                /*typeArguments*/ undefined, [ts.createArrayLiteral([arg || ts.createOmittedExpression()]), resolve, reject]))
            ]);
            var func;
            if (languageVersion >= 2 /* ES2015 */) {
                func = ts.createArrowFunction(
                /*modifiers*/ undefined, 
                /*typeParameters*/ undefined, parameters, 
                /*type*/ undefined, 
                /*equalsGreaterThanToken*/ undefined, body);
            }
            else {
                func = ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, parameters, 
                /*type*/ undefined, body);
                // if there is a lexical 'this' in the import call arguments, ensure we indicate
                // that this new function expression indicates it captures 'this' so that the
                // es2015 transformer will properly substitute 'this' with '_this'.
                if (containsLexicalThis) {
                    ts.setEmitFlags(func, 8 /* CapturesThis */);
                }
            }
            var promise = ts.createNew(ts.createIdentifier("Promise"), /*typeArguments*/ undefined, [func]);
            if (compilerOptions.esModuleInterop) {
                context.requestEmitHelper(ts.importStarHelper);
                return ts.createCall(ts.createPropertyAccess(promise, ts.createIdentifier("then")), /*typeArguments*/ undefined, [ts.getHelperName("__importStar")]);
            }
            return promise;
        }
        function createImportCallExpressionCommonJS(arg, containsLexicalThis) {
            // import("./blah")
            // emit as
            // Promise.resolve().then(function () { return require(x); }) /*CommonJs Require*/
            // We have to wrap require in then callback so that require is done in asynchronously
            // if we simply do require in resolve callback in Promise constructor. We will execute the loading immediately
            var promiseResolveCall = ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []);
            var requireCall = ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []);
            if (compilerOptions.esModuleInterop) {
                context.requestEmitHelper(ts.importStarHelper);
                requireCall = ts.createCall(ts.getHelperName("__importStar"), /*typeArguments*/ undefined, [requireCall]);
            }
            var func;
            if (languageVersion >= 2 /* ES2015 */) {
                func = ts.createArrowFunction(
                /*modifiers*/ undefined, 
                /*typeParameters*/ undefined, 
                /*parameters*/ [], 
                /*type*/ undefined, 
                /*equalsGreaterThanToken*/ undefined, requireCall);
            }
            else {
                func = ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, 
                /*parameters*/ [], 
                /*type*/ undefined, ts.createBlock([ts.createReturn(requireCall)]));
                // if there is a lexical 'this' in the import call arguments, ensure we indicate
                // that this new function expression indicates it captures 'this' so that the
                // es2015 transformer will properly substitute 'this' with '_this'.
                if (containsLexicalThis) {
                    ts.setEmitFlags(func, 8 /* CapturesThis */);
                }
            }
            return ts.createCall(ts.createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]);
        }
        function getHelperExpressionForImport(node, innerExpr) {
            if (!compilerOptions.esModuleInterop || ts.getEmitFlags(node) & 67108864 /* NeverApplyImportHelper */) {
                return innerExpr;
            }
            if (ts.getImportNeedsImportStarHelper(node)) {
                context.requestEmitHelper(ts.importStarHelper);
                return ts.createCall(ts.getHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]);
            }
            if (ts.getImportNeedsImportDefaultHelper(node)) {
                context.requestEmitHelper(ts.importDefaultHelper);
                return ts.createCall(ts.getHelperName("__importDefault"), /*typeArguments*/ undefined, [innerExpr]);
            }
            return innerExpr;
        }
        /**
         * Visits an ImportDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportDeclaration(node) {
            var statements;
            var namespaceDeclaration = ts.getNamespaceDeclarationNode(node);
            if (moduleKind !== ts.ModuleKind.AMD) {
                if (!node.importClause) {
                    // import "mod";
                    return ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createRequireCall(node)), node), node);
                }
                else {
                    var variables = [];
                    if (namespaceDeclaration && !ts.isDefaultImport(node)) {
                        // import * as n from "mod";
                        variables.push(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), 
                        /*type*/ undefined, getHelperExpressionForImport(node, createRequireCall(node))));
                    }
                    else {
                        // import d from "mod";
                        // import { x, y } from "mod";
                        // import d, { x, y } from "mod";
                        // import d, * as n from "mod";
                        variables.push(ts.createVariableDeclaration(ts.getGeneratedNameForNode(node), 
                        /*type*/ undefined, getHelperExpressionForImport(node, createRequireCall(node))));
                        if (namespaceDeclaration && ts.isDefaultImport(node)) {
                            variables.push(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), 
                            /*type*/ undefined, ts.getGeneratedNameForNode(node)));
                        }
                    }
                    statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList(variables, languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)), 
                    /*location*/ node), 
                    /*original*/ node));
                }
            }
            else if (namespaceDeclaration && ts.isDefaultImport(node)) {
                // import d, * as n from "mod";
                statements = ts.append(statements, ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.setOriginalNode(ts.setTextRange(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), 
                    /*type*/ undefined, ts.getGeneratedNameForNode(node)), 
                    /*location*/ node), 
                    /*original*/ node)
                ], languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Creates a `require()` call to import an external module.
         *
         * @param importNode The declararation to import.
         */
        function createRequireCall(importNode) {
            var moduleName = ts.getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions);
            var args = [];
            if (moduleName) {
                args.push(moduleName);
            }
            return ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, args);
        }
        /**
         * Visits an ImportEqualsDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportEqualsDeclaration(node) {
            ts.Debug.assert(ts.isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
            var statements;
            if (moduleKind !== ts.ModuleKind.AMD) {
                if (ts.hasModifier(node, 1 /* Export */)) {
                    statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createExportExpression(node.name, createRequireCall(node))), node), node));
                }
                else {
                    statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList([
                        ts.createVariableDeclaration(ts.getSynthesizedClone(node.name), 
                        /*type*/ undefined, createRequireCall(node))
                    ], 
                    /*flags*/ languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)), node), node));
                }
            }
            else {
                if (ts.hasModifier(node, 1 /* Export */)) {
                    statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createExportExpression(ts.getExportName(node), ts.getLocalName(node))), node), node));
                }
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportEqualsDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits an ExportDeclaration node.
         *
         * @param The node to visit.
         */
        function visitExportDeclaration(node) {
            if (!node.moduleSpecifier) {
                // Elide export declarations with no module specifier as they are handled
                // elsewhere.
                return undefined;
            }
            var generatedName = ts.getGeneratedNameForNode(node);
            if (node.exportClause) {
                var statements = [];
                // export { x, y } from "mod";
                if (moduleKind !== ts.ModuleKind.AMD) {
                    statements.push(ts.setOriginalNode(ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList([
                        ts.createVariableDeclaration(generatedName, 
                        /*type*/ undefined, createRequireCall(node))
                    ])), 
                    /*location*/ node), 
                    /* original */ node));
                }
                for (var _i = 0, _a = node.exportClause.elements; _i < _a.length; _i++) {
                    var specifier = _a[_i];
                    var exportedValue = ts.createPropertyAccess(generatedName, specifier.propertyName || specifier.name);
                    statements.push(ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createExportExpression(ts.getExportName(specifier), exportedValue)), specifier), specifier));
                }
                return ts.singleOrMany(statements);
            }
            else {
                // export * from "mod";
                return ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createExportStarHelper(context, moduleKind !== ts.ModuleKind.AMD ? createRequireCall(node) : generatedName)), node), node);
            }
        }
        /**
         * Visits an ExportAssignment node.
         *
         * @param node The node to visit.
         */
        function visitExportAssignment(node) {
            if (node.isExportEquals) {
                return undefined;
            }
            var statements;
            var original = node.original;
            if (original && hasAssociatedEndOfDeclarationMarker(original)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportStatement(deferredExports[id], ts.createIdentifier("default"), ts.visitNode(node.expression, moduleExpressionElementVisitor), /*location*/ node, /*allowComments*/ true);
            }
            else {
                statements = appendExportStatement(statements, ts.createIdentifier("default"), ts.visitNode(node.expression, moduleExpressionElementVisitor), /*location*/ node, /*allowComments*/ true);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a FunctionDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            var statements;
            if (ts.hasModifier(node, 1 /* Export */)) {
                statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createFunctionDeclaration(
                /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), 
                /*typeParameters*/ undefined, ts.visitNodes(node.parameters, moduleExpressionElementVisitor), 
                /*type*/ undefined, ts.visitEachChild(node.body, moduleExpressionElementVisitor, context)), 
                /*location*/ node), 
                /*original*/ node));
            }
            else {
                statements = ts.append(statements, ts.visitEachChild(node, moduleExpressionElementVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfHoistedDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a ClassDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitClassDeclaration(node) {
            var statements;
            if (ts.hasModifier(node, 1 /* Export */)) {
                statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createClassDeclaration(
                /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), 
                /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, moduleExpressionElementVisitor), ts.visitNodes(node.members, moduleExpressionElementVisitor)), node), node));
            }
            else {
                statements = ts.append(statements, ts.visitEachChild(node, moduleExpressionElementVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfHoistedDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a VariableStatement node.
         *
         * @param node The node to visit.
         */
        function visitVariableStatement(node) {
            var statements;
            var variables;
            var expressions;
            if (ts.hasModifier(node, 1 /* Export */)) {
                var modifiers = void 0;
                // If we're exporting these variables, then these just become assignments to 'exports.x'.
                // We only want to emit assignments for variables with initializers.
                for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    if (ts.isIdentifier(variable.name) && ts.isLocalName(variable.name)) {
                        if (!modifiers) {
                            modifiers = ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier);
                        }
                        variables = ts.append(variables, variable);
                    }
                    else if (variable.initializer) {
                        expressions = ts.append(expressions, transformInitializedVariable(variable));
                    }
                }
                if (variables) {
                    statements = ts.append(statements, ts.updateVariableStatement(node, modifiers, ts.updateVariableDeclarationList(node.declarationList, variables)));
                }
                if (expressions) {
                    statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(ts.inlineExpressions(expressions)), node), node));
                }
            }
            else {
                statements = ts.append(statements, ts.visitEachChild(node, moduleExpressionElementVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfVariableStatement(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        function createAllExportExpressions(name, value, location) {
            var exportedNames = getExports(name);
            if (exportedNames) {
                // For each additional export of the declaration, apply an export assignment.
                var expression = ts.isExportName(name) ? value : ts.createAssignment(name, value);
                for (var _i = 0, exportedNames_1 = exportedNames; _i < exportedNames_1.length; _i++) {
                    var exportName = exportedNames_1[_i];
                    // Mark the node to prevent triggering substitution.
                    ts.setEmitFlags(expression, 4 /* NoSubstitution */);
                    expression = createExportExpression(exportName, expression, /*location*/ location);
                }
                return expression;
            }
            return ts.createAssignment(name, value);
        }
        /**
         * Transforms an exported variable with an initializer into an expression.
         *
         * @param node The node to transform.
         */
        function transformInitializedVariable(node) {
            if (ts.isBindingPattern(node.name)) {
                return ts.flattenDestructuringAssignment(ts.visitNode(node, moduleExpressionElementVisitor), 
                /*visitor*/ undefined, context, 0 /* All */, 
                /*needsValue*/ false, createAllExportExpressions);
            }
            else {
                return ts.createAssignment(ts.setTextRange(ts.createPropertyAccess(ts.createIdentifier("exports"), node.name), 
                /*location*/ node.name), ts.visitNode(node.initializer, moduleExpressionElementVisitor));
            }
        }
        /**
         * Visits a MergeDeclarationMarker used as a placeholder for the beginning of a merged
         * and transformed declaration.
         *
         * @param node The node to visit.
         */
        function visitMergeDeclarationMarker(node) {
            // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
            // declaration we do not emit a leading variable declaration. To preserve the
            // begin/end semantics of the declararation and to properly handle exports
            // we wrapped the leading variable declaration in a `MergeDeclarationMarker`.
            //
            // To balance the declaration, add the exports of the elided variable
            // statement.
            if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === 220 /* VariableStatement */) {
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node.original);
            }
            return node;
        }
        /**
         * Determines whether a node has an associated EndOfDeclarationMarker.
         *
         * @param node The node to test.
         */
        function hasAssociatedEndOfDeclarationMarker(node) {
            return (ts.getEmitFlags(node) & 4194304 /* HasEndOfDeclarationMarker */) !== 0;
        }
        /**
         * Visits a DeclarationMarker used as a placeholder for the end of a transformed
         * declaration.
         *
         * @param node The node to visit.
         */
        function visitEndOfDeclarationMarker(node) {
            // For some transformations we emit an `EndOfDeclarationMarker` to mark the actual
            // end of the transformed declaration. We use this marker to emit any deferred exports
            // of the declaration.
            var id = ts.getOriginalNodeId(node);
            var statements = deferredExports[id];
            if (statements) {
                delete deferredExports[id];
                return ts.append(statements, node);
            }
            return node;
        }
        /**
         * Appends the exports of an ImportDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportDeclaration(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            var importClause = decl.importClause;
            if (!importClause) {
                return statements;
            }
            if (importClause.name) {
                statements = appendExportsOfDeclaration(statements, importClause);
            }
            var namedBindings = importClause.namedBindings;
            if (namedBindings) {
                switch (namedBindings.kind) {
                    case 252 /* NamespaceImport */:
                        statements = appendExportsOfDeclaration(statements, namedBindings);
                        break;
                    case 253 /* NamedImports */:
                        for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) {
                            var importBinding = _a[_i];
                            statements = appendExportsOfDeclaration(statements, importBinding);
                        }
                        break;
                }
            }
            return statements;
        }
        /**
         * Appends the exports of an ImportEqualsDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportEqualsDeclaration(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            return appendExportsOfDeclaration(statements, decl);
        }
        /**
         * Appends the exports of a VariableStatement to a statement list, returning the statement
         * list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param node The VariableStatement whose exports are to be recorded.
         */
        function appendExportsOfVariableStatement(statements, node) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                var decl = _a[_i];
                statements = appendExportsOfBindingElement(statements, decl);
            }
            return statements;
        }
        /**
         * Appends the exports of a VariableDeclaration or BindingElement to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfBindingElement(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            if (ts.isBindingPattern(decl.name)) {
                for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        statements = appendExportsOfBindingElement(statements, element);
                    }
                }
            }
            else if (!ts.isGeneratedIdentifier(decl.name)) {
                statements = appendExportsOfDeclaration(statements, decl);
            }
            return statements;
        }
        /**
         * Appends the exports of a ClassDeclaration or FunctionDeclaration to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfHoistedDeclaration(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            if (ts.hasModifier(decl, 1 /* Export */)) {
                var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createIdentifier("default") : ts.getDeclarationName(decl);
                statements = appendExportStatement(statements, exportName, ts.getLocalName(decl), /*location*/ decl);
            }
            if (decl.name) {
                statements = appendExportsOfDeclaration(statements, decl);
            }
            return statements;
        }
        /**
         * Appends the exports of a declaration to a statement list, returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration to export.
         */
        function appendExportsOfDeclaration(statements, decl) {
            var name = ts.getDeclarationName(decl);
            var exportSpecifiers = currentModuleInfo.exportSpecifiers.get(ts.idText(name));
            if (exportSpecifiers) {
                for (var _i = 0, exportSpecifiers_1 = exportSpecifiers; _i < exportSpecifiers_1.length; _i++) {
                    var exportSpecifier = exportSpecifiers_1[_i];
                    statements = appendExportStatement(statements, exportSpecifier.name, name, /*location*/ exportSpecifier.name);
                }
            }
            return statements;
        }
        /**
         * Appends the down-level representation of an export to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param exportName The name of the export.
         * @param expression The expression to export.
         * @param location The location to use for source maps and comments for the export.
         * @param allowComments Whether to allow comments on the export.
         */
        function appendExportStatement(statements, exportName, expression, location, allowComments) {
            statements = ts.append(statements, createExportStatement(exportName, expression, location, allowComments));
            return statements;
        }
        function createUnderscoreUnderscoreESModule() {
            var statement;
            if (languageVersion === 0 /* ES3 */) {
                statement = ts.createExpressionStatement(createExportExpression(ts.createIdentifier("__esModule"), ts.createLiteral(/*value*/ true)));
            }
            else {
                statement = ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
                /*typeArguments*/ undefined, [
                    ts.createIdentifier("exports"),
                    ts.createLiteral("__esModule"),
                    ts.createObjectLiteral([
                        ts.createPropertyAssignment("value", ts.createLiteral(/*value*/ true))
                    ])
                ]));
            }
            ts.setEmitFlags(statement, 1048576 /* CustomPrologue */);
            return statement;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         * @param location The location to use for source maps and comments for the export.
         * @param allowComments An optional value indicating whether to emit comments for the statement.
         */
        function createExportStatement(name, value, location, allowComments) {
            var statement = ts.setTextRange(ts.createExpressionStatement(createExportExpression(name, value)), location);
            ts.startOnNewLine(statement);
            if (!allowComments) {
                ts.setEmitFlags(statement, 1536 /* NoComments */);
            }
            return statement;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         * @param location The location to use for source maps and comments for the export.
         */
        function createExportExpression(name, value, location) {
            return ts.setTextRange(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.getSynthesizedClone(name)), value), location);
        }
        //
        // Modifier Visitors
        //
        /**
         * Visit nodes to elide module-specific modifiers.
         *
         * @param node The node to visit.
         */
        function modifierVisitor(node) {
            // Elide module-specific modifiers.
            switch (node.kind) {
                case 86 /* ExportKeyword */:
                case 81 /* DefaultKeyword */:
                    return undefined;
            }
            return node;
        }
        //
        // Emit Notification
        //
        /**
         * Hook for node emit notifications.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (node.kind === 285 /* SourceFile */) {
                currentSourceFile = node;
                currentModuleInfo = moduleInfoMap[ts.getOriginalNodeId(currentSourceFile)];
                noSubstitution = [];
                previousOnEmitNode(hint, node, emitCallback);
                currentSourceFile = undefined;
                currentModuleInfo = undefined;
                noSubstitution = undefined;
            }
            else {
                previousOnEmitNode(hint, node, emitCallback);
            }
        }
        //
        // Substitutions
        //
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (node.id && noSubstitution[node.id]) {
                return node;
            }
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            else if (ts.isShorthandPropertyAssignment(node)) {
                return substituteShorthandPropertyAssignment(node);
            }
            return node;
        }
        /**
         * Substitution for a ShorthandPropertyAssignment whose declaration name is an imported
         * or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteShorthandPropertyAssignment(node) {
            var name = node.name;
            var exportedOrImportedName = substituteExpressionIdentifier(name);
            if (exportedOrImportedName !== name) {
                // A shorthand property with an assignment initializer is probably part of a
                // destructuring assignment
                if (node.objectAssignmentInitializer) {
                    var initializer = ts.createAssignment(exportedOrImportedName, node.objectAssignmentInitializer);
                    return ts.setTextRange(ts.createPropertyAssignment(name, initializer), node);
                }
                return ts.setTextRange(ts.createPropertyAssignment(name, exportedOrImportedName), node);
            }
            return node;
        }
        /**
         * Substitution for an Expression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteExpression(node) {
            switch (node.kind) {
                case 73 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 205 /* BinaryExpression */:
                    return substituteBinaryExpression(node);
                case 204 /* PostfixUnaryExpression */:
                case 203 /* PrefixUnaryExpression */:
                    return substituteUnaryExpression(node);
            }
            return node;
        }
        /**
         * Substitution for an Identifier expression that may contain an imported or exported
         * symbol.
         *
         * @param node The node to substitute.
         */
        function substituteExpressionIdentifier(node) {
            if (ts.getEmitFlags(node) & 4096 /* HelperName */) {
                var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile);
                if (externalHelpersModuleName) {
                    return ts.createPropertyAccess(externalHelpersModuleName, node);
                }
                return node;
            }
            if (!ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) {
                var exportContainer = resolver.getReferencedExportContainer(node, ts.isExportName(node));
                if (exportContainer && exportContainer.kind === 285 /* SourceFile */) {
                    return ts.setTextRange(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.getSynthesizedClone(node)), 
                    /*location*/ node);
                }
                var importDeclaration = resolver.getReferencedImportDeclaration(node);
                if (importDeclaration) {
                    if (ts.isImportClause(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent), ts.createIdentifier("default")), 
                        /*location*/ node);
                    }
                    else if (ts.isImportSpecifier(importDeclaration)) {
                        var name = importDeclaration.propertyName || importDeclaration.name;
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent.parent.parent), ts.getSynthesizedClone(name)), 
                        /*location*/ node);
                    }
                }
            }
            return node;
        }
        /**
         * Substitution for a BinaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteBinaryExpression(node) {
            // When we see an assignment expression whose left-hand side is an exported symbol,
            // we should ensure all exports of that symbol are updated with the correct value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if (ts.isAssignmentOperator(node.operatorToken.kind)
                && ts.isIdentifier(node.left)
                && !ts.isGeneratedIdentifier(node.left)
                && !ts.isLocalName(node.left)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.left)) {
                var exportedNames = getExports(node.left);
                if (exportedNames) {
                    // For each additional export of the declaration, apply an export assignment.
                    var expression = node;
                    for (var _i = 0, exportedNames_2 = exportedNames; _i < exportedNames_2.length; _i++) {
                        var exportName = exportedNames_2[_i];
                        // Mark the node to prevent triggering this rule again.
                        noSubstitution[ts.getNodeId(expression)] = true;
                        expression = createExportExpression(exportName, expression, /*location*/ node);
                    }
                    return expression;
                }
            }
            return node;
        }
        /**
         * Substitution for a UnaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteUnaryExpression(node) {
            // When we see a prefix or postfix increment expression whose operand is an exported
            // symbol, we should ensure all exports of that symbol are updated with the correct
            // value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if ((node.operator === 44 /* PlusPlusToken */ || node.operator === 45 /* MinusMinusToken */)
                && ts.isIdentifier(node.operand)
                && !ts.isGeneratedIdentifier(node.operand)
                && !ts.isLocalName(node.operand)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.operand)) {
                var exportedNames = getExports(node.operand);
                if (exportedNames) {
                    var expression = node.kind === 204 /* PostfixUnaryExpression */
                        ? ts.setTextRange(ts.createBinary(node.operand, ts.createToken(node.operator === 44 /* PlusPlusToken */ ? 61 /* PlusEqualsToken */ : 62 /* MinusEqualsToken */), ts.createLiteral(1)), 
                        /*location*/ node)
                        : node;
                    for (var _i = 0, exportedNames_3 = exportedNames; _i < exportedNames_3.length; _i++) {
                        var exportName = exportedNames_3[_i];
                        // Mark the node to prevent triggering this rule again.
                        noSubstitution[ts.getNodeId(expression)] = true;
                        expression = createExportExpression(exportName, expression);
                    }
                    return expression;
                }
            }
            return node;
        }
        /**
         * Gets the additional exports of a name.
         *
         * @param name The name.
         */
        function getExports(name) {
            if (!ts.isGeneratedIdentifier(name)) {
                var valueDeclaration = resolver.getReferencedImportDeclaration(name)
                    || resolver.getReferencedValueDeclaration(name);
                if (valueDeclaration) {
                    return currentModuleInfo
                        && currentModuleInfo.exportedBindings[ts.getOriginalNodeId(valueDeclaration)];
                }
            }
        }
    }
    ts.transformModule = transformModule;
    // emit output for the __export helper function
    var exportStarHelper = {
        name: "typescript:export-star",
        scoped: true,
        text: "\n            function __export(m) {\n                for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n            }"
    };
    function createExportStarHelper(context, module) {
        var compilerOptions = context.getCompilerOptions();
        return compilerOptions.importHelpers
            ? ts.createCall(ts.getHelperName("__exportStar"), /*typeArguments*/ undefined, [module, ts.createIdentifier("exports")])
            : ts.createCall(ts.createIdentifier("__export"), /*typeArguments*/ undefined, [module]);
    }
    // emit helper for dynamic import
    var dynamicImportUMDHelper = {
        name: "typescript:dynamicimport-sync-require",
        scoped: true,
        text: "\n            var __syncRequire = typeof module === \"object\" && typeof module.exports === \"object\";"
    };
    // emit helper for `import * as Name from "foo"`
    ts.importStarHelper = {
        name: "typescript:commonjsimportstar",
        scoped: false,
        text: "\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\n    result[\"default\"] = mod;\n    return result;\n};"
    };
    // emit helper for `import Name from "foo"`
    ts.importDefaultHelper = {
        name: "typescript:commonjsimportdefault",
        scoped: false,
        text: "\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n    return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};"
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformSystemModule(context) {
        var startLexicalEnvironment = context.startLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var resolver = context.getEmitResolver();
        var host = context.getEmitHost();
        var previousOnSubstituteNode = context.onSubstituteNode;
        var previousOnEmitNode = context.onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        context.onEmitNode = onEmitNode;
        context.enableSubstitution(73 /* Identifier */); // Substitutes expression identifiers for imported symbols.
        context.enableSubstitution(277 /* ShorthandPropertyAssignment */); // Substitutes expression identifiers for imported symbols
        context.enableSubstitution(205 /* BinaryExpression */); // Substitutes assignments to exported symbols.
        context.enableSubstitution(203 /* PrefixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableSubstitution(204 /* PostfixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableEmitNotification(285 /* SourceFile */); // Restore state when substituting nodes in a file.
        var moduleInfoMap = []; // The ExternalModuleInfo for each file.
        var deferredExports = []; // Exports to defer until an EndOfDeclarationMarker is found.
        var exportFunctionsMap = []; // The export function associated with a source file.
        var noSubstitutionMap = []; // Set of nodes for which substitution rules should be ignored for each file.
        var currentSourceFile; // The current file.
        var moduleInfo; // ExternalModuleInfo for the current file.
        var exportFunction; // The export function for the current file.
        var contextObject; // The context object for the current file.
        var hoistedStatements;
        var enclosingBlockScopedContainer;
        var noSubstitution; // Set of nodes for which substitution rules should be ignored.
        return ts.chainBundle(transformSourceFile);
        /**
         * Transforms the module aspects of a SourceFile.
         *
         * @param node The SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile || !(ts.isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & 524288 /* ContainsDynamicImport */)) {
                return node;
            }
            var id = ts.getOriginalNodeId(node);
            currentSourceFile = node;
            enclosingBlockScopedContainer = node;
            // System modules have the following shape:
            //
            //     System.register(['dep-1', ... 'dep-n'], function(exports) {/* module body function */})
            //
            // The parameter 'exports' here is a callback '<T>(name: string, value: T) => T' that
            // is used to publish exported values. 'exports' returns its 'value' argument so in
            // most cases expressions that mutate exported values can be rewritten as:
            //
            //     expr -> exports('name', expr)
            //
            // The only exception in this rule is postfix unary operators,
            // see comment to 'substitutePostfixUnaryExpression' for more details
            // Collect information about the external module and dependency groups.
            moduleInfo = moduleInfoMap[id] = ts.collectExternalModuleInfo(node, resolver, compilerOptions);
            // Make sure that the name of the 'exports' function does not conflict with
            // existing identifiers.
            exportFunction = ts.createUniqueName("exports");
            exportFunctionsMap[id] = exportFunction;
            contextObject = ts.createUniqueName("context");
            // Add the body of the module.
            var dependencyGroups = collectDependencyGroups(moduleInfo.externalImports);
            var moduleBodyBlock = createSystemModuleBody(node, dependencyGroups);
            var moduleBodyFunction = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [
                ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, exportFunction),
                ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, contextObject)
            ], 
            /*type*/ undefined, moduleBodyBlock);
            // Write the call to `System.register`
            // Clear the emit-helpers flag for later passes since we'll have already used it in the module body
            // So the helper will be emit at the correct position instead of at the top of the source-file
            var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions);
            var dependencies = ts.createArrayLiteral(ts.map(dependencyGroups, function (dependencyGroup) { return dependencyGroup.name; }));
            var updated = ts.setEmitFlags(ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([
                ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("System"), "register"), 
                /*typeArguments*/ undefined, moduleName
                    ? [moduleName, dependencies, moduleBodyFunction]
                    : [dependencies, moduleBodyFunction]))
            ]), node.statements)), 1024 /* NoTrailingComments */);
            if (!(compilerOptions.outFile || compilerOptions.out)) {
                ts.moveEmitHelpers(updated, moduleBodyBlock, function (helper) { return !helper.scoped; });
            }
            if (noSubstitution) {
                noSubstitutionMap[id] = noSubstitution;
                noSubstitution = undefined;
            }
            currentSourceFile = undefined;
            moduleInfo = undefined;
            exportFunction = undefined;
            contextObject = undefined;
            hoistedStatements = undefined;
            enclosingBlockScopedContainer = undefined;
            return ts.aggregateTransformFlags(updated);
        }
        /**
         * Collects the dependency groups for this files imports.
         *
         * @param externalImports The imports for the file.
         */
        function collectDependencyGroups(externalImports) {
            var groupIndices = ts.createMap();
            var dependencyGroups = [];
            for (var _i = 0, externalImports_1 = externalImports; _i < externalImports_1.length; _i++) {
                var externalImport = externalImports_1[_i];
                var externalModuleName = ts.getExternalModuleNameLiteral(externalImport, currentSourceFile, host, resolver, compilerOptions);
                if (externalModuleName) {
                    var text = externalModuleName.text;
                    var groupIndex = groupIndices.get(text);
                    if (groupIndex !== undefined) {
                        // deduplicate/group entries in dependency list by the dependency name
                        dependencyGroups[groupIndex].externalImports.push(externalImport);
                    }
                    else {
                        groupIndices.set(text, dependencyGroups.length);
                        dependencyGroups.push({
                            name: externalModuleName,
                            externalImports: [externalImport]
                        });
                    }
                }
            }
            return dependencyGroups;
        }
        /**
         * Adds the statements for the module body function for the source file.
         *
         * @param node The source file for the module.
         * @param dependencyGroups The grouped dependencies of the module.
         */
        function createSystemModuleBody(node, dependencyGroups) {
            // Shape of the body in system modules:
            //
            //  function (exports) {
            //      <list of local aliases for imports>
            //      <hoisted variable declarations>
            //      <hoisted function declarations>
            //      return {
            //          setters: [
            //              <list of setter function for imports>
            //          ],
            //          execute: function() {
            //              <module statements>
            //          }
            //      }
            //      <temp declarations>
            //  }
            //
            // i.e:
            //
            //   import {x} from 'file1'
            //   var y = 1;
            //   export function foo() { return y + x(); }
            //   console.log(y);
            //
            // Will be transformed to:
            //
            //  function(exports) {
            //      function foo() { return y + file_1.x(); }
            //      exports("foo", foo);
            //      var file_1, y;
            //      return {
            //          setters: [
            //              function(v) { file_1 = v }
            //          ],
            //          execute(): function() {
            //              y = 1;
            //              console.log(y);
            //          }
            //      };
            //  }
            var statements = [];
            // We start a new lexical environment in this function body, but *not* in the
            // body of the execute function. This allows us to emit temporary declarations
            // only in the outer module body and not in the inner one.
            startLexicalEnvironment();
            // Add any prologue directives.
            var ensureUseStrict = ts.getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && ts.isExternalModule(currentSourceFile));
            var statementOffset = ts.addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
            // var __moduleName = context_1 && context_1.id;
            statements.push(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration("__moduleName", 
                /*type*/ undefined, ts.createLogicalAnd(contextObject, ts.createPropertyAccess(contextObject, "id")))
            ])));
            // Visit the synthetic external helpers import declaration if present
            ts.visitNode(moduleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement);
            // Visit the statements of the source file, emitting any transformations into
            // the `executeStatements` array. We do this *before* we fill the `setters` array
            // as we both emit transformations as well as aggregate some data used when creating
            // setters. This allows us to reduce the number of times we need to loop through the
            // statements of the source file.
            var executeStatements = ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset);
            // Emit early exports for function declarations.
            ts.addRange(statements, hoistedStatements);
            // We emit hoisted variables early to align roughly with our previous emit output.
            // Two key differences in this approach are:
            // - Temporary variables will appear at the top rather than at the bottom of the file
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            var exportStarFunction = addExportStarIfNeeded(statements); // TODO: GH#18217
            var moduleObject = ts.createObjectLiteral([
                ts.createPropertyAssignment("setters", createSettersArray(exportStarFunction, dependencyGroups)),
                ts.createPropertyAssignment("execute", ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, 
                /*parameters*/ [], 
                /*type*/ undefined, ts.createBlock(executeStatements, /*multiLine*/ true)))
            ]);
            moduleObject.multiLine = true;
            statements.push(ts.createReturn(moduleObject));
            return ts.createBlock(statements, /*multiLine*/ true);
        }
        /**
         * Adds an exportStar function to a statement list if it is needed for the file.
         *
         * @param statements A statement list.
         */
        function addExportStarIfNeeded(statements) {
            if (!moduleInfo.hasExportStarsToExportValues) {
                return;
            }
            // when resolving exports local exported entries/indirect exported entries in the module
            // should always win over entries with similar names that were added via star exports
            // to support this we store names of local/indirect exported entries in a set.
            // this set is used to filter names brought by star expors.
            // local names set should only be added if we have anything exported
            if (!moduleInfo.exportedNames && moduleInfo.exportSpecifiers.size === 0) {
                // no exported declarations (export var ...) or export specifiers (export {x})
                // check if we have any non star export declarations.
                var hasExportDeclarationWithExportClause = false;
                for (var _i = 0, _a = moduleInfo.externalImports; _i < _a.length; _i++) {
                    var externalImport = _a[_i];
                    if (externalImport.kind === 256 /* ExportDeclaration */ && externalImport.exportClause) {
                        hasExportDeclarationWithExportClause = true;
                        break;
                    }
                }
                if (!hasExportDeclarationWithExportClause) {
                    // we still need to emit exportStar helper
                    var exportStarFunction_1 = createExportStarFunction(/*localNames*/ undefined);
                    statements.push(exportStarFunction_1);
                    return exportStarFunction_1.name;
                }
            }
            var exportedNames = [];
            if (moduleInfo.exportedNames) {
                for (var _b = 0, _c = moduleInfo.exportedNames; _b < _c.length; _b++) {
                    var exportedLocalName = _c[_b];
                    if (exportedLocalName.escapedText === "default") {
                        continue;
                    }
                    // write name of exported declaration, i.e 'export var x...'
                    exportedNames.push(ts.createPropertyAssignment(ts.createLiteral(exportedLocalName), ts.createTrue()));
                }
            }
            for (var _d = 0, _e = moduleInfo.externalImports; _d < _e.length; _d++) {
                var externalImport = _e[_d];
                if (externalImport.kind !== 256 /* ExportDeclaration */) {
                    continue;
                }
                if (!externalImport.exportClause) {
                    // export * from ...
                    continue;
                }
                for (var _f = 0, _g = externalImport.exportClause.elements; _f < _g.length; _f++) {
                    var element = _g[_f];
                    // write name of indirectly exported entry, i.e. 'export {x} from ...'
                    exportedNames.push(ts.createPropertyAssignment(ts.createLiteral(ts.idText(element.name || element.propertyName)), ts.createTrue()));
                }
            }
            var exportedNamesStorageRef = ts.createUniqueName("exportedNames");
            statements.push(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(exportedNamesStorageRef, 
                /*type*/ undefined, ts.createObjectLiteral(exportedNames, /*multiline*/ true))
            ])));
            var exportStarFunction = createExportStarFunction(exportedNamesStorageRef);
            statements.push(exportStarFunction);
            return exportStarFunction.name;
        }
        /**
         * Creates an exportStar function for the file, with an optional set of excluded local
         * names.
         *
         * @param localNames An optional reference to an object containing a set of excluded local
         * names.
         */
        function createExportStarFunction(localNames) {
            var exportStarFunction = ts.createUniqueName("exportStar");
            var m = ts.createIdentifier("m");
            var n = ts.createIdentifier("n");
            var exports = ts.createIdentifier("exports");
            var condition = ts.createStrictInequality(n, ts.createLiteral("default"));
            if (localNames) {
                condition = ts.createLogicalAnd(condition, ts.createLogicalNot(ts.createCall(ts.createPropertyAccess(localNames, "hasOwnProperty"), 
                /*typeArguments*/ undefined, [n])));
            }
            return ts.createFunctionDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, exportStarFunction, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, m)], 
            /*type*/ undefined, ts.createBlock([
                ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(exports, 
                    /*type*/ undefined, ts.createObjectLiteral([]))
                ])),
                ts.createForIn(ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(n, /*type*/ undefined)
                ]), m, ts.createBlock([
                    ts.setEmitFlags(ts.createIf(condition, ts.createExpressionStatement(ts.createAssignment(ts.createElementAccess(exports, n), ts.createElementAccess(m, n)))), 1 /* SingleLine */)
                ])),
                ts.createExpressionStatement(ts.createCall(exportFunction, 
                /*typeArguments*/ undefined, [exports]))
            ], /*multiline*/ true));
        }
        /**
         * Creates an array setter callbacks for each dependency group.
         *
         * @param exportStarFunction A reference to an exportStarFunction for the file.
         * @param dependencyGroups An array of grouped dependencies.
         */
        function createSettersArray(exportStarFunction, dependencyGroups) {
            var setters = [];
            for (var _i = 0, dependencyGroups_1 = dependencyGroups; _i < dependencyGroups_1.length; _i++) {
                var group_1 = dependencyGroups_1[_i];
                // derive a unique name for parameter from the first named entry in the group
                var localName = ts.forEach(group_1.externalImports, function (i) { return ts.getLocalNameForExternalImport(i, currentSourceFile); });
                var parameterName = localName ? ts.getGeneratedNameForNode(localName) : ts.createUniqueName("");
                var statements = [];
                for (var _a = 0, _b = group_1.externalImports; _a < _b.length; _a++) {
                    var entry = _b[_a];
                    var importVariableName = ts.getLocalNameForExternalImport(entry, currentSourceFile); // TODO: GH#18217
                    switch (entry.kind) {
                        case 250 /* ImportDeclaration */:
                            if (!entry.importClause) {
                                // 'import "..."' case
                                // module is imported only for side-effects, no emit required
                                break;
                            }
                        // falls through
                        case 249 /* ImportEqualsDeclaration */:
                            ts.Debug.assert(importVariableName !== undefined);
                            // save import into the local
                            statements.push(ts.createExpressionStatement(ts.createAssignment(importVariableName, parameterName)));
                            break;
                        case 256 /* ExportDeclaration */:
                            ts.Debug.assert(importVariableName !== undefined);
                            if (entry.exportClause) {
                                //  export {a, b as c} from 'foo'
                                //
                                // emit as:
                                //
                                //  exports_({
                                //     "a": _["a"],
                                //     "c": _["b"]
                                //  });
                                var properties = [];
                                for (var _c = 0, _d = entry.exportClause.elements; _c < _d.length; _c++) {
                                    var e = _d[_c];
                                    properties.push(ts.createPropertyAssignment(ts.createLiteral(ts.idText(e.name)), ts.createElementAccess(parameterName, ts.createLiteral(ts.idText(e.propertyName || e.name)))));
                                }
                                statements.push(ts.createExpressionStatement(ts.createCall(exportFunction, 
                                /*typeArguments*/ undefined, [ts.createObjectLiteral(properties, /*multiline*/ true)])));
                            }
                            else {
                                //  export * from 'foo'
                                //
                                // emit as:
                                //
                                //  exportStar(foo_1_1);
                                statements.push(ts.createExpressionStatement(ts.createCall(exportStarFunction, 
                                /*typeArguments*/ undefined, [parameterName])));
                            }
                            break;
                    }
                }
                setters.push(ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], 
                /*type*/ undefined, ts.createBlock(statements, /*multiLine*/ true)));
            }
            return ts.createArrayLiteral(setters, /*multiLine*/ true);
        }
        //
        // Top-level Source Element Visitors
        //
        /**
         * Visit source elements at the top-level of a module.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitor(node) {
            switch (node.kind) {
                case 250 /* ImportDeclaration */:
                    return visitImportDeclaration(node);
                case 249 /* ImportEqualsDeclaration */:
                    return visitImportEqualsDeclaration(node);
                case 256 /* ExportDeclaration */:
                    // ExportDeclarations are elided as they are handled via
                    // `appendExportsOfDeclaration`.
                    return undefined;
                case 255 /* ExportAssignment */:
                    return visitExportAssignment(node);
                default:
                    return nestedElementVisitor(node);
            }
        }
        /**
         * Visits an ImportDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportDeclaration(node) {
            var statements;
            if (node.importClause) {
                hoistVariableDeclaration(ts.getLocalNameForExternalImport(node, currentSourceFile)); // TODO: GH#18217
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits an ImportEqualsDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportEqualsDeclaration(node) {
            ts.Debug.assert(ts.isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
            var statements;
            hoistVariableDeclaration(ts.getLocalNameForExternalImport(node, currentSourceFile)); // TODO: GH#18217
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportEqualsDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits an ExportAssignment node.
         *
         * @param node The node to visit.
         */
        function visitExportAssignment(node) {
            if (node.isExportEquals) {
                // Elide `export=` as it is illegal in a SystemJS module.
                return undefined;
            }
            var expression = ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression);
            var original = node.original;
            if (original && hasAssociatedEndOfDeclarationMarker(original)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportStatement(deferredExports[id], ts.createIdentifier("default"), expression, /*allowComments*/ true);
            }
            else {
                return createExportStatement(ts.createIdentifier("default"), expression, /*allowComments*/ true);
            }
        }
        /**
         * Visits a FunctionDeclaration, hoisting it to the outer module body function.
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            if (ts.hasModifier(node, 1 /* Export */)) {
                hoistedStatements = ts.append(hoistedStatements, ts.updateFunctionDeclaration(node, node.decorators, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), 
                /*typeParameters*/ undefined, ts.visitNodes(node.parameters, destructuringAndImportCallVisitor, ts.isParameterDeclaration), 
                /*type*/ undefined, ts.visitNode(node.body, destructuringAndImportCallVisitor, ts.isBlock)));
            }
            else {
                hoistedStatements = ts.append(hoistedStatements, ts.visitEachChild(node, destructuringAndImportCallVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                hoistedStatements = appendExportsOfHoistedDeclaration(hoistedStatements, node);
            }
            return undefined;
        }
        /**
         * Visits a ClassDeclaration, hoisting its name to the outer module body function.
         *
         * @param node The node to visit.
         */
        function visitClassDeclaration(node) {
            var statements;
            // Hoist the name of the class declaration to the outer module body function.
            var name = ts.getLocalName(node);
            hoistVariableDeclaration(name);
            // Rewrite the class declaration into an assignment of a class expression.
            statements = ts.append(statements, ts.setTextRange(ts.createExpressionStatement(ts.createAssignment(name, ts.setTextRange(ts.createClassExpression(
            /*modifiers*/ undefined, node.name, 
            /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, destructuringAndImportCallVisitor, ts.isHeritageClause), ts.visitNodes(node.members, destructuringAndImportCallVisitor, ts.isClassElement)), node))), node));
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfHoistedDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a variable statement, hoisting declared names to the top-level module body.
         * Each declaration is rewritten into an assignment expression.
         *
         * @param node The node to visit.
         */
        function visitVariableStatement(node) {
            if (!shouldHoistVariableDeclarationList(node.declarationList)) {
                return ts.visitNode(node, destructuringAndImportCallVisitor, ts.isStatement);
            }
            var expressions;
            var isExportedDeclaration = ts.hasModifier(node, 1 /* Export */);
            var isMarkedDeclaration = hasAssociatedEndOfDeclarationMarker(node);
            for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                var variable = _a[_i];
                if (variable.initializer) {
                    expressions = ts.append(expressions, transformInitializedVariable(variable, isExportedDeclaration && !isMarkedDeclaration));
                }
                else {
                    hoistBindingElement(variable);
                }
            }
            var statements;
            if (expressions) {
                statements = ts.append(statements, ts.setTextRange(ts.createExpressionStatement(ts.inlineExpressions(expressions)), node));
            }
            if (isMarkedDeclaration) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node, isExportedDeclaration);
            }
            else {
                statements = appendExportsOfVariableStatement(statements, node, /*exportSelf*/ false);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Hoists the declared names of a VariableDeclaration or BindingElement.
         *
         * @param node The declaration to hoist.
         */
        function hoistBindingElement(node) {
            if (ts.isBindingPattern(node.name)) {
                for (var _i = 0, _a = node.name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        hoistBindingElement(element);
                    }
                }
            }
            else {
                hoistVariableDeclaration(ts.getSynthesizedClone(node.name));
            }
        }
        /**
         * Determines whether a VariableDeclarationList should be hoisted.
         *
         * @param node The node to test.
         */
        function shouldHoistVariableDeclarationList(node) {
            // hoist only non-block scoped declarations or block scoped declarations parented by source file
            return (ts.getEmitFlags(node) & 2097152 /* NoHoisting */) === 0
                && (enclosingBlockScopedContainer.kind === 285 /* SourceFile */
                    || (ts.getOriginalNode(node).flags & 3 /* BlockScoped */) === 0);
        }
        /**
         * Transform an initialized variable declaration into an expression.
         *
         * @param node The node to transform.
         * @param isExportedDeclaration A value indicating whether the variable is exported.
         */
        function transformInitializedVariable(node, isExportedDeclaration) {
            var createAssignment = isExportedDeclaration ? createExportedVariableAssignment : createNonExportedVariableAssignment;
            return ts.isBindingPattern(node.name)
                ? ts.flattenDestructuringAssignment(node, destructuringAndImportCallVisitor, context, 0 /* All */, 
                /*needsValue*/ false, createAssignment)
                : node.initializer ? createAssignment(node.name, ts.visitNode(node.initializer, destructuringAndImportCallVisitor, ts.isExpression)) : node.name;
        }
        /**
         * Creates an assignment expression for an exported variable declaration.
         *
         * @param name The name of the variable.
         * @param value The value of the variable's initializer.
         * @param location The source map location for the assignment.
         */
        function createExportedVariableAssignment(name, value, location) {
            return createVariableAssignment(name, value, location, /*isExportedDeclaration*/ true);
        }
        /**
         * Creates an assignment expression for a non-exported variable declaration.
         *
         * @param name The name of the variable.
         * @param value The value of the variable's initializer.
         * @param location The source map location for the assignment.
         */
        function createNonExportedVariableAssignment(name, value, location) {
            return createVariableAssignment(name, value, location, /*isExportedDeclaration*/ false);
        }
        /**
         * Creates an assignment expression for a variable declaration.
         *
         * @param name The name of the variable.
         * @param value The value of the variable's initializer.
         * @param location The source map location for the assignment.
         * @param isExportedDeclaration A value indicating whether the variable is exported.
         */
        function createVariableAssignment(name, value, location, isExportedDeclaration) {
            hoistVariableDeclaration(ts.getSynthesizedClone(name));
            return isExportedDeclaration
                ? createExportExpression(name, preventSubstitution(ts.setTextRange(ts.createAssignment(name, value), location)))
                : preventSubstitution(ts.setTextRange(ts.createAssignment(name, value), location));
        }
        /**
         * Visits a MergeDeclarationMarker used as a placeholder for the beginning of a merged
         * and transformed declaration.
         *
         * @param node The node to visit.
         */
        function visitMergeDeclarationMarker(node) {
            // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
            // declaration we do not emit a leading variable declaration. To preserve the
            // begin/end semantics of the declararation and to properly handle exports
            // we wrapped the leading variable declaration in a `MergeDeclarationMarker`.
            //
            // To balance the declaration, we defer the exports of the elided variable
            // statement until we visit this declaration's `EndOfDeclarationMarker`.
            if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === 220 /* VariableStatement */) {
                var id = ts.getOriginalNodeId(node);
                var isExportedDeclaration = ts.hasModifier(node.original, 1 /* Export */);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node.original, isExportedDeclaration);
            }
            return node;
        }
        /**
         * Determines whether a node has an associated EndOfDeclarationMarker.
         *
         * @param node The node to test.
         */
        function hasAssociatedEndOfDeclarationMarker(node) {
            return (ts.getEmitFlags(node) & 4194304 /* HasEndOfDeclarationMarker */) !== 0;
        }
        /**
         * Visits a DeclarationMarker used as a placeholder for the end of a transformed
         * declaration.
         *
         * @param node The node to visit.
         */
        function visitEndOfDeclarationMarker(node) {
            // For some transformations we emit an `EndOfDeclarationMarker` to mark the actual
            // end of the transformed declaration. We use this marker to emit any deferred exports
            // of the declaration.
            var id = ts.getOriginalNodeId(node);
            var statements = deferredExports[id];
            if (statements) {
                delete deferredExports[id];
                return ts.append(statements, node);
            }
            else {
                var original = ts.getOriginalNode(node);
                if (ts.isModuleOrEnumDeclaration(original)) {
                    return ts.append(appendExportsOfDeclaration(statements, original), node);
                }
            }
            return node;
        }
        /**
         * Appends the exports of an ImportDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportDeclaration(statements, decl) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            var importClause = decl.importClause;
            if (!importClause) {
                return statements;
            }
            if (importClause.name) {
                statements = appendExportsOfDeclaration(statements, importClause);
            }
            var namedBindings = importClause.namedBindings;
            if (namedBindings) {
                switch (namedBindings.kind) {
                    case 252 /* NamespaceImport */:
                        statements = appendExportsOfDeclaration(statements, namedBindings);
                        break;
                    case 253 /* NamedImports */:
                        for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) {
                            var importBinding = _a[_i];
                            statements = appendExportsOfDeclaration(statements, importBinding);
                        }
                        break;
                }
            }
            return statements;
        }
        /**
         * Appends the export of an ImportEqualsDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportEqualsDeclaration(statements, decl) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            return appendExportsOfDeclaration(statements, decl);
        }
        /**
         * Appends the exports of a VariableStatement to a statement list, returning the statement
         * list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param node The VariableStatement whose exports are to be recorded.
         * @param exportSelf A value indicating whether to also export each VariableDeclaration of
         * `nodes` declaration list.
         */
        function appendExportsOfVariableStatement(statements, node, exportSelf) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                var decl = _a[_i];
                if (decl.initializer || exportSelf) {
                    statements = appendExportsOfBindingElement(statements, decl, exportSelf);
                }
            }
            return statements;
        }
        /**
         * Appends the exports of a VariableDeclaration or BindingElement to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         * @param exportSelf A value indicating whether to also export the declaration itself.
         */
        function appendExportsOfBindingElement(statements, decl, exportSelf) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            if (ts.isBindingPattern(decl.name)) {
                for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        statements = appendExportsOfBindingElement(statements, element, exportSelf);
                    }
                }
            }
            else if (!ts.isGeneratedIdentifier(decl.name)) {
                var excludeName = void 0;
                if (exportSelf) {
                    statements = appendExportStatement(statements, decl.name, ts.getLocalName(decl));
                    excludeName = ts.idText(decl.name);
                }
                statements = appendExportsOfDeclaration(statements, decl, excludeName);
            }
            return statements;
        }
        /**
         * Appends the exports of a ClassDeclaration or FunctionDeclaration to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfHoistedDeclaration(statements, decl) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            var excludeName;
            if (ts.hasModifier(decl, 1 /* Export */)) {
                var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createLiteral("default") : decl.name;
                statements = appendExportStatement(statements, exportName, ts.getLocalName(decl));
                excludeName = ts.getTextOfIdentifierOrLiteral(exportName);
            }
            if (decl.name) {
                statements = appendExportsOfDeclaration(statements, decl, excludeName);
            }
            return statements;
        }
        /**
         * Appends the exports of a declaration to a statement list, returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration to export.
         * @param excludeName An optional name to exclude from exports.
         */
        function appendExportsOfDeclaration(statements, decl, excludeName) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            var name = ts.getDeclarationName(decl);
            var exportSpecifiers = moduleInfo.exportSpecifiers.get(ts.idText(name));
            if (exportSpecifiers) {
                for (var _i = 0, exportSpecifiers_2 = exportSpecifiers; _i < exportSpecifiers_2.length; _i++) {
                    var exportSpecifier = exportSpecifiers_2[_i];
                    if (exportSpecifier.name.escapedText !== excludeName) {
                        statements = appendExportStatement(statements, exportSpecifier.name, name);
                    }
                }
            }
            return statements;
        }
        /**
         * Appends the down-level representation of an export to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param exportName The name of the export.
         * @param expression The expression to export.
         * @param allowComments Whether to allow comments on the export.
         */
        function appendExportStatement(statements, exportName, expression, allowComments) {
            statements = ts.append(statements, createExportStatement(exportName, expression, allowComments));
            return statements;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         * @param allowComments An optional value indicating whether to emit comments for the statement.
         */
        function createExportStatement(name, value, allowComments) {
            var statement = ts.createExpressionStatement(createExportExpression(name, value));
            ts.startOnNewLine(statement);
            if (!allowComments) {
                ts.setEmitFlags(statement, 1536 /* NoComments */);
            }
            return statement;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         */
        function createExportExpression(name, value) {
            var exportName = ts.isIdentifier(name) ? ts.createLiteral(name) : name;
            ts.setEmitFlags(value, ts.getEmitFlags(value) | 1536 /* NoComments */);
            return ts.setCommentRange(ts.createCall(exportFunction, /*typeArguments*/ undefined, [exportName, value]), value);
        }
        //
        // Top-Level or Nested Source Element Visitors
        //
        /**
         * Visit nested elements at the top-level of a module.
         *
         * @param node The node to visit.
         */
        function nestedElementVisitor(node) {
            switch (node.kind) {
                case 220 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 240 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 241 /* ClassDeclaration */:
                    return visitClassDeclaration(node);
                case 226 /* ForStatement */:
                    return visitForStatement(node);
                case 227 /* ForInStatement */:
                    return visitForInStatement(node);
                case 228 /* ForOfStatement */:
                    return visitForOfStatement(node);
                case 224 /* DoStatement */:
                    return visitDoStatement(node);
                case 225 /* WhileStatement */:
                    return visitWhileStatement(node);
                case 234 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                case 232 /* WithStatement */:
                    return visitWithStatement(node);
                case 233 /* SwitchStatement */:
                    return visitSwitchStatement(node);
                case 247 /* CaseBlock */:
                    return visitCaseBlock(node);
                case 272 /* CaseClause */:
                    return visitCaseClause(node);
                case 273 /* DefaultClause */:
                    return visitDefaultClause(node);
                case 236 /* TryStatement */:
                    return visitTryStatement(node);
                case 275 /* CatchClause */:
                    return visitCatchClause(node);
                case 219 /* Block */:
                    return visitBlock(node);
                case 316 /* MergeDeclarationMarker */:
                    return visitMergeDeclarationMarker(node);
                case 317 /* EndOfDeclarationMarker */:
                    return visitEndOfDeclarationMarker(node);
                default:
                    return destructuringAndImportCallVisitor(node);
            }
        }
        /**
         * Visits the body of a ForStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitForStatement(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateFor(node, node.initializer && visitForInitializer(node.initializer), ts.visitNode(node.condition, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.incrementor, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a ForInStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitForInStatement(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateForIn(node, visitForInitializer(node.initializer), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a ForOfStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitForOfStatement(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateForOf(node, node.awaitModifier, visitForInitializer(node.initializer), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Determines whether to hoist the initializer of a ForStatement, ForInStatement, or
         * ForOfStatement.
         *
         * @param node The node to test.
         */
        function shouldHoistForInitializer(node) {
            return ts.isVariableDeclarationList(node)
                && shouldHoistVariableDeclarationList(node);
        }
        /**
         * Visits the initializer of a ForStatement, ForInStatement, or ForOfStatement
         *
         * @param node The node to visit.
         */
        function visitForInitializer(node) {
            if (shouldHoistForInitializer(node)) {
                var expressions = void 0;
                for (var _i = 0, _a = node.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    expressions = ts.append(expressions, transformInitializedVariable(variable, /*isExportedDeclaration*/ false));
                    if (!variable.initializer) {
                        hoistBindingElement(variable);
                    }
                }
                return expressions ? ts.inlineExpressions(expressions) : ts.createOmittedExpression();
            }
            else {
                return ts.visitEachChild(node, nestedElementVisitor, context);
            }
        }
        /**
         * Visits the body of a DoStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitDoStatement(node) {
            return ts.updateDo(node, ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression));
        }
        /**
         * Visits the body of a WhileStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitWhileStatement(node) {
            return ts.updateWhile(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
        }
        /**
         * Visits the body of a LabeledStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitLabeledStatement(node) {
            return ts.updateLabel(node, node.label, ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
        }
        /**
         * Visits the body of a WithStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitWithStatement(node) {
            return ts.updateWith(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
        }
        /**
         * Visits the body of a SwitchStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitSwitchStatement(node) {
            return ts.updateSwitch(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.caseBlock, nestedElementVisitor, ts.isCaseBlock));
        }
        /**
         * Visits the body of a CaseBlock to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitCaseBlock(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateCaseBlock(node, ts.visitNodes(node.clauses, nestedElementVisitor, ts.isCaseOrDefaultClause));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a CaseClause to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitCaseClause(node) {
            return ts.updateCaseClause(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNodes(node.statements, nestedElementVisitor, ts.isStatement));
        }
        /**
         * Visits the body of a DefaultClause to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitDefaultClause(node) {
            return ts.visitEachChild(node, nestedElementVisitor, context);
        }
        /**
         * Visits the body of a TryStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitTryStatement(node) {
            return ts.visitEachChild(node, nestedElementVisitor, context);
        }
        /**
         * Visits the body of a CatchClause to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitCatchClause(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateCatchClause(node, node.variableDeclaration, ts.visitNode(node.block, nestedElementVisitor, ts.isBlock));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a Block to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitBlock(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.visitEachChild(node, nestedElementVisitor, context);
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        //
        // Destructuring Assignment Visitors
        //
        /**
         * Visit nodes to flatten destructuring assignments to exported symbols.
         *
         * @param node The node to visit.
         */
        function destructuringAndImportCallVisitor(node) {
            if (ts.isDestructuringAssignment(node)) {
                return visitDestructuringAssignment(node);
            }
            else if (ts.isImportCall(node)) {
                return visitImportCallExpression(node);
            }
            else if ((node.transformFlags & 512 /* ContainsDestructuringAssignment */) || (node.transformFlags & 524288 /* ContainsDynamicImport */)) {
                return ts.visitEachChild(node, destructuringAndImportCallVisitor, context);
            }
            else {
                return node;
            }
        }
        function visitImportCallExpression(node) {
            // import("./blah")
            // emit as
            // System.register([], function (_export, _context) {
            //     return {
            //         setters: [],
            //         execute: () => {
            //             _context.import('./blah');
            //         }
            //     };
            // });
            return ts.createCall(ts.createPropertyAccess(contextObject, ts.createIdentifier("import")), 
            /*typeArguments*/ undefined, ts.some(node.arguments) ? [ts.visitNode(node.arguments[0], destructuringAndImportCallVisitor)] : []);
        }
        /**
         * Visits a DestructuringAssignment to flatten destructuring to exported symbols.
         *
         * @param node The node to visit.
         */
        function visitDestructuringAssignment(node) {
            if (hasExportedReferenceInDestructuringTarget(node.left)) {
                return ts.flattenDestructuringAssignment(node, destructuringAndImportCallVisitor, context, 0 /* All */, 
                /*needsValue*/ true);
            }
            return ts.visitEachChild(node, destructuringAndImportCallVisitor, context);
        }
        /**
         * Determines whether the target of a destructuring assigment refers to an exported symbol.
         *
         * @param node The destructuring target.
         */
        function hasExportedReferenceInDestructuringTarget(node) {
            if (ts.isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) {
                return hasExportedReferenceInDestructuringTarget(node.left);
            }
            else if (ts.isSpreadElement(node)) {
                return hasExportedReferenceInDestructuringTarget(node.expression);
            }
            else if (ts.isObjectLiteralExpression(node)) {
                return ts.some(node.properties, hasExportedReferenceInDestructuringTarget);
            }
            else if (ts.isArrayLiteralExpression(node)) {
                return ts.some(node.elements, hasExportedReferenceInDestructuringTarget);
            }
            else if (ts.isShorthandPropertyAssignment(node)) {
                return hasExportedReferenceInDestructuringTarget(node.name);
            }
            else if (ts.isPropertyAssignment(node)) {
                return hasExportedReferenceInDestructuringTarget(node.initializer);
            }
            else if (ts.isIdentifier(node)) {
                var container = resolver.getReferencedExportContainer(node);
                return container !== undefined && container.kind === 285 /* SourceFile */;
            }
            else {
                return false;
            }
        }
        //
        // Modifier Visitors
        //
        /**
         * Visit nodes to elide module-specific modifiers.
         *
         * @param node The node to visit.
         */
        function modifierVisitor(node) {
            switch (node.kind) {
                case 86 /* ExportKeyword */:
                case 81 /* DefaultKeyword */:
                    return undefined;
            }
            return node;
        }
        //
        // Emit Notification
        //
        /**
         * Hook for node emit notifications.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (node.kind === 285 /* SourceFile */) {
                var id = ts.getOriginalNodeId(node);
                currentSourceFile = node;
                moduleInfo = moduleInfoMap[id];
                exportFunction = exportFunctionsMap[id];
                noSubstitution = noSubstitutionMap[id];
                if (noSubstitution) {
                    delete noSubstitutionMap[id];
                }
                previousOnEmitNode(hint, node, emitCallback);
                currentSourceFile = undefined;
                moduleInfo = undefined;
                exportFunction = undefined;
                noSubstitution = undefined;
            }
            else {
                previousOnEmitNode(hint, node, emitCallback);
            }
        }
        //
        // Substitutions
        //
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (isSubstitutionPrevented(node)) {
                return node;
            }
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            else if (hint === 4 /* Unspecified */) {
                return substituteUnspecified(node);
            }
            return node;
        }
        /**
         * Substitute the node, if necessary.
         *
         * @param node The node to substitute.
         */
        function substituteUnspecified(node) {
            switch (node.kind) {
                case 277 /* ShorthandPropertyAssignment */:
                    return substituteShorthandPropertyAssignment(node);
            }
            return node;
        }
        /**
         * Substitution for a ShorthandPropertyAssignment whose name that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteShorthandPropertyAssignment(node) {
            var name = node.name;
            if (!ts.isGeneratedIdentifier(name) && !ts.isLocalName(name)) {
                var importDeclaration = resolver.getReferencedImportDeclaration(name);
                if (importDeclaration) {
                    if (ts.isImportClause(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAssignment(ts.getSynthesizedClone(name), ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent), ts.createIdentifier("default"))), 
                        /*location*/ node);
                    }
                    else if (ts.isImportSpecifier(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAssignment(ts.getSynthesizedClone(name), ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent.parent.parent), ts.getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name))), 
                        /*location*/ node);
                    }
                }
            }
            return node;
        }
        /**
         * Substitute the expression, if necessary.
         *
         * @param node The node to substitute.
         */
        function substituteExpression(node) {
            switch (node.kind) {
                case 73 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 205 /* BinaryExpression */:
                    return substituteBinaryExpression(node);
                case 203 /* PrefixUnaryExpression */:
                case 204 /* PostfixUnaryExpression */:
                    return substituteUnaryExpression(node);
            }
            return node;
        }
        /**
         * Substitution for an Identifier expression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteExpressionIdentifier(node) {
            if (ts.getEmitFlags(node) & 4096 /* HelperName */) {
                var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile);
                if (externalHelpersModuleName) {
                    return ts.createPropertyAccess(externalHelpersModuleName, node);
                }
                return node;
            }
            // When we see an identifier in an expression position that
            // points to an imported symbol, we should substitute a qualified
            // reference to the imported symbol if one is needed.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            if (!ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) {
                var importDeclaration = resolver.getReferencedImportDeclaration(node);
                if (importDeclaration) {
                    if (ts.isImportClause(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent), ts.createIdentifier("default")), 
                        /*location*/ node);
                    }
                    else if (ts.isImportSpecifier(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent.parent.parent), ts.getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name)), 
                        /*location*/ node);
                    }
                }
            }
            return node;
        }
        /**
         * Substitution for a BinaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteBinaryExpression(node) {
            // When we see an assignment expression whose left-hand side is an exported symbol,
            // we should ensure all exports of that symbol are updated with the correct value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if (ts.isAssignmentOperator(node.operatorToken.kind)
                && ts.isIdentifier(node.left)
                && !ts.isGeneratedIdentifier(node.left)
                && !ts.isLocalName(node.left)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.left)) {
                var exportedNames = getExports(node.left);
                if (exportedNames) {
                    // For each additional export of the declaration, apply an export assignment.
                    var expression = node;
                    for (var _i = 0, exportedNames_4 = exportedNames; _i < exportedNames_4.length; _i++) {
                        var exportName = exportedNames_4[_i];
                        expression = createExportExpression(exportName, preventSubstitution(expression));
                    }
                    return expression;
                }
            }
            return node;
        }
        /**
         * Substitution for a UnaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteUnaryExpression(node) {
            // When we see a prefix or postfix increment expression whose operand is an exported
            // symbol, we should ensure all exports of that symbol are updated with the correct
            // value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if ((node.operator === 44 /* PlusPlusToken */ || node.operator === 45 /* MinusMinusToken */)
                && ts.isIdentifier(node.operand)
                && !ts.isGeneratedIdentifier(node.operand)
                && !ts.isLocalName(node.operand)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.operand)) {
                var exportedNames = getExports(node.operand);
                if (exportedNames) {
                    var expression = node.kind === 204 /* PostfixUnaryExpression */
                        ? ts.setTextRange(ts.createPrefix(node.operator, node.operand), node)
                        : node;
                    for (var _i = 0, exportedNames_5 = exportedNames; _i < exportedNames_5.length; _i++) {
                        var exportName = exportedNames_5[_i];
                        expression = createExportExpression(exportName, preventSubstitution(expression));
                    }
                    if (node.kind === 204 /* PostfixUnaryExpression */) {
                        expression = node.operator === 44 /* PlusPlusToken */
                            ? ts.createSubtract(preventSubstitution(expression), ts.createLiteral(1))
                            : ts.createAdd(preventSubstitution(expression), ts.createLiteral(1));
                    }
                    return expression;
                }
            }
            return node;
        }
        /**
         * Gets the exports of a name.
         *
         * @param name The name.
         */
        function getExports(name) {
            var exportedNames;
            if (!ts.isGeneratedIdentifier(name)) {
                var valueDeclaration = resolver.getReferencedImportDeclaration(name)
                    || resolver.getReferencedValueDeclaration(name);
                if (valueDeclaration) {
                    var exportContainer = resolver.getReferencedExportContainer(name, /*prefixLocals*/ false);
                    if (exportContainer && exportContainer.kind === 285 /* SourceFile */) {
                        exportedNames = ts.append(exportedNames, ts.getDeclarationName(valueDeclaration));
                    }
                    exportedNames = ts.addRange(exportedNames, moduleInfo && moduleInfo.exportedBindings[ts.getOriginalNodeId(valueDeclaration)]);
                }
            }
            return exportedNames;
        }
        /**
         * Prevent substitution of a node for this transformer.
         *
         * @param node The node which should not be substituted.
         */
        function preventSubstitution(node) {
            if (noSubstitution === undefined)
                noSubstitution = [];
            noSubstitution[ts.getNodeId(node)] = true;
            return node;
        }
        /**
         * Determines whether a node should not be substituted.
         *
         * @param node The node to test.
         */
        function isSubstitutionPrevented(node) {
            return noSubstitution && node.id && noSubstitution[node.id];
        }
    }
    ts.transformSystemModule = transformSystemModule;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformES2015Module(context) {
        var compilerOptions = context.getCompilerOptions();
        var previousOnEmitNode = context.onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        context.enableEmitNotification(285 /* SourceFile */);
        context.enableSubstitution(73 /* Identifier */);
        var currentSourceFile;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            if (ts.isExternalModule(node) || compilerOptions.isolatedModules) {
                var externalHelpersModuleName = ts.getOrCreateExternalHelpersModuleNameIfNeeded(node, compilerOptions);
                if (externalHelpersModuleName) {
                    var statements = [];
                    var statementOffset = ts.addPrologue(statements, node.statements);
                    var tslibImport = ts.createImportDeclaration(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(externalHelpersModuleName)), ts.createLiteral(ts.externalHelpersModuleNameText));
                    ts.addEmitFlags(tslibImport, 67108864 /* NeverApplyImportHelper */);
                    ts.append(statements, tslibImport);
                    ts.addRange(statements, ts.visitNodes(node.statements, visitor, ts.isStatement, statementOffset));
                    return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(statements), node.statements));
                }
                else {
                    return ts.visitEachChild(node, visitor, context);
                }
            }
            return node;
        }
        function visitor(node) {
            switch (node.kind) {
                case 249 /* ImportEqualsDeclaration */:
                    // Elide `import=` as it is not legal with --module ES6
                    return undefined;
                case 255 /* ExportAssignment */:
                    return visitExportAssignment(node);
            }
            return node;
        }
        function visitExportAssignment(node) {
            // Elide `export=` as it is not legal with --module ES6
            return node.isExportEquals ? undefined : node;
        }
        //
        // Emit Notification
        //
        /**
         * Hook for node emit.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (ts.isSourceFile(node)) {
                currentSourceFile = node;
                previousOnEmitNode(hint, node, emitCallback);
                currentSourceFile = undefined;
            }
            else {
                previousOnEmitNode(hint, node, emitCallback);
            }
        }
        //
        // Substitutions
        //
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (ts.isIdentifier(node) && hint === 1 /* Expression */) {
                return substituteExpressionIdentifier(node);
            }
            return node;
        }
        function substituteExpressionIdentifier(node) {
            if (ts.getEmitFlags(node) & 4096 /* HelperName */) {
                var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile);
                if (externalHelpersModuleName) {
                    return ts.createPropertyAccess(externalHelpersModuleName, node);
                }
            }
            return node;
        }
    }
    ts.transformES2015Module = transformES2015Module;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function canProduceDiagnostics(node) {
        return ts.isVariableDeclaration(node) ||
            ts.isPropertyDeclaration(node) ||
            ts.isPropertySignature(node) ||
            ts.isBindingElement(node) ||
            ts.isSetAccessor(node) ||
            ts.isGetAccessor(node) ||
            ts.isConstructSignatureDeclaration(node) ||
            ts.isCallSignatureDeclaration(node) ||
            ts.isMethodDeclaration(node) ||
            ts.isMethodSignature(node) ||
            ts.isFunctionDeclaration(node) ||
            ts.isParameter(node) ||
            ts.isTypeParameterDeclaration(node) ||
            ts.isExpressionWithTypeArguments(node) ||
            ts.isImportEqualsDeclaration(node) ||
            ts.isTypeAliasDeclaration(node) ||
            ts.isConstructorDeclaration(node) ||
            ts.isIndexSignatureDeclaration(node) ||
            ts.isPropertyAccessExpression(node);
    }
    ts.canProduceDiagnostics = canProduceDiagnostics;
    function createGetSymbolAccessibilityDiagnosticForNodeName(node) {
        if (ts.isSetAccessor(node) || ts.isGetAccessor(node)) {
            return getAccessorNameVisibilityError;
        }
        else if (ts.isMethodSignature(node) || ts.isMethodDeclaration(node)) {
            return getMethodNameVisibilityError;
        }
        else {
            return createGetSymbolAccessibilityDiagnosticForNode(node);
        }
        function getAccessorNameVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage = getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult);
            return diagnosticMessage !== undefined ? {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: node.name
            } : undefined;
        }
        function getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult) {
            if (ts.hasModifier(node, 32 /* Static */)) {
                return symbolAccessibilityResult.errorModuleName ?
                    symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                        ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                        ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1;
            }
            else if (node.parent.kind === 241 /* ClassDeclaration */) {
                return symbolAccessibilityResult.errorModuleName ?
                    symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                        ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                        ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1;
            }
            else {
                return symbolAccessibilityResult.errorModuleName ?
                    ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1;
            }
        }
        function getMethodNameVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage = getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult);
            return diagnosticMessage !== undefined ? {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: node.name
            } : undefined;
        }
        function getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult) {
            if (ts.hasModifier(node, 32 /* Static */)) {
                return symbolAccessibilityResult.errorModuleName ?
                    symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                        ts.Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                        ts.Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_private_name_1;
            }
            else if (node.parent.kind === 241 /* ClassDeclaration */) {
                return symbolAccessibilityResult.errorModuleName ?
                    symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                        ts.Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                        ts.Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Public_method_0_of_exported_class_has_or_is_using_private_name_1;
            }
            else {
                return symbolAccessibilityResult.errorModuleName ?
                    ts.Diagnostics.Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Method_0_of_exported_interface_has_or_is_using_private_name_1;
            }
        }
    }
    ts.createGetSymbolAccessibilityDiagnosticForNodeName = createGetSymbolAccessibilityDiagnosticForNodeName;
    function createGetSymbolAccessibilityDiagnosticForNode(node) {
        if (ts.isVariableDeclaration(node) || ts.isPropertyDeclaration(node) || ts.isPropertySignature(node) || ts.isPropertyAccessExpression(node) || ts.isBindingElement(node) || ts.isConstructorDeclaration(node)) {
            return getVariableDeclarationTypeVisibilityError;
        }
        else if (ts.isSetAccessor(node) || ts.isGetAccessor(node)) {
            return getAccessorDeclarationTypeVisibilityError;
        }
        else if (ts.isConstructSignatureDeclaration(node) || ts.isCallSignatureDeclaration(node) || ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isFunctionDeclaration(node) || ts.isIndexSignatureDeclaration(node)) {
            return getReturnTypeVisibilityError;
        }
        else if (ts.isParameter(node)) {
            if (ts.isParameterPropertyDeclaration(node) && ts.hasModifier(node.parent, 8 /* Private */)) {
                return getVariableDeclarationTypeVisibilityError;
            }
            return getParameterDeclarationTypeVisibilityError;
        }
        else if (ts.isTypeParameterDeclaration(node)) {
            return getTypeParameterConstraintVisibilityError;
        }
        else if (ts.isExpressionWithTypeArguments(node)) {
            return getHeritageClauseVisibilityError;
        }
        else if (ts.isImportEqualsDeclaration(node)) {
            return getImportEntityNameVisibilityError;
        }
        else if (ts.isTypeAliasDeclaration(node)) {
            return getTypeAliasDeclarationVisibilityError;
        }
        else {
            return ts.Debug.assertNever(node, "Attempted to set a declaration diagnostic context for unhandled node kind: " + ts.SyntaxKind[node.kind]);
        }
        function getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult) {
            if (node.kind === 238 /* VariableDeclaration */ || node.kind === 187 /* BindingElement */) {
                return symbolAccessibilityResult.errorModuleName ?
                    symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                        ts.Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                        ts.Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Exported_variable_0_has_or_is_using_private_name_1;
            }
            // This check is to ensure we don't report error on constructor parameter property as that error would be reported during parameter emit
            // The only exception here is if the constructor was marked as private. we are not emitting the constructor parameters at all.
            else if (node.kind === 155 /* PropertyDeclaration */ || node.kind === 190 /* PropertyAccessExpression */ || node.kind === 154 /* PropertySignature */ ||
                (node.kind === 152 /* Parameter */ && ts.hasModifier(node.parent, 8 /* Private */))) {
                // TODO(jfreeman): Deal with computed properties in error reporting.
                if (ts.hasModifier(node, 32 /* Static */)) {
                    return symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1;
                }
                else if (node.parent.kind === 241 /* ClassDeclaration */ || node.kind === 152 /* Parameter */) {
                    return symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1;
                }
                else {
                    // Interfaces cannot have types that cannot be named
                    return symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1;
                }
            }
        }
        function getVariableDeclarationTypeVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
            return diagnosticMessage !== undefined ? {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: node.name
            } : undefined;
        }
        function getAccessorDeclarationTypeVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage;
            if (node.kind === 160 /* SetAccessor */) {
                // Getters can infer the return type from the returned expression, but setters cannot, so the
                // "_from_external_module_1_but_cannot_be_named" case cannot occur.
                if (ts.hasModifier(node, 32 /* Static */)) {
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1;
                }
                else {
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1;
                }
            }
            else {
                if (ts.hasModifier(node, 32 /* Static */)) {
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1;
                }
                else {
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1;
                }
            }
            return {
                diagnosticMessage: diagnosticMessage,
                errorNode: node.name,
                typeName: node.name
            };
        }
        function getReturnTypeVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage;
            switch (node.kind) {
                case 162 /* ConstructSignature */:
                    // Interfaces cannot have return types that cannot be named
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                        ts.Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0;
                    break;
                case 161 /* CallSignature */:
                    // Interfaces cannot have return types that cannot be named
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                        ts.Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0;
                    break;
                case 163 /* IndexSignature */:
                    // Interfaces cannot have return types that cannot be named
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                        ts.Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0;
                    break;
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                    if (ts.hasModifier(node, 32 /* Static */)) {
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
                                ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
                            ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0;
                    }
                    else if (node.parent.kind === 241 /* ClassDeclaration */) {
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
                                ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
                            ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0;
                    }
                    else {
                        // Interfaces cannot have return types that cannot be named
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            ts.Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                            ts.Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0;
                    }
                    break;
                case 240 /* FunctionDeclaration */:
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
                            ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1 :
                        ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_private_name_0;
                    break;
                default:
                    return ts.Debug.fail("This is unknown kind for signature: " + node.kind);
            }
            return {
                diagnosticMessage: diagnosticMessage,
                errorNode: node.name || node
            };
        }
        function getParameterDeclarationTypeVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
            return diagnosticMessage !== undefined ? {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: node.name
            } : undefined;
        }
        function getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult) {
            switch (node.parent.kind) {
                case 158 /* Constructor */:
                    return symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1;
                case 162 /* ConstructSignature */:
                case 167 /* ConstructorType */:
                    // Interfaces cannot have parameter types that cannot be named
                    return symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
                case 161 /* CallSignature */:
                    // Interfaces cannot have parameter types that cannot be named
                    return symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
                case 163 /* IndexSignature */:
                    // Interfaces cannot have parameter types that cannot be named
                    return symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1;
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                    if (ts.hasModifier(node.parent, 32 /* Static */)) {
                        return symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                                ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
                    }
                    else if (node.parent.parent.kind === 241 /* ClassDeclaration */) {
                        return symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                                ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
                    }
                    else {
                        // Interfaces cannot have parameter types that cannot be named
                        return symbolAccessibilityResult.errorModuleName ?
                            ts.Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
                    }
                case 240 /* FunctionDeclaration */:
                case 166 /* FunctionType */:
                    return symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_private_name_1;
                default:
                    return ts.Debug.fail("Unknown parent for parameter: " + ts.SyntaxKind[node.parent.kind]);
            }
        }
        function getTypeParameterConstraintVisibilityError() {
            // Type parameter constraints are named by user so we should always be able to name it
            var diagnosticMessage;
            switch (node.parent.kind) {
                case 241 /* ClassDeclaration */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_class_has_or_is_using_private_name_1;
                    break;
                case 242 /* InterfaceDeclaration */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1;
                    break;
                case 182 /* MappedType */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1;
                    break;
                case 167 /* ConstructorType */:
                case 162 /* ConstructSignature */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
                    break;
                case 161 /* CallSignature */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
                    break;
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                    if (ts.hasModifier(node.parent, 32 /* Static */)) {
                        diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
                    }
                    else if (node.parent.parent.kind === 241 /* ClassDeclaration */) {
                        diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
                    }
                    else {
                        diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
                    }
                    break;
                case 166 /* FunctionType */:
                case 240 /* FunctionDeclaration */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_function_has_or_is_using_private_name_1;
                    break;
                case 243 /* TypeAliasDeclaration */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1;
                    break;
                default:
                    return ts.Debug.fail("This is unknown parent for type parameter: " + node.parent.kind);
            }
            return {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: node.name
            };
        }
        function getHeritageClauseVisibilityError() {
            var diagnosticMessage;
            // Heritage clause is written by user so it can always be named
            if (node.parent.parent.kind === 241 /* ClassDeclaration */) {
                // Class or Interface implemented/extended is inaccessible
                diagnosticMessage = ts.isHeritageClause(node.parent) && node.parent.token === 110 /* ImplementsKeyword */ ?
                    ts.Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 :
                    ts.Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1;
            }
            else {
                // interface is inaccessible
                diagnosticMessage = ts.Diagnostics.extends_clause_of_exported_interface_0_has_or_is_using_private_name_1;
            }
            return {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: ts.getNameOfDeclaration(node.parent.parent)
            };
        }
        function getImportEntityNameVisibilityError() {
            return {
                diagnosticMessage: ts.Diagnostics.Import_declaration_0_is_using_private_name_1,
                errorNode: node,
                typeName: node.name
            };
        }
        function getTypeAliasDeclarationVisibilityError() {
            return {
                diagnosticMessage: ts.Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1,
                errorNode: node.type,
                typeName: node.name
            };
        }
    }
    ts.createGetSymbolAccessibilityDiagnosticForNode = createGetSymbolAccessibilityDiagnosticForNode;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function getDeclarationDiagnostics(host, resolver, file) {
        if (file && ts.isSourceFileJS(file)) {
            return []; // No declaration diagnostics for js for now
        }
        var compilerOptions = host.getCompilerOptions();
        var result = ts.transformNodes(resolver, host, compilerOptions, file ? [file] : ts.filter(host.getSourceFiles(), ts.isSourceFileNotJS), [transformDeclarations], /*allowDtsFiles*/ false);
        return result.diagnostics;
    }
    ts.getDeclarationDiagnostics = getDeclarationDiagnostics;
    function hasInternalAnnotation(range, currentSourceFile) {
        var comment = currentSourceFile.text.substring(range.pos, range.end);
        return ts.stringContains(comment, "@internal");
    }
    function isInternalDeclaration(node, currentSourceFile) {
        var parseTreeNode = ts.getParseTreeNode(node);
        if (parseTreeNode && parseTreeNode.kind === 152 /* Parameter */) {
            var paramIdx = parseTreeNode.parent.parameters.indexOf(parseTreeNode);
            var previousSibling = paramIdx > 0 ? parseTreeNode.parent.parameters[paramIdx - 1] : undefined;
            var text = currentSourceFile.text;
            var commentRanges = previousSibling
                ? ts.concatenate(
                // to handle
                // ... parameters, /* @internal */
                // public param: string
                ts.getTrailingCommentRanges(text, ts.skipTrivia(text, previousSibling.end + 1, /* stopAfterLineBreak */ false, /* stopAtComments */ true)), ts.getLeadingCommentRanges(text, node.pos))
                : ts.getTrailingCommentRanges(text, ts.skipTrivia(text, node.pos, /* stopAfterLineBreak */ false, /* stopAtComments */ true));
            return commentRanges && commentRanges.length && hasInternalAnnotation(ts.last(commentRanges), currentSourceFile);
        }
        var leadingCommentRanges = parseTreeNode && ts.getLeadingCommentRangesOfNode(parseTreeNode, currentSourceFile);
        return !!ts.forEach(leadingCommentRanges, function (range) {
            return hasInternalAnnotation(range, currentSourceFile);
        });
    }
    ts.isInternalDeclaration = isInternalDeclaration;
    var declarationEmitNodeBuilderFlags = 1024 /* MultilineObjectLiterals */ |
        2048 /* WriteClassExpressionAsTypeLiteral */ |
        4096 /* UseTypeOfFunction */ |
        8 /* UseStructuralFallback */ |
        524288 /* AllowEmptyTuple */ |
        4 /* GenerateNamesForShadowedTypeParams */ |
        1 /* NoTruncation */;
    /**
     * Transforms a ts file into a .d.ts file
     * This process requires type information, which is retrieved through the emit resolver. Because of this,
     * in many places this transformer assumes it will be operating on parse tree nodes directly.
     * This means that _no transforms should be allowed to occur before this one_.
     */
    function transformDeclarations(context) {
        var throwDiagnostic = function () { return ts.Debug.fail("Diagnostic emitted without context"); };
        var getSymbolAccessibilityDiagnostic = throwDiagnostic;
        var needsDeclare = true;
        var isBundledEmit = false;
        var resultHasExternalModuleIndicator = false;
        var needsScopeFixMarker = false;
        var resultHasScopeMarker = false;
        var enclosingDeclaration;
        var necessaryTypeReferences;
        var lateMarkedStatements;
        var lateStatementReplacementMap;
        var suppressNewDiagnosticContexts;
        var exportedModulesFromDeclarationEmit;
        var host = context.getEmitHost();
        var symbolTracker = {
            trackSymbol: trackSymbol,
            reportInaccessibleThisError: reportInaccessibleThisError,
            reportInaccessibleUniqueSymbolError: reportInaccessibleUniqueSymbolError,
            reportPrivateInBaseOfClassExpression: reportPrivateInBaseOfClassExpression,
            reportLikelyUnsafeImportRequiredError: reportLikelyUnsafeImportRequiredError,
            moduleResolverHost: host,
            trackReferencedAmbientModule: trackReferencedAmbientModule,
            trackExternalModuleSymbolOfImportTypeNode: trackExternalModuleSymbolOfImportTypeNode
        };
        var errorNameNode;
        var currentSourceFile;
        var refs;
        var libs;
        var resolver = context.getEmitResolver();
        var options = context.getCompilerOptions();
        var newLine = ts.getNewLineCharacter(options);
        var noResolve = options.noResolve, stripInternal = options.stripInternal;
        return transformRoot;
        function recordTypeReferenceDirectivesIfNecessary(typeReferenceDirectives) {
            if (!typeReferenceDirectives) {
                return;
            }
            necessaryTypeReferences = necessaryTypeReferences || ts.createMap();
            for (var _i = 0, typeReferenceDirectives_2 = typeReferenceDirectives; _i < typeReferenceDirectives_2.length; _i++) {
                var ref = typeReferenceDirectives_2[_i];
                necessaryTypeReferences.set(ref, true);
            }
        }
        function trackReferencedAmbientModule(node, symbol) {
            // If it is visible via `// <reference types="..."/>`, then we should just use that
            var directives = resolver.getTypeReferenceDirectivesForSymbol(symbol, 67108863 /* All */);
            if (ts.length(directives)) {
                return recordTypeReferenceDirectivesIfNecessary(directives);
            }
            // Otherwise we should emit a path-based reference
            var container = ts.getSourceFileOfNode(node);
            refs.set("" + ts.getOriginalNodeId(container), container);
        }
        function handleSymbolAccessibilityError(symbolAccessibilityResult) {
            if (symbolAccessibilityResult.accessibility === 0 /* Accessible */) {
                // Add aliases back onto the possible imports list if they're not there so we can try them again with updated visibility info
                if (symbolAccessibilityResult && symbolAccessibilityResult.aliasesToMakeVisible) {
                    if (!lateMarkedStatements) {
                        lateMarkedStatements = symbolAccessibilityResult.aliasesToMakeVisible;
                    }
                    else {
                        for (var _i = 0, _a = symbolAccessibilityResult.aliasesToMakeVisible; _i < _a.length; _i++) {
                            var ref = _a[_i];
                            ts.pushIfUnique(lateMarkedStatements, ref);
                        }
                    }
                }
                // TODO: Do all these accessibility checks inside/after the first pass in the checker when declarations are enabled, if possible
            }
            else {
                // Report error
                var errorInfo = getSymbolAccessibilityDiagnostic(symbolAccessibilityResult);
                if (errorInfo) {
                    if (errorInfo.typeName) {
                        context.addDiagnostic(ts.createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getTextOfNode(errorInfo.typeName), symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName));
                    }
                    else {
                        context.addDiagnostic(ts.createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName));
                    }
                }
            }
        }
        function trackExternalModuleSymbolOfImportTypeNode(symbol) {
            if (!isBundledEmit) {
                (exportedModulesFromDeclarationEmit || (exportedModulesFromDeclarationEmit = [])).push(symbol);
            }
        }
        function trackSymbol(symbol, enclosingDeclaration, meaning) {
            if (symbol.flags & 262144 /* TypeParameter */)
                return;
            handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ true));
            recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol, meaning));
        }
        function reportPrivateInBaseOfClassExpression(propertyName) {
            if (errorNameNode) {
                context.addDiagnostic(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.Property_0_of_exported_class_expression_may_not_be_private_or_protected, propertyName));
            }
        }
        function reportInaccessibleUniqueSymbolError() {
            if (errorNameNode) {
                context.addDiagnostic(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, ts.declarationNameToString(errorNameNode), "unique symbol"));
            }
        }
        function reportInaccessibleThisError() {
            if (errorNameNode) {
                context.addDiagnostic(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, ts.declarationNameToString(errorNameNode), "this"));
            }
        }
        function reportLikelyUnsafeImportRequiredError(specifier) {
            if (errorNameNode) {
                context.addDiagnostic(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_annotation_is_necessary, ts.declarationNameToString(errorNameNode), specifier));
            }
        }
        function transformRoot(node) {
            if (node.kind === 285 /* SourceFile */ && (node.isDeclarationFile || ts.isSourceFileJS(node))) {
                return node;
            }
            if (node.kind === 286 /* Bundle */) {
                isBundledEmit = true;
                refs = ts.createMap();
                libs = ts.createMap();
                var hasNoDefaultLib_1 = false;
                var bundle = ts.createBundle(ts.map(node.sourceFiles, function (sourceFile) {
                    if (sourceFile.isDeclarationFile || ts.isSourceFileJS(sourceFile))
                        return undefined; // Omit declaration files from bundle results, too // TODO: GH#18217
                    hasNoDefaultLib_1 = hasNoDefaultLib_1 || sourceFile.hasNoDefaultLib;
                    currentSourceFile = sourceFile;
                    enclosingDeclaration = sourceFile;
                    lateMarkedStatements = undefined;
                    suppressNewDiagnosticContexts = false;
                    lateStatementReplacementMap = ts.createMap();
                    getSymbolAccessibilityDiagnostic = throwDiagnostic;
                    needsScopeFixMarker = false;
                    resultHasScopeMarker = false;
                    collectReferences(sourceFile, refs);
                    collectLibs(sourceFile, libs);
                    if (ts.isExternalModule(sourceFile)) {
                        resultHasExternalModuleIndicator = false; // unused in external module bundle emit (all external modules are within module blocks, therefore are known to be modules)
                        needsDeclare = false;
                        var statements_4 = ts.visitNodes(sourceFile.statements, visitDeclarationStatements);
                        var newFile = ts.updateSourceFileNode(sourceFile, [ts.createModuleDeclaration([], [ts.createModifier(126 /* DeclareKeyword */)], ts.createLiteral(ts.getResolvedExternalModuleName(context.getEmitHost(), sourceFile)), ts.createModuleBlock(ts.setTextRange(ts.createNodeArray(transformAndReplaceLatePaintedStatements(statements_4)), sourceFile.statements)))], /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []);
                        return newFile;
                    }
                    needsDeclare = true;
                    var updated = ts.visitNodes(sourceFile.statements, visitDeclarationStatements);
                    return ts.updateSourceFileNode(sourceFile, transformAndReplaceLatePaintedStatements(updated), /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []);
                }), ts.mapDefined(node.prepends, function (prepend) {
                    if (prepend.kind === 288 /* InputFiles */) {
                        var sourceFile = ts.createUnparsedSourceFile(prepend, "dts", stripInternal);
                        hasNoDefaultLib_1 = hasNoDefaultLib_1 || !!sourceFile.hasNoDefaultLib;
                        collectReferences(sourceFile, refs);
                        recordTypeReferenceDirectivesIfNecessary(sourceFile.typeReferenceDirectives);
                        collectLibs(sourceFile, libs);
                        return sourceFile;
                    }
                    return prepend;
                }));
                bundle.syntheticFileReferences = [];
                bundle.syntheticTypeReferences = getFileReferencesForUsedTypeReferences();
                bundle.syntheticLibReferences = getLibReferences();
                bundle.hasNoDefaultLib = hasNoDefaultLib_1;
                var outputFilePath_1 = ts.getDirectoryPath(ts.normalizeSlashes(ts.getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath));
                var referenceVisitor_1 = mapReferencesIntoArray(bundle.syntheticFileReferences, outputFilePath_1);
                refs.forEach(referenceVisitor_1);
                return bundle;
            }
            // Single source file
            needsDeclare = true;
            needsScopeFixMarker = false;
            resultHasScopeMarker = false;
            enclosingDeclaration = node;
            currentSourceFile = node;
            getSymbolAccessibilityDiagnostic = throwDiagnostic;
            isBundledEmit = false;
            resultHasExternalModuleIndicator = false;
            suppressNewDiagnosticContexts = false;
            lateMarkedStatements = undefined;
            lateStatementReplacementMap = ts.createMap();
            necessaryTypeReferences = undefined;
            refs = collectReferences(currentSourceFile, ts.createMap());
            libs = collectLibs(currentSourceFile, ts.createMap());
            var references = [];
            var outputFilePath = ts.getDirectoryPath(ts.normalizeSlashes(ts.getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath));
            var referenceVisitor = mapReferencesIntoArray(references, outputFilePath);
            var statements = ts.visitNodes(node.statements, visitDeclarationStatements);
            var combinedStatements = ts.setTextRange(ts.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), node.statements);
            refs.forEach(referenceVisitor);
            var emittedImports = ts.filter(combinedStatements, ts.isAnyImportSyntax);
            if (ts.isExternalModule(node) && (!resultHasExternalModuleIndicator || (needsScopeFixMarker && !resultHasScopeMarker))) {
                combinedStatements = ts.setTextRange(ts.createNodeArray(combinedStatements.concat([ts.createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, ts.createNamedExports([]), /*moduleSpecifier*/ undefined)])), combinedStatements);
            }
            var updated = ts.updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib, getLibReferences());
            updated.exportedModulesFromDeclarationEmit = exportedModulesFromDeclarationEmit;
            return updated;
            function getLibReferences() {
                return ts.map(ts.arrayFrom(libs.keys()), function (lib) { return ({ fileName: lib, pos: -1, end: -1 }); });
            }
            function getFileReferencesForUsedTypeReferences() {
                return necessaryTypeReferences ? ts.mapDefined(ts.arrayFrom(necessaryTypeReferences.keys()), getFileReferenceForTypeName) : [];
            }
            function getFileReferenceForTypeName(typeName) {
                // Elide type references for which we have imports
                if (emittedImports) {
                    for (var _i = 0, emittedImports_1 = emittedImports; _i < emittedImports_1.length; _i++) {
                        var importStatement = emittedImports_1[_i];
                        if (ts.isImportEqualsDeclaration(importStatement) && ts.isExternalModuleReference(importStatement.moduleReference)) {
                            var expr = importStatement.moduleReference.expression;
                            if (ts.isStringLiteralLike(expr) && expr.text === typeName) {
                                return undefined;
                            }
                        }
                        else if (ts.isImportDeclaration(importStatement) && ts.isStringLiteral(importStatement.moduleSpecifier) && importStatement.moduleSpecifier.text === typeName) {
                            return undefined;
                        }
                    }
                }
                return { fileName: typeName, pos: -1, end: -1 };
            }
            function mapReferencesIntoArray(references, outputFilePath) {
                return function (file) {
                    var declFileName;
                    if (file.isDeclarationFile) { // Neither decl files or js should have their refs changed
                        declFileName = file.fileName;
                    }
                    else {
                        if (isBundledEmit && ts.contains(node.sourceFiles, file))
                            return; // Omit references to files which are being merged
                        var paths = ts.getOutputPathsFor(file, host, /*forceDtsPaths*/ true);
                        declFileName = paths.declarationFilePath || paths.jsFilePath || file.fileName;
                    }
                    if (declFileName) {
                        var fileName = ts.getRelativePathToDirectoryOrUrl(outputFilePath, declFileName, host.getCurrentDirectory(), host.getCanonicalFileName, 
                        /*isAbsolutePathAnUrl*/ false);
                        if (ts.startsWith(fileName, "./") && ts.hasExtension(fileName)) {
                            fileName = fileName.substring(2);
                        }
                        // omit references to files from node_modules (npm may disambiguate module
                        // references when installing this package, making the path is unreliable).
                        if (ts.startsWith(fileName, "node_modules/") || fileName.indexOf("/node_modules/") !== -1) {
                            return;
                        }
                        references.push({ pos: -1, end: -1, fileName: fileName });
                    }
                };
            }
        }
        function collectReferences(sourceFile, ret) {
            if (noResolve || (!ts.isUnparsedSource(sourceFile) && ts.isSourceFileJS(sourceFile)))
                return ret;
            ts.forEach(sourceFile.referencedFiles, function (f) {
                var elem = ts.tryResolveScriptReference(host, sourceFile, f);
                if (elem) {
                    ret.set("" + ts.getOriginalNodeId(elem), elem);
                }
            });
            return ret;
        }
        function collectLibs(sourceFile, ret) {
            ts.forEach(sourceFile.libReferenceDirectives, function (ref) {
                var lib = host.getLibFileFromReference(ref);
                if (lib) {
                    ret.set(ref.fileName.toLocaleLowerCase(), true);
                }
            });
            return ret;
        }
        function filterBindingPatternInitializers(name) {
            if (name.kind === 73 /* Identifier */) {
                return name;
            }
            else {
                if (name.kind === 186 /* ArrayBindingPattern */) {
                    return ts.updateArrayBindingPattern(name, ts.visitNodes(name.elements, visitBindingElement));
                }
                else {
                    return ts.updateObjectBindingPattern(name, ts.visitNodes(name.elements, visitBindingElement));
                }
            }
            function visitBindingElement(elem) {
                if (elem.kind === 211 /* OmittedExpression */) {
                    return elem;
                }
                return ts.updateBindingElement(elem, elem.dotDotDotToken, elem.propertyName, filterBindingPatternInitializers(elem.name), shouldPrintWithInitializer(elem) ? elem.initializer : undefined);
            }
        }
        function ensureParameter(p, modifierMask) {
            var oldDiag;
            if (!suppressNewDiagnosticContexts) {
                oldDiag = getSymbolAccessibilityDiagnostic;
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(p);
            }
            var newParam = ts.updateParameter(p, 
            /*decorators*/ undefined, maskModifiers(p, modifierMask), p.dotDotDotToken, filterBindingPatternInitializers(p.name), resolver.isOptionalParameter(p) ? (p.questionToken || ts.createToken(56 /* QuestionToken */)) : undefined, ensureType(p, p.type, /*ignorePrivate*/ true), // Ignore private param props, since this type is going straight back into a param
            ensureNoInitializer(p));
            if (!suppressNewDiagnosticContexts) {
                getSymbolAccessibilityDiagnostic = oldDiag;
            }
            return newParam;
        }
        function shouldPrintWithInitializer(node) {
            return canHaveLiteralInitializer(node) && resolver.isLiteralConstDeclaration(ts.getParseTreeNode(node)); // TODO: Make safe
        }
        function ensureNoInitializer(node) {
            if (shouldPrintWithInitializer(node)) {
                return resolver.createLiteralConstValue(ts.getParseTreeNode(node), symbolTracker); // TODO: Make safe
            }
            return undefined;
        }
        function ensureType(node, type, ignorePrivate) {
            if (!ignorePrivate && ts.hasModifier(node, 8 /* Private */)) {
                // Private nodes emit no types (except private parameter properties, whose parameter types are actually visible)
                return;
            }
            if (shouldPrintWithInitializer(node)) {
                // Literal const declarations will have an initializer ensured rather than a type
                return;
            }
            var shouldUseResolverType = node.kind === 152 /* Parameter */ &&
                (resolver.isRequiredInitializedParameter(node) ||
                    resolver.isOptionalUninitializedParameterProperty(node));
            if (type && !shouldUseResolverType) {
                return ts.visitNode(type, visitDeclarationSubtree);
            }
            if (!ts.getParseTreeNode(node)) {
                return type ? ts.visitNode(type, visitDeclarationSubtree) : ts.createKeywordTypeNode(121 /* AnyKeyword */);
            }
            if (node.kind === 160 /* SetAccessor */) {
                // Set accessors with no associated type node (from it's param or get accessor return) are `any` since they are never contextually typed right now
                // (The inferred type here will be void, but the old declaration emitter printed `any`, so this replicates that)
                return ts.createKeywordTypeNode(121 /* AnyKeyword */);
            }
            errorNameNode = node.name;
            var oldDiag;
            if (!suppressNewDiagnosticContexts) {
                oldDiag = getSymbolAccessibilityDiagnostic;
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(node);
            }
            if (node.kind === 238 /* VariableDeclaration */ || node.kind === 187 /* BindingElement */) {
                return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker));
            }
            if (node.kind === 152 /* Parameter */
                || node.kind === 155 /* PropertyDeclaration */
                || node.kind === 154 /* PropertySignature */) {
                if (!node.initializer)
                    return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker, shouldUseResolverType));
                return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker, shouldUseResolverType) || resolver.createTypeOfExpression(node.initializer, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker));
            }
            return cleanup(resolver.createReturnTypeOfSignatureDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker));
            function cleanup(returnValue) {
                errorNameNode = undefined;
                if (!suppressNewDiagnosticContexts) {
                    getSymbolAccessibilityDiagnostic = oldDiag;
                }
                return returnValue || ts.createKeywordTypeNode(121 /* AnyKeyword */);
            }
        }
        function isDeclarationAndNotVisible(node) {
            node = ts.getParseTreeNode(node);
            switch (node.kind) {
                case 240 /* FunctionDeclaration */:
                case 245 /* ModuleDeclaration */:
                case 242 /* InterfaceDeclaration */:
                case 241 /* ClassDeclaration */:
                case 243 /* TypeAliasDeclaration */:
                case 244 /* EnumDeclaration */:
                    return !resolver.isDeclarationVisible(node);
                // The following should be doing their own visibility checks based on filtering their members
                case 238 /* VariableDeclaration */:
                    return !getBindingNameVisible(node);
                case 249 /* ImportEqualsDeclaration */:
                case 250 /* ImportDeclaration */:
                case 256 /* ExportDeclaration */:
                case 255 /* ExportAssignment */:
                    return false;
            }
            return false;
        }
        function getBindingNameVisible(elem) {
            if (ts.isOmittedExpression(elem)) {
                return false;
            }
            if (ts.isBindingPattern(elem.name)) {
                // If any child binding pattern element has been marked visible (usually by collect linked aliases), then this is visible
                return ts.some(elem.name.elements, getBindingNameVisible);
            }
            else {
                return resolver.isDeclarationVisible(elem);
            }
        }
        function updateParamsList(node, params, modifierMask) {
            if (ts.hasModifier(node, 8 /* Private */)) {
                return undefined; // TODO: GH#18217
            }
            var newParams = ts.map(params, function (p) { return ensureParameter(p, modifierMask); });
            if (!newParams) {
                return undefined; // TODO: GH#18217
            }
            return ts.createNodeArray(newParams, params.hasTrailingComma);
        }
        function ensureTypeParams(node, params) {
            return ts.hasModifier(node, 8 /* Private */) ? undefined : ts.visitNodes(params, visitDeclarationSubtree);
        }
        function isEnclosingDeclaration(node) {
            return ts.isSourceFile(node)
                || ts.isTypeAliasDeclaration(node)
                || ts.isModuleDeclaration(node)
                || ts.isClassDeclaration(node)
                || ts.isInterfaceDeclaration(node)
                || ts.isFunctionLike(node)
                || ts.isIndexSignatureDeclaration(node)
                || ts.isMappedTypeNode(node);
        }
        function checkEntityNameVisibility(entityName, enclosingDeclaration) {
            var visibilityResult = resolver.isEntityNameVisible(entityName, enclosingDeclaration);
            handleSymbolAccessibilityError(visibilityResult);
            recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForEntityName(entityName));
        }
        function preserveJsDoc(updated, original) {
            if (ts.hasJSDocNodes(updated) && ts.hasJSDocNodes(original)) {
                updated.jsDoc = original.jsDoc;
            }
            return ts.setCommentRange(updated, ts.getCommentRange(original));
        }
        function rewriteModuleSpecifier(parent, input) {
            if (!input)
                return undefined; // TODO: GH#18217
            resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || (parent.kind !== 245 /* ModuleDeclaration */ && parent.kind !== 184 /* ImportType */);
            if (ts.isStringLiteralLike(input)) {
                if (isBundledEmit) {
                    var newName = ts.getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent);
                    if (newName) {
                        return ts.createLiteral(newName);
                    }
                }
                else {
                    var symbol = resolver.getSymbolOfExternalModuleSpecifier(input);
                    if (symbol) {
                        (exportedModulesFromDeclarationEmit || (exportedModulesFromDeclarationEmit = [])).push(symbol);
                    }
                }
            }
            return input;
        }
        function transformImportEqualsDeclaration(decl) {
            if (!resolver.isDeclarationVisible(decl))
                return;
            if (decl.moduleReference.kind === 260 /* ExternalModuleReference */) {
                // Rewrite external module names if necessary
                var specifier = ts.getExternalModuleImportEqualsDeclarationExpression(decl);
                return ts.updateImportEqualsDeclaration(decl, 
                /*decorators*/ undefined, decl.modifiers, decl.name, ts.updateExternalModuleReference(decl.moduleReference, rewriteModuleSpecifier(decl, specifier)));
            }
            else {
                var oldDiag = getSymbolAccessibilityDiagnostic;
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(decl);
                checkEntityNameVisibility(decl.moduleReference, enclosingDeclaration);
                getSymbolAccessibilityDiagnostic = oldDiag;
                return decl;
            }
        }
        function transformImportDeclaration(decl) {
            if (!decl.importClause) {
                // import "mod" - possibly needed for side effects? (global interface patches, module augmentations, etc)
                return ts.updateImportDeclaration(decl, 
                /*decorators*/ undefined, decl.modifiers, decl.importClause, rewriteModuleSpecifier(decl, decl.moduleSpecifier));
            }
            // The `importClause` visibility corresponds to the default's visibility.
            var visibleDefaultBinding = decl.importClause && decl.importClause.name && resolver.isDeclarationVisible(decl.importClause) ? decl.importClause.name : undefined;
            if (!decl.importClause.namedBindings) {
                // No named bindings (either namespace or list), meaning the import is just default or should be elided
                return visibleDefaultBinding && ts.updateImportDeclaration(decl, /*decorators*/ undefined, decl.modifiers, ts.updateImportClause(decl.importClause, visibleDefaultBinding, 
                /*namedBindings*/ undefined), rewriteModuleSpecifier(decl, decl.moduleSpecifier));
            }
            if (decl.importClause.namedBindings.kind === 252 /* NamespaceImport */) {
                // Namespace import (optionally with visible default)
                var namedBindings = resolver.isDeclarationVisible(decl.importClause.namedBindings) ? decl.importClause.namedBindings : /*namedBindings*/ undefined;
                return visibleDefaultBinding || namedBindings ? ts.updateImportDeclaration(decl, /*decorators*/ undefined, decl.modifiers, ts.updateImportClause(decl.importClause, visibleDefaultBinding, namedBindings), rewriteModuleSpecifier(decl, decl.moduleSpecifier)) : undefined;
            }
            // Named imports (optionally with visible default)
            var bindingList = ts.mapDefined(decl.importClause.namedBindings.elements, function (b) { return resolver.isDeclarationVisible(b) ? b : undefined; });
            if ((bindingList && bindingList.length) || visibleDefaultBinding) {
                return ts.updateImportDeclaration(decl, 
                /*decorators*/ undefined, decl.modifiers, ts.updateImportClause(decl.importClause, visibleDefaultBinding, bindingList && bindingList.length ? ts.updateNamedImports(decl.importClause.namedBindings, bindingList) : undefined), rewriteModuleSpecifier(decl, decl.moduleSpecifier));
            }
            // Nothing visible
        }
        function transformAndReplaceLatePaintedStatements(statements) {
            // This is a `while` loop because `handleSymbolAccessibilityError` can see additional import aliases marked as visible during
            // error handling which must now be included in the output and themselves checked for errors.
            // For example:
            // ```
            // module A {
            //   export module Q {}
            //   import B = Q;
            //   import C = B;
            //   export import D = C;
            // }
            // ```
            // In such a scenario, only Q and D are initially visible, but we don't consider imports as private names - instead we say they if they are referenced they must
            // be recorded. So while checking D's visibility we mark C as visible, then we must check C which in turn marks B, completing the chain of
            // dependent imports and allowing a valid declaration file output. Today, this dependent alias marking only happens for internal import aliases.
            while (ts.length(lateMarkedStatements)) {
                var i = lateMarkedStatements.shift();
                if (!ts.isLateVisibilityPaintedStatement(i)) {
                    return ts.Debug.fail("Late replaced statement was found which is not handled by the declaration transformer!: " + (ts.SyntaxKind ? ts.SyntaxKind[i.kind] : i.kind));
                }
                var priorNeedsDeclare = needsDeclare;
                needsDeclare = i.parent && ts.isSourceFile(i.parent) && !(ts.isExternalModule(i.parent) && isBundledEmit);
                var result = transformTopLevelDeclaration(i, /*privateDeclaration*/ true);
                needsDeclare = priorNeedsDeclare;
                lateStatementReplacementMap.set("" + ts.getOriginalNodeId(i), result);
            }
            // And lastly, we need to get the final form of all those indetermine import declarations from before and add them to the output list
            // (and remove them from the set to examine for outter declarations)
            return ts.visitNodes(statements, visitLateVisibilityMarkedStatements);
            function visitLateVisibilityMarkedStatements(statement) {
                if (ts.isLateVisibilityPaintedStatement(statement)) {
                    var key = "" + ts.getOriginalNodeId(statement);
                    if (lateStatementReplacementMap.has(key)) {
                        var result = lateStatementReplacementMap.get(key);
                        lateStatementReplacementMap.delete(key);
                        if (result && ts.isSourceFile(statement.parent)) {
                            if (ts.isArray(result) ? ts.some(result, needsScopeMarker) : needsScopeMarker(result)) {
                                // Top-level declarations in .d.ts files are always considered exported even without a modifier unless there's an export assignment or specifier
                                needsScopeFixMarker = true;
                            }
                            if (ts.isArray(result) ? ts.some(result, isExternalModuleIndicator) : isExternalModuleIndicator(result)) {
                                resultHasExternalModuleIndicator = true;
                            }
                        }
                        return result;
                    }
                }
                return statement;
            }
        }
        function isExternalModuleIndicator(result) {
            // Exported top-level member indicates moduleness
            return ts.isAnyImportOrReExport(result) || ts.isExportAssignment(result) || ts.hasModifier(result, 1 /* Export */);
        }
        function needsScopeMarker(result) {
            return !ts.isAnyImportOrReExport(result) && !ts.isExportAssignment(result) && !ts.hasModifier(result, 1 /* Export */) && !ts.isAmbientModule(result);
        }
        function visitDeclarationSubtree(input) {
            if (shouldStripInternal(input))
                return;
            if (ts.isDeclaration(input)) {
                if (isDeclarationAndNotVisible(input))
                    return;
                if (ts.hasDynamicName(input) && !resolver.isLateBound(ts.getParseTreeNode(input))) {
                    return;
                }
            }
            // Elide implementation signatures from overload sets
            if (ts.isFunctionLike(input) && resolver.isImplementationOfOverload(input))
                return;
            // Elide semicolon class statements
            if (ts.isSemicolonClassElement(input))
                return;
            var previousEnclosingDeclaration;
            if (isEnclosingDeclaration(input)) {
                previousEnclosingDeclaration = enclosingDeclaration;
                enclosingDeclaration = input;
            }
            var oldDiag = getSymbolAccessibilityDiagnostic;
            // Emit methods which are private as properties with no type information
            if (ts.isMethodDeclaration(input) || ts.isMethodSignature(input)) {
                if (ts.hasModifier(input, 8 /* Private */)) {
                    if (input.symbol && input.symbol.declarations && input.symbol.declarations[0] !== input)
                        return; // Elide all but the first overload
                    return cleanup(ts.createProperty(/*decorators*/ undefined, ensureModifiers(input), input.name, /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined));
                }
            }
            var canProdiceDiagnostic = ts.canProduceDiagnostics(input);
            if (canProdiceDiagnostic && !suppressNewDiagnosticContexts) {
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(input);
            }
            if (ts.isTypeQueryNode(input)) {
                checkEntityNameVisibility(input.exprName, enclosingDeclaration);
            }
            var oldWithinObjectLiteralType = suppressNewDiagnosticContexts;
            var shouldEnterSuppressNewDiagnosticsContextContext = ((input.kind === 169 /* TypeLiteral */ || input.kind === 182 /* MappedType */) && input.parent.kind !== 243 /* TypeAliasDeclaration */);
            if (shouldEnterSuppressNewDiagnosticsContextContext) {
                // We stop making new diagnostic contexts within object literal types. Unless it's an object type on the RHS of a type alias declaration. Then we do.
                suppressNewDiagnosticContexts = true;
            }
            if (isProcessedComponent(input)) {
                switch (input.kind) {
                    case 212 /* ExpressionWithTypeArguments */: {
                        if ((ts.isEntityName(input.expression) || ts.isEntityNameExpression(input.expression))) {
                            checkEntityNameVisibility(input.expression, enclosingDeclaration);
                        }
                        var node = ts.visitEachChild(input, visitDeclarationSubtree, context);
                        return cleanup(ts.updateExpressionWithTypeArguments(node, ts.parenthesizeTypeParameters(node.typeArguments), node.expression));
                    }
                    case 165 /* TypeReference */: {
                        checkEntityNameVisibility(input.typeName, enclosingDeclaration);
                        var node = ts.visitEachChild(input, visitDeclarationSubtree, context);
                        return cleanup(ts.updateTypeReferenceNode(node, node.typeName, ts.parenthesizeTypeParameters(node.typeArguments)));
                    }
                    case 162 /* ConstructSignature */:
                        return cleanup(ts.updateConstructSignature(input, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type)));
                    case 158 /* Constructor */: {
                        var isPrivate = ts.hasModifier(input, 8 /* Private */);
                        // A constructor declaration may not have a type annotation
                        var ctor = ts.createSignatureDeclaration(158 /* Constructor */, isPrivate ? undefined : ensureTypeParams(input, input.typeParameters), 
                        // TODO: GH#18217
                        isPrivate ? undefined : updateParamsList(input, input.parameters, 0 /* None */), 
                        /*type*/ undefined);
                        ctor.modifiers = ts.createNodeArray(ensureModifiers(input));
                        return cleanup(ctor);
                    }
                    case 157 /* MethodDeclaration */: {
                        var sig = ts.createSignatureDeclaration(156 /* MethodSignature */, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type));
                        sig.name = input.name;
                        sig.modifiers = ts.createNodeArray(ensureModifiers(input));
                        sig.questionToken = input.questionToken;
                        return cleanup(sig);
                    }
                    case 159 /* GetAccessor */: {
                        var newNode = ensureAccessor(input);
                        return cleanup(newNode);
                    }
                    case 160 /* SetAccessor */: {
                        var newNode = ensureAccessor(input);
                        return cleanup(newNode);
                    }
                    case 155 /* PropertyDeclaration */:
                        return cleanup(ts.updateProperty(input, 
                        /*decorators*/ undefined, ensureModifiers(input), input.name, input.questionToken, !ts.hasModifier(input, 8 /* Private */) ? ensureType(input, input.type) : undefined, ensureNoInitializer(input)));
                    case 154 /* PropertySignature */:
                        return cleanup(ts.updatePropertySignature(input, ensureModifiers(input), input.name, input.questionToken, !ts.hasModifier(input, 8 /* Private */) ? ensureType(input, input.type) : undefined, ensureNoInitializer(input)));
                    case 156 /* MethodSignature */: {
                        return cleanup(ts.updateMethodSignature(input, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type), input.name, input.questionToken));
                    }
                    case 161 /* CallSignature */: {
                        return cleanup(ts.updateCallSignature(input, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type)));
                    }
                    case 163 /* IndexSignature */: {
                        return cleanup(ts.updateIndexSignature(input, 
                        /*decorators*/ undefined, ensureModifiers(input), updateParamsList(input, input.parameters), ts.visitNode(input.type, visitDeclarationSubtree) || ts.createKeywordTypeNode(121 /* AnyKeyword */)));
                    }
                    case 238 /* VariableDeclaration */: {
                        if (ts.isBindingPattern(input.name)) {
                            return recreateBindingPattern(input.name);
                        }
                        shouldEnterSuppressNewDiagnosticsContextContext = true;
                        suppressNewDiagnosticContexts = true; // Variable declaration types also suppress new diagnostic contexts, provided the contexts wouldn't be made for binding pattern types
                        return cleanup(ts.updateVariableDeclaration(input, input.name, ensureType(input, input.type), ensureNoInitializer(input)));
                    }
                    case 151 /* TypeParameter */: {
                        if (isPrivateMethodTypeParameter(input) && (input.default || input.constraint)) {
                            return cleanup(ts.updateTypeParameterDeclaration(input, input.name, /*constraint*/ undefined, /*defaultType*/ undefined));
                        }
                        return cleanup(ts.visitEachChild(input, visitDeclarationSubtree, context));
                    }
                    case 176 /* ConditionalType */: {
                        // We have to process conditional types in a special way because for visibility purposes we need to push a new enclosingDeclaration
                        // just for the `infer` types in the true branch. It's an implicit declaration scope that only applies to _part_ of the type.
                        var checkType = ts.visitNode(input.checkType, visitDeclarationSubtree);
                        var extendsType = ts.visitNode(input.extendsType, visitDeclarationSubtree);
                        var oldEnclosingDecl = enclosingDeclaration;
                        enclosingDeclaration = input.trueType;
                        var trueType = ts.visitNode(input.trueType, visitDeclarationSubtree);
                        enclosingDeclaration = oldEnclosingDecl;
                        var falseType = ts.visitNode(input.falseType, visitDeclarationSubtree);
                        return cleanup(ts.updateConditionalTypeNode(input, checkType, extendsType, trueType, falseType));
                    }
                    case 166 /* FunctionType */: {
                        return cleanup(ts.updateFunctionTypeNode(input, ts.visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), ts.visitNode(input.type, visitDeclarationSubtree)));
                    }
                    case 167 /* ConstructorType */: {
                        return cleanup(ts.updateConstructorTypeNode(input, ts.visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), ts.visitNode(input.type, visitDeclarationSubtree)));
                    }
                    case 184 /* ImportType */: {
                        if (!ts.isLiteralImportTypeNode(input))
                            return cleanup(input);
                        return cleanup(ts.updateImportTypeNode(input, ts.updateLiteralTypeNode(input.argument, rewriteModuleSpecifier(input, input.argument.literal)), input.qualifier, ts.visitNodes(input.typeArguments, visitDeclarationSubtree, ts.isTypeNode), input.isTypeOf));
                    }
                    default: ts.Debug.assertNever(input, "Attempted to process unhandled node kind: " + ts.SyntaxKind[input.kind]);
                }
            }
            return cleanup(ts.visitEachChild(input, visitDeclarationSubtree, context));
            function cleanup(returnValue) {
                if (returnValue && canProdiceDiagnostic && ts.hasDynamicName(input)) {
                    checkName(input);
                }
                if (isEnclosingDeclaration(input)) {
                    enclosingDeclaration = previousEnclosingDeclaration;
                }
                if (canProdiceDiagnostic && !suppressNewDiagnosticContexts) {
                    getSymbolAccessibilityDiagnostic = oldDiag;
                }
                if (shouldEnterSuppressNewDiagnosticsContextContext) {
                    suppressNewDiagnosticContexts = oldWithinObjectLiteralType;
                }
                if (returnValue === input) {
                    return returnValue;
                }
                return returnValue && ts.setOriginalNode(preserveJsDoc(returnValue, input), input);
            }
        }
        function isPrivateMethodTypeParameter(node) {
            return node.parent.kind === 157 /* MethodDeclaration */ && ts.hasModifier(node.parent, 8 /* Private */);
        }
        function visitDeclarationStatements(input) {
            if (!isPreservedDeclarationStatement(input)) {
                // return undefined for unmatched kinds to omit them from the tree
                return;
            }
            if (shouldStripInternal(input))
                return;
            switch (input.kind) {
                case 256 /* ExportDeclaration */: {
                    if (ts.isSourceFile(input.parent)) {
                        resultHasExternalModuleIndicator = true;
                        resultHasScopeMarker = true;
                    }
                    // Always visible if the parent node isn't dropped for being not visible
                    // Rewrite external module names if necessary
                    return ts.updateExportDeclaration(input, /*decorators*/ undefined, input.modifiers, input.exportClause, rewriteModuleSpecifier(input, input.moduleSpecifier));
                }
                case 255 /* ExportAssignment */: {
                    // Always visible if the parent node isn't dropped for being not visible
                    if (ts.isSourceFile(input.parent)) {
                        resultHasExternalModuleIndicator = true;
                        resultHasScopeMarker = true;
                    }
                    if (input.expression.kind === 73 /* Identifier */) {
                        return input;
                    }
                    else {
                        var newId = ts.createOptimisticUniqueName("_default");
                        getSymbolAccessibilityDiagnostic = function () { return ({
                            diagnosticMessage: ts.Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0,
                            errorNode: input
                        }); };
                        var varDecl = ts.createVariableDeclaration(newId, resolver.createTypeOfExpression(input.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined);
                        var statement = ts.createVariableStatement(needsDeclare ? [ts.createModifier(126 /* DeclareKeyword */)] : [], ts.createVariableDeclarationList([varDecl], 2 /* Const */));
                        return [statement, ts.updateExportAssignment(input, input.decorators, input.modifiers, newId)];
                    }
                }
            }
            var result = transformTopLevelDeclaration(input);
            // Don't actually transform yet; just leave as original node - will be elided/swapped by late pass
            lateStatementReplacementMap.set("" + ts.getOriginalNodeId(input), result);
            return input;
        }
        function transformTopLevelDeclaration(input, isPrivate) {
            if (shouldStripInternal(input))
                return;
            switch (input.kind) {
                case 249 /* ImportEqualsDeclaration */: {
                    return transformImportEqualsDeclaration(input);
                }
                case 250 /* ImportDeclaration */: {
                    return transformImportDeclaration(input);
                }
            }
            if (ts.isDeclaration(input) && isDeclarationAndNotVisible(input))
                return;
            // Elide implementation signatures from overload sets
            if (ts.isFunctionLike(input) && resolver.isImplementationOfOverload(input))
                return;
            var previousEnclosingDeclaration;
            if (isEnclosingDeclaration(input)) {
                previousEnclosingDeclaration = enclosingDeclaration;
                enclosingDeclaration = input;
            }
            var canProdiceDiagnostic = ts.canProduceDiagnostics(input);
            var oldDiag = getSymbolAccessibilityDiagnostic;
            if (canProdiceDiagnostic) {
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(input);
            }
            var previousNeedsDeclare = needsDeclare;
            switch (input.kind) {
                case 243 /* TypeAliasDeclaration */: // Type aliases get `declare`d if need be (for legacy support), but that's all
                    return cleanup(ts.updateTypeAliasDeclaration(input, 
                    /*decorators*/ undefined, ensureModifiers(input, isPrivate), input.name, ts.visitNodes(input.typeParameters, visitDeclarationSubtree, ts.isTypeParameterDeclaration), ts.visitNode(input.type, visitDeclarationSubtree, ts.isTypeNode)));
                case 242 /* InterfaceDeclaration */: {
                    return cleanup(ts.updateInterfaceDeclaration(input, 
                    /*decorators*/ undefined, ensureModifiers(input, isPrivate), input.name, ensureTypeParams(input, input.typeParameters), transformHeritageClauses(input.heritageClauses), ts.visitNodes(input.members, visitDeclarationSubtree)));
                }
                case 240 /* FunctionDeclaration */: {
                    // Generators lose their generator-ness, excepting their return type
                    var clean = cleanup(ts.updateFunctionDeclaration(input, 
                    /*decorators*/ undefined, ensureModifiers(input, isPrivate), 
                    /*asteriskToken*/ undefined, input.name, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type), 
                    /*body*/ undefined));
                    if (clean && resolver.isExpandoFunctionDeclaration(input)) {
                        var props = resolver.getPropertiesOfContainerFunction(input);
                        var fakespace_1 = ts.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, clean.name || ts.createIdentifier("_default"), ts.createModuleBlock([]), 16 /* Namespace */);
                        fakespace_1.flags ^= 8 /* Synthesized */; // unset synthesized so it is usable as an enclosing declaration
                        fakespace_1.parent = enclosingDeclaration;
                        fakespace_1.locals = ts.createSymbolTable(props);
                        fakespace_1.symbol = props[0].parent;
                        var declarations = ts.mapDefined(props, function (p) {
                            if (!ts.isPropertyAccessExpression(p.valueDeclaration)) {
                                return undefined;
                            }
                            getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(p.valueDeclaration);
                            var type = resolver.createTypeOfDeclaration(p.valueDeclaration, fakespace_1, declarationEmitNodeBuilderFlags, symbolTracker);
                            getSymbolAccessibilityDiagnostic = oldDiag;
                            var varDecl = ts.createVariableDeclaration(ts.unescapeLeadingUnderscores(p.escapedName), type, /*initializer*/ undefined);
                            return ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([varDecl]));
                        });
                        var namespaceDecl = ts.createModuleDeclaration(/*decorators*/ undefined, ensureModifiers(input, isPrivate), input.name, ts.createModuleBlock(declarations), 16 /* Namespace */);
                        if (!ts.hasModifier(clean, 512 /* Default */)) {
                            return [clean, namespaceDecl];
                        }
                        var modifiers = ts.createModifiersFromModifierFlags((ts.getModifierFlags(clean) & ~513 /* ExportDefault */) | 2 /* Ambient */);
                        var cleanDeclaration = ts.updateFunctionDeclaration(clean, 
                        /*decorators*/ undefined, modifiers, 
                        /*asteriskToken*/ undefined, clean.name, clean.typeParameters, clean.parameters, clean.type, 
                        /*body*/ undefined);
                        var namespaceDeclaration = ts.updateModuleDeclaration(namespaceDecl, 
                        /*decorators*/ undefined, modifiers, namespaceDecl.name, namespaceDecl.body);
                        var exportDefaultDeclaration = ts.createExportAssignment(
                        /*decorators*/ undefined, 
                        /*modifiers*/ undefined, 
                        /*isExportEquals*/ false, namespaceDecl.name);
                        resultHasExternalModuleIndicator = true;
                        resultHasScopeMarker = true;
                        return [cleanDeclaration, namespaceDeclaration, exportDefaultDeclaration];
                    }
                    else {
                        return clean;
                    }
                }
                case 245 /* ModuleDeclaration */: {
                    needsDeclare = false;
                    var inner = input.body;
                    if (inner && inner.kind === 246 /* ModuleBlock */) {
                        var statements = ts.visitNodes(inner.statements, visitDeclarationStatements);
                        var body = ts.updateModuleBlock(inner, transformAndReplaceLatePaintedStatements(statements));
                        needsDeclare = previousNeedsDeclare;
                        var mods = ensureModifiers(input, isPrivate);
                        return cleanup(ts.updateModuleDeclaration(input, 
                        /*decorators*/ undefined, mods, ts.isExternalModuleAugmentation(input) ? rewriteModuleSpecifier(input, input.name) : input.name, body));
                    }
                    else {
                        needsDeclare = previousNeedsDeclare;
                        var mods = ensureModifiers(input, isPrivate);
                        needsDeclare = false;
                        ts.visitNode(inner, visitDeclarationStatements);
                        // eagerly transform nested namespaces (the nesting doesn't need any elision or painting done)
                        var id = "" + ts.getOriginalNodeId(inner); // TODO: GH#18217
                        var body = lateStatementReplacementMap.get(id);
                        lateStatementReplacementMap.delete(id);
                        return cleanup(ts.updateModuleDeclaration(input, 
                        /*decorators*/ undefined, mods, input.name, body));
                    }
                }
                case 241 /* ClassDeclaration */: {
                    var modifiers = ts.createNodeArray(ensureModifiers(input, isPrivate));
                    var typeParameters = ensureTypeParams(input, input.typeParameters);
                    var ctor = ts.getFirstConstructorWithBody(input);
                    var parameterProperties = void 0;
                    if (ctor) {
                        var oldDiag_1 = getSymbolAccessibilityDiagnostic;
                        parameterProperties = ts.compact(ts.flatMap(ctor.parameters, function (param) {
                            if (!ts.hasModifier(param, 92 /* ParameterPropertyModifier */) || shouldStripInternal(param))
                                return;
                            getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(param);
                            if (param.name.kind === 73 /* Identifier */) {
                                return preserveJsDoc(ts.createProperty(
                                /*decorators*/ undefined, ensureModifiers(param), param.name, param.questionToken, ensureType(param, param.type), ensureNoInitializer(param)), param);
                            }
                            else {
                                // Pattern - this is currently an error, but we emit declarations for it somewhat correctly
                                return walkBindingPattern(param.name);
                            }
                            function walkBindingPattern(pattern) {
                                var elems;
                                for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                                    var elem = _a[_i];
                                    if (ts.isOmittedExpression(elem))
                                        continue;
                                    if (ts.isBindingPattern(elem.name)) {
                                        elems = ts.concatenate(elems, walkBindingPattern(elem.name));
                                    }
                                    elems = elems || [];
                                    elems.push(ts.createProperty(
                                    /*decorators*/ undefined, ensureModifiers(param), elem.name, 
                                    /*questionToken*/ undefined, ensureType(elem, /*type*/ undefined), 
                                    /*initializer*/ undefined));
                                }
                                return elems;
                            }
                        }));
                        getSymbolAccessibilityDiagnostic = oldDiag_1;
                    }
                    var members = ts.createNodeArray(ts.concatenate(parameterProperties, ts.visitNodes(input.members, visitDeclarationSubtree)));
                    var extendsClause_1 = ts.getEffectiveBaseTypeNode(input);
                    if (extendsClause_1 && !ts.isEntityNameExpression(extendsClause_1.expression) && extendsClause_1.expression.kind !== 97 /* NullKeyword */) {
                        // We must add a temporary declaration for the extends clause expression
                        var oldId = input.name ? ts.unescapeLeadingUnderscores(input.name.escapedText) : "default";
                        var newId_1 = ts.createOptimisticUniqueName(oldId + "_base");
                        getSymbolAccessibilityDiagnostic = function () { return ({
                            diagnosticMessage: ts.Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1,
                            errorNode: extendsClause_1,
                            typeName: input.name
                        }); };
                        var varDecl = ts.createVariableDeclaration(newId_1, resolver.createTypeOfExpression(extendsClause_1.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined);
                        var statement = ts.createVariableStatement(needsDeclare ? [ts.createModifier(126 /* DeclareKeyword */)] : [], ts.createVariableDeclarationList([varDecl], 2 /* Const */));
                        var heritageClauses = ts.createNodeArray(ts.map(input.heritageClauses, function (clause) {
                            if (clause.token === 87 /* ExtendsKeyword */) {
                                var oldDiag_2 = getSymbolAccessibilityDiagnostic;
                                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(clause.types[0]);
                                var newClause = ts.updateHeritageClause(clause, ts.map(clause.types, function (t) { return ts.updateExpressionWithTypeArguments(t, ts.visitNodes(t.typeArguments, visitDeclarationSubtree), newId_1); }));
                                getSymbolAccessibilityDiagnostic = oldDiag_2;
                                return newClause;
                            }
                            return ts.updateHeritageClause(clause, ts.visitNodes(ts.createNodeArray(ts.filter(clause.types, function (t) { return ts.isEntityNameExpression(t.expression) || t.expression.kind === 97 /* NullKeyword */; })), visitDeclarationSubtree));
                        }));
                        return [statement, cleanup(ts.updateClassDeclaration(input, 
                            /*decorators*/ undefined, modifiers, input.name, typeParameters, heritageClauses, members))]; // TODO: GH#18217
                    }
                    else {
                        var heritageClauses = transformHeritageClauses(input.heritageClauses);
                        return cleanup(ts.updateClassDeclaration(input, 
                        /*decorators*/ undefined, modifiers, input.name, typeParameters, heritageClauses, members));
                    }
                }
                case 220 /* VariableStatement */: {
                    return cleanup(transformVariableStatement(input, isPrivate));
                }
                case 244 /* EnumDeclaration */: {
                    return cleanup(ts.updateEnumDeclaration(input, /*decorators*/ undefined, ts.createNodeArray(ensureModifiers(input, isPrivate)), input.name, ts.createNodeArray(ts.mapDefined(input.members, function (m) {
                        if (shouldStripInternal(m))
                            return;
                        // Rewrite enum values to their constants, if available
                        var constValue = resolver.getConstantValue(m);
                        return preserveJsDoc(ts.updateEnumMember(m, m.name, constValue !== undefined ? ts.createLiteral(constValue) : undefined), m);
                    }))));
                }
            }
            // Anything left unhandled is an error, so this should be unreachable
            return ts.Debug.assertNever(input, "Unhandled top-level node in declaration emit: " + ts.SyntaxKind[input.kind]);
            function cleanup(node) {
                if (isEnclosingDeclaration(input)) {
                    enclosingDeclaration = previousEnclosingDeclaration;
                }
                if (canProdiceDiagnostic) {
                    getSymbolAccessibilityDiagnostic = oldDiag;
                }
                if (input.kind === 245 /* ModuleDeclaration */) {
                    needsDeclare = previousNeedsDeclare;
                }
                if (node === input) {
                    return node;
                }
                return node && ts.setOriginalNode(preserveJsDoc(node, input), input);
            }
        }
        function transformVariableStatement(input, privateDeclaration) {
            if (!ts.forEach(input.declarationList.declarations, getBindingNameVisible))
                return;
            var nodes = ts.visitNodes(input.declarationList.declarations, visitDeclarationSubtree);
            if (!ts.length(nodes))
                return;
            return ts.updateVariableStatement(input, ts.createNodeArray(ensureModifiers(input, privateDeclaration)), ts.updateVariableDeclarationList(input.declarationList, nodes));
        }
        function recreateBindingPattern(d) {
            return ts.flatten(ts.mapDefined(d.elements, function (e) { return recreateBindingElement(e); }));
        }
        function recreateBindingElement(e) {
            if (e.kind === 211 /* OmittedExpression */) {
                return;
            }
            if (e.name) {
                if (!getBindingNameVisible(e))
                    return;
                if (ts.isBindingPattern(e.name)) {
                    return recreateBindingPattern(e.name);
                }
                else {
                    return ts.createVariableDeclaration(e.name, ensureType(e, /*type*/ undefined), /*initializer*/ undefined);
                }
            }
        }
        function checkName(node) {
            var oldDiag;
            if (!suppressNewDiagnosticContexts) {
                oldDiag = getSymbolAccessibilityDiagnostic;
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNodeName(node);
            }
            errorNameNode = node.name;
            ts.Debug.assert(resolver.isLateBound(ts.getParseTreeNode(node))); // Should only be called with dynamic names
            var decl = node;
            var entityName = decl.name.expression;
            checkEntityNameVisibility(entityName, enclosingDeclaration);
            if (!suppressNewDiagnosticContexts) {
                getSymbolAccessibilityDiagnostic = oldDiag;
            }
            errorNameNode = undefined;
        }
        function shouldStripInternal(node) {
            return !!stripInternal && !!node && isInternalDeclaration(node, currentSourceFile);
        }
        function isScopeMarker(node) {
            return ts.isExportAssignment(node) || ts.isExportDeclaration(node);
        }
        function hasScopeMarker(node) {
            if (ts.isModuleBlock(node)) {
                return ts.some(node.statements, isScopeMarker);
            }
            return false;
        }
        function ensureModifiers(node, privateDeclaration) {
            var currentFlags = ts.getModifierFlags(node);
            var newFlags = ensureModifierFlags(node, privateDeclaration);
            if (currentFlags === newFlags) {
                return node.modifiers;
            }
            return ts.createModifiersFromModifierFlags(newFlags);
        }
        function ensureModifierFlags(node, privateDeclaration) {
            var mask = 3071 /* All */ ^ (4 /* Public */ | 256 /* Async */); // No async modifiers in declaration files
            var additions = (needsDeclare && !isAlwaysType(node)) ? 2 /* Ambient */ : 0 /* None */;
            var parentIsFile = node.parent.kind === 285 /* SourceFile */;
            if (!parentIsFile || (isBundledEmit && parentIsFile && ts.isExternalModule(node.parent))) {
                mask ^= ((privateDeclaration || (isBundledEmit && parentIsFile) || hasScopeMarker(node.parent) ? 0 : 1 /* Export */) | 2 /* Ambient */);
                additions = 0 /* None */;
            }
            return maskModifierFlags(node, mask, additions);
        }
        function ensureAccessor(node) {
            var accessors = resolver.getAllAccessorDeclarations(node);
            if (node.kind !== accessors.firstAccessor.kind) {
                return;
            }
            var accessorType = getTypeAnnotationFromAccessor(node);
            if (!accessorType && accessors.secondAccessor) {
                accessorType = getTypeAnnotationFromAccessor(accessors.secondAccessor);
                // If we end up pulling the type from the second accessor, we also need to change the diagnostic context to get the expected error message
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(accessors.secondAccessor);
            }
            var prop = ts.createProperty(/*decorators*/ undefined, maskModifiers(node, /*mask*/ undefined, (!accessors.setAccessor) ? 64 /* Readonly */ : 0 /* None */), node.name, node.questionToken, ensureType(node, accessorType), /*initializer*/ undefined);
            var leadingsSyntheticCommentRanges = accessors.secondAccessor && ts.getLeadingCommentRangesOfNode(accessors.secondAccessor, currentSourceFile);
            if (leadingsSyntheticCommentRanges) {
                var _loop_13 = function (range) {
                    if (range.kind === 3 /* MultiLineCommentTrivia */) {
                        var text = currentSourceFile.text.slice(range.pos + 2, range.end - 2);
                        var lines = text.split(/\r\n?|\n/g);
                        if (lines.length > 1) {
                            var lastLines = lines.slice(1);
                            var indentation_1 = ts.guessIndentation(lastLines);
                            text = [lines[0]].concat(ts.map(lastLines, function (l) { return l.slice(indentation_1); })).join(newLine);
                        }
                        ts.addSyntheticLeadingComment(prop, range.kind, text, range.hasTrailingNewLine);
                    }
                };
                for (var _i = 0, leadingsSyntheticCommentRanges_1 = leadingsSyntheticCommentRanges; _i < leadingsSyntheticCommentRanges_1.length; _i++) {
                    var range = leadingsSyntheticCommentRanges_1[_i];
                    _loop_13(range);
                }
            }
            return prop;
        }
        function transformHeritageClauses(nodes) {
            return ts.createNodeArray(ts.filter(ts.map(nodes, function (clause) { return ts.updateHeritageClause(clause, ts.visitNodes(ts.createNodeArray(ts.filter(clause.types, function (t) {
                return ts.isEntityNameExpression(t.expression) || (clause.token === 87 /* ExtendsKeyword */ && t.expression.kind === 97 /* NullKeyword */);
            })), visitDeclarationSubtree)); }), function (clause) { return clause.types && !!clause.types.length; }));
        }
    }
    ts.transformDeclarations = transformDeclarations;
    function isAlwaysType(node) {
        if (node.kind === 242 /* InterfaceDeclaration */) {
            return true;
        }
        return false;
    }
    // Elide "public" modifier, as it is the default
    function maskModifiers(node, modifierMask, modifierAdditions) {
        return ts.createModifiersFromModifierFlags(maskModifierFlags(node, modifierMask, modifierAdditions));
    }
    function maskModifierFlags(node, modifierMask, modifierAdditions) {
        if (modifierMask === void 0) { modifierMask = 3071 /* All */ ^ 4 /* Public */; }
        if (modifierAdditions === void 0) { modifierAdditions = 0 /* None */; }
        var flags = (ts.getModifierFlags(node) & modifierMask) | modifierAdditions;
        if (flags & 512 /* Default */ && !(flags & 1 /* Export */)) {
            // A non-exported default is a nonsequitor - we usually try to remove all export modifiers
            // from statements in ambient declarations; but a default export must retain its export modifier to be syntactically valid
            flags ^= 1 /* Export */;
        }
        if (flags & 512 /* Default */ && flags & 2 /* Ambient */) {
            flags ^= 2 /* Ambient */; // `declare` is never required alongside `default` (and would be an error if printed)
        }
        return flags;
    }
    function getTypeAnnotationFromAccessor(accessor) {
        if (accessor) {
            return accessor.kind === 159 /* GetAccessor */
                ? accessor.type // Getter - return type
                : accessor.parameters.length > 0
                    ? accessor.parameters[0].type // Setter parameter type
                    : undefined;
        }
    }
    function canHaveLiteralInitializer(node) {
        switch (node.kind) {
            case 155 /* PropertyDeclaration */:
            case 154 /* PropertySignature */:
                return !ts.hasModifier(node, 8 /* Private */);
            case 152 /* Parameter */:
            case 238 /* VariableDeclaration */:
                return true;
        }
        return false;
    }
    function isPreservedDeclarationStatement(node) {
        switch (node.kind) {
            case 240 /* FunctionDeclaration */:
            case 245 /* ModuleDeclaration */:
            case 249 /* ImportEqualsDeclaration */:
            case 242 /* InterfaceDeclaration */:
            case 241 /* ClassDeclaration */:
            case 243 /* TypeAliasDeclaration */:
            case 244 /* EnumDeclaration */:
            case 220 /* VariableStatement */:
            case 250 /* ImportDeclaration */:
            case 256 /* ExportDeclaration */:
            case 255 /* ExportAssignment */:
                return true;
        }
        return false;
    }
    function isProcessedComponent(node) {
        switch (node.kind) {
            case 162 /* ConstructSignature */:
            case 158 /* Constructor */:
            case 157 /* MethodDeclaration */:
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
            case 155 /* PropertyDeclaration */:
            case 154 /* PropertySignature */:
            case 156 /* MethodSignature */:
            case 161 /* CallSignature */:
            case 163 /* IndexSignature */:
            case 238 /* VariableDeclaration */:
            case 151 /* TypeParameter */:
            case 212 /* ExpressionWithTypeArguments */:
            case 165 /* TypeReference */:
            case 176 /* ConditionalType */:
            case 166 /* FunctionType */:
            case 167 /* ConstructorType */:
            case 184 /* ImportType */:
                return true;
        }
        return false;
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function getModuleTransformer(moduleKind) {
        switch (moduleKind) {
            case ts.ModuleKind.ESNext:
            case ts.ModuleKind.ES2015:
                return ts.transformES2015Module;
            case ts.ModuleKind.System:
                return ts.transformSystemModule;
            default:
                return ts.transformModule;
        }
    }
    var TransformationState;
    (function (TransformationState) {
        TransformationState[TransformationState["Uninitialized"] = 0] = "Uninitialized";
        TransformationState[TransformationState["Initialized"] = 1] = "Initialized";
        TransformationState[TransformationState["Completed"] = 2] = "Completed";
        TransformationState[TransformationState["Disposed"] = 3] = "Disposed";
    })(TransformationState || (TransformationState = {}));
    var SyntaxKindFeatureFlags;
    (function (SyntaxKindFeatureFlags) {
        SyntaxKindFeatureFlags[SyntaxKindFeatureFlags["Substitution"] = 1] = "Substitution";
        SyntaxKindFeatureFlags[SyntaxKindFeatureFlags["EmitNotifications"] = 2] = "EmitNotifications";
    })(SyntaxKindFeatureFlags || (SyntaxKindFeatureFlags = {}));
    ts.noTransformers = { scriptTransformers: ts.emptyArray, declarationTransformers: ts.emptyArray };
    function getTransformers(compilerOptions, customTransformers, emitOnlyDtsFiles) {
        return {
            scriptTransformers: getScriptTransformers(compilerOptions, customTransformers, emitOnlyDtsFiles),
            declarationTransformers: getDeclarationTransformers(customTransformers),
        };
    }
    ts.getTransformers = getTransformers;
    function getScriptTransformers(compilerOptions, customTransformers, emitOnlyDtsFiles) {
        if (emitOnlyDtsFiles)
            return ts.emptyArray;
        var jsx = compilerOptions.jsx;
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        var transformers = [];
        ts.addRange(transformers, customTransformers && ts.map(customTransformers.before, wrapScriptTransformerFactory));
        transformers.push(ts.transformTypeScript);
        if (jsx === 2 /* React */) {
            transformers.push(ts.transformJsx);
        }
        if (languageVersion < 8 /* ESNext */) {
            transformers.push(ts.transformESNext);
        }
        if (languageVersion < 6 /* ES2019 */) {
            transformers.push(ts.transformES2019);
        }
        if (languageVersion < 5 /* ES2018 */) {
            transformers.push(ts.transformES2018);
        }
        if (languageVersion < 4 /* ES2017 */) {
            transformers.push(ts.transformES2017);
        }
        if (languageVersion < 3 /* ES2016 */) {
            transformers.push(ts.transformES2016);
        }
        if (languageVersion < 2 /* ES2015 */) {
            transformers.push(ts.transformES2015);
            transformers.push(ts.transformGenerators);
        }
        transformers.push(getModuleTransformer(moduleKind));
        // The ES5 transformer is last so that it can substitute expressions like `exports.default`
        // for ES3.
        if (languageVersion < 1 /* ES5 */) {
            transformers.push(ts.transformES5);
        }
        ts.addRange(transformers, customTransformers && ts.map(customTransformers.after, wrapScriptTransformerFactory));
        return transformers;
    }
    function getDeclarationTransformers(customTransformers) {
        var transformers = [];
        transformers.push(ts.transformDeclarations);
        ts.addRange(transformers, customTransformers && ts.map(customTransformers.afterDeclarations, wrapDeclarationTransformerFactory));
        return transformers;
    }
    /**
     * Wrap a custom script or declaration transformer object in a `Transformer` callback with fallback support for transforming bundles.
     */
    function wrapCustomTransformer(transformer) {
        return function (node) { return ts.isBundle(node) ? transformer.transformBundle(node) : transformer.transformSourceFile(node); };
    }
    /**
     * Wrap a transformer factory that may return a custom script or declaration transformer object.
     */
    function wrapCustomTransformerFactory(transformer, handleDefault) {
        return function (context) {
            var customTransformer = transformer(context);
            return typeof customTransformer === "function"
                ? handleDefault(customTransformer)
                : wrapCustomTransformer(customTransformer);
        };
    }
    function wrapScriptTransformerFactory(transformer) {
        return wrapCustomTransformerFactory(transformer, ts.chainBundle);
    }
    function wrapDeclarationTransformerFactory(transformer) {
        return wrapCustomTransformerFactory(transformer, ts.identity);
    }
    function noEmitSubstitution(_hint, node) {
        return node;
    }
    ts.noEmitSubstitution = noEmitSubstitution;
    function noEmitNotification(hint, node, callback) {
        callback(hint, node);
    }
    ts.noEmitNotification = noEmitNotification;
    /**
     * Transforms an array of SourceFiles by passing them through each transformer.
     *
     * @param resolver The emit resolver provided by the checker.
     * @param host The emit host object used to interact with the file system.
     * @param options Compiler options to surface in the `TransformationContext`.
     * @param nodes An array of nodes to transform.
     * @param transforms An array of `TransformerFactory` callbacks.
     * @param allowDtsFiles A value indicating whether to allow the transformation of .d.ts files.
     */
    function transformNodes(resolver, host, options, nodes, transformers, allowDtsFiles) {
        var enabledSyntaxKindFeatures = new Array(318 /* Count */);
        var lexicalEnvironmentVariableDeclarations;
        var lexicalEnvironmentFunctionDeclarations;
        var lexicalEnvironmentVariableDeclarationsStack = [];
        var lexicalEnvironmentFunctionDeclarationsStack = [];
        var lexicalEnvironmentStackOffset = 0;
        var lexicalEnvironmentSuspended = false;
        var emitHelpers;
        var onSubstituteNode = noEmitSubstitution;
        var onEmitNode = noEmitNotification;
        var state = 0 /* Uninitialized */;
        var diagnostics = [];
        // The transformation context is provided to each transformer as part of transformer
        // initialization.
        var context = {
            getCompilerOptions: function () { return options; },
            getEmitResolver: function () { return resolver; },
            getEmitHost: function () { return host; },
            startLexicalEnvironment: startLexicalEnvironment,
            suspendLexicalEnvironment: suspendLexicalEnvironment,
            resumeLexicalEnvironment: resumeLexicalEnvironment,
            endLexicalEnvironment: endLexicalEnvironment,
            hoistVariableDeclaration: hoistVariableDeclaration,
            hoistFunctionDeclaration: hoistFunctionDeclaration,
            requestEmitHelper: requestEmitHelper,
            readEmitHelpers: readEmitHelpers,
            enableSubstitution: enableSubstitution,
            enableEmitNotification: enableEmitNotification,
            isSubstitutionEnabled: isSubstitutionEnabled,
            isEmitNotificationEnabled: isEmitNotificationEnabled,
            get onSubstituteNode() { return onSubstituteNode; },
            set onSubstituteNode(value) {
                ts.Debug.assert(state < 1 /* Initialized */, "Cannot modify transformation hooks after initialization has completed.");
                ts.Debug.assert(value !== undefined, "Value must not be 'undefined'");
                onSubstituteNode = value;
            },
            get onEmitNode() { return onEmitNode; },
            set onEmitNode(value) {
                ts.Debug.assert(state < 1 /* Initialized */, "Cannot modify transformation hooks after initialization has completed.");
                ts.Debug.assert(value !== undefined, "Value must not be 'undefined'");
                onEmitNode = value;
            },
            addDiagnostic: function (diag) {
                diagnostics.push(diag);
            }
        };
        // Ensure the parse tree is clean before applying transformations
        for (var _i = 0, nodes_4 = nodes; _i < nodes_4.length; _i++) {
            var node = nodes_4[_i];
            ts.disposeEmitNodes(ts.getSourceFileOfNode(ts.getParseTreeNode(node)));
        }
        ts.performance.mark("beforeTransform");
        // Chain together and initialize each transformer.
        var transformersWithContext = transformers.map(function (t) { return t(context); });
        var transformation = function (node) {
            for (var _i = 0, transformersWithContext_1 = transformersWithContext; _i < transformersWithContext_1.length; _i++) {
                var transform = transformersWithContext_1[_i];
                node = transform(node);
            }
            return node;
        };
        // prevent modification of transformation hooks.
        state = 1 /* Initialized */;
        // Transform each node.
        var transformed = ts.map(nodes, allowDtsFiles ? transformation : transformRoot);
        // prevent modification of the lexical environment.
        state = 2 /* Completed */;
        ts.performance.mark("afterTransform");
        ts.performance.measure("transformTime", "beforeTransform", "afterTransform");
        return {
            transformed: transformed,
            substituteNode: substituteNode,
            emitNodeWithNotification: emitNodeWithNotification,
            dispose: dispose,
            diagnostics: diagnostics
        };
        function transformRoot(node) {
            return node && (!ts.isSourceFile(node) || !node.isDeclarationFile) ? transformation(node) : node;
        }
        /**
         * Enables expression substitutions in the pretty printer for the provided SyntaxKind.
         */
        function enableSubstitution(kind) {
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            enabledSyntaxKindFeatures[kind] |= 1 /* Substitution */;
        }
        /**
         * Determines whether expression substitutions are enabled for the provided node.
         */
        function isSubstitutionEnabled(node) {
            return (enabledSyntaxKindFeatures[node.kind] & 1 /* Substitution */) !== 0
                && (ts.getEmitFlags(node) & 4 /* NoSubstitution */) === 0;
        }
        /**
         * Emits a node with possible substitution.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback The callback used to emit the node or its substitute.
         */
        function substituteNode(hint, node) {
            ts.Debug.assert(state < 3 /* Disposed */, "Cannot substitute a node after the result is disposed.");
            return node && isSubstitutionEnabled(node) && onSubstituteNode(hint, node) || node;
        }
        /**
         * Enables before/after emit notifications in the pretty printer for the provided SyntaxKind.
         */
        function enableEmitNotification(kind) {
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            enabledSyntaxKindFeatures[kind] |= 2 /* EmitNotifications */;
        }
        /**
         * Determines whether before/after emit notifications should be raised in the pretty
         * printer when it emits a node.
         */
        function isEmitNotificationEnabled(node) {
            return (enabledSyntaxKindFeatures[node.kind] & 2 /* EmitNotifications */) !== 0
                || (ts.getEmitFlags(node) & 2 /* AdviseOnEmitNode */) !== 0;
        }
        /**
         * Emits a node with possible emit notification.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback The callback used to emit the node.
         */
        function emitNodeWithNotification(hint, node, emitCallback) {
            ts.Debug.assert(state < 3 /* Disposed */, "Cannot invoke TransformationResult callbacks after the result is disposed.");
            if (node) {
                if (isEmitNotificationEnabled(node)) {
                    onEmitNode(hint, node, emitCallback);
                }
                else {
                    emitCallback(hint, node);
                }
            }
        }
        /**
         * Records a hoisted variable declaration for the provided name within a lexical environment.
         */
        function hoistVariableDeclaration(name) {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            var decl = ts.setEmitFlags(ts.createVariableDeclaration(name), 64 /* NoNestedSourceMaps */);
            if (!lexicalEnvironmentVariableDeclarations) {
                lexicalEnvironmentVariableDeclarations = [decl];
            }
            else {
                lexicalEnvironmentVariableDeclarations.push(decl);
            }
        }
        /**
         * Records a hoisted function declaration within a lexical environment.
         */
        function hoistFunctionDeclaration(func) {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            if (!lexicalEnvironmentFunctionDeclarations) {
                lexicalEnvironmentFunctionDeclarations = [func];
            }
            else {
                lexicalEnvironmentFunctionDeclarations.push(func);
            }
        }
        /**
         * Starts a new lexical environment. Any existing hoisted variable or function declarations
         * are pushed onto a stack, and the related storage variables are reset.
         */
        function startLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
            // Save the current lexical environment. Rather than resizing the array we adjust the
            // stack size variable. This allows us to reuse existing array slots we've
            // already allocated between transformations to avoid allocation and GC overhead during
            // transformation.
            lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentVariableDeclarations;
            lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentFunctionDeclarations;
            lexicalEnvironmentStackOffset++;
            lexicalEnvironmentVariableDeclarations = undefined;
            lexicalEnvironmentFunctionDeclarations = undefined;
        }
        /** Suspends the current lexical environment, usually after visiting a parameter list. */
        function suspendLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is already suspended.");
            lexicalEnvironmentSuspended = true;
        }
        /** Resumes a suspended lexical environment, usually before visiting a function body. */
        function resumeLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(lexicalEnvironmentSuspended, "Lexical environment is not suspended.");
            lexicalEnvironmentSuspended = false;
        }
        /**
         * Ends a lexical environment. The previous set of hoisted declarations are restored and
         * any hoisted declarations added in this environment are returned.
         */
        function endLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
            var statements;
            if (lexicalEnvironmentVariableDeclarations || lexicalEnvironmentFunctionDeclarations) {
                if (lexicalEnvironmentFunctionDeclarations) {
                    statements = lexicalEnvironmentFunctionDeclarations.slice();
                }
                if (lexicalEnvironmentVariableDeclarations) {
                    var statement = ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList(lexicalEnvironmentVariableDeclarations));
                    ts.setEmitFlags(statement, 1048576 /* CustomPrologue */);
                    if (!statements) {
                        statements = [statement];
                    }
                    else {
                        statements.push(statement);
                    }
                }
            }
            // Restore the previous lexical environment.
            lexicalEnvironmentStackOffset--;
            lexicalEnvironmentVariableDeclarations = lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset];
            lexicalEnvironmentFunctionDeclarations = lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset];
            if (lexicalEnvironmentStackOffset === 0) {
                lexicalEnvironmentVariableDeclarationsStack = [];
                lexicalEnvironmentFunctionDeclarationsStack = [];
            }
            return statements;
        }
        function requestEmitHelper(helper) {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the transformation context during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            ts.Debug.assert(!helper.scoped, "Cannot request a scoped emit helper.");
            emitHelpers = ts.append(emitHelpers, helper);
        }
        function readEmitHelpers() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the transformation context during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            var helpers = emitHelpers;
            emitHelpers = undefined;
            return helpers;
        }
        function dispose() {
            if (state < 3 /* Disposed */) {
                // Clean up emit nodes on parse tree
                for (var _i = 0, nodes_5 = nodes; _i < nodes_5.length; _i++) {
                    var node = nodes_5[_i];
                    ts.disposeEmitNodes(ts.getSourceFileOfNode(ts.getParseTreeNode(node)));
                }
                // Release references to external entries for GC purposes.
                lexicalEnvironmentVariableDeclarations = undefined;
                lexicalEnvironmentVariableDeclarationsStack = undefined;
                lexicalEnvironmentFunctionDeclarations = undefined;
                lexicalEnvironmentFunctionDeclarationsStack = undefined;
                onSubstituteNode = undefined;
                onEmitNode = undefined;
                emitHelpers = undefined;
                // Prevent further use of the transformation result.
                state = 3 /* Disposed */;
            }
        }
    }
    ts.transformNodes = transformNodes;
})(ts || (ts = {}));
var ts;
(function (ts) {
    var brackets = createBracketsMap();
    var syntheticParent = { pos: -1, end: -1 };
    /*@internal*/
    function isBuildInfoFile(file) {
        return ts.fileExtensionIs(file, ".tsbuildinfo" /* TsBuildInfo */);
    }
    ts.isBuildInfoFile = isBuildInfoFile;
    /*@internal*/
    /**
     * Iterates over the source files that are expected to have an emit output.
     *
     * @param host An EmitHost.
     * @param action The action to execute.
     * @param sourceFilesOrTargetSourceFile
     *   If an array, the full list of source files to emit.
     *   Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit.
     */
    function forEachEmittedFile(host, action, sourceFilesOrTargetSourceFile, emitOnlyDtsFiles, onlyBuildInfo, includeBuildInfo) {
        if (emitOnlyDtsFiles === void 0) { emitOnlyDtsFiles = false; }
        var sourceFiles = ts.isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : ts.getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile);
        var options = host.getCompilerOptions();
        if (options.outFile || options.out) {
            var prepends = host.getPrependNodes();
            if (sourceFiles.length || prepends.length) {
                var bundle = ts.createBundle(sourceFiles, prepends);
                var result = action(getOutputPathsFor(bundle, host, emitOnlyDtsFiles), bundle);
                if (result) {
                    return result;
                }
            }
        }
        else {
            if (!onlyBuildInfo) {
                for (var _a = 0, sourceFiles_1 = sourceFiles; _a < sourceFiles_1.length; _a++) {
                    var sourceFile = sourceFiles_1[_a];
                    var result = action(getOutputPathsFor(sourceFile, host, emitOnlyDtsFiles), sourceFile);
                    if (result) {
                        return result;
                    }
                }
            }
            if (includeBuildInfo) {
                var buildInfoPath = getOutputPathForBuildInfo(host.getCompilerOptions());
                if (buildInfoPath)
                    return action({ buildInfoPath: buildInfoPath }, /*sourceFileOrBundle*/ undefined);
            }
        }
    }
    ts.forEachEmittedFile = forEachEmittedFile;
    /*@internal*/
    function getOutputPathForBuildInfo(options) {
        var configFile = options.configFilePath;
        if (!ts.isIncrementalCompilation(options))
            return undefined;
        if (options.tsBuildInfoFile)
            return options.tsBuildInfoFile;
        var outPath = options.outFile || options.out;
        var buildInfoExtensionLess;
        if (outPath) {
            buildInfoExtensionLess = ts.removeFileExtension(outPath);
        }
        else {
            if (!configFile)
                return undefined;
            var configFileExtensionLess = ts.removeFileExtension(configFile);
            buildInfoExtensionLess = options.outDir ?
                options.rootDir ?
                    ts.resolvePath(options.outDir, ts.getRelativePathFromDirectory(options.rootDir, configFileExtensionLess, /*ignoreCase*/ true)) :
                    ts.combinePaths(options.outDir, ts.getBaseFileName(configFileExtensionLess)) :
                configFileExtensionLess;
        }
        return buildInfoExtensionLess + ".tsbuildinfo" /* TsBuildInfo */;
    }
    ts.getOutputPathForBuildInfo = getOutputPathForBuildInfo;
    /*@internal*/
    function getOutputPathsForBundle(options, forceDtsPaths) {
        var outPath = options.outFile || options.out;
        var jsFilePath = options.emitDeclarationOnly ? undefined : outPath;
        var sourceMapFilePath = jsFilePath && getSourceMapFilePath(jsFilePath, options);
        var declarationFilePath = (forceDtsPaths || ts.getEmitDeclarations(options)) ? ts.removeFileExtension(outPath) + ".d.ts" /* Dts */ : undefined;
        var declarationMapPath = declarationFilePath && ts.getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
        var buildInfoPath = getOutputPathForBuildInfo(options);
        return { jsFilePath: jsFilePath, sourceMapFilePath: sourceMapFilePath, declarationFilePath: declarationFilePath, declarationMapPath: declarationMapPath, buildInfoPath: buildInfoPath };
    }
    ts.getOutputPathsForBundle = getOutputPathsForBundle;
    /*@internal*/
    function getOutputPathsFor(sourceFile, host, forceDtsPaths) {
        var options = host.getCompilerOptions();
        if (sourceFile.kind === 286 /* Bundle */) {
            return getOutputPathsForBundle(options, forceDtsPaths);
        }
        else {
            var ownOutputFilePath = ts.getOwnEmitOutputFilePath(sourceFile.fileName, host, getOutputExtension(sourceFile, options));
            // If json file emits to the same location skip writing it, if emitDeclarationOnly skip writing it
            var isJsonEmittedToSameLocation = ts.isJsonSourceFile(sourceFile) &&
                ts.comparePaths(sourceFile.fileName, ownOutputFilePath, host.getCurrentDirectory(), !host.useCaseSensitiveFileNames()) === 0 /* EqualTo */;
            var jsFilePath = options.emitDeclarationOnly || isJsonEmittedToSameLocation ? undefined : ownOutputFilePath;
            var sourceMapFilePath = !jsFilePath || ts.isJsonSourceFile(sourceFile) ? undefined : getSourceMapFilePath(jsFilePath, options);
            // For legacy reasons (ie, we have baselines capturing the behavior), js files don't report a .d.ts output path - this would only matter if `declaration` and `allowJs` were both on, which is currently an error
            var isJs = ts.isSourceFileJS(sourceFile);
            var declarationFilePath = ((forceDtsPaths || ts.getEmitDeclarations(options)) && !isJs) ? ts.getDeclarationEmitOutputFilePath(sourceFile.fileName, host) : undefined;
            var declarationMapPath = declarationFilePath && ts.getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
            return { jsFilePath: jsFilePath, sourceMapFilePath: sourceMapFilePath, declarationFilePath: declarationFilePath, declarationMapPath: declarationMapPath, buildInfoPath: undefined };
        }
    }
    ts.getOutputPathsFor = getOutputPathsFor;
    function getSourceMapFilePath(jsFilePath, options) {
        return (options.sourceMap && !options.inlineSourceMap) ? jsFilePath + ".map" : undefined;
    }
    // JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also.
    // So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve.
    // For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve
    /* @internal */
    function getOutputExtension(sourceFile, options) {
        if (ts.isJsonSourceFile(sourceFile)) {
            return ".json" /* Json */;
        }
        if (options.jsx === 1 /* Preserve */) {
            if (ts.isSourceFileJS(sourceFile)) {
                if (ts.fileExtensionIs(sourceFile.fileName, ".jsx" /* Jsx */)) {
                    return ".jsx" /* Jsx */;
                }
            }
            else if (sourceFile.languageVariant === 1 /* JSX */) {
                // TypeScript source file preserving JSX syntax
                return ".jsx" /* Jsx */;
            }
        }
        return ".js" /* Js */;
    }
    ts.getOutputExtension = getOutputExtension;
    function rootDirOfOptions(configFile) {
        return configFile.options.rootDir || ts.getDirectoryPath(ts.Debug.assertDefined(configFile.options.configFilePath));
    }
    function getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, outputDir) {
        return outputDir ?
            ts.resolvePath(outputDir, ts.getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase)) :
            inputFileName;
    }
    /* @internal */
    function getOutputDeclarationFileName(inputFileName, configFile, ignoreCase) {
        ts.Debug.assert(!ts.fileExtensionIs(inputFileName, ".d.ts" /* Dts */) && ts.hasTSFileExtension(inputFileName));
        return ts.changeExtension(getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.declarationDir || configFile.options.outDir), ".d.ts" /* Dts */);
    }
    ts.getOutputDeclarationFileName = getOutputDeclarationFileName;
    function getOutputJSFileName(inputFileName, configFile, ignoreCase) {
        var isJsonFile = ts.fileExtensionIs(inputFileName, ".json" /* Json */);
        var outputFileName = ts.changeExtension(getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.outDir), isJsonFile ?
            ".json" /* Json */ :
            ts.fileExtensionIs(inputFileName, ".tsx" /* Tsx */) && configFile.options.jsx === 1 /* Preserve */ ?
                ".jsx" /* Jsx */ :
                ".js" /* Js */);
        return !isJsonFile || ts.comparePaths(inputFileName, outputFileName, ts.Debug.assertDefined(configFile.options.configFilePath), ignoreCase) !== 0 /* EqualTo */ ?
            outputFileName :
            undefined;
    }
    /*@internal*/
    function getAllProjectOutputs(configFile, ignoreCase) {
        var outputs;
        var addOutput = function (path) { return path && (outputs || (outputs = [])).push(path); };
        if (configFile.options.outFile || configFile.options.out) {
            var _a = getOutputPathsForBundle(configFile.options, /*forceDtsPaths*/ false), jsFilePath = _a.jsFilePath, sourceMapFilePath = _a.sourceMapFilePath, declarationFilePath = _a.declarationFilePath, declarationMapPath = _a.declarationMapPath, buildInfoPath = _a.buildInfoPath;
            addOutput(jsFilePath);
            addOutput(sourceMapFilePath);
            addOutput(declarationFilePath);
            addOutput(declarationMapPath);
            addOutput(buildInfoPath);
        }
        else {
            for (var _b = 0, _c = configFile.fileNames; _b < _c.length; _b++) {
                var inputFileName = _c[_b];
                if (ts.fileExtensionIs(inputFileName, ".d.ts" /* Dts */))
                    continue;
                var js = getOutputJSFileName(inputFileName, configFile, ignoreCase);
                addOutput(js);
                if (ts.fileExtensionIs(inputFileName, ".json" /* Json */))
                    continue;
                if (configFile.options.sourceMap) {
                    addOutput(js + ".map");
                }
                if (ts.getEmitDeclarations(configFile.options) && ts.hasTSFileExtension(inputFileName)) {
                    var dts = getOutputDeclarationFileName(inputFileName, configFile, ignoreCase);
                    addOutput(dts);
                    if (configFile.options.declarationMap) {
                        addOutput(dts + ".map");
                    }
                }
            }
            addOutput(getOutputPathForBuildInfo(configFile.options));
        }
        return outputs || ts.emptyArray;
    }
    ts.getAllProjectOutputs = getAllProjectOutputs;
    /*@internal*/
    function getFirstProjectOutput(configFile, ignoreCase) {
        if (configFile.options.outFile || configFile.options.out) {
            var jsFilePath = getOutputPathsForBundle(configFile.options, /*forceDtsPaths*/ false).jsFilePath;
            return ts.Debug.assertDefined(jsFilePath, "project " + configFile.options.configFilePath + " expected to have at least one output");
        }
        for (var _a = 0, _b = configFile.fileNames; _a < _b.length; _a++) {
            var inputFileName = _b[_a];
            if (ts.fileExtensionIs(inputFileName, ".d.ts" /* Dts */))
                continue;
            var jsFilePath = getOutputJSFileName(inputFileName, configFile, ignoreCase);
            if (jsFilePath)
                return jsFilePath;
        }
        var buildInfoPath = getOutputPathForBuildInfo(configFile.options);
        if (buildInfoPath)
            return buildInfoPath;
        return ts.Debug.fail("project " + configFile.options.configFilePath + " expected to have at least one output");
    }
    ts.getFirstProjectOutput = getFirstProjectOutput;
    /*@internal*/
    // targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
    function emitFiles(resolver, host, targetSourceFile, _a, emitOnlyDtsFiles, onlyBuildInfo) {
        var scriptTransformers = _a.scriptTransformers, declarationTransformers = _a.declarationTransformers;
        var compilerOptions = host.getCompilerOptions();
        var sourceMapDataList = (compilerOptions.sourceMap || compilerOptions.inlineSourceMap || ts.getAreDeclarationMapsEnabled(compilerOptions)) ? [] : undefined;
        var emittedFilesList = compilerOptions.listEmittedFiles ? [] : undefined;
        var emitterDiagnostics = ts.createDiagnosticCollection();
        var newLine = ts.getNewLineCharacter(compilerOptions, function () { return host.getNewLine(); });
        var writer = ts.createTextWriter(newLine);
        var _b = ts.performance.createTimer("printTime", "beforePrint", "afterPrint"), enter = _b.enter, exit = _b.exit;
        var bundleBuildInfo;
        var emitSkipped = false;
        var exportedModulesFromDeclarationEmit;
        // Emit each output file
        enter();
        forEachEmittedFile(host, emitSourceFileOrBundle, ts.getSourceFilesToEmit(host, targetSourceFile), emitOnlyDtsFiles, onlyBuildInfo, !targetSourceFile);
        exit();
        return {
            emitSkipped: emitSkipped,
            diagnostics: emitterDiagnostics.getDiagnostics(),
            emittedFiles: emittedFilesList,
            sourceMaps: sourceMapDataList,
            exportedModulesFromDeclarationEmit: exportedModulesFromDeclarationEmit
        };
        function emitSourceFileOrBundle(_a, sourceFileOrBundle) {
            var jsFilePath = _a.jsFilePath, sourceMapFilePath = _a.sourceMapFilePath, declarationFilePath = _a.declarationFilePath, declarationMapPath = _a.declarationMapPath, buildInfoPath = _a.buildInfoPath;
            if (buildInfoPath && sourceFileOrBundle && ts.isBundle(sourceFileOrBundle)) {
                bundleBuildInfo = {
                    commonSourceDirectory: host.getCommonSourceDirectory(),
                    sourceFiles: sourceFileOrBundle.sourceFiles.map(function (file) { return file.fileName; })
                };
            }
            emitJsFileOrBundle(sourceFileOrBundle, jsFilePath, sourceMapFilePath);
            emitDeclarationFileOrBundle(sourceFileOrBundle, declarationFilePath, declarationMapPath);
            emitBuildInfo(bundleBuildInfo, buildInfoPath);
            if (!emitSkipped && emittedFilesList) {
                if (!emitOnlyDtsFiles) {
                    if (jsFilePath) {
                        emittedFilesList.push(jsFilePath);
                    }
                    if (sourceMapFilePath) {
                        emittedFilesList.push(sourceMapFilePath);
                    }
                    if (buildInfoPath) {
                        emittedFilesList.push(buildInfoPath);
                    }
                }
                if (declarationFilePath) {
                    emittedFilesList.push(declarationFilePath);
                }
                if (declarationMapPath) {
                    emittedFilesList.push(declarationMapPath);
                }
            }
        }
        function emitBuildInfo(bundle, buildInfoPath) {
            // Write build information if applicable
            if (!buildInfoPath || targetSourceFile || emitSkipped)
                return;
            var program = host.getProgramBuildInfo();
            if (!bundle && !program)
                return;
            if (host.isEmitBlocked(buildInfoPath) || compilerOptions.noEmit) {
                emitSkipped = true;
                return;
            }
            ts.writeFile(host, emitterDiagnostics, buildInfoPath, getBuildInfoText({ bundle: bundle, program: program, version: ts.version }), /*writeByteOrderMark*/ false);
        }
        function emitJsFileOrBundle(sourceFileOrBundle, jsFilePath, sourceMapFilePath) {
            if (!sourceFileOrBundle || emitOnlyDtsFiles || !jsFilePath) {
                return;
            }
            // Make sure not to write js file and source map file if any of them cannot be written
            if ((jsFilePath && host.isEmitBlocked(jsFilePath)) || compilerOptions.noEmit) {
                emitSkipped = true;
                return;
            }
            // Transform the source files
            var transform = ts.transformNodes(resolver, host, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false);
            var printerOptions = {
                removeComments: compilerOptions.removeComments,
                newLine: compilerOptions.newLine,
                noEmitHelpers: compilerOptions.noEmitHelpers,
                module: compilerOptions.module,
                target: compilerOptions.target,
                sourceMap: compilerOptions.sourceMap,
                inlineSourceMap: compilerOptions.inlineSourceMap,
                inlineSources: compilerOptions.inlineSources,
                extendedDiagnostics: compilerOptions.extendedDiagnostics,
                writeBundleFileInfo: !!bundleBuildInfo
            };
            // Create a printer to print the nodes
            var printer = createPrinter(printerOptions, {
                // resolver hooks
                hasGlobalName: resolver.hasGlobalName,
                // transform hooks
                onEmitNode: transform.emitNodeWithNotification,
                substituteNode: transform.substituteNode,
            });
            ts.Debug.assert(transform.transformed.length === 1, "Should only see one output from the transform");
            printSourceFileOrBundle(jsFilePath, sourceMapFilePath, transform.transformed[0], printer, compilerOptions);
            // Clean up emit nodes on parse tree
            transform.dispose();
            if (bundleBuildInfo)
                bundleBuildInfo.js = printer.bundleFileInfo;
        }
        function emitDeclarationFileOrBundle(sourceFileOrBundle, declarationFilePath, declarationMapPath) {
            if (!sourceFileOrBundle || !(declarationFilePath && !ts.isInJSFile(sourceFileOrBundle))) {
                return;
            }
            var sourceFiles = ts.isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : sourceFileOrBundle.sourceFiles;
            // Setup and perform the transformation to retrieve declarations from the input files
            var nonJsFiles = ts.filter(sourceFiles, ts.isSourceFileNotJS);
            var inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [ts.createBundle(nonJsFiles, !ts.isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : nonJsFiles;
            if (emitOnlyDtsFiles && !ts.getEmitDeclarations(compilerOptions)) {
                // Checker wont collect the linked aliases since thats only done when declaration is enabled.
                // Do that here when emitting only dts files
                nonJsFiles.forEach(collectLinkedAliases);
            }
            var declarationTransform = ts.transformNodes(resolver, host, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false);
            if (ts.length(declarationTransform.diagnostics)) {
                for (var _a = 0, _b = declarationTransform.diagnostics; _a < _b.length; _a++) {
                    var diagnostic = _b[_a];
                    emitterDiagnostics.add(diagnostic);
                }
            }
            var printerOptions = {
                removeComments: compilerOptions.removeComments,
                newLine: compilerOptions.newLine,
                noEmitHelpers: true,
                module: compilerOptions.module,
                target: compilerOptions.target,
                sourceMap: compilerOptions.sourceMap,
                inlineSourceMap: compilerOptions.inlineSourceMap,
                extendedDiagnostics: compilerOptions.extendedDiagnostics,
                onlyPrintJsDocStyle: true,
                writeBundleFileInfo: !!bundleBuildInfo,
                recordInternalSection: !!bundleBuildInfo
            };
            var declarationPrinter = createPrinter(printerOptions, {
                // resolver hooks
                hasGlobalName: resolver.hasGlobalName,
                // transform hooks
                onEmitNode: declarationTransform.emitNodeWithNotification,
                substituteNode: declarationTransform.substituteNode,
            });
            var declBlocked = (!!declarationTransform.diagnostics && !!declarationTransform.diagnostics.length) || !!host.isEmitBlocked(declarationFilePath) || !!compilerOptions.noEmit;
            emitSkipped = emitSkipped || declBlocked;
            if (!declBlocked || emitOnlyDtsFiles) {
                ts.Debug.assert(declarationTransform.transformed.length === 1, "Should only see one output from the decl transform");
                printSourceFileOrBundle(declarationFilePath, declarationMapPath, declarationTransform.transformed[0], declarationPrinter, {
                    sourceMap: compilerOptions.declarationMap,
                    sourceRoot: compilerOptions.sourceRoot,
                    mapRoot: compilerOptions.mapRoot,
                    extendedDiagnostics: compilerOptions.extendedDiagnostics,
                });
                if (emitOnlyDtsFiles && declarationTransform.transformed[0].kind === 285 /* SourceFile */) {
                    var sourceFile = declarationTransform.transformed[0];
                    exportedModulesFromDeclarationEmit = sourceFile.exportedModulesFromDeclarationEmit;
                }
            }
            declarationTransform.dispose();
            if (bundleBuildInfo)
                bundleBuildInfo.dts = declarationPrinter.bundleFileInfo;
        }
        function collectLinkedAliases(node) {
            if (ts.isExportAssignment(node)) {
                if (node.expression.kind === 73 /* Identifier */) {
                    resolver.collectLinkedAliases(node.expression, /*setVisibility*/ true);
                }
                return;
            }
            else if (ts.isExportSpecifier(node)) {
                resolver.collectLinkedAliases(node.propertyName || node.name, /*setVisibility*/ true);
                return;
            }
            ts.forEachChild(node, collectLinkedAliases);
        }
        function printSourceFileOrBundle(jsFilePath, sourceMapFilePath, sourceFileOrBundle, printer, mapOptions) {
            var bundle = sourceFileOrBundle.kind === 286 /* Bundle */ ? sourceFileOrBundle : undefined;
            var sourceFile = sourceFileOrBundle.kind === 285 /* SourceFile */ ? sourceFileOrBundle : undefined;
            var sourceFiles = bundle ? bundle.sourceFiles : [sourceFile];
            var sourceMapGenerator;
            if (shouldEmitSourceMaps(mapOptions, sourceFileOrBundle)) {
                sourceMapGenerator = ts.createSourceMapGenerator(host, ts.getBaseFileName(ts.normalizeSlashes(jsFilePath)), getSourceRoot(mapOptions), getSourceMapDirectory(mapOptions, jsFilePath, sourceFile), mapOptions);
            }
            if (bundle) {
                printer.writeBundle(bundle, writer, sourceMapGenerator);
            }
            else {
                printer.writeFile(sourceFile, writer, sourceMapGenerator);
            }
            if (sourceMapGenerator) {
                if (sourceMapDataList) {
                    sourceMapDataList.push({
                        inputSourceFileNames: sourceMapGenerator.getSources(),
                        sourceMap: sourceMapGenerator.toJSON()
                    });
                }
                var sourceMappingURL = getSourceMappingURL(mapOptions, sourceMapGenerator, jsFilePath, sourceMapFilePath, sourceFile);
                if (sourceMappingURL) {
                    if (!writer.isAtStartOfLine())
                        writer.rawWrite(newLine);
                    writer.writeComment("//# " + "sourceMappingURL" + "=" + sourceMappingURL); // Tools can sometimes see this line as a source mapping url comment
                }
                // Write the source map
                if (sourceMapFilePath) {
                    var sourceMap = sourceMapGenerator.toString();
                    ts.writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap, /*writeByteOrderMark*/ false, sourceFiles);
                }
            }
            else {
                writer.writeLine();
            }
            // Write the output file
            ts.writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), !!compilerOptions.emitBOM, sourceFiles);
            // Reset state
            writer.clear();
        }
        function shouldEmitSourceMaps(mapOptions, sourceFileOrBundle) {
            return (mapOptions.sourceMap || mapOptions.inlineSourceMap)
                && (sourceFileOrBundle.kind !== 285 /* SourceFile */ || !ts.fileExtensionIs(sourceFileOrBundle.fileName, ".json" /* Json */));
        }
        function getSourceRoot(mapOptions) {
            // Normalize source root and make sure it has trailing "/" so that it can be used to combine paths with the
            // relative paths of the sources list in the sourcemap
            var sourceRoot = ts.normalizeSlashes(mapOptions.sourceRoot || "");
            return sourceRoot ? ts.ensureTrailingDirectorySeparator(sourceRoot) : sourceRoot;
        }
        function getSourceMapDirectory(mapOptions, filePath, sourceFile) {
            if (mapOptions.sourceRoot)
                return host.getCommonSourceDirectory();
            if (mapOptions.mapRoot) {
                var sourceMapDir = ts.normalizeSlashes(mapOptions.mapRoot);
                if (sourceFile) {
                    // For modules or multiple emit files the mapRoot will have directory structure like the sources
                    // So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
                    sourceMapDir = ts.getDirectoryPath(ts.getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
                }
                if (ts.getRootLength(sourceMapDir) === 0) {
                    // The relative paths are relative to the common directory
                    sourceMapDir = ts.combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
                }
                return sourceMapDir;
            }
            return ts.getDirectoryPath(ts.normalizePath(filePath));
        }
        function getSourceMappingURL(mapOptions, sourceMapGenerator, filePath, sourceMapFilePath, sourceFile) {
            if (mapOptions.inlineSourceMap) {
                // Encode the sourceMap into the sourceMap url
                var sourceMapText = sourceMapGenerator.toString();
                var base64SourceMapText = ts.base64encode(ts.sys, sourceMapText);
                return "data:application/json;base64," + base64SourceMapText;
            }
            var sourceMapFile = ts.getBaseFileName(ts.normalizeSlashes(ts.Debug.assertDefined(sourceMapFilePath)));
            if (mapOptions.mapRoot) {
                var sourceMapDir = ts.normalizeSlashes(mapOptions.mapRoot);
                if (sourceFile) {
                    // For modules or multiple emit files the mapRoot will have directory structure like the sources
                    // So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
                    sourceMapDir = ts.getDirectoryPath(ts.getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
                }
                if (ts.getRootLength(sourceMapDir) === 0) {
                    // The relative paths are relative to the common directory
                    sourceMapDir = ts.combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
                    return ts.getRelativePathToDirectoryOrUrl(ts.getDirectoryPath(ts.normalizePath(filePath)), // get the relative sourceMapDir path based on jsFilePath
                    ts.combinePaths(sourceMapDir, sourceMapFile), // this is where user expects to see sourceMap
                    host.getCurrentDirectory(), host.getCanonicalFileName, 
                    /*isAbsolutePathAnUrl*/ true);
                }
                else {
                    return ts.combinePaths(sourceMapDir, sourceMapFile);
                }
            }
            return sourceMapFile;
        }
    }
    ts.emitFiles = emitFiles;
    /*@internal*/
    function getBuildInfoText(buildInfo) {
        return JSON.stringify(buildInfo, undefined, 2);
    }
    ts.getBuildInfoText = getBuildInfoText;
    /*@internal*/
    function getBuildInfo(buildInfoText) {
        return JSON.parse(buildInfoText);
    }
    ts.getBuildInfo = getBuildInfo;
    /*@internal*/
    ts.notImplementedResolver = {
        hasGlobalName: ts.notImplemented,
        getReferencedExportContainer: ts.notImplemented,
        getReferencedImportDeclaration: ts.notImplemented,
        getReferencedDeclarationWithCollidingName: ts.notImplemented,
        isDeclarationWithCollidingName: ts.notImplemented,
        isValueAliasDeclaration: ts.notImplemented,
        isReferencedAliasDeclaration: ts.notImplemented,
        isTopLevelValueImportEqualsWithEntityName: ts.notImplemented,
        getNodeCheckFlags: ts.notImplemented,
        isDeclarationVisible: ts.notImplemented,
        isLateBound: function (_node) { return false; },
        collectLinkedAliases: ts.notImplemented,
        isImplementationOfOverload: ts.notImplemented,
        isRequiredInitializedParameter: ts.notImplemented,
        isOptionalUninitializedParameterProperty: ts.notImplemented,
        isExpandoFunctionDeclaration: ts.notImplemented,
        getPropertiesOfContainerFunction: ts.notImplemented,
        createTypeOfDeclaration: ts.notImplemented,
        createReturnTypeOfSignatureDeclaration: ts.notImplemented,
        createTypeOfExpression: ts.notImplemented,
        createLiteralConstValue: ts.notImplemented,
        isSymbolAccessible: ts.notImplemented,
        isEntityNameVisible: ts.notImplemented,
        // Returns the constant value this property access resolves to: notImplemented, or 'undefined' for a non-constant
        getConstantValue: ts.notImplemented,
        getReferencedValueDeclaration: ts.notImplemented,
        getTypeReferenceSerializationKind: ts.notImplemented,
        isOptionalParameter: ts.notImplemented,
        moduleExportsSomeValue: ts.notImplemented,
        isArgumentsLocalBinding: ts.notImplemented,
        getExternalModuleFileFromDeclaration: ts.notImplemented,
        getTypeReferenceDirectivesForEntityName: ts.notImplemented,
        getTypeReferenceDirectivesForSymbol: ts.notImplemented,
        isLiteralConstDeclaration: ts.notImplemented,
        getJsxFactoryEntity: ts.notImplemented,
        getAllAccessorDeclarations: ts.notImplemented,
        getSymbolOfExternalModuleSpecifier: ts.notImplemented,
        isBindingCapturedByNode: ts.notImplemented,
    };
    function createSourceFilesFromBundleBuildInfo(bundle) {
        var sourceFiles = bundle.sourceFiles.map(function (fileName) {
            var sourceFile = ts.createNode(285 /* SourceFile */, 0, 0);
            sourceFile.fileName = fileName;
            sourceFile.text = "";
            sourceFile.statements = ts.createNodeArray();
            return sourceFile;
        });
        var jsBundle = ts.Debug.assertDefined(bundle.js);
        ts.forEach(jsBundle.sources && jsBundle.sources.prologues, function (prologueInfo) {
            var sourceFile = sourceFiles[prologueInfo.file];
            sourceFile.text = prologueInfo.text;
            sourceFile.end = prologueInfo.text.length;
            sourceFile.statements = ts.createNodeArray(prologueInfo.directives.map(function (directive) {
                var statement = ts.createNode(222 /* ExpressionStatement */, directive.pos, directive.end);
                statement.expression = ts.createNode(10 /* StringLiteral */, directive.expression.pos, directive.expression.end);
                statement.expression.text = directive.expression.text;
                return statement;
            }));
        });
        return sourceFiles;
    }
    /*@internal*/
    function emitUsingBuildInfo(config, host, getCommandLine) {
        var _a = getOutputPathsForBundle(config.options, /*forceDtsPaths*/ false), buildInfoPath = _a.buildInfoPath, jsFilePath = _a.jsFilePath, sourceMapFilePath = _a.sourceMapFilePath, declarationFilePath = _a.declarationFilePath, declarationMapPath = _a.declarationMapPath;
        var buildInfoText = host.readFile(ts.Debug.assertDefined(buildInfoPath));
        if (!buildInfoText)
            return buildInfoPath;
        var jsFileText = host.readFile(ts.Debug.assertDefined(jsFilePath));
        if (!jsFileText)
            return jsFilePath;
        var sourceMapText = sourceMapFilePath && host.readFile(sourceMapFilePath);
        // error if no source map or for now if inline sourcemap
        if ((sourceMapFilePath && !sourceMapText) || config.options.inlineSourceMap)
            return sourceMapFilePath || "inline sourcemap decoding";
        // read declaration text
        var declarationText = declarationFilePath && host.readFile(declarationFilePath);
        if (declarationFilePath && !declarationText)
            return declarationFilePath;
        var declarationMapText = declarationMapPath && host.readFile(declarationMapPath);
        // error if no source map or for now if inline sourcemap
        if ((declarationMapPath && !declarationMapText) || config.options.inlineSourceMap)
            return declarationMapPath || "inline sourcemap decoding";
        var buildInfo = getBuildInfo(buildInfoText);
        if (!buildInfo.bundle || !buildInfo.bundle.js || (declarationText && !buildInfo.bundle.dts))
            return buildInfoPath;
        var ownPrependInput = ts.createInputFiles(jsFileText, declarationText, sourceMapFilePath, sourceMapText, declarationMapPath, declarationMapText, jsFilePath, declarationFilePath, buildInfoPath, buildInfo, 
        /*onlyOwnText*/ true);
        var outputFiles = [];
        var prependNodes = ts.createPrependNodes(config.projectReferences, getCommandLine, function (f) { return host.readFile(f); });
        var sourceFilesForJsEmit = createSourceFilesFromBundleBuildInfo(buildInfo.bundle);
        var emitHost = {
            getPrependNodes: ts.memoize(function () { return prependNodes.concat([ownPrependInput]); }),
            getCanonicalFileName: host.getCanonicalFileName,
            getCommonSourceDirectory: function () { return buildInfo.bundle.commonSourceDirectory; },
            getCompilerOptions: function () { return config.options; },
            getCurrentDirectory: function () { return host.getCurrentDirectory(); },
            getNewLine: function () { return host.getNewLine(); },
            getSourceFile: ts.returnUndefined,
            getSourceFileByPath: ts.returnUndefined,
            getSourceFiles: function () { return sourceFilesForJsEmit; },
            getLibFileFromReference: ts.notImplemented,
            isSourceFileFromExternalLibrary: ts.returnFalse,
            getResolvedProjectReferenceToRedirect: ts.returnUndefined,
            writeFile: function (name, text, writeByteOrderMark) {
                switch (name) {
                    case jsFilePath:
                        if (jsFileText === text)
                            return;
                        break;
                    case sourceMapFilePath:
                        if (sourceMapText === text)
                            return;
                        break;
                    case buildInfoPath:
                        var newBuildInfo = getBuildInfo(text);
                        newBuildInfo.program = buildInfo.program;
                        // Update sourceFileInfo
                        var _a = buildInfo.bundle, js = _a.js, dts = _a.dts, sourceFiles = _a.sourceFiles;
                        newBuildInfo.bundle.js.sources = js.sources;
                        if (dts) {
                            newBuildInfo.bundle.dts.sources = dts.sources;
                        }
                        newBuildInfo.bundle.sourceFiles = sourceFiles;
                        outputFiles.push({ name: name, text: getBuildInfoText(newBuildInfo), writeByteOrderMark: writeByteOrderMark });
                        return;
                    case declarationFilePath:
                        if (declarationText === text)
                            return;
                        break;
                    case declarationMapPath:
                        if (declarationMapText === text)
                            return;
                        break;
                    default:
                        ts.Debug.fail("Unexpected path: " + name);
                }
                outputFiles.push({ name: name, text: text, writeByteOrderMark: writeByteOrderMark });
            },
            isEmitBlocked: ts.returnFalse,
            readFile: function (f) { return host.readFile(f); },
            fileExists: function (f) { return host.fileExists(f); },
            directoryExists: host.directoryExists && (function (f) { return host.directoryExists(f); }),
            useCaseSensitiveFileNames: function () { return host.useCaseSensitiveFileNames(); },
            getProgramBuildInfo: ts.returnUndefined
        };
        emitFiles(ts.notImplementedResolver, emitHost, /*targetSourceFile*/ undefined, ts.getTransformers(config.options), /*emitOnlyDtsFiles*/ false);
        return outputFiles;
    }
    ts.emitUsingBuildInfo = emitUsingBuildInfo;
    var PipelinePhase;
    (function (PipelinePhase) {
        PipelinePhase[PipelinePhase["Notification"] = 0] = "Notification";
        PipelinePhase[PipelinePhase["Substitution"] = 1] = "Substitution";
        PipelinePhase[PipelinePhase["Comments"] = 2] = "Comments";
        PipelinePhase[PipelinePhase["SourceMaps"] = 3] = "SourceMaps";
        PipelinePhase[PipelinePhase["Emit"] = 4] = "Emit";
    })(PipelinePhase || (PipelinePhase = {}));
    function createPrinter(printerOptions, handlers) {
        if (printerOptions === void 0) { printerOptions = {}; }
        if (handlers === void 0) { handlers = {}; }
        var hasGlobalName = handlers.hasGlobalName, _a = handlers.onEmitNode, onEmitNode = _a === void 0 ? ts.noEmitNotification : _a, _b = handlers.substituteNode, substituteNode = _b === void 0 ? ts.noEmitSubstitution : _b, onBeforeEmitNodeArray = handlers.onBeforeEmitNodeArray, onAfterEmitNodeArray = handlers.onAfterEmitNodeArray, onBeforeEmitToken = handlers.onBeforeEmitToken, onAfterEmitToken = handlers.onAfterEmitToken;
        var extendedDiagnostics = !!printerOptions.extendedDiagnostics;
        var newLine = ts.getNewLineCharacter(printerOptions);
        var moduleKind = ts.getEmitModuleKind(printerOptions);
        var bundledHelpers = ts.createMap();
        var currentSourceFile;
        var nodeIdToGeneratedName; // Map of generated names for specific nodes.
        var autoGeneratedIdToGeneratedName; // Map of generated names for temp and loop variables.
        var generatedNames; // Set of names generated by the NameGenerator.
        var tempFlagsStack; // Stack of enclosing name generation scopes.
        var tempFlags; // TempFlags for the current name generation scope.
        var reservedNamesStack; // Stack of TempFlags reserved in enclosing name generation scopes.
        var reservedNames; // TempFlags to reserve in nested name generation scopes.
        var writer;
        var ownWriter; // Reusable `EmitTextWriter` for basic printing.
        var write = writeBase;
        var isOwnFileEmit;
        var bundleFileInfo = printerOptions.writeBundleFileInfo ? { sections: [] } : undefined;
        var recordInternalSection = printerOptions.recordInternalSection;
        var sourceFileTextPos = 0;
        var sourceFileTextKind = "text" /* Text */;
        // Source Maps
        var sourceMapsDisabled = true;
        var sourceMapGenerator;
        var sourceMapSource;
        var sourceMapSourceIndex = -1;
        // Comments
        var containerPos = -1;
        var containerEnd = -1;
        var declarationListContainerEnd = -1;
        var currentLineMap;
        var detachedCommentsInfo;
        var hasWrittenComment = false;
        var commentsDisabled = !!printerOptions.removeComments;
        var _c = ts.performance.createTimerIf(extendedDiagnostics, "commentTime", "beforeComment", "afterComment"), enterComment = _c.enter, exitComment = _c.exit;
        reset();
        return {
            // public API
            printNode: printNode,
            printList: printList,
            printFile: printFile,
            printBundle: printBundle,
            // internal API
            writeNode: writeNode,
            writeList: writeList,
            writeFile: writeFile,
            writeBundle: writeBundle,
            bundleFileInfo: bundleFileInfo
        };
        function printNode(hint, node, sourceFile) {
            switch (hint) {
                case 0 /* SourceFile */:
                    ts.Debug.assert(ts.isSourceFile(node), "Expected a SourceFile node.");
                    break;
                case 2 /* IdentifierName */:
                    ts.Debug.assert(ts.isIdentifier(node), "Expected an Identifier node.");
                    break;
                case 1 /* Expression */:
                    ts.Debug.assert(ts.isExpression(node), "Expected an Expression node.");
                    break;
            }
            switch (node.kind) {
                case 285 /* SourceFile */: return printFile(node);
                case 286 /* Bundle */: return printBundle(node);
                case 287 /* UnparsedSource */: return printUnparsedSource(node);
            }
            writeNode(hint, node, sourceFile, beginPrint());
            return endPrint();
        }
        function printList(format, nodes, sourceFile) {
            writeList(format, nodes, sourceFile, beginPrint());
            return endPrint();
        }
        function printBundle(bundle) {
            writeBundle(bundle, beginPrint(), /*sourceMapEmitter*/ undefined);
            return endPrint();
        }
        function printFile(sourceFile) {
            writeFile(sourceFile, beginPrint(), /*sourceMapEmitter*/ undefined);
            return endPrint();
        }
        function printUnparsedSource(unparsed) {
            writeUnparsedSource(unparsed, beginPrint());
            return endPrint();
        }
        function writeNode(hint, node, sourceFile, output) {
            var previousWriter = writer;
            setWriter(output, /*_sourceMapGenerator*/ undefined);
            print(hint, node, sourceFile);
            reset();
            writer = previousWriter;
        }
        function writeList(format, nodes, sourceFile, output) {
            var previousWriter = writer;
            setWriter(output, /*_sourceMapGenerator*/ undefined);
            if (sourceFile) {
                setSourceFile(sourceFile);
            }
            emitList(syntheticParent, nodes, format);
            reset();
            writer = previousWriter;
        }
        function getTextPosWithWriteLine() {
            return writer.getTextPosWithWriteLine ? writer.getTextPosWithWriteLine() : writer.getTextPos();
        }
        function updateOrPushBundleFileTextLike(pos, end, kind) {
            var last = ts.lastOrUndefined(bundleFileInfo.sections);
            if (last && last.kind === kind) {
                last.end = end;
            }
            else {
                bundleFileInfo.sections.push({ pos: pos, end: end, kind: kind });
            }
        }
        function recordBundleFileInternalSectionStart(node) {
            if (recordInternalSection &&
                bundleFileInfo &&
                currentSourceFile &&
                (ts.isDeclaration(node) || ts.isVariableStatement(node)) &&
                ts.isInternalDeclaration(node, currentSourceFile) &&
                sourceFileTextKind !== "internal" /* Internal */) {
                var prevSourceFileTextKind = sourceFileTextKind;
                recordBundleFileTextLikeSection(writer.getTextPos());
                sourceFileTextPos = getTextPosWithWriteLine();
                sourceFileTextKind = "internal" /* Internal */;
                return prevSourceFileTextKind;
            }
            return undefined;
        }
        function recordBundleFileInternalSectionEnd(prevSourceFileTextKind) {
            if (prevSourceFileTextKind) {
                recordBundleFileTextLikeSection(writer.getTextPos());
                sourceFileTextPos = getTextPosWithWriteLine();
                sourceFileTextKind = prevSourceFileTextKind;
            }
        }
        function recordBundleFileTextLikeSection(end) {
            if (sourceFileTextPos < end) {
                updateOrPushBundleFileTextLike(sourceFileTextPos, end, sourceFileTextKind);
                return true;
            }
            return false;
        }
        function writeBundle(bundle, output, sourceMapGenerator) {
            var _a;
            isOwnFileEmit = false;
            var previousWriter = writer;
            setWriter(output, sourceMapGenerator);
            emitShebangIfNeeded(bundle);
            emitPrologueDirectivesIfNeeded(bundle);
            emitHelpers(bundle);
            emitSyntheticTripleSlashReferencesIfNeeded(bundle);
            for (var _b = 0, _c = bundle.prepends; _b < _c.length; _b++) {
                var prepend = _c[_b];
                writeLine();
                var pos = writer.getTextPos();
                var savedSections = bundleFileInfo && bundleFileInfo.sections;
                if (savedSections)
                    bundleFileInfo.sections = [];
                print(4 /* Unspecified */, prepend, /*sourceFile*/ undefined);
                if (bundleFileInfo) {
                    var newSections = bundleFileInfo.sections;
                    bundleFileInfo.sections = savedSections;
                    if (prepend.oldFileOfCurrentEmit)
                        (_a = bundleFileInfo.sections).push.apply(_a, newSections);
                    else {
                        newSections.forEach(function (section) { return ts.Debug.assert(ts.isBundleFileTextLike(section)); });
                        bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "prepend" /* Prepend */, data: prepend.fileName, texts: newSections });
                    }
                }
            }
            sourceFileTextPos = getTextPosWithWriteLine();
            for (var _d = 0, _e = bundle.sourceFiles; _d < _e.length; _d++) {
                var sourceFile = _e[_d];
                print(0 /* SourceFile */, sourceFile, sourceFile);
            }
            if (bundleFileInfo && bundle.sourceFiles.length) {
                var end = writer.getTextPos();
                if (recordBundleFileTextLikeSection(end)) {
                    // Store prologues
                    var prologues = getPrologueDirectivesFromBundledSourceFiles(bundle);
                    if (prologues) {
                        if (!bundleFileInfo.sources)
                            bundleFileInfo.sources = {};
                        bundleFileInfo.sources.prologues = prologues;
                    }
                    // Store helpes
                    var helpers = getHelpersFromBundledSourceFiles(bundle);
                    if (helpers) {
                        if (!bundleFileInfo.sources)
                            bundleFileInfo.sources = {};
                        bundleFileInfo.sources.helpers = helpers;
                    }
                }
            }
            reset();
            writer = previousWriter;
        }
        function writeUnparsedSource(unparsed, output) {
            var previousWriter = writer;
            setWriter(output, /*_sourceMapGenerator*/ undefined);
            print(4 /* Unspecified */, unparsed, /*sourceFile*/ undefined);
            reset();
            writer = previousWriter;
        }
        function writeFile(sourceFile, output, sourceMapGenerator) {
            isOwnFileEmit = true;
            var previousWriter = writer;
            setWriter(output, sourceMapGenerator);
            emitShebangIfNeeded(sourceFile);
            emitPrologueDirectivesIfNeeded(sourceFile);
            print(0 /* SourceFile */, sourceFile, sourceFile);
            reset();
            writer = previousWriter;
        }
        function beginPrint() {
            return ownWriter || (ownWriter = ts.createTextWriter(newLine));
        }
        function endPrint() {
            var text = ownWriter.getText();
            ownWriter.clear();
            return text;
        }
        function print(hint, node, sourceFile) {
            if (sourceFile) {
                setSourceFile(sourceFile);
            }
            var pipelinePhase = getPipelinePhase(0 /* Notification */, node);
            pipelinePhase(hint, node);
        }
        function setSourceFile(sourceFile) {
            currentSourceFile = sourceFile;
            currentLineMap = undefined;
            detachedCommentsInfo = undefined;
            if (sourceFile) {
                setSourceMapSource(sourceFile);
            }
        }
        function setWriter(_writer, _sourceMapGenerator) {
            if (_writer && printerOptions.omitTrailingSemicolon) {
                _writer = ts.getTrailingSemicolonOmittingWriter(_writer);
            }
            writer = _writer; // TODO: GH#18217
            sourceMapGenerator = _sourceMapGenerator;
            sourceMapsDisabled = !writer || !sourceMapGenerator;
        }
        function reset() {
            nodeIdToGeneratedName = [];
            autoGeneratedIdToGeneratedName = [];
            generatedNames = ts.createMap();
            tempFlagsStack = [];
            tempFlags = 0 /* Auto */;
            reservedNamesStack = [];
            currentSourceFile = undefined;
            currentLineMap = undefined;
            detachedCommentsInfo = undefined;
            setWriter(/*output*/ undefined, /*_sourceMapGenerator*/ undefined);
        }
        function getCurrentLineMap() {
            return currentLineMap || (currentLineMap = ts.getLineStarts(currentSourceFile));
        }
        function emit(node) {
            if (node === undefined)
                return;
            var prevSourceFileTextKind = recordBundleFileInternalSectionStart(node);
            var pipelinePhase = getPipelinePhase(0 /* Notification */, node);
            pipelinePhase(4 /* Unspecified */, node);
            recordBundleFileInternalSectionEnd(prevSourceFileTextKind);
        }
        function emitIdentifierName(node) {
            if (node === undefined)
                return;
            var pipelinePhase = getPipelinePhase(0 /* Notification */, node);
            pipelinePhase(2 /* IdentifierName */, node);
        }
        function emitExpression(node) {
            if (node === undefined)
                return;
            var pipelinePhase = getPipelinePhase(0 /* Notification */, node);
            pipelinePhase(1 /* Expression */, node);
        }
        function getPipelinePhase(phase, node) {
            switch (phase) {
                case 0 /* Notification */:
                    if (onEmitNode !== ts.noEmitNotification) {
                        return pipelineEmitWithNotification;
                    }
                // falls through
                case 1 /* Substitution */:
                    if (substituteNode !== ts.noEmitSubstitution) {
                        return pipelineEmitWithSubstitution;
                    }
                // falls through
                case 2 /* Comments */:
                    if (!commentsDisabled && node.kind !== 285 /* SourceFile */) {
                        return pipelineEmitWithComments;
                    }
                // falls through
                case 3 /* SourceMaps */:
                    if (!sourceMapsDisabled && node.kind !== 285 /* SourceFile */ && !ts.isInJsonFile(node)) {
                        return pipelineEmitWithSourceMap;
                    }
                // falls through
                case 4 /* Emit */:
                    return pipelineEmitWithHint;
                default:
                    return ts.Debug.assertNever(phase);
            }
        }
        function getNextPipelinePhase(currentPhase, node) {
            return getPipelinePhase(currentPhase + 1, node);
        }
        function pipelineEmitWithNotification(hint, node) {
            var pipelinePhase = getNextPipelinePhase(0 /* Notification */, node);
            onEmitNode(hint, node, pipelinePhase);
        }
        function pipelineEmitWithHint(hint, node) {
            if (hint === 0 /* SourceFile */)
                return emitSourceFile(ts.cast(node, ts.isSourceFile));
            if (hint === 2 /* IdentifierName */)
                return emitIdentifier(ts.cast(node, ts.isIdentifier));
            if (hint === 3 /* MappedTypeParameter */)
                return emitMappedTypeParameter(ts.cast(node, ts.isTypeParameterDeclaration));
            if (hint === 5 /* EmbeddedStatement */) {
                ts.Debug.assertNode(node, ts.isEmptyStatement);
                return emitEmptyStatement(/*isEmbeddedStatement*/ true);
            }
            if (hint === 4 /* Unspecified */) {
                if (ts.isKeyword(node.kind))
                    return writeTokenNode(node, writeKeyword);
                switch (node.kind) {
                    // Pseudo-literals
                    case 15 /* TemplateHead */:
                    case 16 /* TemplateMiddle */:
                    case 17 /* TemplateTail */:
                        return emitLiteral(node);
                    case 287 /* UnparsedSource */:
                    case 281 /* UnparsedPrepend */:
                        return emitUnparsedSourceOrPrepend(node);
                    case 280 /* UnparsedPrologue */:
                        return writeUnparsedNode(node);
                    case 282 /* UnparsedText */:
                    case 283 /* UnparsedInternalText */:
                        return emitUnparsedTextLike(node);
                    case 284 /* UnparsedSyntheticReference */:
                        return emitUnparsedSyntheticReference(node);
                    // Identifiers
                    case 73 /* Identifier */:
                        return emitIdentifier(node);
                    // Parse tree nodes
                    // Names
                    case 149 /* QualifiedName */:
                        return emitQualifiedName(node);
                    case 150 /* ComputedPropertyName */:
                        return emitComputedPropertyName(node);
                    // Signature elements
                    case 151 /* TypeParameter */:
                        return emitTypeParameter(node);
                    case 152 /* Parameter */:
                        return emitParameter(node);
                    case 153 /* Decorator */:
                        return emitDecorator(node);
                    // Type members
                    case 154 /* PropertySignature */:
                        return emitPropertySignature(node);
                    case 155 /* PropertyDeclaration */:
                        return emitPropertyDeclaration(node);
                    case 156 /* MethodSignature */:
                        return emitMethodSignature(node);
                    case 157 /* MethodDeclaration */:
                        return emitMethodDeclaration(node);
                    case 158 /* Constructor */:
                        return emitConstructor(node);
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                        return emitAccessorDeclaration(node);
                    case 161 /* CallSignature */:
                        return emitCallSignature(node);
                    case 162 /* ConstructSignature */:
                        return emitConstructSignature(node);
                    case 163 /* IndexSignature */:
                        return emitIndexSignature(node);
                    // Types
                    case 164 /* TypePredicate */:
                        return emitTypePredicate(node);
                    case 165 /* TypeReference */:
                        return emitTypeReference(node);
                    case 166 /* FunctionType */:
                        return emitFunctionType(node);
                    case 295 /* JSDocFunctionType */:
                        return emitJSDocFunctionType(node);
                    case 167 /* ConstructorType */:
                        return emitConstructorType(node);
                    case 168 /* TypeQuery */:
                        return emitTypeQuery(node);
                    case 169 /* TypeLiteral */:
                        return emitTypeLiteral(node);
                    case 170 /* ArrayType */:
                        return emitArrayType(node);
                    case 171 /* TupleType */:
                        return emitTupleType(node);
                    case 172 /* OptionalType */:
                        return emitOptionalType(node);
                    case 174 /* UnionType */:
                        return emitUnionType(node);
                    case 175 /* IntersectionType */:
                        return emitIntersectionType(node);
                    case 176 /* ConditionalType */:
                        return emitConditionalType(node);
                    case 177 /* InferType */:
                        return emitInferType(node);
                    case 178 /* ParenthesizedType */:
                        return emitParenthesizedType(node);
                    case 212 /* ExpressionWithTypeArguments */:
                        return emitExpressionWithTypeArguments(node);
                    case 179 /* ThisType */:
                        return emitThisType();
                    case 180 /* TypeOperator */:
                        return emitTypeOperator(node);
                    case 181 /* IndexedAccessType */:
                        return emitIndexedAccessType(node);
                    case 182 /* MappedType */:
                        return emitMappedType(node);
                    case 183 /* LiteralType */:
                        return emitLiteralType(node);
                    case 184 /* ImportType */:
                        return emitImportTypeNode(node);
                    case 290 /* JSDocAllType */:
                        writePunctuation("*");
                        return;
                    case 291 /* JSDocUnknownType */:
                        writePunctuation("?");
                        return;
                    case 292 /* JSDocNullableType */:
                        return emitJSDocNullableType(node);
                    case 293 /* JSDocNonNullableType */:
                        return emitJSDocNonNullableType(node);
                    case 294 /* JSDocOptionalType */:
                        return emitJSDocOptionalType(node);
                    case 173 /* RestType */:
                    case 296 /* JSDocVariadicType */:
                        return emitRestOrJSDocVariadicType(node);
                    // Binding patterns
                    case 185 /* ObjectBindingPattern */:
                        return emitObjectBindingPattern(node);
                    case 186 /* ArrayBindingPattern */:
                        return emitArrayBindingPattern(node);
                    case 187 /* BindingElement */:
                        return emitBindingElement(node);
                    // Misc
                    case 217 /* TemplateSpan */:
                        return emitTemplateSpan(node);
                    case 218 /* SemicolonClassElement */:
                        return emitSemicolonClassElement();
                    // Statements
                    case 219 /* Block */:
                        return emitBlock(node);
                    case 220 /* VariableStatement */:
                        return emitVariableStatement(node);
                    case 221 /* EmptyStatement */:
                        return emitEmptyStatement(/*isEmbeddedStatement*/ false);
                    case 222 /* ExpressionStatement */:
                        return emitExpressionStatement(node);
                    case 223 /* IfStatement */:
                        return emitIfStatement(node);
                    case 224 /* DoStatement */:
                        return emitDoStatement(node);
                    case 225 /* WhileStatement */:
                        return emitWhileStatement(node);
                    case 226 /* ForStatement */:
                        return emitForStatement(node);
                    case 227 /* ForInStatement */:
                        return emitForInStatement(node);
                    case 228 /* ForOfStatement */:
                        return emitForOfStatement(node);
                    case 229 /* ContinueStatement */:
                        return emitContinueStatement(node);
                    case 230 /* BreakStatement */:
                        return emitBreakStatement(node);
                    case 231 /* ReturnStatement */:
                        return emitReturnStatement(node);
                    case 232 /* WithStatement */:
                        return emitWithStatement(node);
                    case 233 /* SwitchStatement */:
                        return emitSwitchStatement(node);
                    case 234 /* LabeledStatement */:
                        return emitLabeledStatement(node);
                    case 235 /* ThrowStatement */:
                        return emitThrowStatement(node);
                    case 236 /* TryStatement */:
                        return emitTryStatement(node);
                    case 237 /* DebuggerStatement */:
                        return emitDebuggerStatement(node);
                    // Declarations
                    case 238 /* VariableDeclaration */:
                        return emitVariableDeclaration(node);
                    case 239 /* VariableDeclarationList */:
                        return emitVariableDeclarationList(node);
                    case 240 /* FunctionDeclaration */:
                        return emitFunctionDeclaration(node);
                    case 241 /* ClassDeclaration */:
                        return emitClassDeclaration(node);
                    case 242 /* InterfaceDeclaration */:
                        return emitInterfaceDeclaration(node);
                    case 243 /* TypeAliasDeclaration */:
                        return emitTypeAliasDeclaration(node);
                    case 244 /* EnumDeclaration */:
                        return emitEnumDeclaration(node);
                    case 245 /* ModuleDeclaration */:
                        return emitModuleDeclaration(node);
                    case 246 /* ModuleBlock */:
                        return emitModuleBlock(node);
                    case 247 /* CaseBlock */:
                        return emitCaseBlock(node);
                    case 248 /* NamespaceExportDeclaration */:
                        return emitNamespaceExportDeclaration(node);
                    case 249 /* ImportEqualsDeclaration */:
                        return emitImportEqualsDeclaration(node);
                    case 250 /* ImportDeclaration */:
                        return emitImportDeclaration(node);
                    case 251 /* ImportClause */:
                        return emitImportClause(node);
                    case 252 /* NamespaceImport */:
                        return emitNamespaceImport(node);
                    case 253 /* NamedImports */:
                        return emitNamedImports(node);
                    case 254 /* ImportSpecifier */:
                        return emitImportSpecifier(node);
                    case 255 /* ExportAssignment */:
                        return emitExportAssignment(node);
                    case 256 /* ExportDeclaration */:
                        return emitExportDeclaration(node);
                    case 257 /* NamedExports */:
                        return emitNamedExports(node);
                    case 258 /* ExportSpecifier */:
                        return emitExportSpecifier(node);
                    case 259 /* MissingDeclaration */:
                        return;
                    // Module references
                    case 260 /* ExternalModuleReference */:
                        return emitExternalModuleReference(node);
                    // JSX (non-expression)
                    case 11 /* JsxText */:
                        return emitJsxText(node);
                    case 263 /* JsxOpeningElement */:
                    case 266 /* JsxOpeningFragment */:
                        return emitJsxOpeningElementOrFragment(node);
                    case 264 /* JsxClosingElement */:
                    case 267 /* JsxClosingFragment */:
                        return emitJsxClosingElementOrFragment(node);
                    case 268 /* JsxAttribute */:
                        return emitJsxAttribute(node);
                    case 269 /* JsxAttributes */:
                        return emitJsxAttributes(node);
                    case 270 /* JsxSpreadAttribute */:
                        return emitJsxSpreadAttribute(node);
                    case 271 /* JsxExpression */:
                        return emitJsxExpression(node);
                    // Clauses
                    case 272 /* CaseClause */:
                        return emitCaseClause(node);
                    case 273 /* DefaultClause */:
                        return emitDefaultClause(node);
                    case 274 /* HeritageClause */:
                        return emitHeritageClause(node);
                    case 275 /* CatchClause */:
                        return emitCatchClause(node);
                    // Property assignments
                    case 276 /* PropertyAssignment */:
                        return emitPropertyAssignment(node);
                    case 277 /* ShorthandPropertyAssignment */:
                        return emitShorthandPropertyAssignment(node);
                    case 278 /* SpreadAssignment */:
                        return emitSpreadAssignment(node);
                    // Enum
                    case 279 /* EnumMember */:
                        return emitEnumMember(node);
                    // JSDoc nodes (only used in codefixes currently)
                    case 305 /* JSDocParameterTag */:
                    case 311 /* JSDocPropertyTag */:
                        return emitJSDocPropertyLikeTag(node);
                    case 306 /* JSDocReturnTag */:
                    case 308 /* JSDocTypeTag */:
                    case 307 /* JSDocThisTag */:
                    case 304 /* JSDocEnumTag */:
                        return emitJSDocSimpleTypedTag(node);
                    case 301 /* JSDocAugmentsTag */:
                        return emitJSDocAugmentsTag(node);
                    case 309 /* JSDocTemplateTag */:
                        return emitJSDocTemplateTag(node);
                    case 310 /* JSDocTypedefTag */:
                        return emitJSDocTypedefTag(node);
                    case 303 /* JSDocCallbackTag */:
                        return emitJSDocCallbackTag(node);
                    case 299 /* JSDocSignature */:
                        return emitJSDocSignature(node);
                    case 298 /* JSDocTypeLiteral */:
                        return emitJSDocTypeLiteral(node);
                    case 302 /* JSDocClassTag */:
                    case 300 /* JSDocTag */:
                        return emitJSDocSimpleTag(node);
                    case 297 /* JSDocComment */:
                        return emitJSDoc(node);
                    // Transformation nodes (ignored)
                }
                if (ts.isExpression(node)) {
                    hint = 1 /* Expression */;
                    if (substituteNode !== ts.noEmitSubstitution) {
                        node = substituteNode(hint, node);
                    }
                }
                else if (ts.isToken(node)) {
                    return writeTokenNode(node, writePunctuation);
                }
            }
            if (hint === 1 /* Expression */) {
                switch (node.kind) {
                    // Literals
                    case 8 /* NumericLiteral */:
                    case 9 /* BigIntLiteral */:
                        return emitNumericOrBigIntLiteral(node);
                    case 10 /* StringLiteral */:
                    case 13 /* RegularExpressionLiteral */:
                    case 14 /* NoSubstitutionTemplateLiteral */:
                        return emitLiteral(node);
                    // Identifiers
                    case 73 /* Identifier */:
                        return emitIdentifier(node);
                    // Reserved words
                    case 88 /* FalseKeyword */:
                    case 97 /* NullKeyword */:
                    case 99 /* SuperKeyword */:
                    case 103 /* TrueKeyword */:
                    case 101 /* ThisKeyword */:
                    case 93 /* ImportKeyword */:
                        writeTokenNode(node, writeKeyword);
                        return;
                    // Expressions
                    case 188 /* ArrayLiteralExpression */:
                        return emitArrayLiteralExpression(node);
                    case 189 /* ObjectLiteralExpression */:
                        return emitObjectLiteralExpression(node);
                    case 190 /* PropertyAccessExpression */:
                        return emitPropertyAccessExpression(node);
                    case 191 /* ElementAccessExpression */:
                        return emitElementAccessExpression(node);
                    case 192 /* CallExpression */:
                        return emitCallExpression(node);
                    case 193 /* NewExpression */:
                        return emitNewExpression(node);
                    case 194 /* TaggedTemplateExpression */:
                        return emitTaggedTemplateExpression(node);
                    case 195 /* TypeAssertionExpression */:
                        return emitTypeAssertionExpression(node);
                    case 196 /* ParenthesizedExpression */:
                        return emitParenthesizedExpression(node);
                    case 197 /* FunctionExpression */:
                        return emitFunctionExpression(node);
                    case 198 /* ArrowFunction */:
                        return emitArrowFunction(node);
                    case 199 /* DeleteExpression */:
                        return emitDeleteExpression(node);
                    case 200 /* TypeOfExpression */:
                        return emitTypeOfExpression(node);
                    case 201 /* VoidExpression */:
                        return emitVoidExpression(node);
                    case 202 /* AwaitExpression */:
                        return emitAwaitExpression(node);
                    case 203 /* PrefixUnaryExpression */:
                        return emitPrefixUnaryExpression(node);
                    case 204 /* PostfixUnaryExpression */:
                        return emitPostfixUnaryExpression(node);
                    case 205 /* BinaryExpression */:
                        return emitBinaryExpression(node);
                    case 206 /* ConditionalExpression */:
                        return emitConditionalExpression(node);
                    case 207 /* TemplateExpression */:
                        return emitTemplateExpression(node);
                    case 208 /* YieldExpression */:
                        return emitYieldExpression(node);
                    case 209 /* SpreadElement */:
                        return emitSpreadExpression(node);
                    case 210 /* ClassExpression */:
                        return emitClassExpression(node);
                    case 211 /* OmittedExpression */:
                        return;
                    case 213 /* AsExpression */:
                        return emitAsExpression(node);
                    case 214 /* NonNullExpression */:
                        return emitNonNullExpression(node);
                    case 215 /* MetaProperty */:
                        return emitMetaProperty(node);
                    // JSX
                    case 261 /* JsxElement */:
                        return emitJsxElement(node);
                    case 262 /* JsxSelfClosingElement */:
                        return emitJsxSelfClosingElement(node);
                    case 265 /* JsxFragment */:
                        return emitJsxFragment(node);
                    // Transformation nodes
                    case 314 /* PartiallyEmittedExpression */:
                        return emitPartiallyEmittedExpression(node);
                    case 315 /* CommaListExpression */:
                        return emitCommaList(node);
                }
            }
        }
        function emitMappedTypeParameter(node) {
            emit(node.name);
            writeSpace();
            writeKeyword("in");
            writeSpace();
            emit(node.constraint);
        }
        function pipelineEmitWithSubstitution(hint, node) {
            var pipelinePhase = getNextPipelinePhase(1 /* Substitution */, node);
            pipelinePhase(hint, substituteNode(hint, node));
        }
        function getHelpersFromBundledSourceFiles(bundle) {
            var result;
            if (moduleKind === ts.ModuleKind.None || printerOptions.noEmitHelpers) {
                return undefined;
            }
            var bundledHelpers = ts.createMap();
            for (var _a = 0, _b = bundle.sourceFiles; _a < _b.length; _a++) {
                var sourceFile = _b[_a];
                var shouldSkip = ts.getExternalHelpersModuleName(sourceFile) !== undefined;
                var helpers = getSortedEmitHelpers(sourceFile);
                if (!helpers)
                    continue;
                for (var _c = 0, helpers_3 = helpers; _c < helpers_3.length; _c++) {
                    var helper = helpers_3[_c];
                    if (!helper.scoped && !shouldSkip && !bundledHelpers.get(helper.name)) {
                        bundledHelpers.set(helper.name, true);
                        (result || (result = [])).push(helper.name);
                    }
                }
            }
            return result;
        }
        function emitHelpers(node) {
            var helpersEmitted = false;
            var bundle = node.kind === 286 /* Bundle */ ? node : undefined;
            if (bundle && moduleKind === ts.ModuleKind.None) {
                return;
            }
            var numPrepends = bundle ? bundle.prepends.length : 0;
            var numNodes = bundle ? bundle.sourceFiles.length + numPrepends : 1;
            for (var i = 0; i < numNodes; i++) {
                var currentNode = bundle ? i < numPrepends ? bundle.prepends[i] : bundle.sourceFiles[i - numPrepends] : node;
                var sourceFile = ts.isSourceFile(currentNode) ? currentNode : ts.isUnparsedSource(currentNode) ? undefined : currentSourceFile;
                var shouldSkip = printerOptions.noEmitHelpers || (!!sourceFile && ts.getExternalHelpersModuleName(sourceFile) !== undefined);
                var shouldBundle = (ts.isSourceFile(currentNode) || ts.isUnparsedSource(currentNode)) && !isOwnFileEmit;
                var helpers = ts.isUnparsedSource(currentNode) ? currentNode.helpers : getSortedEmitHelpers(currentNode);
                if (helpers) {
                    for (var _a = 0, helpers_4 = helpers; _a < helpers_4.length; _a++) {
                        var helper = helpers_4[_a];
                        if (!helper.scoped) {
                            // Skip the helper if it can be skipped and the noEmitHelpers compiler
                            // option is set, or if it can be imported and the importHelpers compiler
                            // option is set.
                            if (shouldSkip)
                                continue;
                            // Skip the helper if it can be bundled but hasn't already been emitted and we
                            // are emitting a bundled module.
                            if (shouldBundle) {
                                if (bundledHelpers.get(helper.name)) {
                                    continue;
                                }
                                bundledHelpers.set(helper.name, true);
                            }
                        }
                        else if (bundle) {
                            // Skip the helper if it is scoped and we are emitting bundled helpers
                            continue;
                        }
                        var pos = getTextPosWithWriteLine();
                        if (typeof helper.text === "string") {
                            writeLines(helper.text);
                        }
                        else {
                            writeLines(helper.text(makeFileLevelOptimisticUniqueName));
                        }
                        if (bundleFileInfo)
                            bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "emitHelpers" /* EmitHelpers */, data: helper.name });
                        helpersEmitted = true;
                    }
                }
            }
            return helpersEmitted;
        }
        function getSortedEmitHelpers(node) {
            var helpers = ts.getEmitHelpers(node);
            return helpers && ts.stableSort(helpers, ts.compareEmitHelpers);
        }
        //
        // Literals/Pseudo-literals
        //
        // SyntaxKind.NumericLiteral
        // SyntaxKind.BigIntLiteral
        function emitNumericOrBigIntLiteral(node) {
            emitLiteral(node);
        }
        // SyntaxKind.StringLiteral
        // SyntaxKind.RegularExpressionLiteral
        // SyntaxKind.NoSubstitutionTemplateLiteral
        // SyntaxKind.TemplateHead
        // SyntaxKind.TemplateMiddle
        // SyntaxKind.TemplateTail
        function emitLiteral(node) {
            var text = getLiteralTextOfNode(node, printerOptions.neverAsciiEscape);
            if ((printerOptions.sourceMap || printerOptions.inlineSourceMap)
                && (node.kind === 10 /* StringLiteral */ || ts.isTemplateLiteralKind(node.kind))) {
                writeLiteral(text);
            }
            else {
                // Quick info expects all literals to be called with writeStringLiteral, as there's no specific type for numberLiterals
                writeStringLiteral(text);
            }
        }
        // SyntaxKind.UnparsedSource
        // SyntaxKind.UnparsedPrepend
        function emitUnparsedSourceOrPrepend(unparsed) {
            for (var _a = 0, _b = unparsed.texts; _a < _b.length; _a++) {
                var text = _b[_a];
                writeLine();
                emit(text);
            }
        }
        // SyntaxKind.UnparsedPrologue
        // SyntaxKind.UnparsedText
        // SyntaxKind.UnparsedInternal
        // SyntaxKind.UnparsedSyntheticReference
        function writeUnparsedNode(unparsed) {
            writer.rawWrite(unparsed.parent.text.substring(unparsed.pos, unparsed.end));
        }
        // SyntaxKind.UnparsedText
        // SyntaxKind.UnparsedInternal
        function emitUnparsedTextLike(unparsed) {
            var pos = getTextPosWithWriteLine();
            writeUnparsedNode(unparsed);
            if (bundleFileInfo) {
                updateOrPushBundleFileTextLike(pos, writer.getTextPos(), unparsed.kind === 282 /* UnparsedText */ ?
                    "text" /* Text */ :
                    "internal" /* Internal */);
            }
        }
        // SyntaxKind.UnparsedSyntheticReference
        function emitUnparsedSyntheticReference(unparsed) {
            var pos = getTextPosWithWriteLine();
            writeUnparsedNode(unparsed);
            if (bundleFileInfo) {
                var section = ts.clone(unparsed.section);
                section.pos = pos;
                section.end = writer.getTextPos();
                bundleFileInfo.sections.push(section);
            }
        }
        //
        // Identifiers
        //
        function emitIdentifier(node) {
            var writeText = node.symbol ? writeSymbol : write;
            writeText(getTextOfNode(node, /*includeTrivia*/ false), node.symbol);
            emitList(node, node.typeArguments, 53776 /* TypeParameters */); // Call emitList directly since it could be an array of TypeParameterDeclarations _or_ type arguments
        }
        //
        // Names
        //
        function emitQualifiedName(node) {
            emitEntityName(node.left);
            writePunctuation(".");
            emit(node.right);
        }
        function emitEntityName(node) {
            if (node.kind === 73 /* Identifier */) {
                emitExpression(node);
            }
            else {
                emit(node);
            }
        }
        function emitComputedPropertyName(node) {
            writePunctuation("[");
            emitExpression(node.expression);
            writePunctuation("]");
        }
        //
        // Signature elements
        //
        function emitTypeParameter(node) {
            emit(node.name);
            if (node.constraint) {
                writeSpace();
                writeKeyword("extends");
                writeSpace();
                emit(node.constraint);
            }
            if (node.default) {
                writeSpace();
                writeOperator("=");
                writeSpace();
                emit(node.default);
            }
        }
        function emitParameter(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emit(node.dotDotDotToken);
            emitNodeWithWriter(node.name, writeParameter);
            emit(node.questionToken);
            if (node.parent && node.parent.kind === 295 /* JSDocFunctionType */ && !node.name) {
                emit(node.type);
            }
            else {
                emitTypeAnnotation(node.type);
            }
            // The comment position has to fallback to any present node within the parameterdeclaration because as it turns out, the parser can make parameter declarations with _just_ an initializer.
            emitInitializer(node.initializer, node.type ? node.type.end : node.questionToken ? node.questionToken.end : node.name ? node.name.end : node.modifiers ? node.modifiers.end : node.decorators ? node.decorators.end : node.pos, node);
        }
        function emitDecorator(decorator) {
            writePunctuation("@");
            emitExpression(decorator.expression);
        }
        //
        // Type members
        //
        function emitPropertySignature(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitNodeWithWriter(node.name, writeProperty);
            emit(node.questionToken);
            emitTypeAnnotation(node.type);
            writeTrailingSemicolon();
        }
        function emitPropertyDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emit(node.name);
            emit(node.questionToken);
            emit(node.exclamationToken);
            emitTypeAnnotation(node.type);
            emitInitializer(node.initializer, node.type ? node.type.end : node.questionToken ? node.questionToken.end : node.name.end, node);
            writeTrailingSemicolon();
        }
        function emitMethodSignature(node) {
            pushNameGenerationScope(node);
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emit(node.name);
            emit(node.questionToken);
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitTypeAnnotation(node.type);
            writeTrailingSemicolon();
            popNameGenerationScope(node);
        }
        function emitMethodDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emit(node.asteriskToken);
            emit(node.name);
            emit(node.questionToken);
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitConstructor(node) {
            emitModifiers(node, node.modifiers);
            writeKeyword("constructor");
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitAccessorDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword(node.kind === 159 /* GetAccessor */ ? "get" : "set");
            writeSpace();
            emit(node.name);
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitCallSignature(node) {
            pushNameGenerationScope(node);
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitTypeAnnotation(node.type);
            writeTrailingSemicolon();
            popNameGenerationScope(node);
        }
        function emitConstructSignature(node) {
            pushNameGenerationScope(node);
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword("new");
            writeSpace();
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitTypeAnnotation(node.type);
            writeTrailingSemicolon();
            popNameGenerationScope(node);
        }
        function emitIndexSignature(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitParametersForIndexSignature(node, node.parameters);
            emitTypeAnnotation(node.type);
            writeTrailingSemicolon();
        }
        function emitSemicolonClassElement() {
            writeTrailingSemicolon();
        }
        //
        // Types
        //
        function emitTypePredicate(node) {
            emit(node.parameterName);
            writeSpace();
            writeKeyword("is");
            writeSpace();
            emit(node.type);
        }
        function emitTypeReference(node) {
            emit(node.typeName);
            emitTypeArguments(node, node.typeArguments);
        }
        function emitFunctionType(node) {
            pushNameGenerationScope(node);
            emitTypeParameters(node, node.typeParameters);
            emitParametersForArrow(node, node.parameters);
            writeSpace();
            writePunctuation("=>");
            writeSpace();
            emit(node.type);
            popNameGenerationScope(node);
        }
        function emitJSDocFunctionType(node) {
            writeKeyword("function");
            emitParameters(node, node.parameters);
            writePunctuation(":");
            emit(node.type);
        }
        function emitJSDocNullableType(node) {
            writePunctuation("?");
            emit(node.type);
        }
        function emitJSDocNonNullableType(node) {
            writePunctuation("!");
            emit(node.type);
        }
        function emitJSDocOptionalType(node) {
            emit(node.type);
            writePunctuation("=");
        }
        function emitConstructorType(node) {
            pushNameGenerationScope(node);
            writeKeyword("new");
            writeSpace();
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            writeSpace();
            writePunctuation("=>");
            writeSpace();
            emit(node.type);
            popNameGenerationScope(node);
        }
        function emitTypeQuery(node) {
            writeKeyword("typeof");
            writeSpace();
            emit(node.exprName);
        }
        function emitTypeLiteral(node) {
            writePunctuation("{");
            var flags = ts.getEmitFlags(node) & 1 /* SingleLine */ ? 768 /* SingleLineTypeLiteralMembers */ : 32897 /* MultiLineTypeLiteralMembers */;
            emitList(node, node.members, flags | 524288 /* NoSpaceIfEmpty */);
            writePunctuation("}");
        }
        function emitArrayType(node) {
            emit(node.elementType);
            writePunctuation("[");
            writePunctuation("]");
        }
        function emitRestOrJSDocVariadicType(node) {
            writePunctuation("...");
            emit(node.type);
        }
        function emitTupleType(node) {
            writePunctuation("[");
            emitList(node, node.elementTypes, 528 /* TupleTypeElements */);
            writePunctuation("]");
        }
        function emitOptionalType(node) {
            emit(node.type);
            writePunctuation("?");
        }
        function emitUnionType(node) {
            emitList(node, node.types, 516 /* UnionTypeConstituents */);
        }
        function emitIntersectionType(node) {
            emitList(node, node.types, 520 /* IntersectionTypeConstituents */);
        }
        function emitConditionalType(node) {
            emit(node.checkType);
            writeSpace();
            writeKeyword("extends");
            writeSpace();
            emit(node.extendsType);
            writeSpace();
            writePunctuation("?");
            writeSpace();
            emit(node.trueType);
            writeSpace();
            writePunctuation(":");
            writeSpace();
            emit(node.falseType);
        }
        function emitInferType(node) {
            writeKeyword("infer");
            writeSpace();
            emit(node.typeParameter);
        }
        function emitParenthesizedType(node) {
            writePunctuation("(");
            emit(node.type);
            writePunctuation(")");
        }
        function emitThisType() {
            writeKeyword("this");
        }
        function emitTypeOperator(node) {
            writeTokenText(node.operator, writeKeyword);
            writeSpace();
            emit(node.type);
        }
        function emitIndexedAccessType(node) {
            emit(node.objectType);
            writePunctuation("[");
            emit(node.indexType);
            writePunctuation("]");
        }
        function emitMappedType(node) {
            var emitFlags = ts.getEmitFlags(node);
            writePunctuation("{");
            if (emitFlags & 1 /* SingleLine */) {
                writeSpace();
            }
            else {
                writeLine();
                increaseIndent();
            }
            if (node.readonlyToken) {
                emit(node.readonlyToken);
                if (node.readonlyToken.kind !== 134 /* ReadonlyKeyword */) {
                    writeKeyword("readonly");
                }
                writeSpace();
            }
            writePunctuation("[");
            var pipelinePhase = getPipelinePhase(0 /* Notification */, node.typeParameter);
            pipelinePhase(3 /* MappedTypeParameter */, node.typeParameter);
            writePunctuation("]");
            if (node.questionToken) {
                emit(node.questionToken);
                if (node.questionToken.kind !== 56 /* QuestionToken */) {
                    writePunctuation("?");
                }
            }
            writePunctuation(":");
            writeSpace();
            emit(node.type);
            writeTrailingSemicolon();
            if (emitFlags & 1 /* SingleLine */) {
                writeSpace();
            }
            else {
                writeLine();
                decreaseIndent();
            }
            writePunctuation("}");
        }
        function emitLiteralType(node) {
            emitExpression(node.literal);
        }
        function emitImportTypeNode(node) {
            if (node.isTypeOf) {
                writeKeyword("typeof");
                writeSpace();
            }
            writeKeyword("import");
            writePunctuation("(");
            emit(node.argument);
            writePunctuation(")");
            if (node.qualifier) {
                writePunctuation(".");
                emit(node.qualifier);
            }
            emitTypeArguments(node, node.typeArguments);
        }
        //
        // Binding patterns
        //
        function emitObjectBindingPattern(node) {
            writePunctuation("{");
            emitList(node, node.elements, 525136 /* ObjectBindingPatternElements */);
            writePunctuation("}");
        }
        function emitArrayBindingPattern(node) {
            writePunctuation("[");
            emitList(node, node.elements, 524880 /* ArrayBindingPatternElements */);
            writePunctuation("]");
        }
        function emitBindingElement(node) {
            emit(node.dotDotDotToken);
            if (node.propertyName) {
                emit(node.propertyName);
                writePunctuation(":");
                writeSpace();
            }
            emit(node.name);
            emitInitializer(node.initializer, node.name.end, node);
        }
        //
        // Expressions
        //
        function emitArrayLiteralExpression(node) {
            var elements = node.elements;
            var preferNewLine = node.multiLine ? 65536 /* PreferNewLine */ : 0 /* None */;
            emitExpressionList(node, elements, 8914 /* ArrayLiteralExpressionElements */ | preferNewLine);
        }
        function emitObjectLiteralExpression(node) {
            ts.forEach(node.properties, generateMemberNames);
            var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */;
            if (indentedFlag) {
                increaseIndent();
            }
            var preferNewLine = node.multiLine ? 65536 /* PreferNewLine */ : 0 /* None */;
            var allowTrailingComma = currentSourceFile.languageVersion >= 1 /* ES5 */ && !ts.isJsonSourceFile(currentSourceFile) ? 64 /* AllowTrailingComma */ : 0 /* None */;
            emitList(node, node.properties, 526226 /* ObjectLiteralExpressionProperties */ | allowTrailingComma | preferNewLine);
            if (indentedFlag) {
                decreaseIndent();
            }
        }
        function emitPropertyAccessExpression(node) {
            var indentBeforeDot = false;
            var indentAfterDot = false;
            var dotRangeFirstCommentStart = ts.skipTrivia(currentSourceFile.text, node.expression.end, 
            /*stopAfterLineBreak*/ false, 
            /*stopAtComments*/ true);
            var dotRangeStart = ts.skipTrivia(currentSourceFile.text, dotRangeFirstCommentStart);
            var dotRangeEnd = dotRangeStart + 1;
            if (!(ts.getEmitFlags(node) & 131072 /* NoIndentation */)) {
                var dotToken = ts.createToken(24 /* DotToken */);
                dotToken.pos = node.expression.end;
                dotToken.end = dotRangeEnd;
                indentBeforeDot = needsIndentation(node, node.expression, dotToken);
                indentAfterDot = needsIndentation(node, dotToken, node.name);
            }
            emitExpression(node.expression);
            increaseIndentIf(indentBeforeDot, /*writeSpaceIfNotIndenting*/ false);
            var dotHasCommentTrivia = dotRangeFirstCommentStart !== dotRangeStart;
            var shouldEmitDotDot = !indentBeforeDot && needsDotDotForPropertyAccess(node.expression, dotHasCommentTrivia);
            if (shouldEmitDotDot) {
                writePunctuation(".");
            }
            emitTokenWithComment(24 /* DotToken */, node.expression.end, writePunctuation, node);
            increaseIndentIf(indentAfterDot, /*writeSpaceIfNotIndenting*/ false);
            emit(node.name);
            decreaseIndentIf(indentBeforeDot, indentAfterDot);
        }
        // 1..toString is a valid property access, emit a dot after the literal
        // Also emit a dot if expression is a integer const enum value - it will appear in generated code as numeric literal
        function needsDotDotForPropertyAccess(expression, dotHasTrivia) {
            expression = ts.skipPartiallyEmittedExpressions(expression);
            if (ts.isNumericLiteral(expression)) {
                // check if numeric literal is a decimal literal that was originally written with a dot
                var text = getLiteralTextOfNode(expression, /*neverAsciiEscape*/ true);
                // If he number will be printed verbatim and it doesn't already contain a dot, add one
                // if the expression doesn't have any comments that will be emitted.
                return !expression.numericLiteralFlags && !ts.stringContains(text, ts.tokenToString(24 /* DotToken */)) &&
                    (!dotHasTrivia || printerOptions.removeComments);
            }
            else if (ts.isPropertyAccessExpression(expression) || ts.isElementAccessExpression(expression)) {
                // check if constant enum value is integer
                var constantValue = ts.getConstantValue(expression);
                // isFinite handles cases when constantValue is undefined
                return typeof constantValue === "number" && isFinite(constantValue)
                    && Math.floor(constantValue) === constantValue
                    && printerOptions.removeComments;
            }
        }
        function emitElementAccessExpression(node) {
            emitExpression(node.expression);
            emitTokenWithComment(22 /* OpenBracketToken */, node.expression.end, writePunctuation, node);
            emitExpression(node.argumentExpression);
            emitTokenWithComment(23 /* CloseBracketToken */, node.argumentExpression.end, writePunctuation, node);
        }
        function emitCallExpression(node) {
            emitExpression(node.expression);
            emitTypeArguments(node, node.typeArguments);
            emitExpressionList(node, node.arguments, 2576 /* CallExpressionArguments */);
        }
        function emitNewExpression(node) {
            emitTokenWithComment(96 /* NewKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
            emitTypeArguments(node, node.typeArguments);
            emitExpressionList(node, node.arguments, 18960 /* NewExpressionArguments */);
        }
        function emitTaggedTemplateExpression(node) {
            emitExpression(node.tag);
            emitTypeArguments(node, node.typeArguments);
            writeSpace();
            emitExpression(node.template);
        }
        function emitTypeAssertionExpression(node) {
            writePunctuation("<");
            emit(node.type);
            writePunctuation(">");
            emitExpression(node.expression);
        }
        function emitParenthesizedExpression(node) {
            var openParenPos = emitTokenWithComment(20 /* OpenParenToken */, node.pos, writePunctuation, node);
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression ? node.expression.end : openParenPos, writePunctuation, node);
        }
        function emitFunctionExpression(node) {
            generateNameIfNeeded(node.name);
            emitFunctionDeclarationOrExpression(node);
        }
        function emitArrowFunction(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitSignatureAndBody(node, emitArrowFunctionHead);
        }
        function emitArrowFunctionHead(node) {
            emitTypeParameters(node, node.typeParameters);
            emitParametersForArrow(node, node.parameters);
            emitTypeAnnotation(node.type);
            writeSpace();
            emit(node.equalsGreaterThanToken);
        }
        function emitDeleteExpression(node) {
            emitTokenWithComment(82 /* DeleteKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
        }
        function emitTypeOfExpression(node) {
            emitTokenWithComment(105 /* TypeOfKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
        }
        function emitVoidExpression(node) {
            emitTokenWithComment(107 /* VoidKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
        }
        function emitAwaitExpression(node) {
            emitTokenWithComment(123 /* AwaitKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
        }
        function emitPrefixUnaryExpression(node) {
            writeTokenText(node.operator, writeOperator);
            if (shouldEmitWhitespaceBeforeOperand(node)) {
                writeSpace();
            }
            emitExpression(node.operand);
        }
        function shouldEmitWhitespaceBeforeOperand(node) {
            // In some cases, we need to emit a space between the operator and the operand. One obvious case
            // is when the operator is an identifier, like delete or typeof. We also need to do this for plus
            // and minus expressions in certain cases. Specifically, consider the following two cases (parens
            // are just for clarity of exposition, and not part of the source code):
            //
            //  (+(+1))
            //  (+(++1))
            //
            // We need to emit a space in both cases. In the first case, the absence of a space will make
            // the resulting expression a prefix increment operation. And in the second, it will make the resulting
            // expression a prefix increment whose operand is a plus expression - (++(+x))
            // The same is true of minus of course.
            var operand = node.operand;
            return operand.kind === 203 /* PrefixUnaryExpression */
                && ((node.operator === 38 /* PlusToken */ && (operand.operator === 38 /* PlusToken */ || operand.operator === 44 /* PlusPlusToken */))
                    || (node.operator === 39 /* MinusToken */ && (operand.operator === 39 /* MinusToken */ || operand.operator === 45 /* MinusMinusToken */)));
        }
        function emitPostfixUnaryExpression(node) {
            emitExpression(node.operand);
            writeTokenText(node.operator, writeOperator);
        }
        function emitBinaryExpression(node) {
            var isCommaOperator = node.operatorToken.kind !== 27 /* CommaToken */;
            var indentBeforeOperator = needsIndentation(node, node.left, node.operatorToken);
            var indentAfterOperator = needsIndentation(node, node.operatorToken, node.right);
            emitExpression(node.left);
            increaseIndentIf(indentBeforeOperator, isCommaOperator);
            emitLeadingCommentsOfPosition(node.operatorToken.pos);
            writeTokenNode(node.operatorToken, node.operatorToken.kind === 94 /* InKeyword */ ? writeKeyword : writeOperator);
            emitTrailingCommentsOfPosition(node.operatorToken.end, /*prefixSpace*/ true); // Binary operators should have a space before the comment starts
            increaseIndentIf(indentAfterOperator, /*writeSpaceIfNotIndenting*/ true);
            emitExpression(node.right);
            decreaseIndentIf(indentBeforeOperator, indentAfterOperator);
        }
        function emitConditionalExpression(node) {
            var indentBeforeQuestion = needsIndentation(node, node.condition, node.questionToken);
            var indentAfterQuestion = needsIndentation(node, node.questionToken, node.whenTrue);
            var indentBeforeColon = needsIndentation(node, node.whenTrue, node.colonToken);
            var indentAfterColon = needsIndentation(node, node.colonToken, node.whenFalse);
            emitExpression(node.condition);
            increaseIndentIf(indentBeforeQuestion, /*writeSpaceIfNotIndenting*/ true);
            emit(node.questionToken);
            increaseIndentIf(indentAfterQuestion, /*writeSpaceIfNotIndenting*/ true);
            emitExpression(node.whenTrue);
            decreaseIndentIf(indentBeforeQuestion, indentAfterQuestion);
            increaseIndentIf(indentBeforeColon, /*writeSpaceIfNotIndenting*/ true);
            emit(node.colonToken);
            increaseIndentIf(indentAfterColon, /*writeSpaceIfNotIndenting*/ true);
            emitExpression(node.whenFalse);
            decreaseIndentIf(indentBeforeColon, indentAfterColon);
        }
        function emitTemplateExpression(node) {
            emit(node.head);
            emitList(node, node.templateSpans, 262144 /* TemplateExpressionSpans */);
        }
        function emitYieldExpression(node) {
            emitTokenWithComment(118 /* YieldKeyword */, node.pos, writeKeyword, node);
            emit(node.asteriskToken);
            emitExpressionWithLeadingSpace(node.expression);
        }
        function emitSpreadExpression(node) {
            emitTokenWithComment(25 /* DotDotDotToken */, node.pos, writePunctuation, node);
            emitExpression(node.expression);
        }
        function emitClassExpression(node) {
            generateNameIfNeeded(node.name);
            emitClassDeclarationOrExpression(node);
        }
        function emitExpressionWithTypeArguments(node) {
            emitExpression(node.expression);
            emitTypeArguments(node, node.typeArguments);
        }
        function emitAsExpression(node) {
            emitExpression(node.expression);
            if (node.type) {
                writeSpace();
                writeKeyword("as");
                writeSpace();
                emit(node.type);
            }
        }
        function emitNonNullExpression(node) {
            emitExpression(node.expression);
            writeOperator("!");
        }
        function emitMetaProperty(node) {
            writeToken(node.keywordToken, node.pos, writePunctuation);
            writePunctuation(".");
            emit(node.name);
        }
        //
        // Misc
        //
        function emitTemplateSpan(node) {
            emitExpression(node.expression);
            emit(node.literal);
        }
        //
        // Statements
        //
        function emitBlock(node) {
            emitBlockStatements(node, /*forceSingleLine*/ !node.multiLine && isEmptyBlock(node));
        }
        function emitBlockStatements(node, forceSingleLine) {
            emitTokenWithComment(18 /* OpenBraceToken */, node.pos, writePunctuation, /*contextNode*/ node);
            var format = forceSingleLine || ts.getEmitFlags(node) & 1 /* SingleLine */ ? 768 /* SingleLineBlockStatements */ : 129 /* MultiLineBlockStatements */;
            emitList(node, node.statements, format);
            emitTokenWithComment(19 /* CloseBraceToken */, node.statements.end, writePunctuation, /*contextNode*/ node, /*indentLeading*/ !!(format & 1 /* MultiLine */));
        }
        function emitVariableStatement(node) {
            emitModifiers(node, node.modifiers);
            emit(node.declarationList);
            writeTrailingSemicolon();
        }
        function emitEmptyStatement(isEmbeddedStatement) {
            // While most trailing semicolons are possibly insignificant, an embedded "empty"
            // statement is significant and cannot be elided by a trailing-semicolon-omitting writer.
            if (isEmbeddedStatement) {
                writePunctuation(";");
            }
            else {
                writeTrailingSemicolon();
            }
        }
        function emitExpressionStatement(node) {
            emitExpression(node.expression);
            // Emit semicolon in non json files
            // or if json file that created synthesized expression(eg.define expression statement when --out and amd code generation)
            if (!ts.isJsonSourceFile(currentSourceFile) || ts.nodeIsSynthesized(node.expression)) {
                writeTrailingSemicolon();
            }
        }
        function emitIfStatement(node) {
            var openParenPos = emitTokenWithComment(92 /* IfKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
            emitEmbeddedStatement(node, node.thenStatement);
            if (node.elseStatement) {
                writeLineOrSpace(node);
                emitTokenWithComment(84 /* ElseKeyword */, node.thenStatement.end, writeKeyword, node);
                if (node.elseStatement.kind === 223 /* IfStatement */) {
                    writeSpace();
                    emit(node.elseStatement);
                }
                else {
                    emitEmbeddedStatement(node, node.elseStatement);
                }
            }
        }
        function emitWhileClause(node, startPos) {
            var openParenPos = emitTokenWithComment(108 /* WhileKeyword */, startPos, writeKeyword, node);
            writeSpace();
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
        }
        function emitDoStatement(node) {
            emitTokenWithComment(83 /* DoKeyword */, node.pos, writeKeyword, node);
            emitEmbeddedStatement(node, node.statement);
            if (ts.isBlock(node.statement)) {
                writeSpace();
            }
            else {
                writeLineOrSpace(node);
            }
            emitWhileClause(node, node.statement.end);
            writePunctuation(";");
        }
        function emitWhileStatement(node) {
            emitWhileClause(node, node.pos);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForStatement(node) {
            var openParenPos = emitTokenWithComment(90 /* ForKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            var pos = emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, /*contextNode*/ node);
            emitForBinding(node.initializer);
            pos = emitTokenWithComment(26 /* SemicolonToken */, node.initializer ? node.initializer.end : pos, writePunctuation, node);
            emitExpressionWithLeadingSpace(node.condition);
            pos = emitTokenWithComment(26 /* SemicolonToken */, node.condition ? node.condition.end : pos, writePunctuation, node);
            emitExpressionWithLeadingSpace(node.incrementor);
            emitTokenWithComment(21 /* CloseParenToken */, node.incrementor ? node.incrementor.end : pos, writePunctuation, node);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForInStatement(node) {
            var openParenPos = emitTokenWithComment(90 /* ForKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitForBinding(node.initializer);
            writeSpace();
            emitTokenWithComment(94 /* InKeyword */, node.initializer.end, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForOfStatement(node) {
            var openParenPos = emitTokenWithComment(90 /* ForKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitWithTrailingSpace(node.awaitModifier);
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitForBinding(node.initializer);
            writeSpace();
            emitTokenWithComment(148 /* OfKeyword */, node.initializer.end, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForBinding(node) {
            if (node !== undefined) {
                if (node.kind === 239 /* VariableDeclarationList */) {
                    emit(node);
                }
                else {
                    emitExpression(node);
                }
            }
        }
        function emitContinueStatement(node) {
            emitTokenWithComment(79 /* ContinueKeyword */, node.pos, writeKeyword, node);
            emitWithLeadingSpace(node.label);
            writeTrailingSemicolon();
        }
        function emitBreakStatement(node) {
            emitTokenWithComment(74 /* BreakKeyword */, node.pos, writeKeyword, node);
            emitWithLeadingSpace(node.label);
            writeTrailingSemicolon();
        }
        function emitTokenWithComment(token, pos, writer, contextNode, indentLeading) {
            var node = ts.getParseTreeNode(contextNode);
            var isSimilarNode = node && node.kind === contextNode.kind;
            var startPos = pos;
            if (isSimilarNode) {
                pos = ts.skipTrivia(currentSourceFile.text, pos);
            }
            if (emitLeadingCommentsOfPosition && isSimilarNode && contextNode.pos !== startPos) {
                var needsIndent = indentLeading && !ts.positionsAreOnSameLine(startPos, pos, currentSourceFile);
                if (needsIndent) {
                    increaseIndent();
                }
                emitLeadingCommentsOfPosition(startPos);
                if (needsIndent) {
                    decreaseIndent();
                }
            }
            pos = writeTokenText(token, writer, pos);
            if (emitTrailingCommentsOfPosition && isSimilarNode && contextNode.end !== pos) {
                emitTrailingCommentsOfPosition(pos, /*prefixSpace*/ true);
            }
            return pos;
        }
        function emitReturnStatement(node) {
            emitTokenWithComment(98 /* ReturnKeyword */, node.pos, writeKeyword, /*contextNode*/ node);
            emitExpressionWithLeadingSpace(node.expression);
            writeTrailingSemicolon();
        }
        function emitWithStatement(node) {
            var openParenPos = emitTokenWithComment(109 /* WithKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitSwitchStatement(node) {
            var openParenPos = emitTokenWithComment(100 /* SwitchKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
            writeSpace();
            emit(node.caseBlock);
        }
        function emitLabeledStatement(node) {
            emit(node.label);
            emitTokenWithComment(57 /* ColonToken */, node.label.end, writePunctuation, node);
            writeSpace();
            emit(node.statement);
        }
        function emitThrowStatement(node) {
            emitTokenWithComment(102 /* ThrowKeyword */, node.pos, writeKeyword, node);
            emitExpressionWithLeadingSpace(node.expression);
            writeTrailingSemicolon();
        }
        function emitTryStatement(node) {
            emitTokenWithComment(104 /* TryKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emit(node.tryBlock);
            if (node.catchClause) {
                writeLineOrSpace(node);
                emit(node.catchClause);
            }
            if (node.finallyBlock) {
                writeLineOrSpace(node);
                emitTokenWithComment(89 /* FinallyKeyword */, (node.catchClause || node.tryBlock).end, writeKeyword, node);
                writeSpace();
                emit(node.finallyBlock);
            }
        }
        function emitDebuggerStatement(node) {
            writeToken(80 /* DebuggerKeyword */, node.pos, writeKeyword);
            writeTrailingSemicolon();
        }
        //
        // Declarations
        //
        function emitVariableDeclaration(node) {
            emit(node.name);
            emitTypeAnnotation(node.type);
            emitInitializer(node.initializer, node.type ? node.type.end : node.name.end, node);
        }
        function emitVariableDeclarationList(node) {
            writeKeyword(ts.isLet(node) ? "let" : ts.isVarConst(node) ? "const" : "var");
            writeSpace();
            emitList(node, node.declarations, 528 /* VariableDeclarationList */);
        }
        function emitFunctionDeclaration(node) {
            emitFunctionDeclarationOrExpression(node);
        }
        function emitFunctionDeclarationOrExpression(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword("function");
            emit(node.asteriskToken);
            writeSpace();
            emitIdentifierName(node.name); // TODO: GH#18217
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitBlockCallback(_hint, body) {
            emitBlockFunctionBody(body);
        }
        function emitSignatureAndBody(node, emitSignatureHead) {
            var body = node.body;
            if (body) {
                if (ts.isBlock(body)) {
                    var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */;
                    if (indentedFlag) {
                        increaseIndent();
                    }
                    pushNameGenerationScope(node);
                    ts.forEach(node.parameters, generateNames);
                    generateNames(node.body);
                    emitSignatureHead(node);
                    if (onEmitNode) {
                        onEmitNode(4 /* Unspecified */, body, emitBlockCallback);
                    }
                    else {
                        emitBlockFunctionBody(body);
                    }
                    popNameGenerationScope(node);
                    if (indentedFlag) {
                        decreaseIndent();
                    }
                }
                else {
                    emitSignatureHead(node);
                    writeSpace();
                    emitExpression(body);
                }
            }
            else {
                emitSignatureHead(node);
                writeTrailingSemicolon();
            }
        }
        function emitSignatureHead(node) {
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitTypeAnnotation(node.type);
        }
        function shouldEmitBlockFunctionBodyOnSingleLine(body) {
            // We must emit a function body as a single-line body in the following case:
            // * The body has NodeEmitFlags.SingleLine specified.
            // We must emit a function body as a multi-line body in the following cases:
            // * The body is explicitly marked as multi-line.
            // * A non-synthesized body's start and end position are on different lines.
            // * Any statement in the body starts on a new line.
            if (ts.getEmitFlags(body) & 1 /* SingleLine */) {
                return true;
            }
            if (body.multiLine) {
                return false;
            }
            if (!ts.nodeIsSynthesized(body) && !ts.rangeIsOnSingleLine(body, currentSourceFile)) {
                return false;
            }
            if (shouldWriteLeadingLineTerminator(body, body.statements, 2 /* PreserveLines */)
                || shouldWriteClosingLineTerminator(body, body.statements, 2 /* PreserveLines */)) {
                return false;
            }
            var previousStatement;
            for (var _a = 0, _b = body.statements; _a < _b.length; _a++) {
                var statement = _b[_a];
                if (shouldWriteSeparatingLineTerminator(previousStatement, statement, 2 /* PreserveLines */)) {
                    return false;
                }
                previousStatement = statement;
            }
            return true;
        }
        function emitBlockFunctionBody(body) {
            writeSpace();
            writePunctuation("{");
            increaseIndent();
            var emitBlockFunctionBody = shouldEmitBlockFunctionBodyOnSingleLine(body)
                ? emitBlockFunctionBodyOnSingleLine
                : emitBlockFunctionBodyWorker;
            if (emitBodyWithDetachedComments) {
                emitBodyWithDetachedComments(body, body.statements, emitBlockFunctionBody);
            }
            else {
                emitBlockFunctionBody(body);
            }
            decreaseIndent();
            writeToken(19 /* CloseBraceToken */, body.statements.end, writePunctuation, body);
        }
        function emitBlockFunctionBodyOnSingleLine(body) {
            emitBlockFunctionBodyWorker(body, /*emitBlockFunctionBodyOnSingleLine*/ true);
        }
        function emitBlockFunctionBodyWorker(body, emitBlockFunctionBodyOnSingleLine) {
            // Emit all the prologue directives (like "use strict").
            var statementOffset = emitPrologueDirectives(body.statements);
            var pos = writer.getTextPos();
            emitHelpers(body);
            if (statementOffset === 0 && pos === writer.getTextPos() && emitBlockFunctionBodyOnSingleLine) {
                decreaseIndent();
                emitList(body, body.statements, 768 /* SingleLineFunctionBodyStatements */);
                increaseIndent();
            }
            else {
                emitList(body, body.statements, 1 /* MultiLineFunctionBodyStatements */, statementOffset);
            }
        }
        function emitClassDeclaration(node) {
            emitClassDeclarationOrExpression(node);
        }
        function emitClassDeclarationOrExpression(node) {
            ts.forEach(node.members, generateMemberNames);
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword("class");
            if (node.name) {
                writeSpace();
                emitIdentifierName(node.name);
            }
            var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */;
            if (indentedFlag) {
                increaseIndent();
            }
            emitTypeParameters(node, node.typeParameters);
            emitList(node, node.heritageClauses, 0 /* ClassHeritageClauses */);
            writeSpace();
            writePunctuation("{");
            emitList(node, node.members, 129 /* ClassMembers */);
            writePunctuation("}");
            if (indentedFlag) {
                decreaseIndent();
            }
        }
        function emitInterfaceDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword("interface");
            writeSpace();
            emit(node.name);
            emitTypeParameters(node, node.typeParameters);
            emitList(node, node.heritageClauses, 512 /* HeritageClauses */);
            writeSpace();
            writePunctuation("{");
            emitList(node, node.members, 129 /* InterfaceMembers */);
            writePunctuation("}");
        }
        function emitTypeAliasDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword("type");
            writeSpace();
            emit(node.name);
            emitTypeParameters(node, node.typeParameters);
            writeSpace();
            writePunctuation("=");
            writeSpace();
            emit(node.type);
            writeTrailingSemicolon();
        }
        function emitEnumDeclaration(node) {
            emitModifiers(node, node.modifiers);
            writeKeyword("enum");
            writeSpace();
            emit(node.name);
            writeSpace();
            writePunctuation("{");
            emitList(node, node.members, 145 /* EnumMembers */);
            writePunctuation("}");
        }
        function emitModuleDeclaration(node) {
            emitModifiers(node, node.modifiers);
            if (~node.flags & 512 /* GlobalAugmentation */) {
                writeKeyword(node.flags & 16 /* Namespace */ ? "namespace" : "module");
                writeSpace();
            }
            emit(node.name);
            var body = node.body;
            if (!body)
                return writeTrailingSemicolon();
            while (body.kind === 245 /* ModuleDeclaration */) {
                writePunctuation(".");
                emit(body.name);
                body = body.body;
            }
            writeSpace();
            emit(body);
        }
        function emitModuleBlock(node) {
            pushNameGenerationScope(node);
            ts.forEach(node.statements, generateNames);
            emitBlockStatements(node, /*forceSingleLine*/ isEmptyBlock(node));
            popNameGenerationScope(node);
        }
        function emitCaseBlock(node) {
            emitTokenWithComment(18 /* OpenBraceToken */, node.pos, writePunctuation, node);
            emitList(node, node.clauses, 129 /* CaseBlockClauses */);
            emitTokenWithComment(19 /* CloseBraceToken */, node.clauses.end, writePunctuation, node, /*indentLeading*/ true);
        }
        function emitImportEqualsDeclaration(node) {
            emitModifiers(node, node.modifiers);
            emitTokenWithComment(93 /* ImportKeyword */, node.modifiers ? node.modifiers.end : node.pos, writeKeyword, node);
            writeSpace();
            emit(node.name);
            writeSpace();
            emitTokenWithComment(60 /* EqualsToken */, node.name.end, writePunctuation, node);
            writeSpace();
            emitModuleReference(node.moduleReference);
            writeTrailingSemicolon();
        }
        function emitModuleReference(node) {
            if (node.kind === 73 /* Identifier */) {
                emitExpression(node);
            }
            else {
                emit(node);
            }
        }
        function emitImportDeclaration(node) {
            emitModifiers(node, node.modifiers);
            emitTokenWithComment(93 /* ImportKeyword */, node.modifiers ? node.modifiers.end : node.pos, writeKeyword, node);
            writeSpace();
            if (node.importClause) {
                emit(node.importClause);
                writeSpace();
                emitTokenWithComment(145 /* FromKeyword */, node.importClause.end, writeKeyword, node);
                writeSpace();
            }
            emitExpression(node.moduleSpecifier);
            writeTrailingSemicolon();
        }
        function emitImportClause(node) {
            emit(node.name);
            if (node.name && node.namedBindings) {
                emitTokenWithComment(27 /* CommaToken */, node.name.end, writePunctuation, node);
                writeSpace();
            }
            emit(node.namedBindings);
        }
        function emitNamespaceImport(node) {
            var asPos = emitTokenWithComment(40 /* AsteriskToken */, node.pos, writePunctuation, node);
            writeSpace();
            emitTokenWithComment(120 /* AsKeyword */, asPos, writeKeyword, node);
            writeSpace();
            emit(node.name);
        }
        function emitNamedImports(node) {
            emitNamedImportsOrExports(node);
        }
        function emitImportSpecifier(node) {
            emitImportOrExportSpecifier(node);
        }
        function emitExportAssignment(node) {
            var nextPos = emitTokenWithComment(86 /* ExportKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            if (node.isExportEquals) {
                emitTokenWithComment(60 /* EqualsToken */, nextPos, writeOperator, node);
            }
            else {
                emitTokenWithComment(81 /* DefaultKeyword */, nextPos, writeKeyword, node);
            }
            writeSpace();
            emitExpression(node.expression);
            writeTrailingSemicolon();
        }
        function emitExportDeclaration(node) {
            var nextPos = emitTokenWithComment(86 /* ExportKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            if (node.exportClause) {
                emit(node.exportClause);
            }
            else {
                nextPos = emitTokenWithComment(40 /* AsteriskToken */, nextPos, writePunctuation, node);
            }
            if (node.moduleSpecifier) {
                writeSpace();
                var fromPos = node.exportClause ? node.exportClause.end : nextPos;
                emitTokenWithComment(145 /* FromKeyword */, fromPos, writeKeyword, node);
                writeSpace();
                emitExpression(node.moduleSpecifier);
            }
            writeTrailingSemicolon();
        }
        function emitNamespaceExportDeclaration(node) {
            var nextPos = emitTokenWithComment(86 /* ExportKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            nextPos = emitTokenWithComment(120 /* AsKeyword */, nextPos, writeKeyword, node);
            writeSpace();
            nextPos = emitTokenWithComment(132 /* NamespaceKeyword */, nextPos, writeKeyword, node);
            writeSpace();
            emit(node.name);
            writeTrailingSemicolon();
        }
        function emitNamedExports(node) {
            emitNamedImportsOrExports(node);
        }
        function emitExportSpecifier(node) {
            emitImportOrExportSpecifier(node);
        }
        function emitNamedImportsOrExports(node) {
            writePunctuation("{");
            emitList(node, node.elements, 525136 /* NamedImportsOrExportsElements */);
            writePunctuation("}");
        }
        function emitImportOrExportSpecifier(node) {
            if (node.propertyName) {
                emit(node.propertyName);
                writeSpace();
                emitTokenWithComment(120 /* AsKeyword */, node.propertyName.end, writeKeyword, node);
                writeSpace();
            }
            emit(node.name);
        }
        //
        // Module references
        //
        function emitExternalModuleReference(node) {
            writeKeyword("require");
            writePunctuation("(");
            emitExpression(node.expression);
            writePunctuation(")");
        }
        //
        // JSX
        //
        function emitJsxElement(node) {
            emit(node.openingElement);
            emitList(node, node.children, 262144 /* JsxElementOrFragmentChildren */);
            emit(node.closingElement);
        }
        function emitJsxSelfClosingElement(node) {
            writePunctuation("<");
            emitJsxTagName(node.tagName);
            emitTypeArguments(node, node.typeArguments);
            writeSpace();
            emit(node.attributes);
            writePunctuation("/>");
        }
        function emitJsxFragment(node) {
            emit(node.openingFragment);
            emitList(node, node.children, 262144 /* JsxElementOrFragmentChildren */);
            emit(node.closingFragment);
        }
        function emitJsxOpeningElementOrFragment(node) {
            writePunctuation("<");
            if (ts.isJsxOpeningElement(node)) {
                emitJsxTagName(node.tagName);
                emitTypeArguments(node, node.typeArguments);
                if (node.attributes.properties && node.attributes.properties.length > 0) {
                    writeSpace();
                }
                emit(node.attributes);
            }
            writePunctuation(">");
        }
        function emitJsxText(node) {
            writer.writeLiteral(node.text);
        }
        function emitJsxClosingElementOrFragment(node) {
            writePunctuation("</");
            if (ts.isJsxClosingElement(node)) {
                emitJsxTagName(node.tagName);
            }
            writePunctuation(">");
        }
        function emitJsxAttributes(node) {
            emitList(node, node.properties, 262656 /* JsxElementAttributes */);
        }
        function emitJsxAttribute(node) {
            emit(node.name);
            emitNodeWithPrefix("=", writePunctuation, node.initializer, emit); // TODO: GH#18217
        }
        function emitJsxSpreadAttribute(node) {
            writePunctuation("{...");
            emitExpression(node.expression);
            writePunctuation("}");
        }
        function emitJsxExpression(node) {
            if (node.expression) {
                writePunctuation("{");
                emit(node.dotDotDotToken);
                emitExpression(node.expression);
                writePunctuation("}");
            }
        }
        function emitJsxTagName(node) {
            if (node.kind === 73 /* Identifier */) {
                emitExpression(node);
            }
            else {
                emit(node);
            }
        }
        //
        // Clauses
        //
        function emitCaseClause(node) {
            emitTokenWithComment(75 /* CaseKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
            emitCaseOrDefaultClauseRest(node, node.statements, node.expression.end);
        }
        function emitDefaultClause(node) {
            var pos = emitTokenWithComment(81 /* DefaultKeyword */, node.pos, writeKeyword, node);
            emitCaseOrDefaultClauseRest(node, node.statements, pos);
        }
        function emitCaseOrDefaultClauseRest(parentNode, statements, colonPos) {
            var emitAsSingleStatement = statements.length === 1 &&
                (
                // treat synthesized nodes as located on the same line for emit purposes
                ts.nodeIsSynthesized(parentNode) ||
                    ts.nodeIsSynthesized(statements[0]) ||
                    ts.rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile));
            var format = 163969 /* CaseOrDefaultClauseStatements */;
            if (emitAsSingleStatement) {
                writeToken(57 /* ColonToken */, colonPos, writePunctuation, parentNode);
                writeSpace();
                format &= ~(1 /* MultiLine */ | 128 /* Indented */);
            }
            else {
                emitTokenWithComment(57 /* ColonToken */, colonPos, writePunctuation, parentNode);
            }
            emitList(parentNode, statements, format);
        }
        function emitHeritageClause(node) {
            writeSpace();
            writeTokenText(node.token, writeKeyword);
            writeSpace();
            emitList(node, node.types, 528 /* HeritageClauseTypes */);
        }
        function emitCatchClause(node) {
            var openParenPos = emitTokenWithComment(76 /* CatchKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            if (node.variableDeclaration) {
                emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
                emit(node.variableDeclaration);
                emitTokenWithComment(21 /* CloseParenToken */, node.variableDeclaration.end, writePunctuation, node);
                writeSpace();
            }
            emit(node.block);
        }
        //
        // Property assignments
        //
        function emitPropertyAssignment(node) {
            emit(node.name);
            writePunctuation(":");
            writeSpace();
            // This is to ensure that we emit comment in the following case:
            //      For example:
            //          obj = {
            //              id: /*comment1*/ ()=>void
            //          }
            // "comment1" is not considered to be leading comment for node.initializer
            // but rather a trailing comment on the previous node.
            var initializer = node.initializer;
            if (emitTrailingCommentsOfPosition && (ts.getEmitFlags(initializer) & 512 /* NoLeadingComments */) === 0) {
                var commentRange = ts.getCommentRange(initializer);
                emitTrailingCommentsOfPosition(commentRange.pos);
            }
            emitExpression(initializer);
        }
        function emitShorthandPropertyAssignment(node) {
            emit(node.name);
            if (node.objectAssignmentInitializer) {
                writeSpace();
                writePunctuation("=");
                writeSpace();
                emitExpression(node.objectAssignmentInitializer);
            }
        }
        function emitSpreadAssignment(node) {
            if (node.expression) {
                emitTokenWithComment(25 /* DotDotDotToken */, node.pos, writePunctuation, node);
                emitExpression(node.expression);
            }
        }
        //
        // Enum
        //
        function emitEnumMember(node) {
            emit(node.name);
            emitInitializer(node.initializer, node.name.end, node);
        }
        //
        // JSDoc
        //
        function emitJSDoc(node) {
            write("/**");
            if (node.comment) {
                var lines = node.comment.split(/\r\n?|\n/g);
                for (var _a = 0, lines_2 = lines; _a < lines_2.length; _a++) {
                    var line = lines_2[_a];
                    writeLine();
                    writeSpace();
                    writePunctuation("*");
                    writeSpace();
                    write(line);
                }
            }
            if (node.tags) {
                if (node.tags.length === 1 && node.tags[0].kind === 308 /* JSDocTypeTag */ && !node.comment) {
                    writeSpace();
                    emit(node.tags[0]);
                }
                else {
                    emitList(node, node.tags, 33 /* JSDocComment */);
                }
            }
            writeSpace();
            write("*/");
        }
        function emitJSDocSimpleTypedTag(tag) {
            emitJSDocTagName(tag.tagName);
            emitJSDocTypeExpression(tag.typeExpression);
            emitJSDocComment(tag.comment);
        }
        function emitJSDocAugmentsTag(tag) {
            emitJSDocTagName(tag.tagName);
            writeSpace();
            writePunctuation("{");
            emit(tag.class);
            writePunctuation("}");
            emitJSDocComment(tag.comment);
        }
        function emitJSDocTemplateTag(tag) {
            emitJSDocTagName(tag.tagName);
            emitJSDocTypeExpression(tag.constraint);
            writeSpace();
            emitList(tag, tag.typeParameters, 528 /* CommaListElements */);
            emitJSDocComment(tag.comment);
        }
        function emitJSDocTypedefTag(tag) {
            emitJSDocTagName(tag.tagName);
            if (tag.typeExpression) {
                if (tag.typeExpression.kind === 289 /* JSDocTypeExpression */) {
                    emitJSDocTypeExpression(tag.typeExpression);
                }
                else {
                    writeSpace();
                    writePunctuation("{");
                    write("Object");
                    if (tag.typeExpression.isArrayType) {
                        writePunctuation("[");
                        writePunctuation("]");
                    }
                    writePunctuation("}");
                }
            }
            if (tag.fullName) {
                writeSpace();
                emit(tag.fullName);
            }
            emitJSDocComment(tag.comment);
            if (tag.typeExpression && tag.typeExpression.kind === 298 /* JSDocTypeLiteral */) {
                emitJSDocTypeLiteral(tag.typeExpression);
            }
        }
        function emitJSDocCallbackTag(tag) {
            emitJSDocTagName(tag.tagName);
            if (tag.name) {
                writeSpace();
                emit(tag.name);
            }
            emitJSDocComment(tag.comment);
            emitJSDocSignature(tag.typeExpression);
        }
        function emitJSDocSimpleTag(tag) {
            emitJSDocTagName(tag.tagName);
            emitJSDocComment(tag.comment);
        }
        function emitJSDocTypeLiteral(lit) {
            emitList(lit, ts.createNodeArray(lit.jsDocPropertyTags), 33 /* JSDocComment */);
        }
        function emitJSDocSignature(sig) {
            if (sig.typeParameters) {
                emitList(sig, ts.createNodeArray(sig.typeParameters), 33 /* JSDocComment */);
            }
            if (sig.parameters) {
                emitList(sig, ts.createNodeArray(sig.parameters), 33 /* JSDocComment */);
            }
            if (sig.type) {
                writeLine();
                writeSpace();
                writePunctuation("*");
                writeSpace();
                emit(sig.type);
            }
        }
        function emitJSDocPropertyLikeTag(param) {
            emitJSDocTagName(param.tagName);
            emitJSDocTypeExpression(param.typeExpression);
            writeSpace();
            if (param.isBracketed) {
                writePunctuation("[");
            }
            emit(param.name);
            if (param.isBracketed) {
                writePunctuation("]");
            }
            emitJSDocComment(param.comment);
        }
        function emitJSDocTagName(tagName) {
            writePunctuation("@");
            emit(tagName);
        }
        function emitJSDocComment(comment) {
            if (comment) {
                writeSpace();
                write(comment);
            }
        }
        function emitJSDocTypeExpression(typeExpression) {
            if (typeExpression) {
                writeSpace();
                writePunctuation("{");
                emit(typeExpression.type);
                writePunctuation("}");
            }
        }
        //
        // Top-level nodes
        //
        function emitSourceFile(node) {
            writeLine();
            var statements = node.statements;
            if (emitBodyWithDetachedComments) {
                // Emit detached comment if there are no prologue directives or if the first node is synthesized.
                // The synthesized node will have no leading comment so some comments may be missed.
                var shouldEmitDetachedComment = statements.length === 0 ||
                    !ts.isPrologueDirective(statements[0]) ||
                    ts.nodeIsSynthesized(statements[0]);
                if (shouldEmitDetachedComment) {
                    emitBodyWithDetachedComments(node, statements, emitSourceFileWorker);
                    return;
                }
            }
            emitSourceFileWorker(node);
        }
        function emitSyntheticTripleSlashReferencesIfNeeded(node) {
            emitTripleSlashDirectives(!!node.hasNoDefaultLib, node.syntheticFileReferences || [], node.syntheticTypeReferences || [], node.syntheticLibReferences || []);
            for (var _a = 0, _b = node.prepends; _a < _b.length; _a++) {
                var prepend = _b[_a];
                if (ts.isUnparsedSource(prepend) && prepend.syntheticReferences) {
                    for (var _c = 0, _d = prepend.syntheticReferences; _c < _d.length; _c++) {
                        var ref = _d[_c];
                        emit(ref);
                        writeLine();
                    }
                }
            }
        }
        function emitTripleSlashDirectivesIfNeeded(node) {
            if (node.isDeclarationFile)
                emitTripleSlashDirectives(node.hasNoDefaultLib, node.referencedFiles, node.typeReferenceDirectives, node.libReferenceDirectives);
        }
        function emitTripleSlashDirectives(hasNoDefaultLib, files, types, libs) {
            if (hasNoDefaultLib) {
                var pos = writer.getTextPos();
                writeComment("/// <reference no-default-lib=\"true\"/>");
                if (bundleFileInfo)
                    bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "no-default-lib" /* NoDefaultLib */ });
                writeLine();
            }
            if (currentSourceFile && currentSourceFile.moduleName) {
                writeComment("/// <amd-module name=\"" + currentSourceFile.moduleName + "\" />");
                writeLine();
            }
            if (currentSourceFile && currentSourceFile.amdDependencies) {
                for (var _a = 0, _b = currentSourceFile.amdDependencies; _a < _b.length; _a++) {
                    var dep = _b[_a];
                    if (dep.name) {
                        writeComment("/// <amd-dependency name=\"" + dep.name + "\" path=\"" + dep.path + "\" />");
                    }
                    else {
                        writeComment("/// <amd-dependency path=\"" + dep.path + "\" />");
                    }
                    writeLine();
                }
            }
            for (var _c = 0, files_1 = files; _c < files_1.length; _c++) {
                var directive = files_1[_c];
                var pos = writer.getTextPos();
                writeComment("/// <reference path=\"" + directive.fileName + "\" />");
                if (bundleFileInfo)
                    bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "reference" /* Reference */, data: directive.fileName });
                writeLine();
            }
            for (var _d = 0, types_18 = types; _d < types_18.length; _d++) {
                var directive = types_18[_d];
                var pos = writer.getTextPos();
                writeComment("/// <reference types=\"" + directive.fileName + "\" />");
                if (bundleFileInfo)
                    bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "type" /* Type */, data: directive.fileName });
                writeLine();
            }
            for (var _e = 0, libs_1 = libs; _e < libs_1.length; _e++) {
                var directive = libs_1[_e];
                var pos = writer.getTextPos();
                writeComment("/// <reference lib=\"" + directive.fileName + "\" />");
                if (bundleFileInfo)
                    bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "lib" /* Lib */, data: directive.fileName });
                writeLine();
            }
        }
        function emitSourceFileWorker(node) {
            var statements = node.statements;
            pushNameGenerationScope(node);
            ts.forEach(node.statements, generateNames);
            emitHelpers(node);
            var index = ts.findIndex(statements, function (statement) { return !ts.isPrologueDirective(statement); });
            emitTripleSlashDirectivesIfNeeded(node);
            emitList(node, statements, 1 /* MultiLine */, index === -1 ? statements.length : index);
            popNameGenerationScope(node);
        }
        // Transformation nodes
        function emitPartiallyEmittedExpression(node) {
            emitExpression(node.expression);
        }
        function emitCommaList(node) {
            emitExpressionList(node, node.elements, 528 /* CommaListElements */);
        }
        /**
         * Emits any prologue directives at the start of a Statement list, returning the
         * number of prologue directives written to the output.
         */
        function emitPrologueDirectives(statements, sourceFile, seenPrologueDirectives, recordBundleFileSection) {
            var needsToSetSourceFile = !!sourceFile;
            for (var i = 0; i < statements.length; i++) {
                var statement = statements[i];
                if (ts.isPrologueDirective(statement)) {
                    var shouldEmitPrologueDirective = seenPrologueDirectives ? !seenPrologueDirectives.has(statement.expression.text) : true;
                    if (shouldEmitPrologueDirective) {
                        if (needsToSetSourceFile) {
                            needsToSetSourceFile = false;
                            setSourceFile(sourceFile);
                        }
                        writeLine();
                        var pos = writer.getTextPos();
                        emit(statement);
                        if (recordBundleFileSection && bundleFileInfo)
                            bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "prologue" /* Prologue */, data: statement.expression.text });
                        if (seenPrologueDirectives) {
                            seenPrologueDirectives.set(statement.expression.text, true);
                        }
                    }
                }
                else {
                    // return index of the first non prologue directive
                    return i;
                }
            }
            return statements.length;
        }
        function emitUnparsedPrologues(prologues, seenPrologueDirectives) {
            for (var _a = 0, prologues_1 = prologues; _a < prologues_1.length; _a++) {
                var prologue = prologues_1[_a];
                if (!seenPrologueDirectives.has(prologue.data)) {
                    writeLine();
                    var pos = writer.getTextPos();
                    emit(prologue);
                    if (bundleFileInfo)
                        bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "prologue" /* Prologue */, data: prologue.data });
                    if (seenPrologueDirectives) {
                        seenPrologueDirectives.set(prologue.data, true);
                    }
                }
            }
        }
        function emitPrologueDirectivesIfNeeded(sourceFileOrBundle) {
            if (ts.isSourceFile(sourceFileOrBundle)) {
                emitPrologueDirectives(sourceFileOrBundle.statements, sourceFileOrBundle);
            }
            else {
                var seenPrologueDirectives = ts.createMap();
                for (var _a = 0, _b = sourceFileOrBundle.prepends; _a < _b.length; _a++) {
                    var prepend = _b[_a];
                    emitUnparsedPrologues(prepend.prologues, seenPrologueDirectives);
                }
                for (var _c = 0, _d = sourceFileOrBundle.sourceFiles; _c < _d.length; _c++) {
                    var sourceFile = _d[_c];
                    emitPrologueDirectives(sourceFile.statements, sourceFile, seenPrologueDirectives, /*recordBundleFileSection*/ true);
                }
                setSourceFile(undefined);
            }
        }
        function getPrologueDirectivesFromBundledSourceFiles(bundle) {
            var seenPrologueDirectives = ts.createMap();
            var prologues;
            for (var index = 0; index < bundle.sourceFiles.length; index++) {
                var sourceFile = bundle.sourceFiles[index];
                var directives = void 0;
                var end = 0;
                for (var _a = 0, _b = sourceFile.statements; _a < _b.length; _a++) {
                    var statement = _b[_a];
                    if (!ts.isPrologueDirective(statement))
                        break;
                    if (seenPrologueDirectives.has(statement.expression.text))
                        continue;
                    seenPrologueDirectives.set(statement.expression.text, true);
                    (directives || (directives = [])).push({
                        pos: statement.pos,
                        end: statement.end,
                        expression: {
                            pos: statement.expression.pos,
                            end: statement.expression.end,
                            text: statement.expression.text
                        }
                    });
                    end = end < statement.end ? statement.end : end;
                }
                if (directives)
                    (prologues || (prologues = [])).push({ file: index, text: sourceFile.text.substring(0, end), directives: directives });
            }
            return prologues;
        }
        function emitShebangIfNeeded(sourceFileOrBundle) {
            if (ts.isSourceFile(sourceFileOrBundle) || ts.isUnparsedSource(sourceFileOrBundle)) {
                var shebang = ts.getShebang(sourceFileOrBundle.text);
                if (shebang) {
                    writeComment(shebang);
                    writeLine();
                    return true;
                }
            }
            else {
                for (var _a = 0, _b = sourceFileOrBundle.prepends; _a < _b.length; _a++) {
                    var prepend = _b[_a];
                    ts.Debug.assertNode(prepend, ts.isUnparsedSource);
                    if (emitShebangIfNeeded(prepend)) {
                        return true;
                    }
                }
                for (var _c = 0, _d = sourceFileOrBundle.sourceFiles; _c < _d.length; _c++) {
                    var sourceFile = _d[_c];
                    // Emit only the first encountered shebang
                    if (emitShebangIfNeeded(sourceFile)) {
                        return true;
                    }
                }
            }
        }
        //
        // Helpers
        //
        function emitNodeWithWriter(node, writer) {
            if (!node)
                return;
            var savedWrite = write;
            write = writer;
            emit(node);
            write = savedWrite;
        }
        function emitModifiers(node, modifiers) {
            if (modifiers && modifiers.length) {
                emitList(node, modifiers, 262656 /* Modifiers */);
                writeSpace();
            }
        }
        function emitTypeAnnotation(node) {
            if (node) {
                writePunctuation(":");
                writeSpace();
                emit(node);
            }
        }
        function emitInitializer(node, equalCommentStartPos, container) {
            if (node) {
                writeSpace();
                emitTokenWithComment(60 /* EqualsToken */, equalCommentStartPos, writeOperator, container);
                writeSpace();
                emitExpression(node);
            }
        }
        function emitNodeWithPrefix(prefix, prefixWriter, node, emit) {
            if (node) {
                prefixWriter(prefix);
                emit(node);
            }
        }
        function emitWithLeadingSpace(node) {
            if (node) {
                writeSpace();
                emit(node);
            }
        }
        function emitExpressionWithLeadingSpace(node) {
            if (node) {
                writeSpace();
                emitExpression(node);
            }
        }
        function emitWithTrailingSpace(node) {
            if (node) {
                emit(node);
                writeSpace();
            }
        }
        function emitEmbeddedStatement(parent, node) {
            if (ts.isBlock(node) || ts.getEmitFlags(parent) & 1 /* SingleLine */) {
                writeSpace();
                emit(node);
            }
            else {
                writeLine();
                increaseIndent();
                if (ts.isEmptyStatement(node)) {
                    var pipelinePhase = getPipelinePhase(0 /* Notification */, node);
                    pipelinePhase(5 /* EmbeddedStatement */, node);
                }
                else {
                    emit(node);
                }
                decreaseIndent();
            }
        }
        function emitDecorators(parentNode, decorators) {
            emitList(parentNode, decorators, 49153 /* Decorators */);
        }
        function emitTypeArguments(parentNode, typeArguments) {
            emitList(parentNode, typeArguments, 53776 /* TypeArguments */);
        }
        function emitTypeParameters(parentNode, typeParameters) {
            if (ts.isFunctionLike(parentNode) && parentNode.typeArguments) { // Quick info uses type arguments in place of type parameters on instantiated signatures
                return emitTypeArguments(parentNode, parentNode.typeArguments);
            }
            emitList(parentNode, typeParameters, 53776 /* TypeParameters */);
        }
        function emitParameters(parentNode, parameters) {
            emitList(parentNode, parameters, 2576 /* Parameters */);
        }
        function canEmitSimpleArrowHead(parentNode, parameters) {
            var parameter = ts.singleOrUndefined(parameters);
            return parameter
                && parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter
                && ts.isArrowFunction(parentNode) // only arrow functions may have simple arrow head
                && !parentNode.type // arrow function may not have return type annotation
                && !ts.some(parentNode.decorators) // parent may not have decorators
                && !ts.some(parentNode.modifiers) // parent may not have modifiers
                && !ts.some(parentNode.typeParameters) // parent may not have type parameters
                && !ts.some(parameter.decorators) // parameter may not have decorators
                && !ts.some(parameter.modifiers) // parameter may not have modifiers
                && !parameter.dotDotDotToken // parameter may not be rest
                && !parameter.questionToken // parameter may not be optional
                && !parameter.type // parameter may not have a type annotation
                && !parameter.initializer // parameter may not have an initializer
                && ts.isIdentifier(parameter.name); // parameter name must be identifier
        }
        function emitParametersForArrow(parentNode, parameters) {
            if (canEmitSimpleArrowHead(parentNode, parameters)) {
                emitList(parentNode, parameters, 2576 /* Parameters */ & ~2048 /* Parenthesis */);
            }
            else {
                emitParameters(parentNode, parameters);
            }
        }
        function emitParametersForIndexSignature(parentNode, parameters) {
            emitList(parentNode, parameters, 8848 /* IndexSignatureParameters */);
        }
        function emitList(parentNode, children, format, start, count) {
            emitNodeList(emit, parentNode, children, format, start, count);
        }
        function emitExpressionList(parentNode, children, format, start, count) {
            emitNodeList(emitExpression, parentNode, children, format, start, count); // TODO: GH#18217
        }
        function writeDelimiter(format) {
            switch (format & 60 /* DelimitersMask */) {
                case 0 /* None */:
                    break;
                case 16 /* CommaDelimited */:
                    writePunctuation(",");
                    break;
                case 4 /* BarDelimited */:
                    writeSpace();
                    writePunctuation("|");
                    break;
                case 32 /* AsteriskDelimited */:
                    writeSpace();
                    writePunctuation("*");
                    writeSpace();
                    break;
                case 8 /* AmpersandDelimited */:
                    writeSpace();
                    writePunctuation("&");
                    break;
            }
        }
        function emitNodeList(emit, parentNode, children, format, start, count) {
            if (start === void 0) { start = 0; }
            if (count === void 0) { count = children ? children.length - start : 0; }
            var isUndefined = children === undefined;
            if (isUndefined && format & 16384 /* OptionalIfUndefined */) {
                return;
            }
            var isEmpty = children === undefined || start >= children.length || count === 0;
            if (isEmpty && format & 32768 /* OptionalIfEmpty */) {
                if (onBeforeEmitNodeArray) {
                    onBeforeEmitNodeArray(children);
                }
                if (onAfterEmitNodeArray) {
                    onAfterEmitNodeArray(children);
                }
                return;
            }
            if (format & 15360 /* BracketsMask */) {
                writePunctuation(getOpeningBracket(format));
                if (isEmpty && !isUndefined) {
                    // TODO: GH#18217
                    emitTrailingCommentsOfPosition(children.pos, /*prefixSpace*/ true); // Emit comments within empty bracketed lists
                }
            }
            if (onBeforeEmitNodeArray) {
                onBeforeEmitNodeArray(children);
            }
            if (isEmpty) {
                // Write a line terminator if the parent node was multi-line
                if (format & 1 /* MultiLine */) {
                    writeLine();
                }
                else if (format & 256 /* SpaceBetweenBraces */ && !(format & 524288 /* NoSpaceIfEmpty */)) {
                    writeSpace();
                }
            }
            else {
                // Write the opening line terminator or leading whitespace.
                var mayEmitInterveningComments = (format & 262144 /* NoInterveningComments */) === 0;
                var shouldEmitInterveningComments = mayEmitInterveningComments;
                if (shouldWriteLeadingLineTerminator(parentNode, children, format)) { // TODO: GH#18217
                    writeLine();
                    shouldEmitInterveningComments = false;
                }
                else if (format & 256 /* SpaceBetweenBraces */) {
                    writeSpace();
                }
                // Increase the indent, if requested.
                if (format & 128 /* Indented */) {
                    increaseIndent();
                }
                // Emit each child.
                var previousSibling = void 0;
                var previousSourceFileTextKind = void 0;
                var shouldDecreaseIndentAfterEmit = false;
                for (var i = 0; i < count; i++) {
                    var child = children[start + i];
                    // Write the delimiter if this is not the first node.
                    if (format & 32 /* AsteriskDelimited */) {
                        // always write JSDoc in the format "\n *"
                        writeLine();
                        writeDelimiter(format);
                    }
                    else if (previousSibling) {
                        // i.e
                        //      function commentedParameters(
                        //          /* Parameter a */
                        //          a
                        //          /* End of parameter a */ -> this comment isn't considered to be trailing comment of parameter "a" due to newline
                        //          ,
                        if (format & 60 /* DelimitersMask */ && previousSibling.end !== parentNode.end) {
                            emitLeadingCommentsOfPosition(previousSibling.end);
                        }
                        writeDelimiter(format);
                        recordBundleFileInternalSectionEnd(previousSourceFileTextKind);
                        // Write either a line terminator or whitespace to separate the elements.
                        if (shouldWriteSeparatingLineTerminator(previousSibling, child, format)) {
                            // If a synthesized node in a single-line list starts on a new
                            // line, we should increase the indent.
                            if ((format & (3 /* LinesMask */ | 128 /* Indented */)) === 0 /* SingleLine */) {
                                increaseIndent();
                                shouldDecreaseIndentAfterEmit = true;
                            }
                            writeLine();
                            shouldEmitInterveningComments = false;
                        }
                        else if (previousSibling && format & 512 /* SpaceBetweenSiblings */) {
                            writeSpace();
                        }
                    }
                    // Emit this child.
                    previousSourceFileTextKind = recordBundleFileInternalSectionStart(child);
                    if (shouldEmitInterveningComments) {
                        if (emitTrailingCommentsOfPosition) {
                            var commentRange = ts.getCommentRange(child);
                            emitTrailingCommentsOfPosition(commentRange.pos);
                        }
                    }
                    else {
                        shouldEmitInterveningComments = mayEmitInterveningComments;
                    }
                    emit(child);
                    if (shouldDecreaseIndentAfterEmit) {
                        decreaseIndent();
                        shouldDecreaseIndentAfterEmit = false;
                    }
                    previousSibling = child;
                }
                // Write a trailing comma, if requested.
                var hasTrailingComma = (format & 64 /* AllowTrailingComma */) && children.hasTrailingComma;
                if (format & 16 /* CommaDelimited */ && hasTrailingComma) {
                    writePunctuation(",");
                }
                // Emit any trailing comment of the last element in the list
                // i.e
                //       var array = [...
                //          2
                //          /* end of element 2 */
                //       ];
                if (previousSibling && format & 60 /* DelimitersMask */ && previousSibling.end !== parentNode.end && !(ts.getEmitFlags(previousSibling) & 1024 /* NoTrailingComments */)) {
                    emitLeadingCommentsOfPosition(previousSibling.end);
                }
                // Decrease the indent, if requested.
                if (format & 128 /* Indented */) {
                    decreaseIndent();
                }
                recordBundleFileInternalSectionEnd(previousSourceFileTextKind);
                // Write the closing line terminator or closing whitespace.
                if (shouldWriteClosingLineTerminator(parentNode, children, format)) {
                    writeLine();
                }
                else if (format & 256 /* SpaceBetweenBraces */) {
                    writeSpace();
                }
            }
            if (onAfterEmitNodeArray) {
                onAfterEmitNodeArray(children);
            }
            if (format & 15360 /* BracketsMask */) {
                if (isEmpty && !isUndefined) {
                    // TODO: GH#18217
                    emitLeadingCommentsOfPosition(children.end); // Emit leading comments within empty lists
                }
                writePunctuation(getClosingBracket(format));
            }
        }
        // Writers
        function writeLiteral(s) {
            writer.writeLiteral(s);
        }
        function writeStringLiteral(s) {
            writer.writeStringLiteral(s);
        }
        function writeBase(s) {
            writer.write(s);
        }
        function writeSymbol(s, sym) {
            writer.writeSymbol(s, sym);
        }
        function writePunctuation(s) {
            writer.writePunctuation(s);
        }
        function writeTrailingSemicolon() {
            writer.writeTrailingSemicolon(";");
        }
        function writeKeyword(s) {
            writer.writeKeyword(s);
        }
        function writeOperator(s) {
            writer.writeOperator(s);
        }
        function writeParameter(s) {
            writer.writeParameter(s);
        }
        function writeComment(s) {
            writer.writeComment(s);
        }
        function writeSpace() {
            writer.writeSpace(" ");
        }
        function writeProperty(s) {
            writer.writeProperty(s);
        }
        function writeLine() {
            writer.writeLine();
        }
        function increaseIndent() {
            writer.increaseIndent();
        }
        function decreaseIndent() {
            writer.decreaseIndent();
        }
        function writeToken(token, pos, writer, contextNode) {
            return !sourceMapsDisabled
                ? emitTokenWithSourceMap(contextNode, token, writer, pos, writeTokenText)
                : writeTokenText(token, writer, pos);
        }
        function writeTokenNode(node, writer) {
            if (onBeforeEmitToken) {
                onBeforeEmitToken(node);
            }
            writer(ts.tokenToString(node.kind));
            if (onAfterEmitToken) {
                onAfterEmitToken(node);
            }
        }
        function writeTokenText(token, writer, pos) {
            var tokenString = ts.tokenToString(token);
            writer(tokenString);
            return pos < 0 ? pos : pos + tokenString.length;
        }
        function writeLineOrSpace(node) {
            if (ts.getEmitFlags(node) & 1 /* SingleLine */) {
                writeSpace();
            }
            else {
                writeLine();
            }
        }
        function writeLines(text) {
            var lines = text.split(/\r\n?|\n/g);
            var indentation = ts.guessIndentation(lines);
            for (var _a = 0, lines_3 = lines; _a < lines_3.length; _a++) {
                var lineText = lines_3[_a];
                var line = indentation ? lineText.slice(indentation) : lineText;
                if (line.length) {
                    writeLine();
                    write(line);
                }
            }
        }
        function increaseIndentIf(value, writeSpaceIfNotIndenting) {
            if (value) {
                increaseIndent();
                writeLine();
            }
            else if (writeSpaceIfNotIndenting) {
                writeSpace();
            }
        }
        // Helper function to decrease the indent if we previously indented.  Allows multiple
        // previous indent values to be considered at a time.  This also allows caller to just
        // call this once, passing in all their appropriate indent values, instead of needing
        // to call this helper function multiple times.
        function decreaseIndentIf(value1, value2) {
            if (value1) {
                decreaseIndent();
            }
            if (value2) {
                decreaseIndent();
            }
        }
        function shouldWriteLeadingLineTerminator(parentNode, children, format) {
            if (format & 1 /* MultiLine */) {
                return true;
            }
            if (format & 2 /* PreserveLines */) {
                if (format & 65536 /* PreferNewLine */) {
                    return true;
                }
                var firstChild = children[0];
                if (firstChild === undefined) {
                    return !ts.rangeIsOnSingleLine(parentNode, currentSourceFile);
                }
                else if (ts.positionIsSynthesized(parentNode.pos) || ts.nodeIsSynthesized(firstChild)) {
                    return synthesizedNodeStartsOnNewLine(firstChild, format);
                }
                else {
                    return !ts.rangeStartPositionsAreOnSameLine(parentNode, firstChild, currentSourceFile);
                }
            }
            else {
                return false;
            }
        }
        function shouldWriteSeparatingLineTerminator(previousNode, nextNode, format) {
            if (format & 1 /* MultiLine */) {
                return true;
            }
            else if (format & 2 /* PreserveLines */) {
                if (previousNode === undefined || nextNode === undefined) {
                    return false;
                }
                else if (ts.nodeIsSynthesized(previousNode) || ts.nodeIsSynthesized(nextNode)) {
                    return synthesizedNodeStartsOnNewLine(previousNode, format) || synthesizedNodeStartsOnNewLine(nextNode, format);
                }
                else {
                    return !ts.rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile);
                }
            }
            else {
                return ts.getStartsOnNewLine(nextNode);
            }
        }
        function shouldWriteClosingLineTerminator(parentNode, children, format) {
            if (format & 1 /* MultiLine */) {
                return (format & 131072 /* NoTrailingNewLine */) === 0;
            }
            else if (format & 2 /* PreserveLines */) {
                if (format & 65536 /* PreferNewLine */) {
                    return true;
                }
                var lastChild = ts.lastOrUndefined(children);
                if (lastChild === undefined) {
                    return !ts.rangeIsOnSingleLine(parentNode, currentSourceFile);
                }
                else if (ts.positionIsSynthesized(parentNode.pos) || ts.nodeIsSynthesized(lastChild)) {
                    return synthesizedNodeStartsOnNewLine(lastChild, format);
                }
                else {
                    return !ts.rangeEndPositionsAreOnSameLine(parentNode, lastChild, currentSourceFile);
                }
            }
            else {
                return false;
            }
        }
        function synthesizedNodeStartsOnNewLine(node, format) {
            if (ts.nodeIsSynthesized(node)) {
                var startsOnNewLine = ts.getStartsOnNewLine(node);
                if (startsOnNewLine === undefined) {
                    return (format & 65536 /* PreferNewLine */) !== 0;
                }
                return startsOnNewLine;
            }
            return (format & 65536 /* PreferNewLine */) !== 0;
        }
        function needsIndentation(parent, node1, node2) {
            parent = skipSynthesizedParentheses(parent);
            node1 = skipSynthesizedParentheses(node1);
            node2 = skipSynthesizedParentheses(node2);
            // Always use a newline for synthesized code if the synthesizer desires it.
            if (ts.getStartsOnNewLine(node2)) {
                return true;
            }
            return !ts.nodeIsSynthesized(parent)
                && !ts.nodeIsSynthesized(node1)
                && !ts.nodeIsSynthesized(node2)
                && !ts.rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile);
        }
        function isEmptyBlock(block) {
            return block.statements.length === 0
                && ts.rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile);
        }
        function skipSynthesizedParentheses(node) {
            while (node.kind === 196 /* ParenthesizedExpression */ && ts.nodeIsSynthesized(node)) {
                node = node.expression;
            }
            return node;
        }
        function getTextOfNode(node, includeTrivia) {
            if (ts.isGeneratedIdentifier(node)) {
                return generateName(node);
            }
            else if (ts.isIdentifier(node) && (ts.nodeIsSynthesized(node) || !node.parent || !currentSourceFile || (node.parent && currentSourceFile && ts.getSourceFileOfNode(node) !== ts.getOriginalNode(currentSourceFile)))) {
                return ts.idText(node);
            }
            else if (node.kind === 10 /* StringLiteral */ && node.textSourceNode) {
                return getTextOfNode(node.textSourceNode, includeTrivia);
            }
            else if (ts.isLiteralExpression(node) && (ts.nodeIsSynthesized(node) || !node.parent)) {
                return node.text;
            }
            return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node, includeTrivia);
        }
        function getLiteralTextOfNode(node, neverAsciiEscape) {
            if (node.kind === 10 /* StringLiteral */ && node.textSourceNode) {
                var textSourceNode = node.textSourceNode;
                if (ts.isIdentifier(textSourceNode)) {
                    return neverAsciiEscape || (ts.getEmitFlags(node) & 16777216 /* NoAsciiEscaping */) ?
                        "\"" + ts.escapeString(getTextOfNode(textSourceNode)) + "\"" :
                        "\"" + ts.escapeNonAsciiString(getTextOfNode(textSourceNode)) + "\"";
                }
                else {
                    return getLiteralTextOfNode(textSourceNode, neverAsciiEscape);
                }
            }
            return ts.getLiteralText(node, currentSourceFile, neverAsciiEscape);
        }
        /**
         * Push a new name generation scope.
         */
        function pushNameGenerationScope(node) {
            if (node && ts.getEmitFlags(node) & 524288 /* ReuseTempVariableScope */) {
                return;
            }
            tempFlagsStack.push(tempFlags);
            tempFlags = 0;
            reservedNamesStack.push(reservedNames);
        }
        /**
         * Pop the current name generation scope.
         */
        function popNameGenerationScope(node) {
            if (node && ts.getEmitFlags(node) & 524288 /* ReuseTempVariableScope */) {
                return;
            }
            tempFlags = tempFlagsStack.pop();
            reservedNames = reservedNamesStack.pop();
        }
        function reserveNameInNestedScopes(name) {
            if (!reservedNames || reservedNames === ts.lastOrUndefined(reservedNamesStack)) {
                reservedNames = ts.createMap();
            }
            reservedNames.set(name, true);
        }
        function generateNames(node) {
            if (!node)
                return;
            switch (node.kind) {
                case 219 /* Block */:
                    ts.forEach(node.statements, generateNames);
                    break;
                case 234 /* LabeledStatement */:
                case 232 /* WithStatement */:
                case 224 /* DoStatement */:
                case 225 /* WhileStatement */:
                    generateNames(node.statement);
                    break;
                case 223 /* IfStatement */:
                    generateNames(node.thenStatement);
                    generateNames(node.elseStatement);
                    break;
                case 226 /* ForStatement */:
                case 228 /* ForOfStatement */:
                case 227 /* ForInStatement */:
                    generateNames(node.initializer);
                    generateNames(node.statement);
                    break;
                case 233 /* SwitchStatement */:
                    generateNames(node.caseBlock);
                    break;
                case 247 /* CaseBlock */:
                    ts.forEach(node.clauses, generateNames);
                    break;
                case 272 /* CaseClause */:
                case 273 /* DefaultClause */:
                    ts.forEach(node.statements, generateNames);
                    break;
                case 236 /* TryStatement */:
                    generateNames(node.tryBlock);
                    generateNames(node.catchClause);
                    generateNames(node.finallyBlock);
                    break;
                case 275 /* CatchClause */:
                    generateNames(node.variableDeclaration);
                    generateNames(node.block);
                    break;
                case 220 /* VariableStatement */:
                    generateNames(node.declarationList);
                    break;
                case 239 /* VariableDeclarationList */:
                    ts.forEach(node.declarations, generateNames);
                    break;
                case 238 /* VariableDeclaration */:
                case 152 /* Parameter */:
                case 187 /* BindingElement */:
                case 241 /* ClassDeclaration */:
                    generateNameIfNeeded(node.name);
                    break;
                case 240 /* FunctionDeclaration */:
                    generateNameIfNeeded(node.name);
                    if (ts.getEmitFlags(node) & 524288 /* ReuseTempVariableScope */) {
                        ts.forEach(node.parameters, generateNames);
                        generateNames(node.body);
                    }
                    break;
                case 185 /* ObjectBindingPattern */:
                case 186 /* ArrayBindingPattern */:
                    ts.forEach(node.elements, generateNames);
                    break;
                case 250 /* ImportDeclaration */:
                    generateNames(node.importClause);
                    break;
                case 251 /* ImportClause */:
                    generateNameIfNeeded(node.name);
                    generateNames(node.namedBindings);
                    break;
                case 252 /* NamespaceImport */:
                    generateNameIfNeeded(node.name);
                    break;
                case 253 /* NamedImports */:
                    ts.forEach(node.elements, generateNames);
                    break;
                case 254 /* ImportSpecifier */:
                    generateNameIfNeeded(node.propertyName || node.name);
                    break;
            }
        }
        function generateMemberNames(node) {
            if (!node)
                return;
            switch (node.kind) {
                case 276 /* PropertyAssignment */:
                case 277 /* ShorthandPropertyAssignment */:
                case 155 /* PropertyDeclaration */:
                case 157 /* MethodDeclaration */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    generateNameIfNeeded(node.name);
                    break;
            }
        }
        function generateNameIfNeeded(name) {
            if (name) {
                if (ts.isGeneratedIdentifier(name)) {
                    generateName(name);
                }
                else if (ts.isBindingPattern(name)) {
                    generateNames(name);
                }
            }
        }
        /**
         * Generate the text for a generated identifier.
         */
        function generateName(name) {
            if ((name.autoGenerateFlags & 7 /* KindMask */) === 4 /* Node */) {
                // Node names generate unique names based on their original node
                // and are cached based on that node's id.
                return generateNameCached(getNodeForGeneratedName(name), name.autoGenerateFlags);
            }
            else {
                // Auto, Loop, and Unique names are cached based on their unique
                // autoGenerateId.
                var autoGenerateId = name.autoGenerateId;
                return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = makeName(name));
            }
        }
        function generateNameCached(node, flags) {
            var nodeId = ts.getNodeId(node);
            return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = generateNameForNode(node, flags));
        }
        /**
         * Returns a value indicating whether a name is unique globally, within the current file,
         * or within the NameGenerator.
         */
        function isUniqueName(name) {
            return isFileLevelUniqueName(name)
                && !generatedNames.has(name)
                && !(reservedNames && reservedNames.has(name));
        }
        /**
         * Returns a value indicating whether a name is unique globally or within the current file.
         */
        function isFileLevelUniqueName(name) {
            return currentSourceFile ? ts.isFileLevelUniqueName(currentSourceFile, name, hasGlobalName) : true;
        }
        /**
         * Returns a value indicating whether a name is unique within a container.
         */
        function isUniqueLocalName(name, container) {
            for (var node = container; ts.isNodeDescendantOf(node, container); node = node.nextContainer) {
                if (node.locals) {
                    var local = node.locals.get(ts.escapeLeadingUnderscores(name));
                    // We conservatively include alias symbols to cover cases where they're emitted as locals
                    if (local && local.flags & (67220415 /* Value */ | 1048576 /* ExportValue */ | 2097152 /* Alias */)) {
                        return false;
                    }
                }
            }
            return true;
        }
        /**
         * Return the next available name in the pattern _a ... _z, _0, _1, ...
         * TempFlags._i or TempFlags._n may be used to express a preference for that dedicated name.
         * Note that names generated by makeTempVariableName and makeUniqueName will never conflict.
         */
        function makeTempVariableName(flags, reservedInNestedScopes) {
            if (flags && !(tempFlags & flags)) {
                var name = flags === 268435456 /* _i */ ? "_i" : "_n";
                if (isUniqueName(name)) {
                    tempFlags |= flags;
                    if (reservedInNestedScopes) {
                        reserveNameInNestedScopes(name);
                    }
                    return name;
                }
            }
            while (true) {
                var count = tempFlags & 268435455 /* CountMask */;
                tempFlags++;
                // Skip over 'i' and 'n'
                if (count !== 8 && count !== 13) {
                    var name = count < 26
                        ? "_" + String.fromCharCode(97 /* a */ + count)
                        : "_" + (count - 26);
                    if (isUniqueName(name)) {
                        if (reservedInNestedScopes) {
                            reserveNameInNestedScopes(name);
                        }
                        return name;
                    }
                }
            }
        }
        /**
         * Generate a name that is unique within the current file and doesn't conflict with any names
         * in global scope. The name is formed by adding an '_n' suffix to the specified base name,
         * where n is a positive integer. Note that names generated by makeTempVariableName and
         * makeUniqueName are guaranteed to never conflict.
         * If `optimistic` is set, the first instance will use 'baseName' verbatim instead of 'baseName_1'
         */
        function makeUniqueName(baseName, checkFn, optimistic, scoped) {
            if (checkFn === void 0) { checkFn = isUniqueName; }
            if (optimistic) {
                if (checkFn(baseName)) {
                    if (scoped) {
                        reserveNameInNestedScopes(baseName);
                    }
                    else {
                        generatedNames.set(baseName, true);
                    }
                    return baseName;
                }
            }
            // Find the first unique 'name_n', where n is a positive number
            if (baseName.charCodeAt(baseName.length - 1) !== 95 /* _ */) {
                baseName += "_";
            }
            var i = 1;
            while (true) {
                var generatedName = baseName + i;
                if (checkFn(generatedName)) {
                    if (scoped) {
                        reserveNameInNestedScopes(generatedName);
                    }
                    else {
                        generatedNames.set(generatedName, true);
                    }
                    return generatedName;
                }
                i++;
            }
        }
        function makeFileLevelOptimisticUniqueName(name) {
            return makeUniqueName(name, isFileLevelUniqueName, /*optimistic*/ true);
        }
        /**
         * Generates a unique name for a ModuleDeclaration or EnumDeclaration.
         */
        function generateNameForModuleOrEnum(node) {
            var name = getTextOfNode(node.name);
            // Use module/enum name itself if it is unique, otherwise make a unique variation
            return isUniqueLocalName(name, node) ? name : makeUniqueName(name);
        }
        /**
         * Generates a unique name for an ImportDeclaration or ExportDeclaration.
         */
        function generateNameForImportOrExportDeclaration(node) {
            var expr = ts.getExternalModuleName(node); // TODO: GH#18217
            var baseName = ts.isStringLiteral(expr) ?
                ts.makeIdentifierFromModuleName(expr.text) : "module";
            return makeUniqueName(baseName);
        }
        /**
         * Generates a unique name for a default export.
         */
        function generateNameForExportDefault() {
            return makeUniqueName("default");
        }
        /**
         * Generates a unique name for a class expression.
         */
        function generateNameForClassExpression() {
            return makeUniqueName("class");
        }
        function generateNameForMethodOrAccessor(node) {
            if (ts.isIdentifier(node.name)) {
                return generateNameCached(node.name);
            }
            return makeTempVariableName(0 /* Auto */);
        }
        /**
         * Generates a unique name from a node.
         */
        function generateNameForNode(node, flags) {
            switch (node.kind) {
                case 73 /* Identifier */:
                    return makeUniqueName(getTextOfNode(node), isUniqueName, !!(flags & 16 /* Optimistic */), !!(flags & 8 /* ReservedInNestedScopes */));
                case 245 /* ModuleDeclaration */:
                case 244 /* EnumDeclaration */:
                    return generateNameForModuleOrEnum(node);
                case 250 /* ImportDeclaration */:
                case 256 /* ExportDeclaration */:
                    return generateNameForImportOrExportDeclaration(node);
                case 240 /* FunctionDeclaration */:
                case 241 /* ClassDeclaration */:
                case 255 /* ExportAssignment */:
                    return generateNameForExportDefault();
                case 210 /* ClassExpression */:
                    return generateNameForClassExpression();
                case 157 /* MethodDeclaration */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    return generateNameForMethodOrAccessor(node);
                case 150 /* ComputedPropertyName */:
                    return makeTempVariableName(0 /* Auto */, /*reserveInNestedScopes*/ true);
                default:
                    return makeTempVariableName(0 /* Auto */);
            }
        }
        /**
         * Generates a unique identifier for a node.
         */
        function makeName(name) {
            switch (name.autoGenerateFlags & 7 /* KindMask */) {
                case 1 /* Auto */:
                    return makeTempVariableName(0 /* Auto */, !!(name.autoGenerateFlags & 8 /* ReservedInNestedScopes */));
                case 2 /* Loop */:
                    return makeTempVariableName(268435456 /* _i */, !!(name.autoGenerateFlags & 8 /* ReservedInNestedScopes */));
                case 3 /* Unique */:
                    return makeUniqueName(ts.idText(name), (name.autoGenerateFlags & 32 /* FileLevel */) ? isFileLevelUniqueName : isUniqueName, !!(name.autoGenerateFlags & 16 /* Optimistic */), !!(name.autoGenerateFlags & 8 /* ReservedInNestedScopes */));
            }
            return ts.Debug.fail("Unsupported GeneratedIdentifierKind.");
        }
        /**
         * Gets the node from which a name should be generated.
         */
        function getNodeForGeneratedName(name) {
            var autoGenerateId = name.autoGenerateId;
            var node = name;
            var original = node.original;
            while (original) {
                node = original;
                // if "node" is a different generated name (having a different
                // "autoGenerateId"), use it and stop traversing.
                if (ts.isIdentifier(node)
                    && !!(node.autoGenerateFlags & 4 /* Node */)
                    && node.autoGenerateId !== autoGenerateId) {
                    break;
                }
                original = node.original;
            }
            // otherwise, return the original node for the source;
            return node;
        }
        // Comments
        function pipelineEmitWithComments(hint, node) {
            enterComment();
            hasWrittenComment = false;
            var emitFlags = ts.getEmitFlags(node);
            var _a = ts.getCommentRange(node), pos = _a.pos, end = _a.end;
            var isEmittedNode = node.kind !== 313 /* NotEmittedStatement */;
            // We have to explicitly check that the node is JsxText because if the compilerOptions.jsx is "preserve" we will not do any transformation.
            // It is expensive to walk entire tree just to set one kind of node to have no comments.
            var skipLeadingComments = pos < 0 || (emitFlags & 512 /* NoLeadingComments */) !== 0 || node.kind === 11 /* JsxText */;
            var skipTrailingComments = end < 0 || (emitFlags & 1024 /* NoTrailingComments */) !== 0 || node.kind === 11 /* JsxText */;
            // Save current container state on the stack.
            var savedContainerPos = containerPos;
            var savedContainerEnd = containerEnd;
            var savedDeclarationListContainerEnd = declarationListContainerEnd;
            if ((pos > 0 || end > 0) && pos !== end) {
                // Emit leading comments if the position is not synthesized and the node
                // has not opted out from emitting leading comments.
                if (!skipLeadingComments) {
                    emitLeadingComments(pos, isEmittedNode);
                }
                if (!skipLeadingComments || (pos >= 0 && (emitFlags & 512 /* NoLeadingComments */) !== 0)) {
                    // Advance the container position if comments get emitted or if they've been disabled explicitly using NoLeadingComments.
                    containerPos = pos;
                }
                if (!skipTrailingComments || (end >= 0 && (emitFlags & 1024 /* NoTrailingComments */) !== 0)) {
                    // As above.
                    containerEnd = end;
                    // To avoid invalid comment emit in a down-level binding pattern, we
                    // keep track of the last declaration list container's end
                    if (node.kind === 239 /* VariableDeclarationList */) {
                        declarationListContainerEnd = end;
                    }
                }
            }
            ts.forEach(ts.getSyntheticLeadingComments(node), emitLeadingSynthesizedComment);
            exitComment();
            var pipelinePhase = getNextPipelinePhase(2 /* Comments */, node);
            if (emitFlags & 2048 /* NoNestedComments */) {
                commentsDisabled = true;
                pipelinePhase(hint, node);
                commentsDisabled = false;
            }
            else {
                pipelinePhase(hint, node);
            }
            enterComment();
            ts.forEach(ts.getSyntheticTrailingComments(node), emitTrailingSynthesizedComment);
            if ((pos > 0 || end > 0) && pos !== end) {
                // Restore previous container state.
                containerPos = savedContainerPos;
                containerEnd = savedContainerEnd;
                declarationListContainerEnd = savedDeclarationListContainerEnd;
                // Emit trailing comments if the position is not synthesized and the node
                // has not opted out from emitting leading comments and is an emitted node.
                if (!skipTrailingComments && isEmittedNode) {
                    emitTrailingComments(end);
                }
            }
            exitComment();
        }
        function emitLeadingSynthesizedComment(comment) {
            if (comment.kind === 2 /* SingleLineCommentTrivia */) {
                writer.writeLine();
            }
            writeSynthesizedComment(comment);
            if (comment.hasTrailingNewLine || comment.kind === 2 /* SingleLineCommentTrivia */) {
                writer.writeLine();
            }
            else {
                writer.writeSpace(" ");
            }
        }
        function emitTrailingSynthesizedComment(comment) {
            if (!writer.isAtStartOfLine()) {
                writer.writeSpace(" ");
            }
            writeSynthesizedComment(comment);
            if (comment.hasTrailingNewLine) {
                writer.writeLine();
            }
        }
        function writeSynthesizedComment(comment) {
            var text = formatSynthesizedComment(comment);
            var lineMap = comment.kind === 3 /* MultiLineCommentTrivia */ ? ts.computeLineStarts(text) : undefined;
            ts.writeCommentRange(text, lineMap, writer, 0, text.length, newLine);
        }
        function formatSynthesizedComment(comment) {
            return comment.kind === 3 /* MultiLineCommentTrivia */
                ? "/*" + comment.text + "*/"
                : "//" + comment.text;
        }
        function emitBodyWithDetachedComments(node, detachedRange, emitCallback) {
            enterComment();
            var pos = detachedRange.pos, end = detachedRange.end;
            var emitFlags = ts.getEmitFlags(node);
            var skipLeadingComments = pos < 0 || (emitFlags & 512 /* NoLeadingComments */) !== 0;
            var skipTrailingComments = commentsDisabled || end < 0 || (emitFlags & 1024 /* NoTrailingComments */) !== 0;
            if (!skipLeadingComments) {
                emitDetachedCommentsAndUpdateCommentsInfo(detachedRange);
            }
            exitComment();
            if (emitFlags & 2048 /* NoNestedComments */ && !commentsDisabled) {
                commentsDisabled = true;
                emitCallback(node);
                commentsDisabled = false;
            }
            else {
                emitCallback(node);
            }
            enterComment();
            if (!skipTrailingComments) {
                emitLeadingComments(detachedRange.end, /*isEmittedNode*/ true);
                if (hasWrittenComment && !writer.isAtStartOfLine()) {
                    writer.writeLine();
                }
            }
            exitComment();
        }
        function emitLeadingComments(pos, isEmittedNode) {
            hasWrittenComment = false;
            if (isEmittedNode) {
                forEachLeadingCommentToEmit(pos, emitLeadingComment);
            }
            else if (pos === 0) {
                // If the node will not be emitted in JS, remove all the comments(normal, pinned and ///) associated with the node,
                // unless it is a triple slash comment at the top of the file.
                // For Example:
                //      /// <reference-path ...>
                //      declare var x;
                //      /// <reference-path ...>
                //      interface F {}
                //  The first /// will NOT be removed while the second one will be removed even though both node will not be emitted
                forEachLeadingCommentToEmit(pos, emitTripleSlashLeadingComment);
            }
        }
        function emitTripleSlashLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos) {
            if (isTripleSlashComment(commentPos, commentEnd)) {
                emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos);
            }
        }
        function shouldWriteComment(text, pos) {
            if (printerOptions.onlyPrintJsDocStyle) {
                return (ts.isJSDocLikeText(text, pos) || ts.isPinnedComment(text, pos));
            }
            return true;
        }
        function emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos) {
            if (!shouldWriteComment(currentSourceFile.text, commentPos))
                return;
            if (!hasWrittenComment) {
                ts.emitNewLineBeforeLeadingCommentOfPosition(getCurrentLineMap(), writer, rangePos, commentPos);
                hasWrittenComment = true;
            }
            // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
            emitPos(commentPos);
            ts.writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
            emitPos(commentEnd);
            if (hasTrailingNewLine) {
                writer.writeLine();
            }
            else if (kind === 3 /* MultiLineCommentTrivia */) {
                writer.writeSpace(" ");
            }
        }
        function emitLeadingCommentsOfPosition(pos) {
            if (commentsDisabled || pos === -1) {
                return;
            }
            emitLeadingComments(pos, /*isEmittedNode*/ true);
        }
        function emitTrailingComments(pos) {
            forEachTrailingCommentToEmit(pos, emitTrailingComment);
        }
        function emitTrailingComment(commentPos, commentEnd, _kind, hasTrailingNewLine) {
            if (!shouldWriteComment(currentSourceFile.text, commentPos))
                return;
            // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/
            if (!writer.isAtStartOfLine()) {
                writer.writeSpace(" ");
            }
            emitPos(commentPos);
            ts.writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
            emitPos(commentEnd);
            if (hasTrailingNewLine) {
                writer.writeLine();
            }
        }
        function emitTrailingCommentsOfPosition(pos, prefixSpace) {
            if (commentsDisabled) {
                return;
            }
            enterComment();
            forEachTrailingCommentToEmit(pos, prefixSpace ? emitTrailingComment : emitTrailingCommentOfPosition);
            exitComment();
        }
        function emitTrailingCommentOfPosition(commentPos, commentEnd, _kind, hasTrailingNewLine) {
            // trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
            emitPos(commentPos);
            ts.writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
            emitPos(commentEnd);
            if (hasTrailingNewLine) {
                writer.writeLine();
            }
            else {
                writer.writeSpace(" ");
            }
        }
        function forEachLeadingCommentToEmit(pos, cb) {
            // Emit the leading comments only if the container's pos doesn't match because the container should take care of emitting these comments
            if (currentSourceFile && (containerPos === -1 || pos !== containerPos)) {
                if (hasDetachedComments(pos)) {
                    forEachLeadingCommentWithoutDetachedComments(cb);
                }
                else {
                    ts.forEachLeadingCommentRange(currentSourceFile.text, pos, cb, /*state*/ pos);
                }
            }
        }
        function forEachTrailingCommentToEmit(end, cb) {
            // Emit the trailing comments only if the container's end doesn't match because the container should take care of emitting these comments
            if (currentSourceFile && (containerEnd === -1 || (end !== containerEnd && end !== declarationListContainerEnd))) {
                ts.forEachTrailingCommentRange(currentSourceFile.text, end, cb);
            }
        }
        function hasDetachedComments(pos) {
            return detachedCommentsInfo !== undefined && ts.last(detachedCommentsInfo).nodePos === pos;
        }
        function forEachLeadingCommentWithoutDetachedComments(cb) {
            // get the leading comments from detachedPos
            var pos = ts.last(detachedCommentsInfo).detachedCommentEndPos;
            if (detachedCommentsInfo.length - 1) {
                detachedCommentsInfo.pop();
            }
            else {
                detachedCommentsInfo = undefined;
            }
            ts.forEachLeadingCommentRange(currentSourceFile.text, pos, cb, /*state*/ pos);
        }
        function emitDetachedCommentsAndUpdateCommentsInfo(range) {
            var currentDetachedCommentInfo = ts.emitDetachedComments(currentSourceFile.text, getCurrentLineMap(), writer, emitComment, range, newLine, commentsDisabled);
            if (currentDetachedCommentInfo) {
                if (detachedCommentsInfo) {
                    detachedCommentsInfo.push(currentDetachedCommentInfo);
                }
                else {
                    detachedCommentsInfo = [currentDetachedCommentInfo];
                }
            }
        }
        function emitComment(text, lineMap, writer, commentPos, commentEnd, newLine) {
            if (!shouldWriteComment(currentSourceFile.text, commentPos))
                return;
            emitPos(commentPos);
            ts.writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine);
            emitPos(commentEnd);
        }
        /**
         * Determine if the given comment is a triple-slash
         *
         * @return true if the comment is a triple-slash comment else false
         */
        function isTripleSlashComment(commentPos, commentEnd) {
            return ts.isRecognizedTripleSlashComment(currentSourceFile.text, commentPos, commentEnd);
        }
        // Source Maps
        function getParsedSourceMap(node) {
            if (node.parsedSourceMap === undefined && node.sourceMapText !== undefined) {
                node.parsedSourceMap = ts.tryParseRawSourceMap(node.sourceMapText) || false;
            }
            return node.parsedSourceMap || undefined;
        }
        function pipelineEmitWithSourceMap(hint, node) {
            var pipelinePhase = getNextPipelinePhase(3 /* SourceMaps */, node);
            if (ts.isUnparsedSource(node) || ts.isUnparsedPrepend(node)) {
                pipelinePhase(hint, node);
            }
            else if (ts.isUnparsedNode(node)) {
                var parsed = getParsedSourceMap(node.parent);
                if (parsed && sourceMapGenerator) {
                    sourceMapGenerator.appendSourceMap(writer.getLine(), writer.getColumn(), parsed, node.parent.sourceMapPath, node.parent.getLineAndCharacterOfPosition(node.pos), node.parent.getLineAndCharacterOfPosition(node.end));
                }
                pipelinePhase(hint, node);
            }
            else {
                var _a = ts.getSourceMapRange(node), pos = _a.pos, end = _a.end, _b = _a.source, source = _b === void 0 ? sourceMapSource : _b;
                var emitFlags = ts.getEmitFlags(node);
                if (node.kind !== 313 /* NotEmittedStatement */
                    && (emitFlags & 16 /* NoLeadingSourceMap */) === 0
                    && pos >= 0) {
                    emitSourcePos(source, skipSourceTrivia(source, pos));
                }
                if (emitFlags & 64 /* NoNestedSourceMaps */) {
                    sourceMapsDisabled = true;
                    pipelinePhase(hint, node);
                    sourceMapsDisabled = false;
                }
                else {
                    pipelinePhase(hint, node);
                }
                if (node.kind !== 313 /* NotEmittedStatement */
                    && (emitFlags & 32 /* NoTrailingSourceMap */) === 0
                    && end >= 0) {
                    emitSourcePos(source, end);
                }
            }
        }
        /**
         * Skips trivia such as comments and white-space that can be optionally overridden by the source-map source
         */
        function skipSourceTrivia(source, pos) {
            return source.skipTrivia ? source.skipTrivia(pos) : ts.skipTrivia(source.text, pos);
        }
        /**
         * Emits a mapping.
         *
         * If the position is synthetic (undefined or a negative value), no mapping will be
         * created.
         *
         * @param pos The position.
         */
        function emitPos(pos) {
            if (sourceMapsDisabled || ts.positionIsSynthesized(pos) || isJsonSourceMapSource(sourceMapSource)) {
                return;
            }
            var _a = ts.getLineAndCharacterOfPosition(sourceMapSource, pos), sourceLine = _a.line, sourceCharacter = _a.character;
            sourceMapGenerator.addMapping(writer.getLine(), writer.getColumn(), sourceMapSourceIndex, sourceLine, sourceCharacter, 
            /*nameIndex*/ undefined);
        }
        function emitSourcePos(source, pos) {
            if (source !== sourceMapSource) {
                var savedSourceMapSource = sourceMapSource;
                setSourceMapSource(source);
                emitPos(pos);
                setSourceMapSource(savedSourceMapSource);
            }
            else {
                emitPos(pos);
            }
        }
        /**
         * Emits a token of a node with possible leading and trailing source maps.
         *
         * @param node The node containing the token.
         * @param token The token to emit.
         * @param tokenStartPos The start pos of the token.
         * @param emitCallback The callback used to emit the token.
         */
        function emitTokenWithSourceMap(node, token, writer, tokenPos, emitCallback) {
            if (sourceMapsDisabled || node && ts.isInJsonFile(node)) {
                return emitCallback(token, writer, tokenPos);
            }
            var emitNode = node && node.emitNode;
            var emitFlags = emitNode && emitNode.flags || 0 /* None */;
            var range = emitNode && emitNode.tokenSourceMapRanges && emitNode.tokenSourceMapRanges[token];
            var source = range && range.source || sourceMapSource;
            tokenPos = skipSourceTrivia(source, range ? range.pos : tokenPos);
            if ((emitFlags & 128 /* NoTokenLeadingSourceMaps */) === 0 && tokenPos >= 0) {
                emitSourcePos(source, tokenPos);
            }
            tokenPos = emitCallback(token, writer, tokenPos);
            if (range)
                tokenPos = range.end;
            if ((emitFlags & 256 /* NoTokenTrailingSourceMaps */) === 0 && tokenPos >= 0) {
                emitSourcePos(source, tokenPos);
            }
            return tokenPos;
        }
        function setSourceMapSource(source) {
            if (sourceMapsDisabled) {
                return;
            }
            sourceMapSource = source;
            if (isJsonSourceMapSource(source)) {
                return;
            }
            sourceMapSourceIndex = sourceMapGenerator.addSource(source.fileName);
            if (printerOptions.inlineSources) {
                sourceMapGenerator.setSourceContent(sourceMapSourceIndex, source.text);
            }
        }
        function isJsonSourceMapSource(sourceFile) {
            return ts.fileExtensionIs(sourceFile.fileName, ".json" /* Json */);
        }
    }
    ts.createPrinter = createPrinter;
    function createBracketsMap() {
        var brackets = [];
        brackets[1024 /* Braces */] = ["{", "}"];
        brackets[2048 /* Parenthesis */] = ["(", ")"];
        brackets[4096 /* AngleBrackets */] = ["<", ">"];
        brackets[8192 /* SquareBrackets */] = ["[", "]"];
        return brackets;
    }
    function getOpeningBracket(format) {
        return brackets[format & 15360 /* BracketsMask */][0];
    }
    function getClosingBracket(format) {
        return brackets[format & 15360 /* BracketsMask */][1];
    }
    // Flags enum to track count of temp variables and a few dedicated names
    var TempFlags;
    (function (TempFlags) {
        TempFlags[TempFlags["Auto"] = 0] = "Auto";
        TempFlags[TempFlags["CountMask"] = 268435455] = "CountMask";
        TempFlags[TempFlags["_i"] = 268435456] = "_i";
    })(TempFlags || (TempFlags = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function createCachedDirectoryStructureHost(host, currentDirectory, useCaseSensitiveFileNames) {
        if (!host.getDirectories || !host.readDirectory) {
            return undefined;
        }
        var cachedReadDirectoryResult = ts.createMap();
        var getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        return {
            useCaseSensitiveFileNames: useCaseSensitiveFileNames,
            fileExists: fileExists,
            readFile: function (path, encoding) { return host.readFile(path, encoding); },
            directoryExists: host.directoryExists && directoryExists,
            getDirectories: getDirectories,
            readDirectory: readDirectory,
            createDirectory: host.createDirectory && createDirectory,
            writeFile: host.writeFile && writeFile,
            addOrDeleteFileOrDirectory: addOrDeleteFileOrDirectory,
            addOrDeleteFile: addOrDeleteFile,
            clearCache: clearCache,
            realpath: host.realpath && realpath
        };
        function toPath(fileName) {
            return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
        }
        function getCachedFileSystemEntries(rootDirPath) {
            return cachedReadDirectoryResult.get(ts.ensureTrailingDirectorySeparator(rootDirPath));
        }
        function getCachedFileSystemEntriesForBaseDir(path) {
            return getCachedFileSystemEntries(ts.getDirectoryPath(path));
        }
        function getBaseNameOfFileName(fileName) {
            return ts.getBaseFileName(ts.normalizePath(fileName));
        }
        function createCachedFileSystemEntries(rootDir, rootDirPath) {
            var resultFromHost = {
                files: ts.map(host.readDirectory(rootDir, /*extensions*/ undefined, /*exclude*/ undefined, /*include*/ ["*.*"]), getBaseNameOfFileName) || [],
                directories: host.getDirectories(rootDir) || []
            };
            cachedReadDirectoryResult.set(ts.ensureTrailingDirectorySeparator(rootDirPath), resultFromHost);
            return resultFromHost;
        }
        /**
         * If the readDirectory result was already cached, it returns that
         * Otherwise gets result from host and caches it.
         * The host request is done under try catch block to avoid caching incorrect result
         */
        function tryReadDirectory(rootDir, rootDirPath) {
            rootDirPath = ts.ensureTrailingDirectorySeparator(rootDirPath);
            var cachedResult = getCachedFileSystemEntries(rootDirPath);
            if (cachedResult) {
                return cachedResult;
            }
            try {
                return createCachedFileSystemEntries(rootDir, rootDirPath);
            }
            catch (_e) {
                // If there is exception to read directories, dont cache the result and direct the calls to host
                ts.Debug.assert(!cachedReadDirectoryResult.has(ts.ensureTrailingDirectorySeparator(rootDirPath)));
                return undefined;
            }
        }
        function fileNameEqual(name1, name2) {
            return getCanonicalFileName(name1) === getCanonicalFileName(name2);
        }
        function hasEntry(entries, name) {
            return ts.some(entries, function (file) { return fileNameEqual(file, name); });
        }
        function updateFileSystemEntry(entries, baseName, isValid) {
            if (hasEntry(entries, baseName)) {
                if (!isValid) {
                    return ts.filterMutate(entries, function (entry) { return !fileNameEqual(entry, baseName); });
                }
            }
            else if (isValid) {
                return entries.push(baseName);
            }
        }
        function writeFile(fileName, data, writeByteOrderMark) {
            var path = toPath(fileName);
            var result = getCachedFileSystemEntriesForBaseDir(path);
            if (result) {
                updateFilesOfFileSystemEntry(result, getBaseNameOfFileName(fileName), /*fileExists*/ true);
            }
            return host.writeFile(fileName, data, writeByteOrderMark);
        }
        function fileExists(fileName) {
            var path = toPath(fileName);
            var result = getCachedFileSystemEntriesForBaseDir(path);
            return result && hasEntry(result.files, getBaseNameOfFileName(fileName)) ||
                host.fileExists(fileName);
        }
        function directoryExists(dirPath) {
            var path = toPath(dirPath);
            return cachedReadDirectoryResult.has(ts.ensureTrailingDirectorySeparator(path)) || host.directoryExists(dirPath);
        }
        function createDirectory(dirPath) {
            var path = toPath(dirPath);
            var result = getCachedFileSystemEntriesForBaseDir(path);
            var baseFileName = getBaseNameOfFileName(dirPath);
            if (result) {
                updateFileSystemEntry(result.directories, baseFileName, /*isValid*/ true);
            }
            host.createDirectory(dirPath);
        }
        function getDirectories(rootDir) {
            var rootDirPath = toPath(rootDir);
            var result = tryReadDirectory(rootDir, rootDirPath);
            if (result) {
                return result.directories.slice();
            }
            return host.getDirectories(rootDir);
        }
        function readDirectory(rootDir, extensions, excludes, includes, depth) {
            var rootDirPath = toPath(rootDir);
            var result = tryReadDirectory(rootDir, rootDirPath);
            if (result) {
                return ts.matchFiles(rootDir, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries, realpath);
            }
            return host.readDirectory(rootDir, extensions, excludes, includes, depth);
            function getFileSystemEntries(dir) {
                var path = toPath(dir);
                if (path === rootDirPath) {
                    return result;
                }
                return tryReadDirectory(dir, path) || ts.emptyFileSystemEntries;
            }
        }
        function realpath(s) {
            return host.realpath ? host.realpath(s) : s;
        }
        function addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath) {
            var existingResult = getCachedFileSystemEntries(fileOrDirectoryPath);
            if (existingResult) {
                // Just clear the cache for now
                // For now just clear the cache, since this could mean that multiple level entries might need to be re-evaluated
                clearCache();
                return undefined;
            }
            var parentResult = getCachedFileSystemEntriesForBaseDir(fileOrDirectoryPath);
            if (!parentResult) {
                return undefined;
            }
            // This was earlier a file (hence not in cached directory contents)
            // or we never cached the directory containing it
            if (!host.directoryExists) {
                // Since host doesnt support directory exists, clear the cache as otherwise it might not be same
                clearCache();
                return undefined;
            }
            var baseName = getBaseNameOfFileName(fileOrDirectory);
            var fsQueryResult = {
                fileExists: host.fileExists(fileOrDirectoryPath),
                directoryExists: host.directoryExists(fileOrDirectoryPath)
            };
            if (fsQueryResult.directoryExists || hasEntry(parentResult.directories, baseName)) {
                // Folder added or removed, clear the cache instead of updating the folder and its structure
                clearCache();
            }
            else {
                // No need to update the directory structure, just files
                updateFilesOfFileSystemEntry(parentResult, baseName, fsQueryResult.fileExists);
            }
            return fsQueryResult;
        }
        function addOrDeleteFile(fileName, filePath, eventKind) {
            if (eventKind === ts.FileWatcherEventKind.Changed) {
                return;
            }
            var parentResult = getCachedFileSystemEntriesForBaseDir(filePath);
            if (parentResult) {
                updateFilesOfFileSystemEntry(parentResult, getBaseNameOfFileName(fileName), eventKind === ts.FileWatcherEventKind.Created);
            }
        }
        function updateFilesOfFileSystemEntry(parentResult, baseName, fileExists) {
            updateFileSystemEntry(parentResult.files, baseName, fileExists);
        }
        function clearCache() {
            cachedReadDirectoryResult.clear();
        }
    }
    ts.createCachedDirectoryStructureHost = createCachedDirectoryStructureHost;
    var ConfigFileProgramReloadLevel;
    (function (ConfigFileProgramReloadLevel) {
        ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["None"] = 0] = "None";
        /** Update the file name list from the disk */
        ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Partial"] = 1] = "Partial";
        /** Reload completely by re-reading contents of config file from disk and updating program */
        ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Full"] = 2] = "Full";
    })(ConfigFileProgramReloadLevel = ts.ConfigFileProgramReloadLevel || (ts.ConfigFileProgramReloadLevel = {}));
    /**
     * Updates the existing missing file watches with the new set of missing files after new program is created
     */
    function updateMissingFilePathsWatch(program, missingFileWatches, createMissingFileWatch) {
        var missingFilePaths = program.getMissingFilePaths();
        var newMissingFilePathMap = ts.arrayToSet(missingFilePaths);
        // Update the missing file paths watcher
        ts.mutateMap(missingFileWatches, newMissingFilePathMap, {
            // Watch the missing files
            createNewValue: createMissingFileWatch,
            // Files that are no longer missing (e.g. because they are no longer required)
            // should no longer be watched.
            onDeleteValue: ts.closeFileWatcher
        });
    }
    ts.updateMissingFilePathsWatch = updateMissingFilePathsWatch;
    /**
     * Updates the existing wild card directory watches with the new set of wild card directories from the config file
     * after new program is created because the config file was reloaded or program was created first time from the config file
     * Note that there is no need to call this function when the program is updated with additional files without reloading config files,
     * as wildcard directories wont change unless reloading config file
     */
    function updateWatchingWildcardDirectories(existingWatchedForWildcards, wildcardDirectories, watchDirectory) {
        ts.mutateMap(existingWatchedForWildcards, wildcardDirectories, {
            // Create new watch and recursive info
            createNewValue: createWildcardDirectoryWatcher,
            // Close existing watch thats not needed any more
            onDeleteValue: closeFileWatcherOf,
            // Close existing watch that doesnt match in the flags
            onExistingValue: updateWildcardDirectoryWatcher
        });
        function createWildcardDirectoryWatcher(directory, flags) {
            // Create new watch and recursive info
            return {
                watcher: watchDirectory(directory, flags),
                flags: flags
            };
        }
        function updateWildcardDirectoryWatcher(existingWatcher, flags, directory) {
            // Watcher needs to be updated if the recursive flags dont match
            if (existingWatcher.flags === flags) {
                return;
            }
            existingWatcher.watcher.close();
            existingWatchedForWildcards.set(directory, createWildcardDirectoryWatcher(directory, flags));
        }
    }
    ts.updateWatchingWildcardDirectories = updateWatchingWildcardDirectories;
    function isEmittedFileOfProgram(program, file) {
        if (!program) {
            return false;
        }
        return program.isEmittedFile(file);
    }
    ts.isEmittedFileOfProgram = isEmittedFileOfProgram;
    var WatchLogLevel;
    (function (WatchLogLevel) {
        WatchLogLevel[WatchLogLevel["None"] = 0] = "None";
        WatchLogLevel[WatchLogLevel["TriggerOnly"] = 1] = "TriggerOnly";
        WatchLogLevel[WatchLogLevel["Verbose"] = 2] = "Verbose";
    })(WatchLogLevel = ts.WatchLogLevel || (ts.WatchLogLevel = {}));
    function getWatchFactory(watchLogLevel, log, getDetailWatchInfo) {
        return getWatchFactoryWith(watchLogLevel, log, getDetailWatchInfo, watchFile, watchDirectory);
    }
    ts.getWatchFactory = getWatchFactory;
    function getWatchFactoryWith(watchLogLevel, log, getDetailWatchInfo, watchFile, watchDirectory) {
        var createFileWatcher = getCreateFileWatcher(watchLogLevel, watchFile);
        var createFilePathWatcher = watchLogLevel === WatchLogLevel.None ? watchFilePath : createFileWatcher;
        var createDirectoryWatcher = getCreateFileWatcher(watchLogLevel, watchDirectory);
        return {
            watchFile: function (host, file, callback, pollingInterval, detailInfo1, detailInfo2) {
                return createFileWatcher(host, file, callback, pollingInterval, /*passThrough*/ undefined, detailInfo1, detailInfo2, watchFile, log, "FileWatcher", getDetailWatchInfo);
            },
            watchFilePath: function (host, file, callback, pollingInterval, path, detailInfo1, detailInfo2) {
                return createFilePathWatcher(host, file, callback, pollingInterval, path, detailInfo1, detailInfo2, watchFile, log, "FileWatcher", getDetailWatchInfo);
            },
            watchDirectory: function (host, directory, callback, flags, detailInfo1, detailInfo2) {
                return createDirectoryWatcher(host, directory, callback, flags, /*passThrough*/ undefined, detailInfo1, detailInfo2, watchDirectory, log, "DirectoryWatcher", getDetailWatchInfo);
            }
        };
        function watchFilePath(host, file, callback, pollingInterval, path) {
            return watchFile(host, file, function (fileName, eventKind) { return callback(fileName, eventKind, path); }, pollingInterval);
        }
    }
    function watchFile(host, file, callback, pollingInterval) {
        return host.watchFile(file, callback, pollingInterval);
    }
    function watchDirectory(host, directory, callback, flags) {
        return host.watchDirectory(directory, callback, (flags & 1 /* Recursive */) !== 0);
    }
    function getCreateFileWatcher(watchLogLevel, addWatch) {
        switch (watchLogLevel) {
            case WatchLogLevel.None:
                return addWatch;
            case WatchLogLevel.TriggerOnly:
                return createFileWatcherWithTriggerLogging;
            case WatchLogLevel.Verbose:
                return addWatch === watchDirectory ? createDirectoryWatcherWithLogging : createFileWatcherWithLogging;
        }
    }
    function createFileWatcherWithLogging(host, file, cb, flags, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo) {
        log(watchCaption + ":: Added:: " + getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo));
        var watcher = createFileWatcherWithTriggerLogging(host, file, cb, flags, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo);
        return {
            close: function () {
                log(watchCaption + ":: Close:: " + getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo));
                watcher.close();
            }
        };
    }
    function createDirectoryWatcherWithLogging(host, file, cb, flags, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo) {
        var watchInfo = watchCaption + ":: Added:: " + getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo);
        log(watchInfo);
        var start = ts.timestamp();
        var watcher = createFileWatcherWithTriggerLogging(host, file, cb, flags, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo);
        var elapsed = ts.timestamp() - start;
        log("Elapsed:: " + elapsed + "ms " + watchInfo);
        return {
            close: function () {
                var watchInfo = watchCaption + ":: Close:: " + getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo);
                log(watchInfo);
                var start = ts.timestamp();
                watcher.close();
                var elapsed = ts.timestamp() - start;
                log("Elapsed:: " + elapsed + "ms " + watchInfo);
            }
        };
    }
    function createFileWatcherWithTriggerLogging(host, file, cb, flags, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo) {
        return addWatch(host, file, function (fileName, cbOptional) {
            var triggerredInfo = watchCaption + ":: Triggered with " + fileName + " " + (cbOptional !== undefined ? cbOptional : "") + ":: " + getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo);
            log(triggerredInfo);
            var start = ts.timestamp();
            cb(fileName, cbOptional, passThrough);
            var elapsed = ts.timestamp() - start;
            log("Elapsed:: " + elapsed + "ms " + triggerredInfo);
        }, flags);
    }
    function getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo) {
        return "WatchInfo: " + file + " " + flags + " " + (getDetailWatchInfo ? getDetailWatchInfo(detailInfo1, detailInfo2) : detailInfo2 === undefined ? detailInfo1 : detailInfo1 + " " + detailInfo2);
    }
    function closeFileWatcherOf(objWithWatcher) {
        objWithWatcher.watcher.close();
    }
    ts.closeFileWatcherOf = closeFileWatcherOf;
})(ts || (ts = {}));
var ts;
(function (ts) {
    var ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/;
    function findConfigFile(searchPath, fileExists, configName) {
        if (configName === void 0) { configName = "tsconfig.json"; }
        return ts.forEachAncestorDirectory(searchPath, function (ancestor) {
            var fileName = ts.combinePaths(ancestor, configName);
            return fileExists(fileName) ? fileName : undefined;
        });
    }
    ts.findConfigFile = findConfigFile;
    function resolveTripleslashReference(moduleName, containingFile) {
        var basePath = ts.getDirectoryPath(containingFile);
        var referencedFileName = ts.isRootedDiskPath(moduleName) ? moduleName : ts.combinePaths(basePath, moduleName);
        return ts.normalizePath(referencedFileName);
    }
    ts.resolveTripleslashReference = resolveTripleslashReference;
    /* @internal */
    function computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName) {
        var commonPathComponents;
        var failed = ts.forEach(fileNames, function (sourceFile) {
            // Each file contributes into common source file path
            var sourcePathComponents = ts.getNormalizedPathComponents(sourceFile, currentDirectory);
            sourcePathComponents.pop(); // The base file name is not part of the common directory path
            if (!commonPathComponents) {
                // first file
                commonPathComponents = sourcePathComponents;
                return;
            }
            var n = Math.min(commonPathComponents.length, sourcePathComponents.length);
            for (var i = 0; i < n; i++) {
                if (getCanonicalFileName(commonPathComponents[i]) !== getCanonicalFileName(sourcePathComponents[i])) {
                    if (i === 0) {
                        // Failed to find any common path component
                        return true;
                    }
                    // New common path found that is 0 -> i-1
                    commonPathComponents.length = i;
                    break;
                }
            }
            // If the sourcePathComponents was shorter than the commonPathComponents, truncate to the sourcePathComponents
            if (sourcePathComponents.length < commonPathComponents.length) {
                commonPathComponents.length = sourcePathComponents.length;
            }
        });
        // A common path can not be found when paths span multiple drives on windows, for example
        if (failed) {
            return "";
        }
        if (!commonPathComponents) { // Can happen when all input files are .d.ts files
            return currentDirectory;
        }
        return ts.getPathFromPathComponents(commonPathComponents);
    }
    ts.computeCommonSourceDirectoryOfFilenames = computeCommonSourceDirectoryOfFilenames;
    function createCompilerHost(options, setParentNodes) {
        return createCompilerHostWorker(options, setParentNodes);
    }
    ts.createCompilerHost = createCompilerHost;
    /*@internal*/
    // TODO(shkamat): update this after reworking ts build API
    function createCompilerHostWorker(options, setParentNodes, system) {
        if (system === void 0) { system = ts.sys; }
        var existingDirectories = ts.createMap();
        var getCanonicalFileName = ts.createGetCanonicalFileName(system.useCaseSensitiveFileNames);
        function getSourceFile(fileName, languageVersion, onError) {
            var text;
            try {
                ts.performance.mark("beforeIORead");
                text = compilerHost.readFile(fileName);
                ts.performance.mark("afterIORead");
                ts.performance.measure("I/O Read", "beforeIORead", "afterIORead");
            }
            catch (e) {
                if (onError) {
                    onError(e.message);
                }
                text = "";
            }
            return text !== undefined ? ts.createSourceFile(fileName, text, languageVersion, setParentNodes) : undefined;
        }
        function directoryExists(directoryPath) {
            if (existingDirectories.has(directoryPath)) {
                return true;
            }
            if (system.directoryExists(directoryPath)) {
                existingDirectories.set(directoryPath, true);
                return true;
            }
            return false;
        }
        function ensureDirectoriesExist(directoryPath) {
            if (directoryPath.length > ts.getRootLength(directoryPath) && !directoryExists(directoryPath)) {
                var parentDirectory = ts.getDirectoryPath(directoryPath);
                ensureDirectoriesExist(parentDirectory);
                if (compilerHost.createDirectory) {
                    compilerHost.createDirectory(directoryPath);
                }
                else {
                    system.createDirectory(directoryPath);
                }
            }
        }
        var outputFingerprints;
        function writeFileIfUpdated(fileName, data, writeByteOrderMark) {
            if (!outputFingerprints) {
                outputFingerprints = ts.createMap();
            }
            var hash = system.createHash(data); // TODO: GH#18217
            var mtimeBefore = system.getModifiedTime(fileName); // TODO: GH#18217
            if (mtimeBefore) {
                var fingerprint = outputFingerprints.get(fileName);
                // If output has not been changed, and the file has no external modification
                if (fingerprint &&
                    fingerprint.byteOrderMark === writeByteOrderMark &&
                    fingerprint.hash === hash &&
                    fingerprint.mtime.getTime() === mtimeBefore.getTime()) {
                    return;
                }
            }
            system.writeFile(fileName, data, writeByteOrderMark);
            var mtimeAfter = system.getModifiedTime(fileName) || ts.missingFileModifiedTime; // TODO: GH#18217
            outputFingerprints.set(fileName, {
                hash: hash,
                byteOrderMark: writeByteOrderMark,
                mtime: mtimeAfter
            });
        }
        function writeFile(fileName, data, writeByteOrderMark, onError) {
            try {
                ts.performance.mark("beforeIOWrite");
                ensureDirectoriesExist(ts.getDirectoryPath(ts.normalizePath(fileName)));
                if (ts.isWatchSet(options) && system.createHash && system.getModifiedTime) {
                    writeFileIfUpdated(fileName, data, writeByteOrderMark);
                }
                else {
                    system.writeFile(fileName, data, writeByteOrderMark);
                }
                ts.performance.mark("afterIOWrite");
                ts.performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
            }
            catch (e) {
                if (onError) {
                    onError(e.message);
                }
            }
        }
        function getDefaultLibLocation() {
            return ts.getDirectoryPath(ts.normalizePath(system.getExecutingFilePath()));
        }
        var newLine = ts.getNewLineCharacter(options, function () { return system.newLine; });
        var realpath = system.realpath && (function (path) { return system.realpath(path); });
        var compilerHost = {
            getSourceFile: getSourceFile,
            getDefaultLibLocation: getDefaultLibLocation,
            getDefaultLibFileName: function (options) { return ts.combinePaths(getDefaultLibLocation(), ts.getDefaultLibFileName(options)); },
            writeFile: writeFile,
            getCurrentDirectory: ts.memoize(function () { return system.getCurrentDirectory(); }),
            useCaseSensitiveFileNames: function () { return system.useCaseSensitiveFileNames; },
            getCanonicalFileName: getCanonicalFileName,
            getNewLine: function () { return newLine; },
            fileExists: function (fileName) { return system.fileExists(fileName); },
            readFile: function (fileName) { return system.readFile(fileName); },
            trace: function (s) { return system.write(s + newLine); },
            directoryExists: function (directoryName) { return system.directoryExists(directoryName); },
            getEnvironmentVariable: function (name) { return system.getEnvironmentVariable ? system.getEnvironmentVariable(name) : ""; },
            getDirectories: function (path) { return system.getDirectories(path); },
            realpath: realpath,
            readDirectory: function (path, extensions, include, exclude, depth) { return system.readDirectory(path, extensions, include, exclude, depth); },
            createDirectory: function (d) { return system.createDirectory(d); },
            createHash: ts.maybeBind(system, system.createHash)
        };
        return compilerHost;
    }
    ts.createCompilerHostWorker = createCompilerHostWorker;
    /*@internal*/
    function changeCompilerHostLikeToUseCache(host, toPath, getSourceFile) {
        var originalReadFile = host.readFile;
        var originalFileExists = host.fileExists;
        var originalDirectoryExists = host.directoryExists;
        var originalCreateDirectory = host.createDirectory;
        var originalWriteFile = host.writeFile;
        var readFileCache = ts.createMap();
        var fileExistsCache = ts.createMap();
        var directoryExistsCache = ts.createMap();
        var sourceFileCache = ts.createMap();
        var readFileWithCache = function (fileName) {
            var key = toPath(fileName);
            var value = readFileCache.get(key);
            if (value !== undefined)
                return value !== false ? value : undefined;
            return setReadFileCache(key, fileName);
        };
        var setReadFileCache = function (key, fileName) {
            var newValue = originalReadFile.call(host, fileName);
            readFileCache.set(key, newValue !== undefined ? newValue : false);
            return newValue;
        };
        host.readFile = function (fileName) {
            var key = toPath(fileName);
            var value = readFileCache.get(key);
            if (value !== undefined)
                return value !== false ? value : undefined; // could be .d.ts from output
            // Cache json or buildInfo
            if (!ts.fileExtensionIs(fileName, ".json" /* Json */) && !ts.isBuildInfoFile(fileName)) {
                return originalReadFile.call(host, fileName);
            }
            return setReadFileCache(key, fileName);
        };
        var getSourceFileWithCache = getSourceFile ? function (fileName, languageVersion, onError, shouldCreateNewSourceFile) {
            var key = toPath(fileName);
            var value = sourceFileCache.get(key);
            if (value)
                return value;
            var sourceFile = getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
            if (sourceFile && (ts.isDeclarationFileName(fileName) || ts.fileExtensionIs(fileName, ".json" /* Json */))) {
                sourceFileCache.set(key, sourceFile);
            }
            return sourceFile;
        } : undefined;
        // fileExists for any kind of extension
        host.fileExists = function (fileName) {
            var key = toPath(fileName);
            var value = fileExistsCache.get(key);
            if (value !== undefined)
                return value;
            var newValue = originalFileExists.call(host, fileName);
            fileExistsCache.set(key, !!newValue);
            return newValue;
        };
        if (originalWriteFile) {
            host.writeFile = function (fileName, data, writeByteOrderMark, onError, sourceFiles) {
                var key = toPath(fileName);
                fileExistsCache.delete(key);
                var value = readFileCache.get(key);
                if (value !== undefined && value !== data) {
                    readFileCache.delete(key);
                    sourceFileCache.delete(key);
                }
                else if (getSourceFileWithCache) {
                    var sourceFile = sourceFileCache.get(key);
                    if (sourceFile && sourceFile.text !== data) {
                        sourceFileCache.delete(key);
                    }
                }
                originalWriteFile.call(host, fileName, data, writeByteOrderMark, onError, sourceFiles);
            };
        }
        // directoryExists
        if (originalDirectoryExists && originalCreateDirectory) {
            host.directoryExists = function (directory) {
                var key = toPath(directory);
                var value = directoryExistsCache.get(key);
                if (value !== undefined)
                    return value;
                var newValue = originalDirectoryExists.call(host, directory);
                directoryExistsCache.set(key, !!newValue);
                return newValue;
            };
            host.createDirectory = function (directory) {
                var key = toPath(directory);
                directoryExistsCache.delete(key);
                originalCreateDirectory.call(host, directory);
            };
        }
        return {
            originalReadFile: originalReadFile,
            originalFileExists: originalFileExists,
            originalDirectoryExists: originalDirectoryExists,
            originalCreateDirectory: originalCreateDirectory,
            originalWriteFile: originalWriteFile,
            getSourceFileWithCache: getSourceFileWithCache,
            readFileWithCache: readFileWithCache
        };
    }
    ts.changeCompilerHostLikeToUseCache = changeCompilerHostLikeToUseCache;
    function getPreEmitDiagnostics(program, sourceFile, cancellationToken) {
        var diagnostics = program.getConfigFileParsingDiagnostics().concat(program.getOptionsDiagnostics(cancellationToken), program.getSyntacticDiagnostics(sourceFile, cancellationToken), program.getGlobalDiagnostics(cancellationToken), program.getSemanticDiagnostics(sourceFile, cancellationToken));
        if (ts.getEmitDeclarations(program.getCompilerOptions())) {
            ts.addRange(diagnostics, program.getDeclarationDiagnostics(sourceFile, cancellationToken));
        }
        return ts.sortAndDeduplicateDiagnostics(diagnostics);
    }
    ts.getPreEmitDiagnostics = getPreEmitDiagnostics;
    function formatDiagnostics(diagnostics, host) {
        var output = "";
        for (var _i = 0, diagnostics_2 = diagnostics; _i < diagnostics_2.length; _i++) {
            var diagnostic = diagnostics_2[_i];
            output += formatDiagnostic(diagnostic, host);
        }
        return output;
    }
    ts.formatDiagnostics = formatDiagnostics;
    function formatDiagnostic(diagnostic, host) {
        var errorMessage = ts.diagnosticCategoryName(diagnostic) + " TS" + diagnostic.code + ": " + flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) + host.getNewLine();
        if (diagnostic.file) {
            var _a = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start), line = _a.line, character = _a.character; // TODO: GH#18217
            var fileName = diagnostic.file.fileName;
            var relativeFileName = ts.convertToRelativePath(fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); });
            return relativeFileName + "(" + (line + 1) + "," + (character + 1) + "): " + errorMessage;
        }
        return errorMessage;
    }
    ts.formatDiagnostic = formatDiagnostic;
    /** @internal */
    var ForegroundColorEscapeSequences;
    (function (ForegroundColorEscapeSequences) {
        ForegroundColorEscapeSequences["Grey"] = "\u001B[90m";
        ForegroundColorEscapeSequences["Red"] = "\u001B[91m";
        ForegroundColorEscapeSequences["Yellow"] = "\u001B[93m";
        ForegroundColorEscapeSequences["Blue"] = "\u001B[94m";
        ForegroundColorEscapeSequences["Cyan"] = "\u001B[96m";
    })(ForegroundColorEscapeSequences = ts.ForegroundColorEscapeSequences || (ts.ForegroundColorEscapeSequences = {}));
    var gutterStyleSequence = "\u001b[7m";
    var gutterSeparator = " ";
    var resetEscapeSequence = "\u001b[0m";
    var ellipsis = "...";
    var halfIndent = "  ";
    var indent = "    ";
    function getCategoryFormat(category) {
        switch (category) {
            case ts.DiagnosticCategory.Error: return ForegroundColorEscapeSequences.Red;
            case ts.DiagnosticCategory.Warning: return ForegroundColorEscapeSequences.Yellow;
            case ts.DiagnosticCategory.Suggestion: return ts.Debug.fail("Should never get an Info diagnostic on the command line.");
            case ts.DiagnosticCategory.Message: return ForegroundColorEscapeSequences.Blue;
        }
    }
    /** @internal */
    function formatColorAndReset(text, formatStyle) {
        return formatStyle + text + resetEscapeSequence;
    }
    ts.formatColorAndReset = formatColorAndReset;
    function padLeft(s, length) {
        while (s.length < length) {
            s = " " + s;
        }
        return s;
    }
    function formatCodeSpan(file, start, length, indent, squiggleColor, host) {
        var _a = ts.getLineAndCharacterOfPosition(file, start), firstLine = _a.line, firstLineChar = _a.character;
        var _b = ts.getLineAndCharacterOfPosition(file, start + length), lastLine = _b.line, lastLineChar = _b.character;
        var lastLineInFile = ts.getLineAndCharacterOfPosition(file, file.text.length).line;
        var hasMoreThanFiveLines = (lastLine - firstLine) >= 4;
        var gutterWidth = (lastLine + 1 + "").length;
        if (hasMoreThanFiveLines) {
            gutterWidth = Math.max(ellipsis.length, gutterWidth);
        }
        var context = "";
        for (var i = firstLine; i <= lastLine; i++) {
            context += host.getNewLine();
            // If the error spans over 5 lines, we'll only show the first 2 and last 2 lines,
            // so we'll skip ahead to the second-to-last line.
            if (hasMoreThanFiveLines && firstLine + 1 < i && i < lastLine - 1) {
                context += indent + formatColorAndReset(padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + host.getNewLine();
                i = lastLine - 1;
            }
            var lineStart = ts.getPositionOfLineAndCharacter(file, i, 0);
            var lineEnd = i < lastLineInFile ? ts.getPositionOfLineAndCharacter(file, i + 1, 0) : file.text.length;
            var lineContent = file.text.slice(lineStart, lineEnd);
            lineContent = lineContent.replace(/\s+$/g, ""); // trim from end
            lineContent = lineContent.replace("\t", " "); // convert tabs to single spaces
            // Output the gutter and the actual contents of the line.
            context += indent + formatColorAndReset(padLeft(i + 1 + "", gutterWidth), gutterStyleSequence) + gutterSeparator;
            context += lineContent + host.getNewLine();
            // Output the gutter and the error span for the line using tildes.
            context += indent + formatColorAndReset(padLeft("", gutterWidth), gutterStyleSequence) + gutterSeparator;
            context += squiggleColor;
            if (i === firstLine) {
                // If we're on the last line, then limit it to the last character of the last line.
                // Otherwise, we'll just squiggle the rest of the line, giving 'slice' no end position.
                var lastCharForLine = i === lastLine ? lastLineChar : undefined;
                context += lineContent.slice(0, firstLineChar).replace(/\S/g, " ");
                context += lineContent.slice(firstLineChar, lastCharForLine).replace(/./g, "~");
            }
            else if (i === lastLine) {
                context += lineContent.slice(0, lastLineChar).replace(/./g, "~");
            }
            else {
                // Squiggle the entire line.
                context += lineContent.replace(/./g, "~");
            }
            context += resetEscapeSequence;
        }
        return context;
    }
    /* @internal */
    function formatLocation(file, start, host, color) {
        if (color === void 0) { color = formatColorAndReset; }
        var _a = ts.getLineAndCharacterOfPosition(file, start), firstLine = _a.line, firstLineChar = _a.character; // TODO: GH#18217
        var relativeFileName = host ? ts.convertToRelativePath(file.fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }) : file.fileName;
        var output = "";
        output += color(relativeFileName, ForegroundColorEscapeSequences.Cyan);
        output += ":";
        output += color("" + (firstLine + 1), ForegroundColorEscapeSequences.Yellow);
        output += ":";
        output += color("" + (firstLineChar + 1), ForegroundColorEscapeSequences.Yellow);
        return output;
    }
    ts.formatLocation = formatLocation;
    function formatDiagnosticsWithColorAndContext(diagnostics, host) {
        var output = "";
        for (var _i = 0, diagnostics_3 = diagnostics; _i < diagnostics_3.length; _i++) {
            var diagnostic = diagnostics_3[_i];
            if (diagnostic.file) {
                var file = diagnostic.file, start = diagnostic.start;
                output += formatLocation(file, start, host); // TODO: GH#18217
                output += " - ";
            }
            output += formatColorAndReset(ts.diagnosticCategoryName(diagnostic), getCategoryFormat(diagnostic.category));
            output += formatColorAndReset(" TS" + diagnostic.code + ": ", ForegroundColorEscapeSequences.Grey);
            output += flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine());
            if (diagnostic.file) {
                output += host.getNewLine();
                output += formatCodeSpan(diagnostic.file, diagnostic.start, diagnostic.length, "", getCategoryFormat(diagnostic.category), host); // TODO: GH#18217
                if (diagnostic.relatedInformation) {
                    output += host.getNewLine();
                    for (var _a = 0, _b = diagnostic.relatedInformation; _a < _b.length; _a++) {
                        var _c = _b[_a], file = _c.file, start = _c.start, length_4 = _c.length, messageText = _c.messageText;
                        if (file) {
                            output += host.getNewLine();
                            output += halfIndent + formatLocation(file, start, host); // TODO: GH#18217
                            output += formatCodeSpan(file, start, length_4, indent, ForegroundColorEscapeSequences.Cyan, host); // TODO: GH#18217
                        }
                        output += host.getNewLine();
                        output += indent + flattenDiagnosticMessageText(messageText, host.getNewLine());
                    }
                }
            }
            output += host.getNewLine();
        }
        return output;
    }
    ts.formatDiagnosticsWithColorAndContext = formatDiagnosticsWithColorAndContext;
    function flattenDiagnosticMessageText(messageText, newLine) {
        if (ts.isString(messageText)) {
            return messageText;
        }
        else {
            var diagnosticChain = messageText;
            var result = "";
            var indent_1 = 0;
            while (diagnosticChain) {
                if (indent_1) {
                    result += newLine;
                    for (var i = 0; i < indent_1; i++) {
                        result += "  ";
                    }
                }
                result += diagnosticChain.messageText;
                indent_1++;
                diagnosticChain = diagnosticChain.next;
            }
            return result;
        }
    }
    ts.flattenDiagnosticMessageText = flattenDiagnosticMessageText;
    /* @internal */
    function loadWithLocalCache(names, containingFile, redirectedReference, loader) {
        if (names.length === 0) {
            return [];
        }
        var resolutions = [];
        var cache = ts.createMap();
        for (var _i = 0, names_1 = names; _i < names_1.length; _i++) {
            var name = names_1[_i];
            var result = void 0;
            if (cache.has(name)) {
                result = cache.get(name);
            }
            else {
                cache.set(name, result = loader(name, containingFile, redirectedReference));
            }
            resolutions.push(result);
        }
        return resolutions;
    }
    ts.loadWithLocalCache = loadWithLocalCache;
    /**
     * Determines if program structure is upto date or needs to be recreated
     */
    /* @internal */
    function isProgramUptoDate(program, rootFileNames, newOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, projectReferences) {
        // If we haven't created a program yet or have changed automatic type directives, then it is not up-to-date
        if (!program || hasChangedAutomaticTypeDirectiveNames) {
            return false;
        }
        // If number of files in the program do not match, it is not up-to-date
        if (program.getRootFileNames().length !== rootFileNames.length) {
            return false;
        }
        var seenResolvedRefs;
        // If project references dont match
        if (!ts.arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) {
            return false;
        }
        // If any file is not up-to-date, then the whole program is not up-to-date
        if (program.getSourceFiles().some(sourceFileNotUptoDate)) {
            return false;
        }
        // If any of the missing file paths are now created
        if (program.getMissingFilePaths().some(fileExists)) {
            return false;
        }
        var currentOptions = program.getCompilerOptions();
        // If the compilation settings do no match, then the program is not up-to-date
        if (!ts.compareDataObjects(currentOptions, newOptions)) {
            return false;
        }
        // If everything matches but the text of config file is changed,
        // error locations can change for program options, so update the program
        if (currentOptions.configFile && newOptions.configFile) {
            return currentOptions.configFile.text === newOptions.configFile.text;
        }
        return true;
        function sourceFileNotUptoDate(sourceFile) {
            return !sourceFileVersionUptoDate(sourceFile) ||
                hasInvalidatedResolution(sourceFile.path);
        }
        function sourceFileVersionUptoDate(sourceFile) {
            return sourceFile.version === getSourceVersion(sourceFile.resolvedPath);
        }
        function projectReferenceUptoDate(oldRef, newRef, index) {
            if (!ts.projectReferenceIsEqualTo(oldRef, newRef)) {
                return false;
            }
            return resolvedProjectReferenceUptoDate(program.getResolvedProjectReferences()[index], oldRef);
        }
        function resolvedProjectReferenceUptoDate(oldResolvedRef, oldRef) {
            if (oldResolvedRef) {
                if (ts.contains(seenResolvedRefs, oldResolvedRef)) {
                    // Assume true
                    return true;
                }
                // If sourceFile for the oldResolvedRef existed, check the version for uptodate
                if (!sourceFileVersionUptoDate(oldResolvedRef.sourceFile)) {
                    return false;
                }
                // Add to seen before checking the referenced paths of this config file
                (seenResolvedRefs || (seenResolvedRefs = [])).push(oldResolvedRef);
                // If child project references are upto date, this project reference is uptodate
                return !ts.forEach(oldResolvedRef.references, function (childResolvedRef, index) {
                    return !resolvedProjectReferenceUptoDate(childResolvedRef, oldResolvedRef.commandLine.projectReferences[index]);
                });
            }
            // In old program, not able to resolve project reference path,
            // so if config file doesnt exist, it is uptodate.
            return !fileExists(resolveProjectReferencePath(oldRef));
        }
    }
    ts.isProgramUptoDate = isProgramUptoDate;
    function getConfigFileParsingDiagnostics(configFileParseResult) {
        return configFileParseResult.options.configFile ? configFileParseResult.options.configFile.parseDiagnostics.concat(configFileParseResult.errors) :
            configFileParseResult.errors;
    }
    ts.getConfigFileParsingDiagnostics = getConfigFileParsingDiagnostics;
    /**
     * Determine if source file needs to be re-created even if its text hasn't changed
     */
    function shouldProgramCreateNewSourceFiles(program, newOptions) {
        if (!program)
            return false;
        // If any compiler options change, we can't reuse old source file even if version match
        // The change in options like these could result in change in syntax tree or `sourceFile.bindDiagnostics`.
        var oldOptions = program.getCompilerOptions();
        return !!ts.sourceFileAffectingCompilerOptions.some(function (option) {
            return !ts.isJsonEqual(ts.getCompilerOptionValue(oldOptions, option), ts.getCompilerOptionValue(newOptions, option));
        });
    }
    function createCreateProgramOptions(rootNames, options, host, oldProgram, configFileParsingDiagnostics) {
        return {
            rootNames: rootNames,
            options: options,
            host: host,
            oldProgram: oldProgram,
            configFileParsingDiagnostics: configFileParsingDiagnostics
        };
    }
    function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) {
        var createProgramOptions = ts.isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions; // TODO: GH#18217
        var rootNames = createProgramOptions.rootNames, options = createProgramOptions.options, configFileParsingDiagnostics = createProgramOptions.configFileParsingDiagnostics, projectReferences = createProgramOptions.projectReferences;
        var oldProgram = createProgramOptions.oldProgram;
        var program;
        var processingDefaultLibFiles;
        var processingOtherFiles;
        var files;
        var commonSourceDirectory;
        var diagnosticsProducingTypeChecker;
        var noDiagnosticsTypeChecker;
        var classifiableNames;
        var ambientModuleNameToUnmodifiedFileName = ts.createMap();
        var cachedSemanticDiagnosticsForFile = {};
        var cachedDeclarationDiagnosticsForFile = {};
        var resolvedTypeReferenceDirectives = ts.createMap();
        var fileProcessingDiagnostics = ts.createDiagnosticCollection();
        // The below settings are to track if a .js file should be add to the program if loaded via searching under node_modules.
        // This works as imported modules are discovered recursively in a depth first manner, specifically:
        // - For each root file, findSourceFile is called.
        // - This calls processImportedModules for each module imported in the source file.
        // - This calls resolveModuleNames, and then calls findSourceFile for each resolved module.
        // As all these operations happen - and are nested - within the createProgram call, they close over the below variables.
        // The current resolution depth is tracked by incrementing/decrementing as the depth first search progresses.
        var maxNodeModuleJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 0;
        var currentNodeModulesDepth = 0;
        // If a module has some of its imports skipped due to being at the depth limit under node_modules, then track
        // this, as it may be imported at a shallower depth later, and then it will need its skipped imports processed.
        var modulesWithElidedImports = ts.createMap();
        // Track source files that are source files found by searching under node_modules, as these shouldn't be compiled.
        var sourceFilesFoundSearchingNodeModules = ts.createMap();
        ts.performance.mark("beforeProgram");
        var host = createProgramOptions.host || createCompilerHost(options);
        var configParsingHost = parseConfigHostFromCompilerHostLike(host);
        var skipDefaultLib = options.noLib;
        var getDefaultLibraryFileName = ts.memoize(function () { return host.getDefaultLibFileName(options); });
        var defaultLibraryPath = host.getDefaultLibLocation ? host.getDefaultLibLocation() : ts.getDirectoryPath(getDefaultLibraryFileName());
        var programDiagnostics = ts.createDiagnosticCollection();
        var currentDirectory = host.getCurrentDirectory();
        var supportedExtensions = ts.getSupportedExtensions(options);
        var supportedExtensionsWithJsonIfResolveJsonModule = ts.getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions);
        // Map storing if there is emit blocking diagnostics for given input
        var hasEmitBlockingDiagnostics = ts.createMap();
        var _compilerOptionsObjectLiteralSyntax;
        var moduleResolutionCache;
        var resolveModuleNamesWorker;
        var hasInvalidatedResolution = host.hasInvalidatedResolution || ts.returnFalse;
        if (host.resolveModuleNames) {
            resolveModuleNamesWorker = function (moduleNames, containingFile, reusedNames, redirectedReference) { return host.resolveModuleNames(ts.Debug.assertEachDefined(moduleNames), containingFile, reusedNames, redirectedReference).map(function (resolved) {
                // An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
                if (!resolved || resolved.extension !== undefined) {
                    return resolved;
                }
                var withExtension = ts.clone(resolved);
                withExtension.extension = ts.extensionFromPath(resolved.resolvedFileName);
                return withExtension;
            }); };
        }
        else {
            moduleResolutionCache = ts.createModuleResolutionCache(currentDirectory, function (x) { return host.getCanonicalFileName(x); }, options);
            var loader_1 = function (moduleName, containingFile, redirectedReference) { return ts.resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache, redirectedReference).resolvedModule; }; // TODO: GH#18217
            resolveModuleNamesWorker = function (moduleNames, containingFile, _reusedNames, redirectedReference) { return loadWithLocalCache(ts.Debug.assertEachDefined(moduleNames), containingFile, redirectedReference, loader_1); };
        }
        var resolveTypeReferenceDirectiveNamesWorker;
        if (host.resolveTypeReferenceDirectives) {
            resolveTypeReferenceDirectiveNamesWorker = function (typeDirectiveNames, containingFile, redirectedReference) { return host.resolveTypeReferenceDirectives(ts.Debug.assertEachDefined(typeDirectiveNames), containingFile, redirectedReference); };
        }
        else {
            var loader_2 = function (typesRef, containingFile, redirectedReference) { return ts.resolveTypeReferenceDirective(typesRef, containingFile, options, host, redirectedReference).resolvedTypeReferenceDirective; }; // TODO: GH#18217
            resolveTypeReferenceDirectiveNamesWorker = function (typeReferenceDirectiveNames, containingFile, redirectedReference) { return loadWithLocalCache(ts.Debug.assertEachDefined(typeReferenceDirectiveNames), containingFile, redirectedReference, loader_2); };
        }
        // Map from a stringified PackageId to the source file with that id.
        // Only one source file may have a given packageId. Others become redirects (see createRedirectSourceFile).
        // `packageIdToSourceFile` is only used while building the program, while `sourceFileToPackageName` and `isSourceFileTargetOfRedirect` are kept around.
        var packageIdToSourceFile = ts.createMap();
        // Maps from a SourceFile's `.path` to the name of the package it was imported with.
        var sourceFileToPackageName = ts.createMap();
        // Key is a file name. Value is the (non-empty, or undefined) list of files that redirect to it.
        var redirectTargetsMap = ts.createMultiMap();
        /**
         * map with
         * - SourceFile if present
         * - false if sourceFile missing for source of project reference redirect
         * - undefined otherwise
         */
        var filesByName = ts.createMap();
        var missingFilePaths;
        // stores 'filename -> file association' ignoring case
        // used to track cases when two file names differ only in casing
        var filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? ts.createMap() : undefined;
        // A parallel array to projectReferences storing the results of reading in the referenced tsconfig files
        var resolvedProjectReferences;
        var projectReferenceRedirects;
        var mapFromFileToProjectReferenceRedirects;
        var shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
        var structuralIsReused = tryReuseStructureFromOldProgram();
        if (structuralIsReused !== 2 /* Completely */) {
            processingDefaultLibFiles = [];
            processingOtherFiles = [];
            if (projectReferences) {
                if (!resolvedProjectReferences) {
                    resolvedProjectReferences = projectReferences.map(parseProjectReferenceConfigFile);
                }
                if (rootNames.length) {
                    for (var _i = 0, resolvedProjectReferences_1 = resolvedProjectReferences; _i < resolvedProjectReferences_1.length; _i++) {
                        var parsedRef = resolvedProjectReferences_1[_i];
                        if (!parsedRef)
                            continue;
                        var out = parsedRef.commandLine.options.outFile || parsedRef.commandLine.options.out;
                        if (out) {
                            processSourceFile(ts.changeExtension(out, ".d.ts"), /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined);
                        }
                        else if (ts.getEmitModuleKind(parsedRef.commandLine.options) === ts.ModuleKind.None) {
                            for (var _a = 0, _b = parsedRef.commandLine.fileNames; _a < _b.length; _a++) {
                                var fileName = _b[_a];
                                if (!ts.fileExtensionIs(fileName, ".d.ts" /* Dts */) && ts.hasTSFileExtension(fileName)) {
                                    processSourceFile(ts.getOutputDeclarationFileName(fileName, parsedRef.commandLine, !host.useCaseSensitiveFileNames()), /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined);
                                }
                            }
                        }
                    }
                }
            }
            ts.forEach(rootNames, function (name) { return processRootFile(name, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false); });
            // load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders
            var typeReferences = rootNames.length ? ts.getAutomaticTypeDirectiveNames(options, host) : ts.emptyArray;
            if (typeReferences.length) {
                // This containingFilename needs to match with the one used in managed-side
                var containingDirectory = options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();
                var containingFilename = ts.combinePaths(containingDirectory, "__inferred type names__.ts");
                var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);
                for (var i = 0; i < typeReferences.length; i++) {
                    processTypeReferenceDirective(typeReferences[i], resolutions[i]);
                }
            }
            // Do not process the default library if:
            //  - The '--noLib' flag is used.
            //  - A 'no-default-lib' reference comment is encountered in
            //      processing the root files.
            if (rootNames.length && !skipDefaultLib) {
                // If '--lib' is not specified, include default library file according to '--target'
                // otherwise, using options specified in '--lib' instead of '--target' default library file
                var defaultLibraryFileName = getDefaultLibraryFileName();
                if (!options.lib && defaultLibraryFileName) {
                    processRootFile(defaultLibraryFileName, /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ false);
                }
                else {
                    ts.forEach(options.lib, function (libFileName) {
                        processRootFile(ts.combinePaths(defaultLibraryPath, libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ false);
                    });
                }
            }
            missingFilePaths = ts.arrayFrom(ts.mapDefinedIterator(filesByName.entries(), function (_a) {
                var path = _a[0], file = _a[1];
                return file === undefined ? path : undefined;
            }));
            files = ts.stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles);
            processingDefaultLibFiles = undefined;
            processingOtherFiles = undefined;
        }
        ts.Debug.assert(!!missingFilePaths);
        // Release any files we have acquired in the old program but are
        // not part of the new program.
        if (oldProgram && host.onReleaseOldSourceFile) {
            var oldSourceFiles = oldProgram.getSourceFiles();
            for (var _c = 0, oldSourceFiles_1 = oldSourceFiles; _c < oldSourceFiles_1.length; _c++) {
                var oldSourceFile = oldSourceFiles_1[_c];
                var newFile = getSourceFileByPath(oldSourceFile.resolvedPath);
                if (shouldCreateNewSourceFile || !newFile ||
                    // old file wasnt redirect but new file is
                    (oldSourceFile.resolvedPath === oldSourceFile.path && newFile.resolvedPath !== oldSourceFile.path)) {
                    host.onReleaseOldSourceFile(oldSourceFile, oldProgram.getCompilerOptions(), !!getSourceFileByPath(oldSourceFile.path));
                }
            }
            oldProgram.forEachResolvedProjectReference(function (resolvedProjectReference, resolvedProjectReferencePath) {
                if (resolvedProjectReference && !getResolvedProjectReferenceByPath(resolvedProjectReferencePath)) {
                    host.onReleaseOldSourceFile(resolvedProjectReference.sourceFile, oldProgram.getCompilerOptions(), /*hasSourceFileByPath*/ false);
                }
            });
        }
        // unconditionally set oldProgram to undefined to prevent it from being captured in closure
        oldProgram = undefined;
        program = {
            getRootFileNames: function () { return rootNames; },
            getSourceFile: getSourceFile,
            getSourceFileByPath: getSourceFileByPath,
            getSourceFiles: function () { return files; },
            getMissingFilePaths: function () { return missingFilePaths; },
            getCompilerOptions: function () { return options; },
            getSyntacticDiagnostics: getSyntacticDiagnostics,
            getOptionsDiagnostics: getOptionsDiagnostics,
            getGlobalDiagnostics: getGlobalDiagnostics,
            getSemanticDiagnostics: getSemanticDiagnostics,
            getSuggestionDiagnostics: getSuggestionDiagnostics,
            getDeclarationDiagnostics: getDeclarationDiagnostics,
            getTypeChecker: getTypeChecker,
            getClassifiableNames: getClassifiableNames,
            getDiagnosticsProducingTypeChecker: getDiagnosticsProducingTypeChecker,
            getCommonSourceDirectory: getCommonSourceDirectory,
            emit: emit,
            getCurrentDirectory: function () { return currentDirectory; },
            getNodeCount: function () { return getDiagnosticsProducingTypeChecker().getNodeCount(); },
            getIdentifierCount: function () { return getDiagnosticsProducingTypeChecker().getIdentifierCount(); },
            getSymbolCount: function () { return getDiagnosticsProducingTypeChecker().getSymbolCount(); },
            getTypeCount: function () { return getDiagnosticsProducingTypeChecker().getTypeCount(); },
            getRelationCacheSizes: function () { return getDiagnosticsProducingTypeChecker().getRelationCacheSizes(); },
            getFileProcessingDiagnostics: function () { return fileProcessingDiagnostics; },
            getResolvedTypeReferenceDirectives: function () { return resolvedTypeReferenceDirectives; },
            isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary,
            isSourceFileDefaultLibrary: isSourceFileDefaultLibrary,
            dropDiagnosticsProducingTypeChecker: dropDiagnosticsProducingTypeChecker,
            getSourceFileFromReference: getSourceFileFromReference,
            getLibFileFromReference: getLibFileFromReference,
            sourceFileToPackageName: sourceFileToPackageName,
            redirectTargetsMap: redirectTargetsMap,
            isEmittedFile: isEmittedFile,
            getConfigFileParsingDiagnostics: getConfigFileParsingDiagnostics,
            getResolvedModuleWithFailedLookupLocationsFromCache: getResolvedModuleWithFailedLookupLocationsFromCache,
            getProjectReferences: getProjectReferences,
            getResolvedProjectReferences: getResolvedProjectReferences,
            getProjectReferenceRedirect: getProjectReferenceRedirect,
            getResolvedProjectReferenceToRedirect: getResolvedProjectReferenceToRedirect,
            getResolvedProjectReferenceByPath: getResolvedProjectReferenceByPath,
            forEachResolvedProjectReference: forEachResolvedProjectReference,
            emitBuildInfo: emitBuildInfo
        };
        verifyCompilerOptions();
        ts.performance.mark("afterProgram");
        ts.performance.measure("Program", "beforeProgram", "afterProgram");
        return program;
        function compareDefaultLibFiles(a, b) {
            return ts.compareValues(getDefaultLibFilePriority(a), getDefaultLibFilePriority(b));
        }
        function getDefaultLibFilePriority(a) {
            if (ts.containsPath(defaultLibraryPath, a.fileName, /*ignoreCase*/ false)) {
                var basename = ts.getBaseFileName(a.fileName);
                if (basename === "lib.d.ts" || basename === "lib.es6.d.ts")
                    return 0;
                var name = ts.removeSuffix(ts.removePrefix(basename, "lib."), ".d.ts");
                var index = ts.libs.indexOf(name);
                if (index !== -1)
                    return index + 1;
            }
            return ts.libs.length + 2;
        }
        function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName, containingFile) {
            return moduleResolutionCache && ts.resolveModuleNameFromCache(moduleName, containingFile, moduleResolutionCache);
        }
        function toPath(fileName) {
            return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
        }
        function getCommonSourceDirectory() {
            if (commonSourceDirectory === undefined) {
                var emittedFiles = ts.filter(files, function (file) { return ts.sourceFileMayBeEmitted(file, options, isSourceFileFromExternalLibrary, getResolvedProjectReferenceToRedirect); });
                if (options.rootDir && checkSourceFilesBelongToPath(emittedFiles, options.rootDir)) {
                    // If a rootDir is specified use it as the commonSourceDirectory
                    commonSourceDirectory = ts.getNormalizedAbsolutePath(options.rootDir, currentDirectory);
                }
                else if (options.composite && options.configFilePath) {
                    // Project compilations never infer their root from the input source paths
                    commonSourceDirectory = ts.getDirectoryPath(ts.normalizeSlashes(options.configFilePath));
                    checkSourceFilesBelongToPath(emittedFiles, commonSourceDirectory);
                }
                else {
                    commonSourceDirectory = computeCommonSourceDirectory(emittedFiles);
                }
                if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== ts.directorySeparator) {
                    // Make sure directory path ends with directory separator so this string can directly
                    // used to replace with "" to get the relative path of the source file and the relative path doesn't
                    // start with / making it rooted path
                    commonSourceDirectory += ts.directorySeparator;
                }
            }
            return commonSourceDirectory;
        }
        function getClassifiableNames() {
            if (!classifiableNames) {
                // Initialize a checker so that all our files are bound.
                getTypeChecker();
                classifiableNames = ts.createUnderscoreEscapedMap();
                for (var _i = 0, files_2 = files; _i < files_2.length; _i++) {
                    var sourceFile = files_2[_i];
                    ts.copyEntries(sourceFile.classifiableNames, classifiableNames);
                }
            }
            return classifiableNames;
        }
        function resolveModuleNamesReusingOldState(moduleNames, containingFile, file) {
            if (structuralIsReused === 0 /* Not */ && !file.ambientModuleNames.length) {
                // If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
                // the best we can do is fallback to the default logic.
                return resolveModuleNamesWorker(moduleNames, containingFile, /*reusedNames*/ undefined, getResolvedProjectReferenceToRedirect(file.originalFileName));
            }
            var oldSourceFile = oldProgram && oldProgram.getSourceFile(containingFile);
            if (oldSourceFile !== file && file.resolvedModules) {
                // `file` was created for the new program.
                //
                // We only set `file.resolvedModules` via work from the current function,
                // so it is defined iff we already called the current function on `file`.
                // That call happened no later than the creation of the `file` object,
                // which per above occurred during the current program creation.
                // Since we assume the filesystem does not change during program creation,
                // it is safe to reuse resolutions from the earlier call.
                var result_8 = [];
                for (var _i = 0, moduleNames_1 = moduleNames; _i < moduleNames_1.length; _i++) {
                    var moduleName = moduleNames_1[_i];
                    var resolvedModule = file.resolvedModules.get(moduleName);
                    result_8.push(resolvedModule);
                }
                return result_8;
            }
            // At this point, we know at least one of the following hold:
            // - file has local declarations for ambient modules
            // - old program state is available
            // With this information, we can infer some module resolutions without performing resolution.
            /** An ordered list of module names for which we cannot recover the resolution. */
            var unknownModuleNames;
            /**
             * The indexing of elements in this list matches that of `moduleNames`.
             *
             * Before combining results, result[i] is in one of the following states:
             * * undefined: needs to be recomputed,
             * * predictedToResolveToAmbientModuleMarker: known to be an ambient module.
             * Needs to be reset to undefined before returning,
             * * ResolvedModuleFull instance: can be reused.
             */
            var result;
            var reusedNames;
            /** A transient placeholder used to mark predicted resolution in the result list. */
            var predictedToResolveToAmbientModuleMarker = {};
            for (var i = 0; i < moduleNames.length; i++) {
                var moduleName = moduleNames[i];
                // If the source file is unchanged and doesnt have invalidated resolution, reuse the module resolutions
                if (file === oldSourceFile && !hasInvalidatedResolution(oldSourceFile.path)) {
                    var oldResolvedModule = oldSourceFile && oldSourceFile.resolvedModules.get(moduleName);
                    if (oldResolvedModule) {
                        if (ts.isTraceEnabled(options, host)) {
                            ts.trace(host, ts.Diagnostics.Reusing_resolution_of_module_0_to_file_1_from_old_program, moduleName, containingFile);
                        }
                        (result || (result = new Array(moduleNames.length)))[i] = oldResolvedModule;
                        (reusedNames || (reusedNames = [])).push(moduleName);
                        continue;
                    }
                }
                // We know moduleName resolves to an ambient module provided that moduleName:
                // - is in the list of ambient modules locally declared in the current source file.
                // - resolved to an ambient module in the old program whose declaration is in an unmodified file
                //   (so the same module declaration will land in the new program)
                var resolvesToAmbientModuleInNonModifiedFile = false;
                if (ts.contains(file.ambientModuleNames, moduleName)) {
                    resolvesToAmbientModuleInNonModifiedFile = true;
                    if (ts.isTraceEnabled(options, host)) {
                        ts.trace(host, ts.Diagnostics.Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1, moduleName, containingFile);
                    }
                }
                else {
                    resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName);
                }
                if (resolvesToAmbientModuleInNonModifiedFile) {
                    (result || (result = new Array(moduleNames.length)))[i] = predictedToResolveToAmbientModuleMarker;
                }
                else {
                    // Resolution failed in the old program, or resolved to an ambient module for which we can't reuse the result.
                    (unknownModuleNames || (unknownModuleNames = [])).push(moduleName);
                }
            }
            var resolutions = unknownModuleNames && unknownModuleNames.length
                ? resolveModuleNamesWorker(unknownModuleNames, containingFile, reusedNames, getResolvedProjectReferenceToRedirect(file.originalFileName))
                : ts.emptyArray;
            // Combine results of resolutions and predicted results
            if (!result) {
                // There were no unresolved/ambient resolutions.
                ts.Debug.assert(resolutions.length === moduleNames.length);
                return resolutions;
            }
            var j = 0;
            for (var i = 0; i < result.length; i++) {
                if (result[i]) {
                    // `result[i]` is either a `ResolvedModuleFull` or a marker.
                    // If it is the former, we can leave it as is.
                    if (result[i] === predictedToResolveToAmbientModuleMarker) {
                        result[i] = undefined; // TODO: GH#18217
                    }
                }
                else {
                    result[i] = resolutions[j];
                    j++;
                }
            }
            ts.Debug.assert(j === resolutions.length);
            return result;
            // If we change our policy of rechecking failed lookups on each program create,
            // we should adjust the value returned here.
            function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName) {
                var resolutionToFile = ts.getResolvedModule(oldSourceFile, moduleName);
                var resolvedFile = resolutionToFile && oldProgram.getSourceFile(resolutionToFile.resolvedFileName);
                if (resolutionToFile && resolvedFile) {
                    // In the old program, we resolved to an ambient module that was in the same
                    //   place as we expected to find an actual module file.
                    // We actually need to return 'false' here even though this seems like a 'true' case
                    //   because the normal module resolution algorithm will find this anyway.
                    return false;
                }
                // at least one of declarations should come from non-modified source file
                var unmodifiedFile = ambientModuleNameToUnmodifiedFileName.get(moduleName);
                if (!unmodifiedFile) {
                    return false;
                }
                if (ts.isTraceEnabled(options, host)) {
                    ts.trace(host, ts.Diagnostics.Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified, moduleName, unmodifiedFile);
                }
                return true;
            }
        }
        function canReuseProjectReferences() {
            return !forEachProjectReference(oldProgram.getProjectReferences(), oldProgram.getResolvedProjectReferences(), function (oldResolvedRef, index, parent) {
                var newRef = (parent ? parent.commandLine.projectReferences : projectReferences)[index];
                var newResolvedRef = parseProjectReferenceConfigFile(newRef);
                if (oldResolvedRef) {
                    // Resolved project reference has gone missing or changed
                    return !newResolvedRef || newResolvedRef.sourceFile !== oldResolvedRef.sourceFile;
                }
                else {
                    // A previously-unresolved reference may be resolved now
                    return newResolvedRef !== undefined;
                }
            }, function (oldProjectReferences, parent) {
                // If array of references is changed, we cant resue old program
                var newReferences = parent ? getResolvedProjectReferenceByPath(parent.sourceFile.path).commandLine.projectReferences : projectReferences;
                return !ts.arrayIsEqualTo(oldProjectReferences, newReferences, ts.projectReferenceIsEqualTo);
            });
        }
        function tryReuseStructureFromOldProgram() {
            if (!oldProgram) {
                return 0 /* Not */;
            }
            // check properties that can affect structure of the program or module resolution strategy
            // if any of these properties has changed - structure cannot be reused
            var oldOptions = oldProgram.getCompilerOptions();
            if (ts.changesAffectModuleResolution(oldOptions, options)) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            ts.Debug.assert(!(oldProgram.structureIsReused & (2 /* Completely */ | 1 /* SafeModules */)));
            // there is an old program, check if we can reuse its structure
            var oldRootNames = oldProgram.getRootFileNames();
            if (!ts.arrayIsEqualTo(oldRootNames, rootNames)) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            if (!ts.arrayIsEqualTo(options.types, oldOptions.types)) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            // Check if any referenced project tsconfig files are different
            if (!canReuseProjectReferences()) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            if (projectReferences) {
                resolvedProjectReferences = projectReferences.map(parseProjectReferenceConfigFile);
            }
            // check if program source files has changed in the way that can affect structure of the program
            var newSourceFiles = [];
            var modifiedSourceFiles = [];
            oldProgram.structureIsReused = 2 /* Completely */;
            // If the missing file paths are now present, it can change the progam structure,
            // and hence cant reuse the structure.
            // This is same as how we dont reuse the structure if one of the file from old program is now missing
            if (oldProgram.getMissingFilePaths().some(function (missingFilePath) { return host.fileExists(missingFilePath); })) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            var oldSourceFiles = oldProgram.getSourceFiles();
            var SeenPackageName;
            (function (SeenPackageName) {
                SeenPackageName[SeenPackageName["Exists"] = 0] = "Exists";
                SeenPackageName[SeenPackageName["Modified"] = 1] = "Modified";
            })(SeenPackageName || (SeenPackageName = {}));
            var seenPackageNames = ts.createMap();
            for (var _i = 0, oldSourceFiles_2 = oldSourceFiles; _i < oldSourceFiles_2.length; _i++) {
                var oldSourceFile = oldSourceFiles_2[_i];
                var newSourceFile = host.getSourceFileByPath
                    ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath, options.target, /*onError*/ undefined, shouldCreateNewSourceFile)
                    : host.getSourceFile(oldSourceFile.fileName, options.target, /*onError*/ undefined, shouldCreateNewSourceFile); // TODO: GH#18217
                if (!newSourceFile) {
                    return oldProgram.structureIsReused = 0 /* Not */;
                }
                ts.Debug.assert(!newSourceFile.redirectInfo, "Host should not return a redirect source file from `getSourceFile`");
                var fileChanged = void 0;
                if (oldSourceFile.redirectInfo) {
                    // We got `newSourceFile` by path, so it is actually for the unredirected file.
                    // This lets us know if the unredirected file has changed. If it has we should break the redirect.
                    if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {
                        // Underlying file has changed. Might not redirect anymore. Must rebuild program.
                        return oldProgram.structureIsReused = 0 /* Not */;
                    }
                    fileChanged = false;
                    newSourceFile = oldSourceFile; // Use the redirect.
                }
                else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {
                    // If a redirected-to source file changes, the redirect may be broken.
                    if (newSourceFile !== oldSourceFile) {
                        return oldProgram.structureIsReused = 0 /* Not */;
                    }
                    fileChanged = false;
                }
                else {
                    fileChanged = newSourceFile !== oldSourceFile;
                }
                // Since the project references havent changed, its right to set originalFileName and resolvedPath here
                newSourceFile.path = oldSourceFile.path;
                newSourceFile.originalFileName = oldSourceFile.originalFileName;
                newSourceFile.resolvedPath = oldSourceFile.resolvedPath;
                newSourceFile.fileName = oldSourceFile.fileName;
                var packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path);
                if (packageName !== undefined) {
                    // If there are 2 different source files for the same package name and at least one of them changes,
                    // they might become redirects. So we must rebuild the program.
                    var prevKind = seenPackageNames.get(packageName);
                    var newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */;
                    if ((prevKind !== undefined && newKind === 1 /* Modified */) || prevKind === 1 /* Modified */) {
                        return oldProgram.structureIsReused = 0 /* Not */;
                    }
                    seenPackageNames.set(packageName, newKind);
                }
                if (fileChanged) {
                    // The `newSourceFile` object was created for the new program.
                    if (!ts.arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {
                        // 'lib' references has changed. Matches behavior in changesAffectModuleResolution
                        return oldProgram.structureIsReused = 0 /* Not */;
                    }
                    if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {
                        // value of no-default-lib has changed
                        // this will affect if default library is injected into the list of files
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    // check tripleslash references
                    if (!ts.arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {
                        // tripleslash references has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    // check imports and module augmentations
                    collectExternalModuleReferences(newSourceFile);
                    if (!ts.arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {
                        // imports has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    if (!ts.arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {
                        // moduleAugmentations has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    if ((oldSourceFile.flags & 1572864 /* PermanentlySetIncrementalFlags */) !== (newSourceFile.flags & 1572864 /* PermanentlySetIncrementalFlags */)) {
                        // dynamicImport has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    if (!ts.arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {
                        // 'types' references has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    // tentatively approve the file
                    modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
                }
                else if (hasInvalidatedResolution(oldSourceFile.path)) {
                    // 'module/types' references could have changed
                    oldProgram.structureIsReused = 1 /* SafeModules */;
                    // add file to the modified list so that we will resolve it later
                    modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
                }
                // if file has passed all checks it should be safe to reuse it
                newSourceFiles.push(newSourceFile);
            }
            if (oldProgram.structureIsReused !== 2 /* Completely */) {
                return oldProgram.structureIsReused;
            }
            var modifiedFiles = modifiedSourceFiles.map(function (f) { return f.oldFile; });
            for (var _a = 0, oldSourceFiles_3 = oldSourceFiles; _a < oldSourceFiles_3.length; _a++) {
                var oldFile = oldSourceFiles_3[_a];
                if (!ts.contains(modifiedFiles, oldFile)) {
                    for (var _b = 0, _c = oldFile.ambientModuleNames; _b < _c.length; _b++) {
                        var moduleName = _c[_b];
                        ambientModuleNameToUnmodifiedFileName.set(moduleName, oldFile.fileName);
                    }
                }
            }
            // try to verify results of module resolution
            for (var _d = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _d < modifiedSourceFiles_1.length; _d++) {
                var _e = modifiedSourceFiles_1[_d], oldSourceFile = _e.oldFile, newSourceFile = _e.newFile;
                var newSourceFilePath = ts.getNormalizedAbsolutePath(newSourceFile.originalFileName, currentDirectory);
                if (resolveModuleNamesWorker) {
                    var moduleNames = getModuleNames(newSourceFile);
                    var resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFilePath, newSourceFile);
                    // ensure that module resolution results are still correct
                    var resolutionsChanged = ts.hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, ts.moduleResolutionIsEqualTo);
                    if (resolutionsChanged) {
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                        newSourceFile.resolvedModules = ts.zipToMap(moduleNames, resolutions);
                    }
                    else {
                        newSourceFile.resolvedModules = oldSourceFile.resolvedModules;
                    }
                }
                if (resolveTypeReferenceDirectiveNamesWorker) {
                    // We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
                    var typesReferenceDirectives = ts.map(newSourceFile.typeReferenceDirectives, function (ref) { return ref.fileName.toLocaleLowerCase(); });
                    var resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath, getResolvedProjectReferenceToRedirect(newSourceFile.originalFileName));
                    // ensure that types resolutions are still correct
                    var resolutionsChanged = ts.hasChangesInResolutions(typesReferenceDirectives, resolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, ts.typeDirectiveIsEqualTo);
                    if (resolutionsChanged) {
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                        newSourceFile.resolvedTypeReferenceDirectiveNames = ts.zipToMap(typesReferenceDirectives, resolutions);
                    }
                    else {
                        newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;
                    }
                }
            }
            if (oldProgram.structureIsReused !== 2 /* Completely */) {
                return oldProgram.structureIsReused;
            }
            if (host.hasChangedAutomaticTypeDirectiveNames) {
                return oldProgram.structureIsReused = 1 /* SafeModules */;
            }
            missingFilePaths = oldProgram.getMissingFilePaths();
            // update fileName -> file mapping
            for (var _f = 0, newSourceFiles_1 = newSourceFiles; _f < newSourceFiles_1.length; _f++) {
                var newSourceFile = newSourceFiles_1[_f];
                var filePath = newSourceFile.path;
                addFileToFilesByName(newSourceFile, filePath, newSourceFile.resolvedPath);
                // Set the file as found during node modules search if it was found that way in old progra,
                if (oldProgram.isSourceFileFromExternalLibrary(oldProgram.getSourceFileByPath(filePath))) {
                    sourceFilesFoundSearchingNodeModules.set(filePath, true);
                }
            }
            files = newSourceFiles;
            fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();
            for (var _g = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _g < modifiedSourceFiles_2.length; _g++) {
                var modifiedFile = modifiedSourceFiles_2[_g];
                fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile.newFile);
            }
            resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives();
            sourceFileToPackageName = oldProgram.sourceFileToPackageName;
            redirectTargetsMap = oldProgram.redirectTargetsMap;
            return oldProgram.structureIsReused = 2 /* Completely */;
        }
        function getEmitHost(writeFileCallback) {
            return __assign({ getPrependNodes: getPrependNodes,
                getCanonicalFileName: getCanonicalFileName, getCommonSourceDirectory: program.getCommonSourceDirectory, getCompilerOptions: program.getCompilerOptions, getCurrentDirectory: function () { return currentDirectory; }, getNewLine: function () { return host.getNewLine(); }, getSourceFile: program.getSourceFile, getSourceFileByPath: program.getSourceFileByPath, getSourceFiles: program.getSourceFiles, getLibFileFromReference: program.getLibFileFromReference, isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary,
                getResolvedProjectReferenceToRedirect: getResolvedProjectReferenceToRedirect, writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }), isEmitBlocked: isEmitBlocked, readFile: function (f) { return host.readFile(f); }, fileExists: function (f) {
                    // Use local caches
                    var path = toPath(f);
                    if (getSourceFileByPath(path))
                        return true;
                    if (ts.contains(missingFilePaths, path))
                        return false;
                    // Before falling back to the host
                    return host.fileExists(f);
                } }, (host.directoryExists ? { directoryExists: function (f) { return host.directoryExists(f); } } : {}), { useCaseSensitiveFileNames: function () { return host.useCaseSensitiveFileNames(); }, getProgramBuildInfo: function () { return program.getProgramBuildInfo && program.getProgramBuildInfo(); } });
        }
        function emitBuildInfo(writeFileCallback) {
            ts.Debug.assert(!options.out && !options.outFile);
            ts.performance.mark("beforeEmit");
            var emitResult = ts.emitFiles(ts.notImplementedResolver, getEmitHost(writeFileCallback), 
            /*targetSourceFile*/ undefined, 
            /*transformers*/ ts.noTransformers, 
            /*emitOnlyDtsFiles*/ false, 
            /*onlyBuildInfo*/ true);
            ts.performance.mark("afterEmit");
            ts.performance.measure("Emit", "beforeEmit", "afterEmit");
            return emitResult;
        }
        function getResolvedProjectReferences() {
            return resolvedProjectReferences;
        }
        function getProjectReferences() {
            return projectReferences;
        }
        function getPrependNodes() {
            return createPrependNodes(projectReferences, function (_ref, index) { return resolvedProjectReferences[index].commandLine; }, function (fileName) {
                var path = toPath(fileName);
                var sourceFile = getSourceFileByPath(path);
                return sourceFile ? sourceFile.text : filesByName.has(path) ? undefined : host.readFile(path);
            });
        }
        function isSourceFileFromExternalLibrary(file) {
            return !!sourceFilesFoundSearchingNodeModules.get(file.path);
        }
        function isSourceFileDefaultLibrary(file) {
            if (file.hasNoDefaultLib) {
                return true;
            }
            if (!options.noLib) {
                return false;
            }
            // If '--lib' is not specified, include default library file according to '--target'
            // otherwise, using options specified in '--lib' instead of '--target' default library file
            var equalityComparer = host.useCaseSensitiveFileNames() ? ts.equateStringsCaseSensitive : ts.equateStringsCaseInsensitive;
            if (!options.lib) {
                return equalityComparer(file.fileName, getDefaultLibraryFileName());
            }
            else {
                return ts.some(options.lib, function (libFileName) { return equalityComparer(file.fileName, ts.combinePaths(defaultLibraryPath, libFileName)); });
            }
        }
        function getDiagnosticsProducingTypeChecker() {
            return diagnosticsProducingTypeChecker || (diagnosticsProducingTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ true));
        }
        function dropDiagnosticsProducingTypeChecker() {
            diagnosticsProducingTypeChecker = undefined;
        }
        function getTypeChecker() {
            return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ false));
        }
        function emit(sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers) {
            return runWithCancellationToken(function () { return emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers); });
        }
        function isEmitBlocked(emitFileName) {
            return hasEmitBlockingDiagnostics.has(toPath(emitFileName));
        }
        function emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, customTransformers) {
            var declarationDiagnostics = [];
            if (!emitOnlyDtsFiles) {
                if (options.noEmit) {
                    return { diagnostics: declarationDiagnostics, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true };
                }
                // If the noEmitOnError flag is set, then check if we have any errors so far.  If so,
                // immediately bail out.  Note that we pass 'undefined' for 'sourceFile' so that we
                // get any preEmit diagnostics, not just the ones
                if (options.noEmitOnError) {
                    var diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(program.getSyntacticDiagnostics(sourceFile, cancellationToken), program.getGlobalDiagnostics(cancellationToken), program.getSemanticDiagnostics(sourceFile, cancellationToken));
                    if (diagnostics.length === 0 && ts.getEmitDeclarations(program.getCompilerOptions())) {
                        declarationDiagnostics = program.getDeclarationDiagnostics(/*sourceFile*/ undefined, cancellationToken);
                    }
                    if (diagnostics.length > 0 || declarationDiagnostics.length > 0) {
                        return {
                            diagnostics: ts.concatenate(diagnostics, declarationDiagnostics),
                            sourceMaps: undefined,
                            emittedFiles: undefined,
                            emitSkipped: true
                        };
                    }
                }
            }
            // Create the emit resolver outside of the "emitTime" tracking code below.  That way
            // any cost associated with it (like type checking) are appropriate associated with
            // the type-checking counter.
            //
            // If the -out option is specified, we should not pass the source file to getEmitResolver.
            // This is because in the -out scenario all files need to be emitted, and therefore all
            // files need to be type checked. And the way to specify that all files need to be type
            // checked is to not pass the file to getEmitResolver.
            var emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile, cancellationToken);
            ts.performance.mark("beforeEmit");
            var emitResult = ts.emitFiles(emitResolver, getEmitHost(writeFileCallback), sourceFile, ts.getTransformers(options, customTransformers, emitOnlyDtsFiles), emitOnlyDtsFiles);
            ts.performance.mark("afterEmit");
            ts.performance.measure("Emit", "beforeEmit", "afterEmit");
            return emitResult;
        }
        function getSourceFile(fileName) {
            return getSourceFileByPath(toPath(fileName));
        }
        function getSourceFileByPath(path) {
            return filesByName.get(path) || undefined;
        }
        function getDiagnosticsHelper(sourceFile, getDiagnostics, cancellationToken) {
            if (sourceFile) {
                return getDiagnostics(sourceFile, cancellationToken);
            }
            return ts.sortAndDeduplicateDiagnostics(ts.flatMap(program.getSourceFiles(), function (sourceFile) {
                if (cancellationToken) {
                    cancellationToken.throwIfCancellationRequested();
                }
                return getDiagnostics(sourceFile, cancellationToken);
            }));
        }
        function getSyntacticDiagnostics(sourceFile, cancellationToken) {
            return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile, cancellationToken);
        }
        function getSemanticDiagnostics(sourceFile, cancellationToken) {
            return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile, cancellationToken);
        }
        function getDeclarationDiagnostics(sourceFile, cancellationToken) {
            var options = program.getCompilerOptions();
            // collect diagnostics from the program only once if either no source file was specified or out/outFile is set (bundled emit)
            if (!sourceFile || options.out || options.outFile) {
                return getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
            }
            else {
                return getDiagnosticsHelper(sourceFile, getDeclarationDiagnosticsForFile, cancellationToken);
            }
        }
        function getSyntacticDiagnosticsForFile(sourceFile) {
            // For JavaScript files, we report semantic errors for using TypeScript-only
            // constructs from within a JavaScript file as syntactic errors.
            if (ts.isSourceFileJS(sourceFile)) {
                if (!sourceFile.additionalSyntacticDiagnostics) {
                    sourceFile.additionalSyntacticDiagnostics = getJSSyntacticDiagnosticsForFile(sourceFile);
                }
                return ts.concatenate(sourceFile.additionalSyntacticDiagnostics, sourceFile.parseDiagnostics);
            }
            return sourceFile.parseDiagnostics;
        }
        function runWithCancellationToken(func) {
            try {
                return func();
            }
            catch (e) {
                if (e instanceof ts.OperationCanceledException) {
                    // We were canceled while performing the operation.  Because our type checker
                    // might be a bad state, we need to throw it away.
                    //
                    // Note: we are overly aggressive here.  We do not actually *have* to throw away
                    // the "noDiagnosticsTypeChecker".  However, for simplicity, i'd like to keep
                    // the lifetimes of these two TypeCheckers the same.  Also, we generally only
                    // cancel when the user has made a change anyways.  And, in that case, we (the
                    // program instance) will get thrown away anyways.  So trying to keep one of
                    // these type checkers alive doesn't serve much purpose.
                    noDiagnosticsTypeChecker = undefined;
                    diagnosticsProducingTypeChecker = undefined;
                }
                throw e;
            }
        }
        function getSemanticDiagnosticsForFile(sourceFile, cancellationToken) {
            return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedSemanticDiagnosticsForFile, getSemanticDiagnosticsForFileNoCache);
        }
        function getSemanticDiagnosticsForFileNoCache(sourceFile, cancellationToken) {
            return runWithCancellationToken(function () {
                if (ts.skipTypeChecking(sourceFile, options)) {
                    return ts.emptyArray;
                }
                var typeChecker = getDiagnosticsProducingTypeChecker();
                ts.Debug.assert(!!sourceFile.bindDiagnostics);
                var isCheckJs = ts.isCheckJsEnabledForFile(sourceFile, options);
                // By default, only type-check .ts, .tsx, 'Deferred' and 'External' files (external files are added by plugins)
                var includeBindAndCheckDiagnostics = sourceFile.scriptKind === 3 /* TS */ || sourceFile.scriptKind === 4 /* TSX */ ||
                    sourceFile.scriptKind === 5 /* External */ || isCheckJs || sourceFile.scriptKind === 7 /* Deferred */;
                var bindDiagnostics = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : ts.emptyArray;
                var checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : ts.emptyArray;
                var fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
                var programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
                var diagnostics;
                for (var _i = 0, _a = [bindDiagnostics, checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile, isCheckJs ? sourceFile.jsDocDiagnostics : undefined]; _i < _a.length; _i++) {
                    var diags = _a[_i];
                    if (diags) {
                        for (var _b = 0, diags_1 = diags; _b < diags_1.length; _b++) {
                            var diag = diags_1[_b];
                            if (shouldReportDiagnostic(diag)) {
                                diagnostics = ts.append(diagnostics, diag);
                            }
                        }
                    }
                }
                return diagnostics;
            });
        }
        function getSuggestionDiagnostics(sourceFile, cancellationToken) {
            return runWithCancellationToken(function () {
                return getDiagnosticsProducingTypeChecker().getSuggestionDiagnostics(sourceFile, cancellationToken);
            });
        }
        /**
         * Skip errors if previous line start with '// @ts-ignore' comment, not counting non-empty non-comment lines
         */
        function shouldReportDiagnostic(diagnostic) {
            var file = diagnostic.file, start = diagnostic.start;
            if (file) {
                var lineStarts = ts.getLineStarts(file);
                var line = ts.computeLineAndCharacterOfPosition(lineStarts, start).line; // TODO: GH#18217
                while (line > 0) {
                    var previousLineText = file.text.slice(lineStarts[line - 1], lineStarts[line]);
                    var result = ignoreDiagnosticCommentRegEx.exec(previousLineText);
                    if (!result) {
                        // non-empty line
                        return true;
                    }
                    if (result[3]) {
                        // @ts-ignore
                        return false;
                    }
                    line--;
                }
            }
            return true;
        }
        function getJSSyntacticDiagnosticsForFile(sourceFile) {
            return runWithCancellationToken(function () {
                var diagnostics = [];
                var parent = sourceFile;
                walk(sourceFile);
                return diagnostics;
                function walk(node) {
                    // Return directly from the case if the given node doesnt want to visit each child
                    // Otherwise break to visit each child
                    switch (parent.kind) {
                        case 152 /* Parameter */:
                        case 155 /* PropertyDeclaration */:
                            if (parent.questionToken === node) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, "?"));
                                return;
                            }
                        // falls through
                        case 157 /* MethodDeclaration */:
                        case 156 /* MethodSignature */:
                        case 158 /* Constructor */:
                        case 159 /* GetAccessor */:
                        case 160 /* SetAccessor */:
                        case 197 /* FunctionExpression */:
                        case 240 /* FunctionDeclaration */:
                        case 198 /* ArrowFunction */:
                        case 238 /* VariableDeclaration */:
                            // type annotation
                            if (parent.type === node) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.types_can_only_be_used_in_a_ts_file));
                                return;
                            }
                    }
                    switch (node.kind) {
                        case 249 /* ImportEqualsDeclaration */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.import_can_only_be_used_in_a_ts_file));
                            return;
                        case 255 /* ExportAssignment */:
                            if (node.isExportEquals) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.export_can_only_be_used_in_a_ts_file));
                                return;
                            }
                            break;
                        case 274 /* HeritageClause */:
                            var heritageClause = node;
                            if (heritageClause.token === 110 /* ImplementsKeyword */) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.implements_clauses_can_only_be_used_in_a_ts_file));
                                return;
                            }
                            break;
                        case 242 /* InterfaceDeclaration */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.interface_declarations_can_only_be_used_in_a_ts_file));
                            return;
                        case 245 /* ModuleDeclaration */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.module_declarations_can_only_be_used_in_a_ts_file));
                            return;
                        case 243 /* TypeAliasDeclaration */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.type_aliases_can_only_be_used_in_a_ts_file));
                            return;
                        case 244 /* EnumDeclaration */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.enum_declarations_can_only_be_used_in_a_ts_file));
                            return;
                        case 214 /* NonNullExpression */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.non_null_assertions_can_only_be_used_in_a_ts_file));
                            return;
                        case 213 /* AsExpression */:
                            diagnostics.push(createDiagnosticForNode(node.type, ts.Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file));
                            return;
                        case 195 /* TypeAssertionExpression */:
                            ts.Debug.fail(); // Won't parse these in a JS file anyway, as they are interpreted as JSX.
                    }
                    var prevParent = parent;
                    parent = node;
                    ts.forEachChild(node, walk, walkArray);
                    parent = prevParent;
                }
                function walkArray(nodes) {
                    if (parent.decorators === nodes && !options.experimentalDecorators) {
                        diagnostics.push(createDiagnosticForNode(parent, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning));
                    }
                    switch (parent.kind) {
                        case 241 /* ClassDeclaration */:
                        case 157 /* MethodDeclaration */:
                        case 156 /* MethodSignature */:
                        case 158 /* Constructor */:
                        case 159 /* GetAccessor */:
                        case 160 /* SetAccessor */:
                        case 197 /* FunctionExpression */:
                        case 240 /* FunctionDeclaration */:
                        case 198 /* ArrowFunction */:
                            // Check type parameters
                            if (nodes === parent.typeParameters) {
                                diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.type_parameter_declarations_can_only_be_used_in_a_ts_file));
                                return;
                            }
                        // falls through
                        case 220 /* VariableStatement */:
                            // Check modifiers
                            if (nodes === parent.modifiers) {
                                return checkModifiers(nodes, parent.kind === 220 /* VariableStatement */);
                            }
                            break;
                        case 155 /* PropertyDeclaration */:
                            // Check modifiers of property declaration
                            if (nodes === parent.modifiers) {
                                for (var _i = 0, _a = nodes; _i < _a.length; _i++) {
                                    var modifier = _a[_i];
                                    if (modifier.kind !== 117 /* StaticKeyword */) {
                                        diagnostics.push(createDiagnosticForNode(modifier, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, ts.tokenToString(modifier.kind)));
                                    }
                                }
                                return;
                            }
                            break;
                        case 152 /* Parameter */:
                            // Check modifiers of parameter declaration
                            if (nodes === parent.modifiers) {
                                diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.parameter_modifiers_can_only_be_used_in_a_ts_file));
                                return;
                            }
                            break;
                        case 192 /* CallExpression */:
                        case 193 /* NewExpression */:
                        case 212 /* ExpressionWithTypeArguments */:
                        case 262 /* JsxSelfClosingElement */:
                        case 263 /* JsxOpeningElement */:
                            // Check type arguments
                            if (nodes === parent.typeArguments) {
                                diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.type_arguments_can_only_be_used_in_a_ts_file));
                                return;
                            }
                            break;
                    }
                    for (var _b = 0, nodes_6 = nodes; _b < nodes_6.length; _b++) {
                        var node = nodes_6[_b];
                        walk(node);
                    }
                }
                function checkModifiers(modifiers, isConstValid) {
                    for (var _i = 0, modifiers_1 = modifiers; _i < modifiers_1.length; _i++) {
                        var modifier = modifiers_1[_i];
                        switch (modifier.kind) {
                            case 78 /* ConstKeyword */:
                                if (isConstValid) {
                                    continue;
                                }
                            // to report error,
                            // falls through
                            case 116 /* PublicKeyword */:
                            case 114 /* PrivateKeyword */:
                            case 115 /* ProtectedKeyword */:
                            case 134 /* ReadonlyKeyword */:
                            case 126 /* DeclareKeyword */:
                            case 119 /* AbstractKeyword */:
                                diagnostics.push(createDiagnosticForNode(modifier, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, ts.tokenToString(modifier.kind)));
                                break;
                            // These are all legal modifiers.
                            case 117 /* StaticKeyword */:
                            case 86 /* ExportKeyword */:
                            case 81 /* DefaultKeyword */:
                        }
                    }
                }
                function createDiagnosticForNodeArray(nodes, message, arg0, arg1, arg2) {
                    var start = nodes.pos;
                    return ts.createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2);
                }
                // Since these are syntactic diagnostics, parent might not have been set
                // this means the sourceFile cannot be infered from the node
                function createDiagnosticForNode(node, message, arg0, arg1, arg2) {
                    return ts.createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2);
                }
            });
        }
        function getDeclarationDiagnosticsWorker(sourceFile, cancellationToken) {
            return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedDeclarationDiagnosticsForFile, getDeclarationDiagnosticsForFileNoCache);
        }
        function getDeclarationDiagnosticsForFileNoCache(sourceFile, cancellationToken) {
            return runWithCancellationToken(function () {
                var resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
                // Don't actually write any files since we're just getting diagnostics.
                return ts.getDeclarationDiagnostics(getEmitHost(ts.noop), resolver, sourceFile);
            });
        }
        function getAndCacheDiagnostics(sourceFile, cancellationToken, cache, getDiagnostics) {
            var cachedResult = sourceFile
                ? cache.perFile && cache.perFile.get(sourceFile.path)
                : cache.allDiagnostics;
            if (cachedResult) {
                return cachedResult;
            }
            var result = getDiagnostics(sourceFile, cancellationToken) || ts.emptyArray; // TODO: GH#18217
            if (sourceFile) {
                if (!cache.perFile) {
                    cache.perFile = ts.createMap();
                }
                cache.perFile.set(sourceFile.path, result);
            }
            else {
                cache.allDiagnostics = result;
            }
            return result;
        }
        function getDeclarationDiagnosticsForFile(sourceFile, cancellationToken) {
            return sourceFile.isDeclarationFile ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
        }
        function getOptionsDiagnostics() {
            return ts.sortAndDeduplicateDiagnostics(ts.concatenate(fileProcessingDiagnostics.getGlobalDiagnostics(), ts.concatenate(programDiagnostics.getGlobalDiagnostics(), getOptionsDiagnosticsOfConfigFile())));
        }
        function getOptionsDiagnosticsOfConfigFile() {
            if (!options.configFile) {
                return ts.emptyArray;
            }
            var diagnostics = programDiagnostics.getDiagnostics(options.configFile.fileName);
            forEachResolvedProjectReference(function (resolvedRef) {
                if (resolvedRef) {
                    diagnostics = ts.concatenate(diagnostics, programDiagnostics.getDiagnostics(resolvedRef.sourceFile.fileName));
                }
            });
            return diagnostics;
        }
        function getGlobalDiagnostics() {
            return rootNames.length ? ts.sortAndDeduplicateDiagnostics(getDiagnosticsProducingTypeChecker().getGlobalDiagnostics().slice()) : ts.emptyArray;
        }
        function getConfigFileParsingDiagnostics() {
            return configFileParsingDiagnostics || ts.emptyArray;
        }
        function processRootFile(fileName, isDefaultLib, ignoreNoDefaultLib) {
            processSourceFile(ts.normalizePath(fileName), isDefaultLib, ignoreNoDefaultLib, /*packageId*/ undefined);
        }
        function fileReferenceIsEqualTo(a, b) {
            return a.fileName === b.fileName;
        }
        function moduleNameIsEqualTo(a, b) {
            return a.kind === 73 /* Identifier */
                ? b.kind === 73 /* Identifier */ && a.escapedText === b.escapedText
                : b.kind === 10 /* StringLiteral */ && a.text === b.text;
        }
        function collectExternalModuleReferences(file) {
            if (file.imports) {
                return;
            }
            var isJavaScriptFile = ts.isSourceFileJS(file);
            var isExternalModuleFile = ts.isExternalModule(file);
            // file.imports may not be undefined if there exists dynamic import
            var imports;
            var moduleAugmentations;
            var ambientModules;
            // If we are importing helpers, we need to add a synthetic reference to resolve the
            // helpers library.
            if (options.importHelpers
                && (options.isolatedModules || isExternalModuleFile)
                && !file.isDeclarationFile) {
                // synthesize 'import "tslib"' declaration
                var externalHelpersModuleReference = ts.createLiteral(ts.externalHelpersModuleNameText);
                var importDecl = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference);
                ts.addEmitFlags(importDecl, 67108864 /* NeverApplyImportHelper */);
                externalHelpersModuleReference.parent = importDecl;
                importDecl.parent = file;
                imports = [externalHelpersModuleReference];
            }
            for (var _i = 0, _a = file.statements; _i < _a.length; _i++) {
                var node = _a[_i];
                collectModuleReferences(node, /*inAmbientModule*/ false);
            }
            if ((file.flags & 524288 /* PossiblyContainsDynamicImport */) || isJavaScriptFile) {
                collectDynamicImportOrRequireCalls(file);
            }
            file.imports = imports || ts.emptyArray;
            file.moduleAugmentations = moduleAugmentations || ts.emptyArray;
            file.ambientModuleNames = ambientModules || ts.emptyArray;
            return;
            function collectModuleReferences(node, inAmbientModule) {
                if (ts.isAnyImportOrReExport(node)) {
                    var moduleNameExpr = ts.getExternalModuleName(node);
                    // TypeScript 1.0 spec (April 2014): 12.1.6
                    // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference other external modules
                    // only through top - level external module names. Relative external module names are not permitted.
                    if (moduleNameExpr && ts.isStringLiteral(moduleNameExpr) && moduleNameExpr.text && (!inAmbientModule || !ts.isExternalModuleNameRelative(moduleNameExpr.text))) {
                        imports = ts.append(imports, moduleNameExpr);
                    }
                }
                else if (ts.isModuleDeclaration(node)) {
                    if (ts.isAmbientModule(node) && (inAmbientModule || ts.hasModifier(node, 2 /* Ambient */) || file.isDeclarationFile)) {
                        var nameText = ts.getTextOfIdentifierOrLiteral(node.name);
                        // Ambient module declarations can be interpreted as augmentations for some existing external modules.
                        // This will happen in two cases:
                        // - if current file is external module then module augmentation is a ambient module declaration defined in the top level scope
                        // - if current file is not external module then module augmentation is an ambient module declaration with non-relative module name
                        //   immediately nested in top level ambient module declaration .
                        if (isExternalModuleFile || (inAmbientModule && !ts.isExternalModuleNameRelative(nameText))) {
                            (moduleAugmentations || (moduleAugmentations = [])).push(node.name);
                        }
                        else if (!inAmbientModule) {
                            if (file.isDeclarationFile) {
                                // for global .d.ts files record name of ambient module
                                (ambientModules || (ambientModules = [])).push(nameText);
                            }
                            // An AmbientExternalModuleDeclaration declares an external module.
                            // This type of declaration is permitted only in the global module.
                            // The StringLiteral must specify a top - level external module name.
                            // Relative external module names are not permitted
                            // NOTE: body of ambient module is always a module block, if it exists
                            var body = node.body;
                            if (body) {
                                for (var _i = 0, _a = body.statements; _i < _a.length; _i++) {
                                    var statement = _a[_i];
                                    collectModuleReferences(statement, /*inAmbientModule*/ true);
                                }
                            }
                        }
                    }
                }
            }
            function collectDynamicImportOrRequireCalls(file) {
                var r = /import|require/g;
                while (r.exec(file.text) !== null) {
                    var node = getNodeAtPosition(file, r.lastIndex);
                    if (ts.isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) {
                        imports = ts.append(imports, node.arguments[0]);
                    }
                    // we have to check the argument list has length of 1. We will still have to process these even though we have parsing error.
                    else if (ts.isImportCall(node) && node.arguments.length === 1 && ts.isStringLiteralLike(node.arguments[0])) {
                        imports = ts.append(imports, node.arguments[0]);
                    }
                    else if (ts.isLiteralImportTypeNode(node)) {
                        imports = ts.append(imports, node.argument.literal);
                    }
                }
            }
            /** Returns a token if position is in [start-of-leading-trivia, end), includes JSDoc only in JS files */
            function getNodeAtPosition(sourceFile, position) {
                var current = sourceFile;
                var getContainingChild = function (child) {
                    if (child.pos <= position && (position < child.end || (position === child.end && (child.kind === 1 /* EndOfFileToken */)))) {
                        return child;
                    }
                };
                while (true) {
                    var child = isJavaScriptFile && ts.hasJSDocNodes(current) && ts.forEach(current.jsDoc, getContainingChild) || ts.forEachChild(current, getContainingChild);
                    if (!child) {
                        return current;
                    }
                    current = child;
                }
            }
        }
        function getLibFileFromReference(ref) {
            var libName = ref.fileName.toLocaleLowerCase();
            var libFileName = ts.libMap.get(libName);
            if (libFileName) {
                return getSourceFile(ts.combinePaths(defaultLibraryPath, libFileName));
            }
        }
        /** This should have similar behavior to 'processSourceFile' without diagnostics or mutation. */
        function getSourceFileFromReference(referencingFile, ref) {
            return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), function (fileName) { return filesByName.get(toPath(fileName)) || undefined; });
        }
        function getSourceFileFromReferenceWorker(fileName, getSourceFile, fail, refFile) {
            if (ts.hasExtension(fileName)) {
                if (!options.allowNonTsExtensions && !ts.forEach(supportedExtensionsWithJsonIfResolveJsonModule, function (extension) { return ts.fileExtensionIs(host.getCanonicalFileName(fileName), extension); })) {
                    if (fail)
                        fail(ts.Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + supportedExtensions.join("', '") + "'");
                    return undefined;
                }
                var sourceFile = getSourceFile(fileName);
                if (fail) {
                    if (!sourceFile) {
                        var redirect = getProjectReferenceRedirect(fileName);
                        if (redirect) {
                            fail(ts.Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, redirect, fileName);
                        }
                        else {
                            fail(ts.Diagnostics.File_0_not_found, fileName);
                        }
                    }
                    else if (refFile && host.getCanonicalFileName(fileName) === host.getCanonicalFileName(refFile.fileName)) {
                        fail(ts.Diagnostics.A_file_cannot_have_a_reference_to_itself);
                    }
                }
                return sourceFile;
            }
            else {
                var sourceFileNoExtension = options.allowNonTsExtensions && getSourceFile(fileName);
                if (sourceFileNoExtension)
                    return sourceFileNoExtension;
                if (fail && options.allowNonTsExtensions) {
                    fail(ts.Diagnostics.File_0_not_found, fileName);
                    return undefined;
                }
                var sourceFileWithAddedExtension = ts.forEach(supportedExtensions, function (extension) { return getSourceFile(fileName + extension); });
                if (fail && !sourceFileWithAddedExtension)
                    fail(ts.Diagnostics.File_0_not_found, fileName + ".ts" /* Ts */);
                return sourceFileWithAddedExtension;
            }
        }
        /** This has side effects through `findSourceFile`. */
        function processSourceFile(fileName, isDefaultLib, ignoreNoDefaultLib, packageId, refFile, refPos, refEnd) {
            getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, ignoreNoDefaultLib, refFile, refPos, refEnd, packageId); }, // TODO: GH#18217
            function (diagnostic) {
                var args = [];
                for (var _i = 1; _i < arguments.length; _i++) {
                    args[_i - 1] = arguments[_i];
                }
                fileProcessingDiagnostics.add(refFile !== undefined && refEnd !== undefined && refPos !== undefined
                    ? ts.createFileDiagnostic.apply(void 0, [refFile, refPos, refEnd - refPos, diagnostic].concat(args)) : ts.createCompilerDiagnostic.apply(void 0, [diagnostic].concat(args)));
            }, refFile);
        }
        function reportFileNamesDifferOnlyInCasingError(fileName, existingFileName, refFile, refPos, refEnd) {
            if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
                fileProcessingDiagnostics.add(ts.createFileDiagnostic(refFile, refPos, refEnd - refPos, ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, existingFileName));
            }
            else {
                fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, existingFileName));
            }
        }
        function createRedirectSourceFile(redirectTarget, unredirected, fileName, path, resolvedPath, originalFileName) {
            var redirect = Object.create(redirectTarget);
            redirect.fileName = fileName;
            redirect.path = path;
            redirect.resolvedPath = resolvedPath;
            redirect.originalFileName = originalFileName;
            redirect.redirectInfo = { redirectTarget: redirectTarget, unredirected: unredirected };
            sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
            Object.defineProperties(redirect, {
                id: {
                    get: function () { return this.redirectInfo.redirectTarget.id; },
                    set: function (value) { this.redirectInfo.redirectTarget.id = value; },
                },
                symbol: {
                    get: function () { return this.redirectInfo.redirectTarget.symbol; },
                    set: function (value) { this.redirectInfo.redirectTarget.symbol = value; },
                },
            });
            return redirect;
        }
        // Get source file from normalized fileName
        function findSourceFile(fileName, path, isDefaultLib, ignoreNoDefaultLib, refFile, refPos, refEnd, packageId) {
            var originalFileName = fileName;
            if (filesByName.has(path)) {
                var file_1 = filesByName.get(path);
                // try to check if we've already seen this file but with a different casing in path
                // NOTE: this only makes sense for case-insensitive file systems, and only on files which are not redirected
                if (file_1 && options.forceConsistentCasingInFileNames) {
                    var inputName = fileName;
                    var checkedName = file_1.fileName;
                    var isRedirect = toPath(checkedName) !== toPath(inputName);
                    if (isRedirect) {
                        inputName = getProjectReferenceRedirect(fileName) || fileName;
                    }
                    // Check if it differs only in drive letters its ok to ignore that error:
                    var checkedAbsolutePath = ts.getNormalizedAbsolutePathWithoutRoot(checkedName, currentDirectory);
                    var inputAbsolutePath = ts.getNormalizedAbsolutePathWithoutRoot(inputName, currentDirectory);
                    if (checkedAbsolutePath !== inputAbsolutePath) {
                        reportFileNamesDifferOnlyInCasingError(inputName, checkedName, refFile, refPos, refEnd);
                    }
                }
                // If the file was previously found via a node_modules search, but is now being processed as a root file,
                // then everything it sucks in may also be marked incorrectly, and needs to be checked again.
                if (file_1 && sourceFilesFoundSearchingNodeModules.get(file_1.path) && currentNodeModulesDepth === 0) {
                    sourceFilesFoundSearchingNodeModules.set(file_1.path, false);
                    if (!options.noResolve) {
                        processReferencedFiles(file_1, isDefaultLib);
                        processTypeReferenceDirectives(file_1);
                    }
                    if (!options.noLib) {
                        processLibReferenceDirectives(file_1);
                    }
                    modulesWithElidedImports.set(file_1.path, false);
                    processImportedModules(file_1);
                }
                // See if we need to reprocess the imports due to prior skipped imports
                else if (file_1 && modulesWithElidedImports.get(file_1.path)) {
                    if (currentNodeModulesDepth < maxNodeModuleJsDepth) {
                        modulesWithElidedImports.set(file_1.path, false);
                        processImportedModules(file_1);
                    }
                }
                return file_1 || undefined;
            }
            var redirectedPath;
            if (refFile) {
                var redirectProject = getProjectReferenceRedirectProject(fileName);
                if (redirectProject) {
                    if (redirectProject.commandLine.options.outFile || redirectProject.commandLine.options.out) {
                        // Shouldnt create many to 1 mapping file in --out scenario
                        return undefined;
                    }
                    var redirect = getProjectReferenceOutputName(redirectProject, fileName);
                    fileName = redirect;
                    // Once we start redirecting to a file, we can potentially come back to it
                    // via a back-reference from another file in the .d.ts folder. If that happens we'll
                    // end up trying to add it to the program *again* because we were tracking it via its
                    // original (un-redirected) name. So we have to map both the original path and the redirected path
                    // to the source file we're about to find/create
                    redirectedPath = toPath(redirect);
                }
            }
            // We haven't looked for this file, do so now and cache result
            var file = host.getSourceFile(fileName, options.target, function (hostErrorMessage) {
                if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
                    fileProcessingDiagnostics.add(ts.createFileDiagnostic(refFile, refPos, refEnd - refPos, ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
                }
                else {
                    fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
                }
            }, shouldCreateNewSourceFile);
            if (packageId) {
                var packageIdKey = ts.packageIdToString(packageId);
                var fileFromPackageId = packageIdToSourceFile.get(packageIdKey);
                if (fileFromPackageId) {
                    // Some other SourceFile already exists with this package name and version.
                    // Instead of creating a duplicate, just redirect to the existing one.
                    var dupFile = createRedirectSourceFile(fileFromPackageId, file, fileName, path, toPath(fileName), originalFileName); // TODO: GH#18217
                    redirectTargetsMap.add(fileFromPackageId.path, fileName);
                    addFileToFilesByName(dupFile, path, redirectedPath);
                    sourceFileToPackageName.set(path, packageId.name);
                    processingOtherFiles.push(dupFile);
                    return dupFile;
                }
                else if (file) {
                    // This is the first source file to have this packageId.
                    packageIdToSourceFile.set(packageIdKey, file);
                    sourceFileToPackageName.set(path, packageId.name);
                }
            }
            addFileToFilesByName(file, path, redirectedPath);
            if (file) {
                sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
                file.path = path;
                file.resolvedPath = toPath(fileName);
                file.originalFileName = originalFileName;
                if (host.useCaseSensitiveFileNames()) {
                    var pathLowerCase = path.toLowerCase();
                    // for case-sensitive file systems check if we've already seen some file with similar filename ignoring case
                    var existingFile = filesByNameIgnoreCase.get(pathLowerCase);
                    if (existingFile) {
                        reportFileNamesDifferOnlyInCasingError(fileName, existingFile.fileName, refFile, refPos, refEnd);
                    }
                    else {
                        filesByNameIgnoreCase.set(pathLowerCase, file);
                    }
                }
                skipDefaultLib = skipDefaultLib || (file.hasNoDefaultLib && !ignoreNoDefaultLib);
                if (!options.noResolve) {
                    processReferencedFiles(file, isDefaultLib);
                    processTypeReferenceDirectives(file);
                }
                if (!options.noLib) {
                    processLibReferenceDirectives(file);
                }
                // always process imported modules to record module name resolutions
                processImportedModules(file);
                if (isDefaultLib) {
                    processingDefaultLibFiles.push(file);
                }
                else {
                    processingOtherFiles.push(file);
                }
            }
            return file;
        }
        function addFileToFilesByName(file, path, redirectedPath) {
            if (redirectedPath) {
                filesByName.set(redirectedPath, file);
                filesByName.set(path, file || false);
            }
            else {
                filesByName.set(path, file);
            }
        }
        function getProjectReferenceRedirect(fileName) {
            var referencedProject = getProjectReferenceRedirectProject(fileName);
            return referencedProject && getProjectReferenceOutputName(referencedProject, fileName);
        }
        function getProjectReferenceRedirectProject(fileName) {
            // Ignore dts or any of the non ts files
            if (!resolvedProjectReferences || !resolvedProjectReferences.length || ts.fileExtensionIs(fileName, ".d.ts" /* Dts */) || !ts.fileExtensionIsOneOf(fileName, ts.supportedTSExtensions)) {
                return undefined;
            }
            // If this file is produced by a referenced project, we need to rewrite it to
            // look in the output folder of the referenced project rather than the input
            return getResolvedProjectReferenceToRedirect(fileName);
        }
        function getProjectReferenceOutputName(referencedProject, fileName) {
            var out = referencedProject.commandLine.options.outFile || referencedProject.commandLine.options.out;
            return out ?
                ts.changeExtension(out, ".d.ts" /* Dts */) :
                ts.getOutputDeclarationFileName(fileName, referencedProject.commandLine, !host.useCaseSensitiveFileNames());
        }
        /**
         * Get the referenced project if the file is input file from that reference project
         */
        function getResolvedProjectReferenceToRedirect(fileName) {
            if (mapFromFileToProjectReferenceRedirects === undefined) {
                mapFromFileToProjectReferenceRedirects = ts.createMap();
                forEachResolvedProjectReference(function (referencedProject, referenceProjectPath) {
                    // not input file from the referenced project, ignore
                    if (referencedProject &&
                        toPath(options.configFilePath) !== referenceProjectPath) {
                        referencedProject.commandLine.fileNames.forEach(function (f) {
                            return mapFromFileToProjectReferenceRedirects.set(toPath(f), referenceProjectPath);
                        });
                    }
                });
            }
            var referencedProjectPath = mapFromFileToProjectReferenceRedirects.get(toPath(fileName));
            return referencedProjectPath && getResolvedProjectReferenceByPath(referencedProjectPath);
        }
        function forEachResolvedProjectReference(cb) {
            return forEachProjectReference(projectReferences, resolvedProjectReferences, function (resolvedRef, index, parent) {
                var ref = (parent ? parent.commandLine.projectReferences : projectReferences)[index];
                var resolvedRefPath = toPath(resolveProjectReferencePath(ref));
                return cb(resolvedRef, resolvedRefPath);
            });
        }
        function forEachProjectReference(projectReferences, resolvedProjectReferences, cbResolvedRef, cbRef) {
            var seenResolvedRefs;
            return worker(projectReferences, resolvedProjectReferences, /*parent*/ undefined, cbResolvedRef, cbRef);
            function worker(projectReferences, resolvedProjectReferences, parent, cbResolvedRef, cbRef) {
                // Visit project references first
                if (cbRef) {
                    var result = cbRef(projectReferences, parent);
                    if (result) {
                        return result;
                    }
                }
                return ts.forEach(resolvedProjectReferences, function (resolvedRef, index) {
                    if (ts.contains(seenResolvedRefs, resolvedRef)) {
                        // ignore recursives
                        return undefined;
                    }
                    var result = cbResolvedRef(resolvedRef, index, parent);
                    if (result) {
                        return result;
                    }
                    if (!resolvedRef)
                        return undefined;
                    (seenResolvedRefs || (seenResolvedRefs = [])).push(resolvedRef);
                    return worker(resolvedRef.commandLine.projectReferences, resolvedRef.references, resolvedRef, cbResolvedRef, cbRef);
                });
            }
        }
        function getResolvedProjectReferenceByPath(projectReferencePath) {
            if (!projectReferenceRedirects) {
                return undefined;
            }
            return projectReferenceRedirects.get(projectReferencePath) || undefined;
        }
        function processReferencedFiles(file, isDefaultLib) {
            ts.forEach(file.referencedFiles, function (ref) {
                var referencedFileName = resolveTripleslashReference(ref.fileName, file.originalFileName);
                processSourceFile(referencedFileName, isDefaultLib, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined, file, ref.pos, ref.end);
            });
        }
        function processTypeReferenceDirectives(file) {
            // We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
            var typeDirectives = ts.map(file.typeReferenceDirectives, function (ref) { return ref.fileName.toLocaleLowerCase(); });
            if (!typeDirectives) {
                return;
            }
            var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.originalFileName, getResolvedProjectReferenceToRedirect(file.originalFileName));
            for (var i = 0; i < typeDirectives.length; i++) {
                var ref = file.typeReferenceDirectives[i];
                var resolvedTypeReferenceDirective = resolutions[i];
                // store resolved type directive on the file
                var fileName = ref.fileName.toLocaleLowerCase();
                ts.setResolvedTypeReferenceDirective(file, fileName, resolvedTypeReferenceDirective);
                processTypeReferenceDirective(fileName, resolvedTypeReferenceDirective, file, ref.pos, ref.end);
            }
        }
        function processTypeReferenceDirective(typeReferenceDirective, resolvedTypeReferenceDirective, refFile, refPos, refEnd) {
            // If we already found this library as a primary reference - nothing to do
            var previousResolution = resolvedTypeReferenceDirectives.get(typeReferenceDirective);
            if (previousResolution && previousResolution.primary) {
                return;
            }
            var saveResolution = true;
            if (resolvedTypeReferenceDirective) {
                if (resolvedTypeReferenceDirective.isExternalLibraryImport)
                    currentNodeModulesDepth++;
                if (resolvedTypeReferenceDirective.primary) {
                    // resolved from the primary path
                    processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd); // TODO: GH#18217
                }
                else {
                    // If we already resolved to this file, it must have been a secondary reference. Check file contents
                    // for sameness and possibly issue an error
                    if (previousResolution) {
                        // Don't bother reading the file again if it's the same file.
                        if (resolvedTypeReferenceDirective.resolvedFileName !== previousResolution.resolvedFileName) {
                            var otherFileText = host.readFile(resolvedTypeReferenceDirective.resolvedFileName);
                            if (otherFileText !== getSourceFile(previousResolution.resolvedFileName).text) {
                                fileProcessingDiagnostics.add(createDiagnostic(refFile, refPos, refEnd, // TODO: GH#18217
                                ts.Diagnostics.Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict, typeReferenceDirective, resolvedTypeReferenceDirective.resolvedFileName, previousResolution.resolvedFileName));
                            }
                        }
                        // don't overwrite previous resolution result
                        saveResolution = false;
                    }
                    else {
                        // First resolution of this library
                        processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd);
                    }
                }
                if (resolvedTypeReferenceDirective.isExternalLibraryImport)
                    currentNodeModulesDepth--;
            }
            else {
                fileProcessingDiagnostics.add(createDiagnostic(refFile, refPos, refEnd, ts.Diagnostics.Cannot_find_type_definition_file_for_0, typeReferenceDirective)); // TODO: GH#18217
            }
            if (saveResolution) {
                resolvedTypeReferenceDirectives.set(typeReferenceDirective, resolvedTypeReferenceDirective);
            }
        }
        function processLibReferenceDirectives(file) {
            ts.forEach(file.libReferenceDirectives, function (libReference) {
                var libName = libReference.fileName.toLocaleLowerCase();
                var libFileName = ts.libMap.get(libName);
                if (libFileName) {
                    // we ignore any 'no-default-lib' reference set on this file.
                    processRootFile(ts.combinePaths(defaultLibraryPath, libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ true);
                }
                else {
                    var unqualifiedLibName = ts.removeSuffix(ts.removePrefix(libName, "lib."), ".d.ts");
                    var suggestion = ts.getSpellingSuggestion(unqualifiedLibName, ts.libs, ts.identity);
                    var message = suggestion ? ts.Diagnostics.Cannot_find_lib_definition_for_0_Did_you_mean_1 : ts.Diagnostics.Cannot_find_lib_definition_for_0;
                    fileProcessingDiagnostics.add(createDiagnostic(file, libReference.pos, libReference.end, message, libName, suggestion));
                }
            });
        }
        function createDiagnostic(refFile, refPos, refEnd, message) {
            var args = [];
            for (var _i = 4; _i < arguments.length; _i++) {
                args[_i - 4] = arguments[_i];
            }
            if (refFile === undefined || refPos === undefined || refEnd === undefined) {
                return ts.createCompilerDiagnostic.apply(void 0, [message].concat(args));
            }
            else {
                return ts.createFileDiagnostic.apply(void 0, [refFile, refPos, refEnd - refPos, message].concat(args));
            }
        }
        function getCanonicalFileName(fileName) {
            return host.getCanonicalFileName(fileName);
        }
        function processImportedModules(file) {
            collectExternalModuleReferences(file);
            if (file.imports.length || file.moduleAugmentations.length) {
                // Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
                var moduleNames = getModuleNames(file);
                var resolutions = resolveModuleNamesReusingOldState(moduleNames, ts.getNormalizedAbsolutePath(file.originalFileName, currentDirectory), file);
                ts.Debug.assert(resolutions.length === moduleNames.length);
                for (var i = 0; i < moduleNames.length; i++) {
                    var resolution = resolutions[i];
                    ts.setResolvedModule(file, moduleNames[i], resolution);
                    if (!resolution) {
                        continue;
                    }
                    var isFromNodeModulesSearch = resolution.isExternalLibraryImport;
                    var isJsFile = !ts.resolutionExtensionIsTSOrJson(resolution.extension);
                    var isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile;
                    var resolvedFileName = resolution.resolvedFileName;
                    if (isFromNodeModulesSearch) {
                        currentNodeModulesDepth++;
                    }
                    // add file to program only if:
                    // - resolution was successful
                    // - noResolve is falsy
                    // - module name comes from the list of imports
                    // - it's not a top level JavaScript module that exceeded the search max
                    var elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModuleJsDepth;
                    // Don't add the file if it has a bad extension (e.g. 'tsx' if we don't have '--allowJs')
                    // This may still end up being an untyped module -- the file won't be included but imports will be allowed.
                    var shouldAddFile = resolvedFileName
                        && !getResolutionDiagnostic(options, resolution)
                        && !options.noResolve
                        && i < file.imports.length
                        && !elideImport
                        && !(isJsFile && !options.allowJs)
                        && (ts.isInJSFile(file.imports[i]) || !(file.imports[i].flags & 2097152 /* JSDoc */));
                    if (elideImport) {
                        modulesWithElidedImports.set(file.path, true);
                    }
                    else if (shouldAddFile) {
                        var path = toPath(resolvedFileName);
                        var pos = ts.skipTrivia(file.text, file.imports[i].pos);
                        findSourceFile(resolvedFileName, path, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, file, pos, file.imports[i].end, resolution.packageId);
                    }
                    if (isFromNodeModulesSearch) {
                        currentNodeModulesDepth--;
                    }
                }
            }
            else {
                // no imports - drop cached module resolutions
                file.resolvedModules = undefined;
            }
        }
        function computeCommonSourceDirectory(sourceFiles) {
            var fileNames = ts.mapDefined(sourceFiles, function (file) { return file.isDeclarationFile ? undefined : file.fileName; });
            return computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName);
        }
        function checkSourceFilesBelongToPath(sourceFiles, rootDirectory) {
            var allFilesBelongToPath = true;
            var absoluteRootDirectoryPath = host.getCanonicalFileName(ts.getNormalizedAbsolutePath(rootDirectory, currentDirectory));
            for (var _i = 0, sourceFiles_2 = sourceFiles; _i < sourceFiles_2.length; _i++) {
                var sourceFile = sourceFiles_2[_i];
                if (!sourceFile.isDeclarationFile) {
                    var absoluteSourceFilePath = host.getCanonicalFileName(ts.getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory));
                    if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) {
                        programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, rootDirectory));
                        allFilesBelongToPath = false;
                    }
                }
            }
            return allFilesBelongToPath;
        }
        function parseProjectReferenceConfigFile(ref) {
            if (!projectReferenceRedirects) {
                projectReferenceRedirects = ts.createMap();
            }
            // The actual filename (i.e. add "/tsconfig.json" if necessary)
            var refPath = resolveProjectReferencePath(ref);
            var sourceFilePath = toPath(refPath);
            var fromCache = projectReferenceRedirects.get(sourceFilePath);
            if (fromCache !== undefined) {
                return fromCache || undefined;
            }
            var commandLine;
            var sourceFile;
            if (host.getParsedCommandLine) {
                commandLine = host.getParsedCommandLine(refPath);
                if (!commandLine) {
                    addFileToFilesByName(/*sourceFile*/ undefined, sourceFilePath, /*redirectedPath*/ undefined);
                    projectReferenceRedirects.set(sourceFilePath, false);
                    return undefined;
                }
                sourceFile = ts.Debug.assertDefined(commandLine.options.configFile);
                ts.Debug.assert(!sourceFile.path || sourceFile.path === sourceFilePath);
                addFileToFilesByName(sourceFile, sourceFilePath, /*redirectedPath*/ undefined);
            }
            else {
                // An absolute path pointing to the containing directory of the config file
                var basePath = ts.getNormalizedAbsolutePath(ts.getDirectoryPath(refPath), host.getCurrentDirectory());
                sourceFile = host.getSourceFile(refPath, 100 /* JSON */);
                addFileToFilesByName(sourceFile, sourceFilePath, /*redirectedPath*/ undefined);
                if (sourceFile === undefined) {
                    projectReferenceRedirects.set(sourceFilePath, false);
                    return undefined;
                }
                commandLine = ts.parseJsonSourceFileConfigFileContent(sourceFile, configParsingHost, basePath, /*existingOptions*/ undefined, refPath);
            }
            sourceFile.path = sourceFilePath;
            sourceFile.resolvedPath = sourceFilePath;
            sourceFile.originalFileName = refPath;
            var resolvedRef = { commandLine: commandLine, sourceFile: sourceFile };
            projectReferenceRedirects.set(sourceFilePath, resolvedRef);
            if (commandLine.projectReferences) {
                resolvedRef.references = commandLine.projectReferences.map(parseProjectReferenceConfigFile);
            }
            return resolvedRef;
        }
        function verifyCompilerOptions() {
            if (options.strictPropertyInitialization && !ts.getStrictOptionValue(options, "strictNullChecks")) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictPropertyInitialization", "strictNullChecks");
            }
            if (options.isolatedModules) {
                if (ts.getEmitDeclarations(options)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, getEmitDeclarationOptionName(options), "isolatedModules");
                }
                if (options.out) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules");
                }
                if (options.outFile) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", "isolatedModules");
                }
            }
            if (options.inlineSourceMap) {
                if (options.sourceMap) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap");
                }
                if (options.mapRoot) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap");
                }
            }
            if (options.paths && options.baseUrl === undefined) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_paths_cannot_be_used_without_specifying_baseUrl_option, "paths");
            }
            if (options.composite) {
                if (options.declaration === false) {
                    createDiagnosticForOptionName(ts.Diagnostics.Composite_projects_may_not_disable_declaration_emit, "declaration");
                }
                if (options.incremental === false) {
                    createDiagnosticForOptionName(ts.Diagnostics.Composite_projects_may_not_disable_incremental_compilation, "declaration");
                }
            }
            if (options.tsBuildInfoFile) {
                if (!ts.isIncrementalCompilation(options)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "tsBuildInfoFile", "incremental", "composite");
                }
            }
            else if (options.incremental && !options.outFile && !options.out && !options.configFilePath) {
                programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBuildInfoFile_is_specified));
            }
            verifyProjectReferences();
            // List of collected files is complete; validate exhautiveness if this is a project with a file list
            if (options.composite) {
                var rootPaths = rootNames.map(toPath);
                for (var _i = 0, files_3 = files; _i < files_3.length; _i++) {
                    var file = files_3[_i];
                    // Ignore file that is not emitted
                    if (!ts.sourceFileMayBeEmitted(file, options, isSourceFileFromExternalLibrary, getResolvedProjectReferenceToRedirect))
                        continue;
                    if (rootPaths.indexOf(file.path) === -1) {
                        programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, file.fileName));
                    }
                }
            }
            if (options.paths) {
                for (var key in options.paths) {
                    if (!ts.hasProperty(options.paths, key)) {
                        continue;
                    }
                    if (!ts.hasZeroOrOneAsteriskCharacter(key)) {
                        createDiagnosticForOptionPaths(/*onKey*/ true, key, ts.Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, key);
                    }
                    if (ts.isArray(options.paths[key])) {
                        var len = options.paths[key].length;
                        if (len === 0) {
                            createDiagnosticForOptionPaths(/*onKey*/ false, key, ts.Diagnostics.Substitutions_for_pattern_0_shouldn_t_be_an_empty_array, key);
                        }
                        for (var i = 0; i < len; i++) {
                            var subst = options.paths[key][i];
                            var typeOfSubst = typeof subst;
                            if (typeOfSubst === "string") {
                                if (!ts.hasZeroOrOneAsteriskCharacter(subst)) {
                                    createDiagnosticForOptionPathKeyValue(key, i, ts.Diagnostics.Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character, subst, key);
                                }
                            }
                            else {
                                createDiagnosticForOptionPathKeyValue(key, i, ts.Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst);
                            }
                        }
                    }
                    else {
                        createDiagnosticForOptionPaths(/*onKey*/ false, key, ts.Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key);
                    }
                }
            }
            if (!options.sourceMap && !options.inlineSourceMap) {
                if (options.inlineSources) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "inlineSources");
                }
                if (options.sourceRoot) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "sourceRoot");
                }
            }
            if (options.out && options.outFile) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "outFile");
            }
            if (options.mapRoot && !(options.sourceMap || options.declarationMap)) {
                // Error to specify --mapRoot without --sourcemap
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "mapRoot", "sourceMap", "declarationMap");
            }
            if (options.declarationDir) {
                if (!ts.getEmitDeclarations(options)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationDir", "declaration", "composite");
                }
                if (options.out || options.outFile) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", options.out ? "out" : "outFile");
                }
            }
            if (options.declarationMap && !ts.getEmitDeclarations(options)) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationMap", "declaration", "composite");
            }
            if (options.lib && options.noLib) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib");
            }
            if (options.noImplicitUseStrict && ts.getStrictOptionValue(options, "alwaysStrict")) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict");
            }
            var languageVersion = options.target || 0 /* ES3 */;
            var outFile = options.outFile || options.out;
            var firstNonAmbientExternalModuleSourceFile = ts.find(files, function (f) { return ts.isExternalModule(f) && !f.isDeclarationFile; });
            if (options.isolatedModules) {
                if (options.module === ts.ModuleKind.None && languageVersion < 2 /* ES2015 */) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher, "isolatedModules", "target");
                }
                var firstNonExternalModuleSourceFile = ts.find(files, function (f) { return !ts.isExternalModule(f) && !ts.isSourceFileJS(f) && !f.isDeclarationFile && f.scriptKind !== 6 /* JSON */; });
                if (firstNonExternalModuleSourceFile) {
                    var span = ts.getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile);
                    programDiagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.All_files_must_be_modules_when_the_isolatedModules_flag_is_provided));
                }
            }
            else if (firstNonAmbientExternalModuleSourceFile && languageVersion < 2 /* ES2015 */ && options.module === ts.ModuleKind.None) {
                // We cannot use createDiagnosticFromNode because nodes do not have parents yet
                var span = ts.getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
                programDiagnostics.add(ts.createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none));
            }
            // Cannot specify module gen that isn't amd or system with --out
            if (outFile && !options.emitDeclarationOnly) {
                if (options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile", "module");
                }
                else if (options.module === undefined && firstNonAmbientExternalModuleSourceFile) {
                    var span = ts.getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
                    programDiagnostics.add(ts.createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system, options.out ? "out" : "outFile"));
                }
            }
            if (options.resolveJsonModule) {
                if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule");
                }
                // Any emit other than common js, amd, es2015 or esnext is error
                else if (!ts.hasJsonModuleEmitEnabled(options)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_esNext, "resolveJsonModule", "module");
                }
            }
            // there has to be common source directory if user specified --outdir || --sourceRoot
            // if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted
            if (options.outDir || // there is --outDir specified
                options.sourceRoot || // there is --sourceRoot specified
                options.mapRoot) { // there is --mapRoot specified
                // Precalculate and cache the common source directory
                var dir = getCommonSourceDirectory();
                // If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure
                if (options.outDir && dir === "" && files.some(function (file) { return ts.getRootLength(file.fileName) > 1; })) {
                    createDiagnosticForOptionName(ts.Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files, "outDir");
                }
            }
            if (!options.noEmit && options.allowJs && ts.getEmitDeclarations(options)) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", getEmitDeclarationOptionName(options));
            }
            if (options.checkJs && !options.allowJs) {
                programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs"));
            }
            if (options.emitDeclarationOnly) {
                if (!ts.getEmitDeclarations(options)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "emitDeclarationOnly", "declaration", "composite");
                }
                if (options.noEmit) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "emitDeclarationOnly", "noEmit");
                }
            }
            if (options.emitDecoratorMetadata &&
                !options.experimentalDecorators) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators");
            }
            if (options.jsxFactory) {
                if (options.reactNamespace) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "reactNamespace", "jsxFactory");
                }
                if (!ts.parseIsolatedEntityName(options.jsxFactory, languageVersion)) {
                    createOptionValueDiagnostic("jsxFactory", ts.Diagnostics.Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFactory);
                }
            }
            else if (options.reactNamespace && !ts.isIdentifierText(options.reactNamespace, languageVersion)) {
                createOptionValueDiagnostic("reactNamespace", ts.Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace);
            }
            // If the emit is enabled make sure that every output file is unique and not overwriting any of the input files
            if (!options.noEmit && !options.suppressOutputPathCheck) {
                var emitHost = getEmitHost();
                var emitFilesSeen_1 = ts.createMap();
                ts.forEachEmittedFile(emitHost, function (emitFileNames) {
                    if (!options.emitDeclarationOnly) {
                        verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen_1);
                    }
                    verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen_1);
                });
            }
            // Verify that all the emit files are unique and don't overwrite input files
            function verifyEmitFilePath(emitFileName, emitFilesSeen) {
                if (emitFileName) {
                    var emitFilePath = toPath(emitFileName);
                    // Report error if the output overwrites input file
                    if (filesByName.has(emitFilePath)) {
                        var chain = void 0;
                        if (!options.configFilePath) {
                            // The program is from either an inferred project or an external project
                            chain = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig);
                        }
                        chain = ts.chainDiagnosticMessages(chain, ts.Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file, emitFileName);
                        blockEmittingOfFile(emitFileName, ts.createCompilerDiagnosticFromMessageChain(chain));
                    }
                    var emitFileKey = !host.useCaseSensitiveFileNames() ? emitFilePath.toLocaleLowerCase() : emitFilePath;
                    // Report error if multiple files write into same file
                    if (emitFilesSeen.has(emitFileKey)) {
                        // Already seen the same emit file - report error
                        blockEmittingOfFile(emitFileName, ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, emitFileName));
                    }
                    else {
                        emitFilesSeen.set(emitFileKey, true);
                    }
                }
            }
        }
        function verifyProjectReferences() {
            var buildInfoPath = !options.noEmit && !options.suppressOutputPathCheck ? ts.getOutputPathForBuildInfo(options) : undefined;
            forEachProjectReference(projectReferences, resolvedProjectReferences, function (resolvedRef, index, parent) {
                var ref = (parent ? parent.commandLine.projectReferences : projectReferences)[index];
                var parentFile = parent && parent.sourceFile;
                if (!resolvedRef) {
                    createDiagnosticForReference(parentFile, index, ts.Diagnostics.File_0_not_found, ref.path);
                    return;
                }
                var options = resolvedRef.commandLine.options;
                if (!options.composite) {
                    // ok to not have composite if the current program is container only
                    var inputs = parent ? parent.commandLine.fileNames : rootNames;
                    if (inputs.length) {
                        createDiagnosticForReference(parentFile, index, ts.Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path);
                    }
                }
                if (ref.prepend) {
                    var out = options.outFile || options.out;
                    if (out) {
                        if (!host.fileExists(out)) {
                            createDiagnosticForReference(parentFile, index, ts.Diagnostics.Output_file_0_from_project_1_does_not_exist, out, ref.path);
                        }
                    }
                    else {
                        createDiagnosticForReference(parentFile, index, ts.Diagnostics.Cannot_prepend_project_0_because_it_does_not_have_outFile_set, ref.path);
                    }
                }
                if (!parent && buildInfoPath && buildInfoPath === ts.getOutputPathForBuildInfo(options)) {
                    createDiagnosticForReference(parentFile, index, ts.Diagnostics.Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1, buildInfoPath, ref.path);
                    hasEmitBlockingDiagnostics.set(toPath(buildInfoPath), true);
                }
            });
        }
        function createDiagnosticForOptionPathKeyValue(key, valueIndex, message, arg0, arg1, arg2) {
            var needCompilerDiagnostic = true;
            var pathsSyntax = getOptionPathsSyntax();
            for (var _i = 0, pathsSyntax_1 = pathsSyntax; _i < pathsSyntax_1.length; _i++) {
                var pathProp = pathsSyntax_1[_i];
                if (ts.isObjectLiteralExpression(pathProp.initializer)) {
                    for (var _a = 0, _b = ts.getPropertyAssignment(pathProp.initializer, key); _a < _b.length; _a++) {
                        var keyProps = _b[_a];
                        var initializer = keyProps.initializer;
                        if (ts.isArrayLiteralExpression(initializer) && initializer.elements.length > valueIndex) {
                            programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(options.configFile, initializer.elements[valueIndex], message, arg0, arg1, arg2));
                            needCompilerDiagnostic = false;
                        }
                    }
                }
            }
            if (needCompilerDiagnostic) {
                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1, arg2));
            }
        }
        function createDiagnosticForOptionPaths(onKey, key, message, arg0) {
            var needCompilerDiagnostic = true;
            var pathsSyntax = getOptionPathsSyntax();
            for (var _i = 0, pathsSyntax_2 = pathsSyntax; _i < pathsSyntax_2.length; _i++) {
                var pathProp = pathsSyntax_2[_i];
                if (ts.isObjectLiteralExpression(pathProp.initializer) &&
                    createOptionDiagnosticInObjectLiteralSyntax(pathProp.initializer, onKey, key, /*key2*/ undefined, message, arg0)) {
                    needCompilerDiagnostic = false;
                }
            }
            if (needCompilerDiagnostic) {
                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0));
            }
        }
        function getOptionsSyntaxByName(name) {
            var compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
            if (compilerOptionsObjectLiteralSyntax) {
                return ts.getPropertyAssignment(compilerOptionsObjectLiteralSyntax, name);
            }
            return undefined;
        }
        function getOptionPathsSyntax() {
            return getOptionsSyntaxByName("paths") || ts.emptyArray;
        }
        function createDiagnosticForOptionName(message, option1, option2, option3) {
            createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2, option3);
        }
        function createOptionValueDiagnostic(option1, message, arg0) {
            createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0);
        }
        function createDiagnosticForReference(sourceFile, index, message, arg0, arg1) {
            var referencesSyntax = ts.firstDefined(ts.getTsConfigPropArray(sourceFile || options.configFile, "references"), function (property) { return ts.isArrayLiteralExpression(property.initializer) ? property.initializer : undefined; });
            if (referencesSyntax && referencesSyntax.elements.length > index) {
                programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(sourceFile || options.configFile, referencesSyntax.elements[index], message, arg0, arg1));
            }
            else {
                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1));
            }
        }
        function createDiagnosticForOption(onKey, option1, option2, message, arg0, arg1, arg2) {
            var compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
            var needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax ||
                !createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, arg0, arg1, arg2);
            if (needCompilerDiagnostic) {
                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1, arg2));
            }
        }
        function getCompilerOptionsObjectLiteralSyntax() {
            if (_compilerOptionsObjectLiteralSyntax === undefined) {
                _compilerOptionsObjectLiteralSyntax = null; // tslint:disable-line:no-null-keyword
                var jsonObjectLiteral = ts.getTsConfigObjectLiteralExpression(options.configFile);
                if (jsonObjectLiteral) {
                    for (var _i = 0, _a = ts.getPropertyAssignment(jsonObjectLiteral, "compilerOptions"); _i < _a.length; _i++) {
                        var prop = _a[_i];
                        if (ts.isObjectLiteralExpression(prop.initializer)) {
                            _compilerOptionsObjectLiteralSyntax = prop.initializer;
                            break;
                        }
                    }
                }
            }
            return _compilerOptionsObjectLiteralSyntax;
        }
        function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral, onKey, key1, key2, message, arg0, arg1, arg2) {
            var props = ts.getPropertyAssignment(objectLiteral, key1, key2);
            for (var _i = 0, props_2 = props; _i < props_2.length; _i++) {
                var prop = props_2[_i];
                programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(options.configFile, onKey ? prop.name : prop.initializer, message, arg0, arg1, arg2));
            }
            return !!props.length;
        }
        function blockEmittingOfFile(emitFileName, diag) {
            hasEmitBlockingDiagnostics.set(toPath(emitFileName), true);
            programDiagnostics.add(diag);
        }
        function isEmittedFile(file) {
            if (options.noEmit) {
                return false;
            }
            // If this is source file, its not emitted file
            var filePath = toPath(file);
            if (getSourceFileByPath(filePath)) {
                return false;
            }
            // If options have --outFile or --out just check that
            var out = options.outFile || options.out;
            if (out) {
                return isSameFile(filePath, out) || isSameFile(filePath, ts.removeFileExtension(out) + ".d.ts" /* Dts */);
            }
            // If declarationDir is specified, return if its a file in that directory
            if (options.declarationDir && ts.containsPath(options.declarationDir, filePath, currentDirectory, !host.useCaseSensitiveFileNames())) {
                return true;
            }
            // If --outDir, check if file is in that directory
            if (options.outDir) {
                return ts.containsPath(options.outDir, filePath, currentDirectory, !host.useCaseSensitiveFileNames());
            }
            if (ts.fileExtensionIsOneOf(filePath, ts.supportedJSExtensions) || ts.fileExtensionIs(filePath, ".d.ts" /* Dts */)) {
                // Otherwise just check if sourceFile with the name exists
                var filePathWithoutExtension = ts.removeFileExtension(filePath);
                return !!getSourceFileByPath((filePathWithoutExtension + ".ts" /* Ts */)) ||
                    !!getSourceFileByPath((filePathWithoutExtension + ".tsx" /* Tsx */));
            }
            return false;
        }
        function isSameFile(file1, file2) {
            return ts.comparePaths(file1, file2, currentDirectory, !host.useCaseSensitiveFileNames()) === 0 /* EqualTo */;
        }
    }
    ts.createProgram = createProgram;
    /* @internal */
    function parseConfigHostFromCompilerHostLike(host, directoryStructureHost) {
        if (directoryStructureHost === void 0) { directoryStructureHost = host; }
        return {
            fileExists: function (f) { return directoryStructureHost.fileExists(f); },
            readDirectory: function (root, extensions, excludes, includes, depth) {
                ts.Debug.assertDefined(directoryStructureHost.readDirectory, "'CompilerHost.readDirectory' must be implemented to correctly process 'projectReferences'");
                return directoryStructureHost.readDirectory(root, extensions, excludes, includes, depth);
            },
            readFile: function (f) { return directoryStructureHost.readFile(f); },
            useCaseSensitiveFileNames: host.useCaseSensitiveFileNames(),
            getCurrentDirectory: function () { return host.getCurrentDirectory(); },
            onUnRecoverableConfigFileDiagnostic: host.onUnRecoverableConfigFileDiagnostic || ts.returnUndefined,
            trace: host.trace ? function (s) { return host.trace(s); } : undefined
        };
    }
    ts.parseConfigHostFromCompilerHostLike = parseConfigHostFromCompilerHostLike;
    /* @internal */
    function createPrependNodes(projectReferences, getCommandLine, readFile) {
        if (!projectReferences)
            return ts.emptyArray;
        var nodes;
        for (var i = 0; i < projectReferences.length; i++) {
            var ref = projectReferences[i];
            var resolvedRefOpts = getCommandLine(ref, i);
            if (ref.prepend && resolvedRefOpts && resolvedRefOpts.options) {
                var out = resolvedRefOpts.options.outFile || resolvedRefOpts.options.out;
                // Upstream project didn't have outFile set -- skip (error will have been issued earlier)
                if (!out)
                    continue;
                var _a = ts.getOutputPathsForBundle(resolvedRefOpts.options, /*forceDtsPaths*/ true), jsFilePath = _a.jsFilePath, sourceMapFilePath = _a.sourceMapFilePath, declarationFilePath = _a.declarationFilePath, declarationMapPath = _a.declarationMapPath, buildInfoPath = _a.buildInfoPath;
                var node = ts.createInputFiles(readFile, jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath);
                (nodes || (nodes = [])).push(node);
            }
        }
        return nodes || ts.emptyArray;
    }
    ts.createPrependNodes = createPrependNodes;
    function resolveProjectReferencePath(hostOrRef, ref) {
        var passedInRef = ref ? ref : hostOrRef;
        return ts.resolveConfigFileProjectName(passedInRef.path);
    }
    ts.resolveProjectReferencePath = resolveProjectReferencePath;
    function getEmitDeclarationOptionName(options) {
        return options.declaration ? "declaration" : "composite";
    }
    /* @internal */
    /**
     * Returns a DiagnosticMessage if we won't include a resolved module due to its extension.
     * The DiagnosticMessage's parameters are the imported module name, and the filename it resolved to.
     * This returns a diagnostic even if the module will be an untyped module.
     */
    function getResolutionDiagnostic(options, _a) {
        var extension = _a.extension;
        switch (extension) {
            case ".ts" /* Ts */:
            case ".d.ts" /* Dts */:
                // These are always allowed.
                return undefined;
            case ".tsx" /* Tsx */:
                return needJsx();
            case ".jsx" /* Jsx */:
                return needJsx() || needAllowJs();
            case ".js" /* Js */:
                return needAllowJs();
            case ".json" /* Json */:
                return needResolveJsonModule();
        }
        function needJsx() {
            return options.jsx ? undefined : ts.Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set;
        }
        function needAllowJs() {
            return options.allowJs || !ts.getStrictOptionValue(options, "noImplicitAny") ? undefined : ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type;
        }
        function needResolveJsonModule() {
            return options.resolveJsonModule ? undefined : ts.Diagnostics.Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used;
        }
    }
    ts.getResolutionDiagnostic = getResolutionDiagnostic;
    function getModuleNames(_a) {
        var imports = _a.imports, moduleAugmentations = _a.moduleAugmentations;
        var res = imports.map(function (i) { return i.text; });
        for (var _i = 0, moduleAugmentations_1 = moduleAugmentations; _i < moduleAugmentations_1.length; _i++) {
            var aug = moduleAugmentations_1[_i];
            if (aug.kind === 10 /* StringLiteral */) {
                res.push(aug.text);
            }
            // Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`.
        }
        return res;
    }
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function getFileEmitOutput(program, sourceFile, emitOnlyDtsFiles, cancellationToken, customTransformers) {
        var outputFiles = [];
        var emitResult = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
        return { outputFiles: outputFiles, emitSkipped: emitResult.emitSkipped, exportedModulesFromDeclarationEmit: emitResult.exportedModulesFromDeclarationEmit };
        function writeFile(fileName, text, writeByteOrderMark) {
            outputFiles.push({ name: fileName, writeByteOrderMark: writeByteOrderMark, text: text });
        }
    }
    ts.getFileEmitOutput = getFileEmitOutput;
    function cloneMapOrUndefined(map) {
        return map ? ts.cloneMap(map) : undefined;
    }
    ts.cloneMapOrUndefined = cloneMapOrUndefined;
})(ts || (ts = {}));
/*@internal*/
(function (ts) {
    var BuilderState;
    (function (BuilderState) {
        /**
         * Get the referencedFile from the imported module symbol
         */
        function getReferencedFileFromImportedModuleSymbol(symbol) {
            if (symbol.declarations && symbol.declarations[0]) {
                var declarationSourceFile = ts.getSourceFileOfNode(symbol.declarations[0]);
                return declarationSourceFile && declarationSourceFile.resolvedPath;
            }
        }
        /**
         * Get the referencedFile from the import name node from file
         */
        function getReferencedFileFromImportLiteral(checker, importName) {
            var symbol = checker.getSymbolAtLocation(importName);
            return symbol && getReferencedFileFromImportedModuleSymbol(symbol);
        }
        /**
         * Gets the path to reference file from file name, it could be resolvedPath if present otherwise path
         */
        function getReferencedFileFromFileName(program, fileName, sourceFileDirectory, getCanonicalFileName) {
            return ts.toPath(program.getProjectReferenceRedirect(fileName) || fileName, sourceFileDirectory, getCanonicalFileName);
        }
        /**
         * Gets the referenced files for a file from the program with values for the keys as referenced file's path to be true
         */
        function getReferencedFiles(program, sourceFile, getCanonicalFileName) {
            var referencedFiles;
            // We need to use a set here since the code can contain the same import twice,
            // but that will only be one dependency.
            // To avoid invernal conversion, the key of the referencedFiles map must be of type Path
            if (sourceFile.imports && sourceFile.imports.length > 0) {
                var checker = program.getTypeChecker();
                for (var _i = 0, _a = sourceFile.imports; _i < _a.length; _i++) {
                    var importName = _a[_i];
                    var declarationSourceFilePath = getReferencedFileFromImportLiteral(checker, importName);
                    if (declarationSourceFilePath) {
                        addReferencedFile(declarationSourceFilePath);
                    }
                }
            }
            var sourceFileDirectory = ts.getDirectoryPath(sourceFile.path);
            // Handle triple slash references
            if (sourceFile.referencedFiles && sourceFile.referencedFiles.length > 0) {
                for (var _b = 0, _c = sourceFile.referencedFiles; _b < _c.length; _b++) {
                    var referencedFile = _c[_b];
                    var referencedPath = getReferencedFileFromFileName(program, referencedFile.fileName, sourceFileDirectory, getCanonicalFileName);
                    addReferencedFile(referencedPath);
                }
            }
            // Handle type reference directives
            if (sourceFile.resolvedTypeReferenceDirectiveNames) {
                sourceFile.resolvedTypeReferenceDirectiveNames.forEach(function (resolvedTypeReferenceDirective) {
                    if (!resolvedTypeReferenceDirective) {
                        return;
                    }
                    var fileName = resolvedTypeReferenceDirective.resolvedFileName; // TODO: GH#18217
                    var typeFilePath = getReferencedFileFromFileName(program, fileName, sourceFileDirectory, getCanonicalFileName);
                    addReferencedFile(typeFilePath);
                });
            }
            // Add module augmentation as references
            if (sourceFile.moduleAugmentations.length) {
                var checker = program.getTypeChecker();
                for (var _d = 0, _e = sourceFile.moduleAugmentations; _d < _e.length; _d++) {
                    var moduleName = _e[_d];
                    if (!ts.isStringLiteral(moduleName)) {
                        continue;
                    }
                    var symbol = checker.getSymbolAtLocation(moduleName);
                    if (!symbol) {
                        continue;
                    }
                    // Add any file other than our own as reference
                    addReferenceFromAmbientModule(symbol);
                }
            }
            // From ambient modules
            for (var _f = 0, _g = program.getTypeChecker().getAmbientModules(); _f < _g.length; _f++) {
                var ambientModule = _g[_f];
                if (ambientModule.declarations.length > 1) {
                    addReferenceFromAmbientModule(ambientModule);
                }
            }
            return referencedFiles;
            function addReferenceFromAmbientModule(symbol) {
                // Add any file other than our own as reference
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    var declarationSourceFile = ts.getSourceFileOfNode(declaration);
                    if (declarationSourceFile &&
                        declarationSourceFile !== sourceFile) {
                        addReferencedFile(declarationSourceFile.resolvedPath);
                    }
                }
            }
            function addReferencedFile(referencedPath) {
                if (!referencedFiles) {
                    referencedFiles = ts.createMap();
                }
                referencedFiles.set(referencedPath, true);
            }
        }
        /**
         * Returns true if oldState is reusable, that is the emitKind = module/non module has not changed
         */
        function canReuseOldState(newReferencedMap, oldState) {
            return oldState && !oldState.referencedMap === !newReferencedMap;
        }
        BuilderState.canReuseOldState = canReuseOldState;
        /**
         * Creates the state of file references and signature for the new program from oldState if it is safe
         */
        function create(newProgram, getCanonicalFileName, oldState) {
            var fileInfos = ts.createMap();
            var referencedMap = newProgram.getCompilerOptions().module !== ts.ModuleKind.None ? ts.createMap() : undefined;
            var exportedModulesMap = referencedMap ? ts.createMap() : undefined;
            var hasCalledUpdateShapeSignature = ts.createMap();
            var useOldState = canReuseOldState(referencedMap, oldState);
            // Create the reference map, and set the file infos
            for (var _i = 0, _a = newProgram.getSourceFiles(); _i < _a.length; _i++) {
                var sourceFile = _a[_i];
                var version_1 = ts.Debug.assertDefined(sourceFile.version, "Program intended to be used with Builder should have source files with versions set");
                var oldInfo = useOldState ? oldState.fileInfos.get(sourceFile.path) : undefined;
                if (referencedMap) {
                    var newReferences = getReferencedFiles(newProgram, sourceFile, getCanonicalFileName);
                    if (newReferences) {
                        referencedMap.set(sourceFile.path, newReferences);
                    }
                    // Copy old visible to outside files map
                    if (useOldState) {
                        var exportedModules = oldState.exportedModulesMap.get(sourceFile.path);
                        if (exportedModules) {
                            exportedModulesMap.set(sourceFile.path, exportedModules);
                        }
                    }
                }
                fileInfos.set(sourceFile.path, { version: version_1, signature: oldInfo && oldInfo.signature });
            }
            return {
                fileInfos: fileInfos,
                referencedMap: referencedMap,
                exportedModulesMap: exportedModulesMap,
                hasCalledUpdateShapeSignature: hasCalledUpdateShapeSignature
            };
        }
        BuilderState.create = create;
        /**
         * Releases needed properties
         */
        function releaseCache(state) {
            state.allFilesExcludingDefaultLibraryFile = undefined;
            state.allFileNames = undefined;
        }
        BuilderState.releaseCache = releaseCache;
        /**
         * Creates a clone of the state
         */
        function clone(state) {
            var fileInfos = ts.createMap();
            state.fileInfos.forEach(function (value, key) {
                fileInfos.set(key, __assign({}, value));
            });
            // Dont need to backup allFiles info since its cache anyway
            return {
                fileInfos: fileInfos,
                referencedMap: ts.cloneMapOrUndefined(state.referencedMap),
                exportedModulesMap: ts.cloneMapOrUndefined(state.exportedModulesMap),
                hasCalledUpdateShapeSignature: ts.cloneMap(state.hasCalledUpdateShapeSignature),
            };
        }
        BuilderState.clone = clone;
        /**
         * Gets the files affected by the path from the program
         */
        function getFilesAffectedBy(state, programOfThisState, path, cancellationToken, computeHash, cacheToUpdateSignature, exportedModulesMapCache) {
            // Since the operation could be cancelled, the signatures are always stored in the cache
            // They will be committed once it is safe to use them
            // eg when calling this api from tsserver, if there is no cancellation of the operation
            // In the other cases the affected files signatures are committed only after the iteration through the result is complete
            var signatureCache = cacheToUpdateSignature || ts.createMap();
            var sourceFile = programOfThisState.getSourceFileByPath(path);
            if (!sourceFile) {
                return ts.emptyArray;
            }
            if (!updateShapeSignature(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash, exportedModulesMapCache)) {
                return [sourceFile];
            }
            var result = (state.referencedMap ? getFilesAffectedByUpdatedShapeWhenModuleEmit : getFilesAffectedByUpdatedShapeWhenNonModuleEmit)(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash, exportedModulesMapCache);
            if (!cacheToUpdateSignature) {
                // Commit all the signatures in the signature cache
                updateSignaturesFromCache(state, signatureCache);
            }
            return result;
        }
        BuilderState.getFilesAffectedBy = getFilesAffectedBy;
        /**
         * Updates the signatures from the cache into state's fileinfo signatures
         * This should be called whenever it is safe to commit the state of the builder
         */
        function updateSignaturesFromCache(state, signatureCache) {
            signatureCache.forEach(function (signature, path) {
                state.fileInfos.get(path).signature = signature;
                state.hasCalledUpdateShapeSignature.set(path, true);
            });
        }
        BuilderState.updateSignaturesFromCache = updateSignaturesFromCache;
        /**
         * Returns if the shape of the signature has changed since last emit
         */
        function updateShapeSignature(state, programOfThisState, sourceFile, cacheToUpdateSignature, cancellationToken, computeHash, exportedModulesMapCache) {
            ts.Debug.assert(!!sourceFile);
            ts.Debug.assert(!exportedModulesMapCache || !!state.exportedModulesMap, "Compute visible to outside map only if visibleToOutsideReferencedMap present in the state");
            // If we have cached the result for this file, that means hence forth we should assume file shape is uptodate
            if (state.hasCalledUpdateShapeSignature.has(sourceFile.path) || cacheToUpdateSignature.has(sourceFile.path)) {
                return false;
            }
            var info = state.fileInfos.get(sourceFile.path);
            if (!info)
                return ts.Debug.fail();
            var prevSignature = info.signature;
            var latestSignature;
            if (sourceFile.isDeclarationFile) {
                latestSignature = sourceFile.version;
                if (exportedModulesMapCache && latestSignature !== prevSignature) {
                    // All the references in this file are exported
                    var references = state.referencedMap ? state.referencedMap.get(sourceFile.path) : undefined;
                    exportedModulesMapCache.set(sourceFile.path, references || false);
                }
            }
            else {
                var emitOutput = ts.getFileEmitOutput(programOfThisState, sourceFile, /*emitOnlyDtsFiles*/ true, cancellationToken);
                if (emitOutput.outputFiles && emitOutput.outputFiles.length > 0) {
                    latestSignature = computeHash(emitOutput.outputFiles[0].text);
                    if (exportedModulesMapCache && latestSignature !== prevSignature) {
                        updateExportedModules(sourceFile, emitOutput.exportedModulesFromDeclarationEmit, exportedModulesMapCache);
                    }
                }
                else {
                    latestSignature = prevSignature; // TODO: GH#18217
                }
            }
            cacheToUpdateSignature.set(sourceFile.path, latestSignature);
            return !prevSignature || latestSignature !== prevSignature;
        }
        BuilderState.updateShapeSignature = updateShapeSignature;
        /**
         * Coverts the declaration emit result into exported modules map
         */
        function updateExportedModules(sourceFile, exportedModulesFromDeclarationEmit, exportedModulesMapCache) {
            if (!exportedModulesFromDeclarationEmit) {
                exportedModulesMapCache.set(sourceFile.path, false);
                return;
            }
            var exportedModules;
            exportedModulesFromDeclarationEmit.forEach(function (symbol) { return addExportedModule(getReferencedFileFromImportedModuleSymbol(symbol)); });
            exportedModulesMapCache.set(sourceFile.path, exportedModules || false);
            function addExportedModule(exportedModulePath) {
                if (exportedModulePath) {
                    if (!exportedModules) {
                        exportedModules = ts.createMap();
                    }
                    exportedModules.set(exportedModulePath, true);
                }
            }
        }
        /**
         * Updates the exported modules from cache into state's exported modules map
         * This should be called whenever it is safe to commit the state of the builder
         */
        function updateExportedFilesMapFromCache(state, exportedModulesMapCache) {
            if (exportedModulesMapCache) {
                ts.Debug.assert(!!state.exportedModulesMap);
                exportedModulesMapCache.forEach(function (exportedModules, path) {
                    if (exportedModules) {
                        state.exportedModulesMap.set(path, exportedModules);
                    }
                    else {
                        state.exportedModulesMap.delete(path);
                    }
                });
            }
        }
        BuilderState.updateExportedFilesMapFromCache = updateExportedFilesMapFromCache;
        /**
         * Get all the dependencies of the sourceFile
         */
        function getAllDependencies(state, programOfThisState, sourceFile) {
            var _a;
            var compilerOptions = programOfThisState.getCompilerOptions();
            // With --out or --outFile all outputs go into single file, all files depend on each other
            if (compilerOptions.outFile || compilerOptions.out) {
                return getAllFileNames(state, programOfThisState);
            }
            // If this is non module emit, or its a global file, it depends on all the source files
            if (!state.referencedMap || isFileAffectingGlobalScope(sourceFile)) {
                return getAllFileNames(state, programOfThisState);
            }
            // Get the references, traversing deep from the referenceMap
            var seenMap = ts.createMap();
            var queue = [sourceFile.path];
            while (queue.length) {
                var path = queue.pop();
                if (!seenMap.has(path)) {
                    seenMap.set(path, true);
                    var references = state.referencedMap.get(path);
                    if (references) {
                        var iterator = references.keys();
                        for (var _b = iterator.next(), value = _b.value, done = _b.done; !done; _a = iterator.next(), value = _a.value, done = _a.done, _a) {
                            queue.push(value);
                        }
                    }
                }
            }
            return ts.arrayFrom(ts.mapDefinedIterator(seenMap.keys(), function (path) {
                var file = programOfThisState.getSourceFileByPath(path);
                return file ? file.fileName : path;
            }));
        }
        BuilderState.getAllDependencies = getAllDependencies;
        /**
         * Gets the names of all files from the program
         */
        function getAllFileNames(state, programOfThisState) {
            if (!state.allFileNames) {
                var sourceFiles = programOfThisState.getSourceFiles();
                state.allFileNames = sourceFiles === ts.emptyArray ? ts.emptyArray : sourceFiles.map(function (file) { return file.fileName; });
            }
            return state.allFileNames;
        }
        /**
         * Gets the files referenced by the the file path
         */
        function getReferencedByPaths(state, referencedFilePath) {
            return ts.arrayFrom(ts.mapDefinedIterator(state.referencedMap.entries(), function (_a) {
                var filePath = _a[0], referencesInFile = _a[1];
                return referencesInFile.has(referencedFilePath) ? filePath : undefined;
            }));
        }
        /**
         * For script files that contains only ambient external modules, although they are not actually external module files,
         * they can only be consumed via importing elements from them. Regular script files cannot consume them. Therefore,
         * there are no point to rebuild all script files if these special files have changed. However, if any statement
         * in the file is not ambient external module, we treat it as a regular script file.
         */
        function containsOnlyAmbientModules(sourceFile) {
            for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
                var statement = _a[_i];
                if (!ts.isModuleWithStringLiteralName(statement)) {
                    return false;
                }
            }
            return true;
        }
        /**
         * Return true if file contains anything that augments to global scope we need to build them as if
         * they are global files as well as module
         */
        function containsGlobalScopeAugmentation(sourceFile) {
            return ts.some(sourceFile.moduleAugmentations, function (augmentation) { return ts.isGlobalScopeAugmentation(augmentation.parent); });
        }
        /**
         * Return true if the file will invalidate all files because it affectes global scope
         */
        function isFileAffectingGlobalScope(sourceFile) {
            return containsGlobalScopeAugmentation(sourceFile) ||
                !ts.isExternalModule(sourceFile) && !containsOnlyAmbientModules(sourceFile);
        }
        /**
         * Gets all files of the program excluding the default library file
         */
        function getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, firstSourceFile) {
            // Use cached result
            if (state.allFilesExcludingDefaultLibraryFile) {
                return state.allFilesExcludingDefaultLibraryFile;
            }
            var result;
            addSourceFile(firstSourceFile);
            for (var _i = 0, _a = programOfThisState.getSourceFiles(); _i < _a.length; _i++) {
                var sourceFile = _a[_i];
                if (sourceFile !== firstSourceFile) {
                    addSourceFile(sourceFile);
                }
            }
            state.allFilesExcludingDefaultLibraryFile = result || ts.emptyArray;
            return state.allFilesExcludingDefaultLibraryFile;
            function addSourceFile(sourceFile) {
                if (!programOfThisState.isSourceFileDefaultLibrary(sourceFile)) {
                    (result || (result = [])).push(sourceFile);
                }
            }
        }
        /**
         * When program emits non modular code, gets the files affected by the sourceFile whose shape has changed
         */
        function getFilesAffectedByUpdatedShapeWhenNonModuleEmit(state, programOfThisState, sourceFileWithUpdatedShape) {
            var compilerOptions = programOfThisState.getCompilerOptions();
            // If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project,
            // so returning the file itself is good enough.
            if (compilerOptions && (compilerOptions.out || compilerOptions.outFile)) {
                return [sourceFileWithUpdatedShape];
            }
            return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape);
        }
        /**
         * When program emits modular code, gets the files affected by the sourceFile whose shape has changed
         */
        function getFilesAffectedByUpdatedShapeWhenModuleEmit(state, programOfThisState, sourceFileWithUpdatedShape, cacheToUpdateSignature, cancellationToken, computeHash, exportedModulesMapCache) {
            if (isFileAffectingGlobalScope(sourceFileWithUpdatedShape)) {
                return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape);
            }
            var compilerOptions = programOfThisState.getCompilerOptions();
            if (compilerOptions && (compilerOptions.isolatedModules || compilerOptions.out || compilerOptions.outFile)) {
                return [sourceFileWithUpdatedShape];
            }
            // Now we need to if each file in the referencedBy list has a shape change as well.
            // Because if so, its own referencedBy files need to be saved as well to make the
            // emitting result consistent with files on disk.
            var seenFileNamesMap = ts.createMap();
            // Start with the paths this file was referenced by
            seenFileNamesMap.set(sourceFileWithUpdatedShape.path, sourceFileWithUpdatedShape);
            var queue = getReferencedByPaths(state, sourceFileWithUpdatedShape.resolvedPath);
            while (queue.length > 0) {
                var currentPath = queue.pop();
                if (!seenFileNamesMap.has(currentPath)) {
                    var currentSourceFile = programOfThisState.getSourceFileByPath(currentPath);
                    seenFileNamesMap.set(currentPath, currentSourceFile);
                    if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cacheToUpdateSignature, cancellationToken, computeHash, exportedModulesMapCache)) { // TODO: GH#18217
                        queue.push.apply(// TODO: GH#18217
                        queue, getReferencedByPaths(state, currentSourceFile.resolvedPath));
                    }
                }
            }
            // Return array of values that needs emit
            // Return array of values that needs emit
            return ts.arrayFrom(ts.mapDefinedIterator(seenFileNamesMap.values(), function (value) { return value; }));
        }
    })(BuilderState = ts.BuilderState || (ts.BuilderState = {}));
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function hasSameKeys(map1, map2) {
        // Has same size and every key is present in both maps
        return map1 === map2 || map1 !== undefined && map2 !== undefined && map1.size === map2.size && !ts.forEachKey(map1, function (key) { return !map2.has(key); });
    }
    /**
     * Create the state so that we can iterate on changedFiles/affected files
     */
    function createBuilderProgramState(newProgram, getCanonicalFileName, oldState) {
        var state = ts.BuilderState.create(newProgram, getCanonicalFileName, oldState);
        state.program = newProgram;
        var compilerOptions = newProgram.getCompilerOptions();
        state.compilerOptions = compilerOptions;
        // With --out or --outFile, any change affects all semantic diagnostics so no need to cache them
        // With --isolatedModules, emitting changed file doesnt emit dependent files so we cant know of dependent files to retrieve errors so dont cache the errors
        if (!compilerOptions.outFile && !compilerOptions.out && !compilerOptions.isolatedModules) {
            state.semanticDiagnosticsPerFile = ts.createMap();
        }
        state.changedFilesSet = ts.createMap();
        var useOldState = ts.BuilderState.canReuseOldState(state.referencedMap, oldState);
        var oldCompilerOptions = useOldState ? oldState.compilerOptions : undefined;
        var canCopySemanticDiagnostics = useOldState && oldState.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile &&
            !ts.compilerOptionsAffectSemanticDiagnostics(compilerOptions, oldCompilerOptions);
        if (useOldState) {
            // Verify the sanity of old state
            if (!oldState.currentChangedFilePath) {
                var affectedSignatures = oldState.currentAffectedFilesSignatures;
                ts.Debug.assert(!oldState.affectedFiles && (!affectedSignatures || !affectedSignatures.size), "Cannot reuse if only few affected files of currentChangedFile were iterated");
            }
            var changedFilesSet = oldState.changedFilesSet;
            if (canCopySemanticDiagnostics) {
                ts.Debug.assert(!changedFilesSet || !ts.forEachKey(changedFilesSet, function (path) { return oldState.semanticDiagnosticsPerFile.has(path); }), "Semantic diagnostics shouldnt be available for changed files");
            }
            // Copy old state's changed files set
            if (changedFilesSet) {
                ts.copyEntries(changedFilesSet, state.changedFilesSet);
            }
            if (!compilerOptions.outFile && !compilerOptions.out && oldState.affectedFilesPendingEmit) {
                state.affectedFilesPendingEmit = oldState.affectedFilesPendingEmit;
                state.affectedFilesPendingEmitIndex = oldState.affectedFilesPendingEmitIndex;
            }
        }
        // Update changed files and copy semantic diagnostics if we can
        var referencedMap = state.referencedMap;
        var oldReferencedMap = useOldState ? oldState.referencedMap : undefined;
        var copyDeclarationFileDiagnostics = canCopySemanticDiagnostics && !compilerOptions.skipLibCheck === !oldCompilerOptions.skipLibCheck;
        var copyLibFileDiagnostics = copyDeclarationFileDiagnostics && !compilerOptions.skipDefaultLibCheck === !oldCompilerOptions.skipDefaultLibCheck;
        state.fileInfos.forEach(function (info, sourceFilePath) {
            var oldInfo;
            var newReferences;
            // if not using old state, every file is changed
            if (!useOldState ||
                // File wasnt present in old state
                !(oldInfo = oldState.fileInfos.get(sourceFilePath)) ||
                // versions dont match
                oldInfo.version !== info.version ||
                // Referenced files changed
                !hasSameKeys(newReferences = referencedMap && referencedMap.get(sourceFilePath), oldReferencedMap && oldReferencedMap.get(sourceFilePath)) ||
                // Referenced file was deleted in the new program
                newReferences && ts.forEachKey(newReferences, function (path) { return !state.fileInfos.has(path) && oldState.fileInfos.has(path); })) {
                // Register file as changed file and do not copy semantic diagnostics, since all changed files need to be re-evaluated
                state.changedFilesSet.set(sourceFilePath, true);
            }
            else if (canCopySemanticDiagnostics) {
                var sourceFile = newProgram.getSourceFileByPath(sourceFilePath);
                if (sourceFile.isDeclarationFile && !copyDeclarationFileDiagnostics) {
                    return;
                }
                if (sourceFile.hasNoDefaultLib && !copyLibFileDiagnostics) {
                    return;
                }
                // Unchanged file copy diagnostics
                var diagnostics = oldState.semanticDiagnosticsPerFile.get(sourceFilePath);
                if (diagnostics) {
                    state.semanticDiagnosticsPerFile.set(sourceFilePath, oldState.hasReusableDiagnostic ? convertToDiagnostics(diagnostics, newProgram) : diagnostics);
                    if (!state.semanticDiagnosticsFromOldState) {
                        state.semanticDiagnosticsFromOldState = ts.createMap();
                    }
                    state.semanticDiagnosticsFromOldState.set(sourceFilePath, true);
                }
            }
        });
        if (oldCompilerOptions && ts.compilerOptionsAffectEmit(compilerOptions, oldCompilerOptions)) {
            // Add all files to affectedFilesPendingEmit since emit changed
            addToAffectedFilesPendingEmit(state, newProgram.getSourceFiles().map(function (f) { return f.path; }));
            ts.Debug.assert(state.seenAffectedFiles === undefined);
            state.seenAffectedFiles = ts.createMap();
        }
        return state;
    }
    function convertToDiagnostics(diagnostics, newProgram) {
        if (!diagnostics.length)
            return ts.emptyArray;
        return diagnostics.map(function (diagnostic) {
            var result = convertToDiagnosticRelatedInformation(diagnostic, newProgram);
            result.reportsUnnecessary = diagnostic.reportsUnnecessary;
            result.source = diagnostic.source;
            var relatedInformation = diagnostic.relatedInformation;
            result.relatedInformation = relatedInformation ?
                relatedInformation.length ?
                    relatedInformation.map(function (r) { return convertToDiagnosticRelatedInformation(r, newProgram); }) :
                    ts.emptyArray :
                undefined;
            return result;
        });
    }
    function convertToDiagnosticRelatedInformation(diagnostic, newProgram) {
        var file = diagnostic.file, messageText = diagnostic.messageText;
        return __assign({}, diagnostic, { file: file && newProgram.getSourceFileByPath(file), messageText: messageText === undefined || ts.isString(messageText) ?
                messageText :
                convertToDiagnosticMessageChain(messageText, newProgram) });
    }
    function convertToDiagnosticMessageChain(diagnostic, newProgram) {
        return __assign({}, diagnostic, { next: diagnostic.next && convertToDiagnosticMessageChain(diagnostic.next, newProgram) });
    }
    /**
     * Releases program and other related not needed properties
     */
    function releaseCache(state) {
        ts.BuilderState.releaseCache(state);
        state.program = undefined;
    }
    /**
     * Creates a clone of the state
     */
    function cloneBuilderProgramState(state) {
        var newState = ts.BuilderState.clone(state);
        newState.semanticDiagnosticsPerFile = ts.cloneMapOrUndefined(state.semanticDiagnosticsPerFile);
        newState.changedFilesSet = ts.cloneMap(state.changedFilesSet);
        newState.affectedFiles = state.affectedFiles;
        newState.affectedFilesIndex = state.affectedFilesIndex;
        newState.currentChangedFilePath = state.currentChangedFilePath;
        newState.currentAffectedFilesSignatures = ts.cloneMapOrUndefined(state.currentAffectedFilesSignatures);
        newState.currentAffectedFilesExportedModulesMap = ts.cloneMapOrUndefined(state.currentAffectedFilesExportedModulesMap);
        newState.seenAffectedFiles = ts.cloneMapOrUndefined(state.seenAffectedFiles);
        newState.cleanedDiagnosticsOfLibFiles = state.cleanedDiagnosticsOfLibFiles;
        newState.semanticDiagnosticsFromOldState = ts.cloneMapOrUndefined(state.semanticDiagnosticsFromOldState);
        newState.program = state.program;
        newState.compilerOptions = state.compilerOptions;
        newState.affectedFilesPendingEmit = state.affectedFilesPendingEmit;
        newState.affectedFilesPendingEmitIndex = state.affectedFilesPendingEmitIndex;
        newState.seenEmittedFiles = ts.cloneMapOrUndefined(state.seenEmittedFiles);
        newState.programEmitComplete = state.programEmitComplete;
        return newState;
    }
    /**
     * Verifies that source file is ok to be used in calls that arent handled by next
     */
    function assertSourceFileOkWithoutNextAffectedCall(state, sourceFile) {
        ts.Debug.assert(!sourceFile || !state.affectedFiles || state.affectedFiles[state.affectedFilesIndex - 1] !== sourceFile || !state.semanticDiagnosticsPerFile.has(sourceFile.path));
    }
    /**
     * This function returns the next affected file to be processed.
     * Note that until doneAffected is called it would keep reporting same result
     * This is to allow the callers to be able to actually remove affected file only when the operation is complete
     * eg. if during diagnostics check cancellation token ends up cancelling the request, the affected file should be retained
     */
    function getNextAffectedFile(state, cancellationToken, computeHash) {
        while (true) {
            var affectedFiles = state.affectedFiles;
            if (affectedFiles) {
                var seenAffectedFiles = state.seenAffectedFiles;
                var affectedFilesIndex = state.affectedFilesIndex; // TODO: GH#18217
                while (affectedFilesIndex < affectedFiles.length) {
                    var affectedFile = affectedFiles[affectedFilesIndex];
                    if (!seenAffectedFiles.has(affectedFile.path)) {
                        // Set the next affected file as seen and remove the cached semantic diagnostics
                        state.affectedFilesIndex = affectedFilesIndex;
                        handleDtsMayChangeOfAffectedFile(state, affectedFile, cancellationToken, computeHash);
                        return affectedFile;
                    }
                    seenAffectedFiles.set(affectedFile.path, true);
                    affectedFilesIndex++;
                }
                // Remove the changed file from the change set
                state.changedFilesSet.delete(state.currentChangedFilePath);
                state.currentChangedFilePath = undefined;
                // Commit the changes in file signature
                ts.BuilderState.updateSignaturesFromCache(state, state.currentAffectedFilesSignatures);
                state.currentAffectedFilesSignatures.clear();
                ts.BuilderState.updateExportedFilesMapFromCache(state, state.currentAffectedFilesExportedModulesMap);
                state.affectedFiles = undefined;
            }
            // Get next changed file
            var nextKey = state.changedFilesSet.keys().next();
            if (nextKey.done) {
                // Done
                return undefined;
            }
            // With --out or --outFile all outputs go into single file
            // so operations are performed directly on program, return program
            var program = ts.Debug.assertDefined(state.program);
            var compilerOptions = program.getCompilerOptions();
            if (compilerOptions.outFile || compilerOptions.out) {
                ts.Debug.assert(!state.semanticDiagnosticsPerFile);
                return program;
            }
            // Get next batch of affected files
            state.currentAffectedFilesSignatures = state.currentAffectedFilesSignatures || ts.createMap();
            if (state.exportedModulesMap) {
                state.currentAffectedFilesExportedModulesMap = state.currentAffectedFilesExportedModulesMap || ts.createMap();
            }
            state.affectedFiles = ts.BuilderState.getFilesAffectedBy(state, program, nextKey.value, cancellationToken, computeHash, state.currentAffectedFilesSignatures, state.currentAffectedFilesExportedModulesMap);
            state.currentChangedFilePath = nextKey.value;
            state.affectedFilesIndex = 0;
            state.seenAffectedFiles = state.seenAffectedFiles || ts.createMap();
        }
    }
    /**
     * Returns next file to be emitted from files that retrieved semantic diagnostics but did not emit yet
     */
    function getNextAffectedFilePendingEmit(state) {
        var affectedFilesPendingEmit = state.affectedFilesPendingEmit;
        if (affectedFilesPendingEmit) {
            var seenEmittedFiles = state.seenEmittedFiles || (state.seenEmittedFiles = ts.createMap());
            for (var i = state.affectedFilesPendingEmitIndex; i < affectedFilesPendingEmit.length; i++) {
                var affectedFile = ts.Debug.assertDefined(state.program).getSourceFileByPath(affectedFilesPendingEmit[i]);
                if (affectedFile && !seenEmittedFiles.has(affectedFile.path)) {
                    // emit this file
                    state.affectedFilesPendingEmitIndex = i;
                    return affectedFile;
                }
            }
            state.affectedFilesPendingEmit = undefined;
            state.affectedFilesPendingEmitIndex = undefined;
        }
        return undefined;
    }
    /**
     *  Handles semantic diagnostics and dts emit for affectedFile and files, that are referencing modules that export entities from affected file
     *  This is because even though js emit doesnt change, dts emit / type used can change resulting in need for dts emit and js change
     */
    function handleDtsMayChangeOfAffectedFile(state, affectedFile, cancellationToken, computeHash) {
        removeSemanticDiagnosticsOf(state, affectedFile.path);
        // If affected files is everything except default library, then nothing more to do
        if (state.allFilesExcludingDefaultLibraryFile === state.affectedFiles) {
            if (!state.cleanedDiagnosticsOfLibFiles) {
                state.cleanedDiagnosticsOfLibFiles = true;
                var program_1 = ts.Debug.assertDefined(state.program);
                var options_2 = program_1.getCompilerOptions();
                ts.forEach(program_1.getSourceFiles(), function (f) {
                    return program_1.isSourceFileDefaultLibrary(f) &&
                        !ts.skipTypeChecking(f, options_2) &&
                        removeSemanticDiagnosticsOf(state, f.path);
                });
            }
            return;
        }
        forEachReferencingModulesOfExportOfAffectedFile(state, affectedFile, function (state, path) { return handleDtsMayChangeOf(state, path, cancellationToken, computeHash); });
    }
    /**
     * Handle the dts may change, so they need to be added to pending emit if dts emit is enabled,
     * Also we need to make sure signature is updated for these files
     */
    function handleDtsMayChangeOf(state, path, cancellationToken, computeHash) {
        removeSemanticDiagnosticsOf(state, path);
        if (!state.changedFilesSet.has(path)) {
            var program = ts.Debug.assertDefined(state.program);
            var sourceFile = program.getSourceFileByPath(path);
            if (sourceFile) {
                // Even though the js emit doesnt change and we are already handling dts emit and semantic diagnostics
                // we need to update the signature to reflect correctness of the signature(which is output d.ts emit) of this file
                // This ensures that we dont later during incremental builds considering wrong signature.
                // Eg where this also is needed to ensure that .tsbuildinfo generated by incremental build should be same as if it was first fresh build
                ts.BuilderState.updateShapeSignature(state, program, sourceFile, ts.Debug.assertDefined(state.currentAffectedFilesSignatures), cancellationToken, computeHash, state.currentAffectedFilesExportedModulesMap);
                // If not dts emit, nothing more to do
                if (ts.getEmitDeclarations(state.compilerOptions)) {
                    addToAffectedFilesPendingEmit(state, [path]);
                }
            }
        }
        return false;
    }
    /**
     * Removes semantic diagnostics for path and
     * returns true if there are no more semantic diagnostics from the old state
     */
    function removeSemanticDiagnosticsOf(state, path) {
        if (!state.semanticDiagnosticsFromOldState) {
            return true;
        }
        state.semanticDiagnosticsFromOldState.delete(path);
        state.semanticDiagnosticsPerFile.delete(path);
        return !state.semanticDiagnosticsFromOldState.size;
    }
    /**
     * Iterate on referencing modules that export entities from affected file
     */
    function forEachReferencingModulesOfExportOfAffectedFile(state, affectedFile, fn) {
        // If there was change in signature (dts output) for the changed file,
        // then only we need to handle pending file emit
        if (!state.exportedModulesMap || state.affectedFiles.length === 1 || !state.changedFilesSet.has(affectedFile.path)) {
            return;
        }
        ts.Debug.assert(!!state.currentAffectedFilesExportedModulesMap);
        var seenFileAndExportsOfFile = ts.createMap();
        // Go through exported modules from cache first
        // If exported modules has path, all files referencing file exported from are affected
        if (ts.forEachEntry(state.currentAffectedFilesExportedModulesMap, function (exportedModules, exportedFromPath) {
            return exportedModules &&
                exportedModules.has(affectedFile.path) &&
                forEachFilesReferencingPath(state, exportedFromPath, seenFileAndExportsOfFile, fn);
        })) {
            return;
        }
        // If exported from path is not from cache and exported modules has path, all files referencing file exported from are affected
        ts.forEachEntry(state.exportedModulesMap, function (exportedModules, exportedFromPath) {
            return !state.currentAffectedFilesExportedModulesMap.has(exportedFromPath) && // If we already iterated this through cache, ignore it
                exportedModules.has(affectedFile.path) &&
                forEachFilesReferencingPath(state, exportedFromPath, seenFileAndExportsOfFile, fn);
        });
    }
    /**
     * Iterate on files referencing referencedPath
     */
    function forEachFilesReferencingPath(state, referencedPath, seenFileAndExportsOfFile, fn) {
        return ts.forEachEntry(state.referencedMap, function (referencesInFile, filePath) {
            return referencesInFile.has(referencedPath) && forEachFileAndExportsOfFile(state, filePath, seenFileAndExportsOfFile, fn);
        });
    }
    /**
     * fn on file and iterate on anything that exports this file
     */
    function forEachFileAndExportsOfFile(state, filePath, seenFileAndExportsOfFile, fn) {
        if (!ts.addToSeen(seenFileAndExportsOfFile, filePath)) {
            return false;
        }
        if (fn(state, filePath)) {
            // If there are no more diagnostics from old cache, done
            return true;
        }
        ts.Debug.assert(!!state.currentAffectedFilesExportedModulesMap);
        // Go through exported modules from cache first
        // If exported modules has path, all files referencing file exported from are affected
        if (ts.forEachEntry(state.currentAffectedFilesExportedModulesMap, function (exportedModules, exportedFromPath) {
            return exportedModules &&
                exportedModules.has(filePath) &&
                forEachFileAndExportsOfFile(state, exportedFromPath, seenFileAndExportsOfFile, fn);
        })) {
            return true;
        }
        // If exported from path is not from cache and exported modules has path, all files referencing file exported from are affected
        if (ts.forEachEntry(state.exportedModulesMap, function (exportedModules, exportedFromPath) {
            return !state.currentAffectedFilesExportedModulesMap.has(exportedFromPath) && // If we already iterated this through cache, ignore it
                exportedModules.has(filePath) &&
                forEachFileAndExportsOfFile(state, exportedFromPath, seenFileAndExportsOfFile, fn);
        })) {
            return true;
        }
        // Remove diagnostics of files that import this file (without going to exports of referencing files)
        return !!ts.forEachEntry(state.referencedMap, function (referencesInFile, referencingFilePath) {
            return referencesInFile.has(filePath) &&
                !seenFileAndExportsOfFile.has(referencingFilePath) && // Not already removed diagnostic file
                fn(state, referencingFilePath);
        } // Dont add to seen since this is not yet done with the export removal
        );
    }
    /**
     * This is called after completing operation on the next affected file.
     * The operations here are postponed to ensure that cancellation during the iteration is handled correctly
     */
    function doneWithAffectedFile(state, affected, isPendingEmit, isBuildInfoEmit) {
        if (isBuildInfoEmit) {
            state.emittedBuildInfo = true;
        }
        else if (affected === state.program) {
            state.changedFilesSet.clear();
            state.programEmitComplete = true;
        }
        else {
            state.seenAffectedFiles.set(affected.path, true);
            if (isPendingEmit) {
                state.affectedFilesPendingEmitIndex++;
            }
            else {
                state.affectedFilesIndex++;
            }
        }
    }
    /**
     * Returns the result with affected file
     */
    function toAffectedFileResult(state, result, affected, isPendingEmit, isBuildInfoEmit) {
        doneWithAffectedFile(state, affected, isPendingEmit, isBuildInfoEmit);
        return { result: result, affected: affected };
    }
    /**
     * Gets the semantic diagnostics either from cache if present, or otherwise from program and caches it
     * Note that it is assumed that the when asked about semantic diagnostics, the file has been taken out of affected files/changed file set
     */
    function getSemanticDiagnosticsOfFile(state, sourceFile, cancellationToken) {
        var path = sourceFile.path;
        if (state.semanticDiagnosticsPerFile) {
            var cachedDiagnostics = state.semanticDiagnosticsPerFile.get(path);
            // Report the semantic diagnostics from the cache if we already have those diagnostics present
            if (cachedDiagnostics) {
                return cachedDiagnostics;
            }
        }
        // Diagnostics werent cached, get them from program, and cache the result
        var diagnostics = ts.Debug.assertDefined(state.program).getSemanticDiagnostics(sourceFile, cancellationToken);
        if (state.semanticDiagnosticsPerFile) {
            state.semanticDiagnosticsPerFile.set(path, diagnostics);
        }
        return diagnostics;
    }
    /**
     * Gets the program information to be emitted in buildInfo so that we can use it to create new program
     */
    function getProgramBuildInfo(state) {
        if (state.compilerOptions.outFile || state.compilerOptions.out)
            return undefined;
        var fileInfos = {};
        state.fileInfos.forEach(function (value, key) {
            var signature = state.currentAffectedFilesSignatures && state.currentAffectedFilesSignatures.get(key);
            fileInfos[key] = signature === undefined ? value : { version: value.version, signature: signature };
        });
        var result = { fileInfos: fileInfos, options: state.compilerOptions };
        if (state.referencedMap) {
            var referencedMap_1 = {};
            state.referencedMap.forEach(function (value, key) {
                referencedMap_1[key] = ts.arrayFrom(value.keys());
            });
            result.referencedMap = referencedMap_1;
        }
        if (state.exportedModulesMap) {
            var exportedModulesMap_1 = {};
            state.exportedModulesMap.forEach(function (value, key) {
                var newValue = state.currentAffectedFilesExportedModulesMap && state.currentAffectedFilesExportedModulesMap.get(key);
                // Not in temporary cache, use existing value
                if (newValue === undefined)
                    exportedModulesMap_1[key] = ts.arrayFrom(value.keys());
                // Value in cache and has updated value map, use that
                else if (newValue)
                    exportedModulesMap_1[key] = ts.arrayFrom(newValue.keys());
            });
            result.exportedModulesMap = exportedModulesMap_1;
        }
        if (state.semanticDiagnosticsPerFile) {
            var semanticDiagnosticsPerFile_1 = [];
            // Currently not recording actual errors since those mean no emit for tsc --build
            state.semanticDiagnosticsPerFile.forEach(function (value, key) { return semanticDiagnosticsPerFile_1.push(value.length ?
                [
                    key,
                    state.hasReusableDiagnostic ?
                        value :
                        convertToReusableDiagnostics(value)
                ] :
                key); });
            result.semanticDiagnosticsPerFile = semanticDiagnosticsPerFile_1;
        }
        return result;
    }
    function convertToReusableDiagnostics(diagnostics) {
        ts.Debug.assert(!!diagnostics.length);
        return diagnostics.map(function (diagnostic) {
            var result = convertToReusableDiagnosticRelatedInformation(diagnostic);
            result.reportsUnnecessary = diagnostic.reportsUnnecessary;
            result.source = diagnostic.source;
            var relatedInformation = diagnostic.relatedInformation;
            result.relatedInformation = relatedInformation ?
                relatedInformation.length ?
                    relatedInformation.map(function (r) { return convertToReusableDiagnosticRelatedInformation(r); }) :
                    ts.emptyArray :
                undefined;
            return result;
        });
    }
    function convertToReusableDiagnosticRelatedInformation(diagnostic) {
        var file = diagnostic.file, messageText = diagnostic.messageText;
        return __assign({}, diagnostic, { file: file && file.path, messageText: messageText === undefined || ts.isString(messageText) ?
                messageText :
                convertToReusableDiagnosticMessageChain(messageText) });
    }
    function convertToReusableDiagnosticMessageChain(diagnostic) {
        return __assign({}, diagnostic, { next: diagnostic.next && convertToReusableDiagnosticMessageChain(diagnostic.next) });
    }
    var BuilderProgramKind;
    (function (BuilderProgramKind) {
        BuilderProgramKind[BuilderProgramKind["SemanticDiagnosticsBuilderProgram"] = 0] = "SemanticDiagnosticsBuilderProgram";
        BuilderProgramKind[BuilderProgramKind["EmitAndSemanticDiagnosticsBuilderProgram"] = 1] = "EmitAndSemanticDiagnosticsBuilderProgram";
    })(BuilderProgramKind = ts.BuilderProgramKind || (ts.BuilderProgramKind = {}));
    function getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
        var host;
        var newProgram;
        var oldProgram;
        if (newProgramOrRootNames === undefined) {
            ts.Debug.assert(hostOrOptions === undefined);
            host = oldProgramOrHost;
            oldProgram = configFileParsingDiagnosticsOrOldProgram;
            ts.Debug.assert(!!oldProgram);
            newProgram = oldProgram.getProgram();
        }
        else if (ts.isArray(newProgramOrRootNames)) {
            oldProgram = configFileParsingDiagnosticsOrOldProgram;
            newProgram = ts.createProgram({
                rootNames: newProgramOrRootNames,
                options: hostOrOptions,
                host: oldProgramOrHost,
                oldProgram: oldProgram && oldProgram.getProgramOrUndefined(),
                configFileParsingDiagnostics: configFileParsingDiagnostics,
                projectReferences: projectReferences
            });
            host = oldProgramOrHost;
        }
        else {
            newProgram = newProgramOrRootNames;
            host = hostOrOptions;
            oldProgram = oldProgramOrHost;
            configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram;
        }
        return { host: host, newProgram: newProgram, oldProgram: oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || ts.emptyArray };
    }
    ts.getBuilderCreationParameters = getBuilderCreationParameters;
    function createBuilderProgram(kind, _a) {
        var newProgram = _a.newProgram, host = _a.host, oldProgram = _a.oldProgram, configFileParsingDiagnostics = _a.configFileParsingDiagnostics;
        // Return same program if underlying program doesnt change
        var oldState = oldProgram && oldProgram.getState();
        if (oldState && newProgram === oldState.program && configFileParsingDiagnostics === newProgram.getConfigFileParsingDiagnostics()) {
            newProgram = undefined; // TODO: GH#18217
            oldState = undefined;
            return oldProgram;
        }
        /**
         * Create the canonical file name for identity
         */
        var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames());
        /**
         * Computing hash to for signature verification
         */
        var computeHash = host.createHash || ts.generateDjb2Hash;
        var state = createBuilderProgramState(newProgram, getCanonicalFileName, oldState);
        var backupState;
        newProgram.getProgramBuildInfo = function () { return getProgramBuildInfo(state); };
        // To ensure that we arent storing any references to old program or new program without state
        newProgram = undefined; // TODO: GH#18217
        oldProgram = undefined;
        oldState = undefined;
        var result = createRedirectedBuilderProgram(state, configFileParsingDiagnostics);
        result.getState = function () { return state; };
        result.backupState = function () {
            ts.Debug.assert(backupState === undefined);
            backupState = cloneBuilderProgramState(state);
        };
        result.restoreState = function () {
            state = ts.Debug.assertDefined(backupState);
            backupState = undefined;
        };
        result.getAllDependencies = function (sourceFile) { return ts.BuilderState.getAllDependencies(state, ts.Debug.assertDefined(state.program), sourceFile); };
        result.getSemanticDiagnostics = getSemanticDiagnostics;
        result.emit = emit;
        result.releaseProgram = function () {
            releaseCache(state);
            backupState = undefined;
        };
        if (kind === BuilderProgramKind.SemanticDiagnosticsBuilderProgram) {
            result.getSemanticDiagnosticsOfNextAffectedFile = getSemanticDiagnosticsOfNextAffectedFile;
        }
        else if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) {
            result.emitNextAffectedFile = emitNextAffectedFile;
        }
        else {
            ts.notImplemented();
        }
        return result;
        /**
         * Emits the next affected file's emit result (EmitResult and sourceFiles emitted) or returns undefined if iteration is complete
         * The first of writeFile if provided, writeFile of BuilderProgramHost if provided, writeFile of compiler host
         * in that order would be used to write the files
         */
        function emitNextAffectedFile(writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) {
            var affected = getNextAffectedFile(state, cancellationToken, computeHash);
            var isPendingEmitFile = false;
            if (!affected) {
                if (!state.compilerOptions.out && !state.compilerOptions.outFile) {
                    affected = getNextAffectedFilePendingEmit(state);
                    if (!affected) {
                        if (state.emittedBuildInfo) {
                            return undefined;
                        }
                        var affected_1 = ts.Debug.assertDefined(state.program);
                        return toAffectedFileResult(state, 
                        // When whole program is affected, do emit only once (eg when --out or --outFile is specified)
                        // Otherwise just affected file
                        affected_1.emitBuildInfo(writeFile || ts.maybeBind(host, host.writeFile), cancellationToken), affected_1, 
                        /*isPendingEmitFile*/ false, 
                        /*isBuildInfoEmit*/ true);
                    }
                    isPendingEmitFile = true;
                }
                else {
                    var program = ts.Debug.assertDefined(state.program);
                    // Check if program uses any prepend project references, if thats the case we cant track of the js files of those, so emit even though there are no changes
                    if (state.programEmitComplete || !ts.some(program.getProjectReferences(), function (ref) { return !!ref.prepend; })) {
                        state.programEmitComplete = true;
                        return undefined;
                    }
                    affected = program;
                }
            }
            return toAffectedFileResult(state, 
            // When whole program is affected, do emit only once (eg when --out or --outFile is specified)
            // Otherwise just affected file
            ts.Debug.assertDefined(state.program).emit(affected === state.program ? undefined : affected, writeFile || ts.maybeBind(host, host.writeFile), cancellationToken, emitOnlyDtsFiles, customTransformers), affected, isPendingEmitFile);
        }
        /**
         * Emits the JavaScript and declaration files.
         * When targetSource file is specified, emits the files corresponding to that source file,
         * otherwise for the whole program.
         * In case of EmitAndSemanticDiagnosticsBuilderProgram, when targetSourceFile is specified,
         * it is assumed that that file is handled from affected file list. If targetSourceFile is not specified,
         * it will only emit all the affected files instead of whole program
         *
         * The first of writeFile if provided, writeFile of BuilderProgramHost if provided, writeFile of compiler host
         * in that order would be used to write the files
         */
        function emit(targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) {
            if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) {
                assertSourceFileOkWithoutNextAffectedCall(state, targetSourceFile);
                if (!targetSourceFile) {
                    // Emit and report any errors we ran into.
                    var sourceMaps = [];
                    var emitSkipped = false;
                    var diagnostics = void 0;
                    var emittedFiles = [];
                    var affectedEmitResult = void 0;
                    while (affectedEmitResult = emitNextAffectedFile(writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers)) {
                        emitSkipped = emitSkipped || affectedEmitResult.result.emitSkipped;
                        diagnostics = ts.addRange(diagnostics, affectedEmitResult.result.diagnostics);
                        emittedFiles = ts.addRange(emittedFiles, affectedEmitResult.result.emittedFiles);
                        sourceMaps = ts.addRange(sourceMaps, affectedEmitResult.result.sourceMaps);
                    }
                    return {
                        emitSkipped: emitSkipped,
                        diagnostics: diagnostics || ts.emptyArray,
                        emittedFiles: emittedFiles,
                        sourceMaps: sourceMaps
                    };
                }
            }
            return ts.Debug.assertDefined(state.program).emit(targetSourceFile, writeFile || ts.maybeBind(host, host.writeFile), cancellationToken, emitOnlyDtsFiles, customTransformers);
        }
        /**
         * Return the semantic diagnostics for the next affected file or undefined if iteration is complete
         * If provided ignoreSourceFile would be called before getting the diagnostics and would ignore the sourceFile if the returned value was true
         */
        function getSemanticDiagnosticsOfNextAffectedFile(cancellationToken, ignoreSourceFile) {
            while (true) {
                var affected = getNextAffectedFile(state, cancellationToken, computeHash);
                if (!affected) {
                    // Done
                    return undefined;
                }
                else if (affected === state.program) {
                    // When whole program is affected, get all semantic diagnostics (eg when --out or --outFile is specified)
                    return toAffectedFileResult(state, state.program.getSemanticDiagnostics(/*targetSourceFile*/ undefined, cancellationToken), affected);
                }
                // Get diagnostics for the affected file if its not ignored
                if (ignoreSourceFile && ignoreSourceFile(affected)) {
                    // Get next affected file
                    doneWithAffectedFile(state, affected);
                    continue;
                }
                return toAffectedFileResult(state, getSemanticDiagnosticsOfFile(state, affected, cancellationToken), affected);
            }
        }
        /**
         * Gets the semantic diagnostics from the program corresponding to this state of file (if provided) or whole program
         * The semantic diagnostics are cached and managed here
         * Note that it is assumed that when asked about semantic diagnostics through this API,
         * the file has been taken out of affected files so it is safe to use cache or get from program and cache the diagnostics
         * In case of SemanticDiagnosticsBuilderProgram if the source file is not provided,
         * it will iterate through all the affected files, to ensure that cache stays valid and yet provide a way to get all semantic diagnostics
         */
        function getSemanticDiagnostics(sourceFile, cancellationToken) {
            assertSourceFileOkWithoutNextAffectedCall(state, sourceFile);
            var compilerOptions = ts.Debug.assertDefined(state.program).getCompilerOptions();
            if (compilerOptions.outFile || compilerOptions.out) {
                ts.Debug.assert(!state.semanticDiagnosticsPerFile);
                // We dont need to cache the diagnostics just return them from program
                return ts.Debug.assertDefined(state.program).getSemanticDiagnostics(sourceFile, cancellationToken);
            }
            if (sourceFile) {
                return getSemanticDiagnosticsOfFile(state, sourceFile, cancellationToken);
            }
            // When semantic builder asks for diagnostics of the whole program,
            // ensure that all the affected files are handled
            var affected;
            var affectedFilesPendingEmit;
            while (affected = getNextAffectedFile(state, cancellationToken, computeHash)) {
                if (affected !== state.program && kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) {
                    (affectedFilesPendingEmit || (affectedFilesPendingEmit = [])).push(affected.path);
                }
                doneWithAffectedFile(state, affected);
            }
            // In case of emit builder, cache the files to be emitted
            if (affectedFilesPendingEmit) {
                addToAffectedFilesPendingEmit(state, affectedFilesPendingEmit);
            }
            var diagnostics;
            for (var _i = 0, _a = ts.Debug.assertDefined(state.program).getSourceFiles(); _i < _a.length; _i++) {
                var sourceFile_1 = _a[_i];
                diagnostics = ts.addRange(diagnostics, getSemanticDiagnosticsOfFile(state, sourceFile_1, cancellationToken));
            }
            return diagnostics || ts.emptyArray;
        }
    }
    ts.createBuilderProgram = createBuilderProgram;
    function addToAffectedFilesPendingEmit(state, affectedFilesPendingEmit) {
        state.affectedFilesPendingEmit = ts.concatenate(state.affectedFilesPendingEmit, affectedFilesPendingEmit);
        // affectedFilesPendingEmitIndex === undefined
        // - means the emit state.affectedFilesPendingEmit was undefined before adding current affected files
        //   so start from 0 as array would be affectedFilesPendingEmit
        // else, continue to iterate from existing index, the current set is appended to existing files
        if (state.affectedFilesPendingEmitIndex === undefined) {
            state.affectedFilesPendingEmitIndex = 0;
        }
    }
    function getMapOfReferencedSet(mapLike) {
        if (!mapLike)
            return undefined;
        var map = ts.createMap();
        // Copies keys/values from template. Note that for..in will not throw if
        // template is undefined, and instead will just exit the loop.
        for (var key in mapLike) {
            if (ts.hasProperty(mapLike, key)) {
                map.set(key, ts.arrayToSet(mapLike[key]));
            }
        }
        return map;
    }
    function createBuildProgramUsingProgramBuildInfo(program) {
        var fileInfos = ts.createMapFromTemplate(program.fileInfos);
        var state = {
            fileInfos: fileInfos,
            compilerOptions: program.options,
            referencedMap: getMapOfReferencedSet(program.referencedMap),
            exportedModulesMap: getMapOfReferencedSet(program.exportedModulesMap),
            semanticDiagnosticsPerFile: program.semanticDiagnosticsPerFile && ts.arrayToMap(program.semanticDiagnosticsPerFile, function (value) { return ts.isString(value) ? value : value[0]; }, function (value) { return ts.isString(value) ? ts.emptyArray : value[1]; }),
            hasReusableDiagnostic: true
        };
        return {
            getState: function () { return state; },
            backupState: ts.noop,
            restoreState: ts.noop,
            getProgram: ts.notImplemented,
            getProgramOrUndefined: ts.returnUndefined,
            releaseProgram: ts.noop,
            getCompilerOptions: function () { return state.compilerOptions; },
            getSourceFile: ts.notImplemented,
            getSourceFiles: ts.notImplemented,
            getOptionsDiagnostics: ts.notImplemented,
            getGlobalDiagnostics: ts.notImplemented,
            getConfigFileParsingDiagnostics: ts.notImplemented,
            getSyntacticDiagnostics: ts.notImplemented,
            getDeclarationDiagnostics: ts.notImplemented,
            getSemanticDiagnostics: ts.notImplemented,
            emit: ts.notImplemented,
            getAllDependencies: ts.notImplemented,
            getCurrentDirectory: ts.notImplemented,
            emitNextAffectedFile: ts.notImplemented,
            getSemanticDiagnosticsOfNextAffectedFile: ts.notImplemented,
        };
    }
    ts.createBuildProgramUsingProgramBuildInfo = createBuildProgramUsingProgramBuildInfo;
    function createRedirectedBuilderProgram(state, configFileParsingDiagnostics) {
        return {
            getState: ts.notImplemented,
            backupState: ts.noop,
            restoreState: ts.noop,
            getProgram: getProgram,
            getProgramOrUndefined: function () { return state.program; },
            releaseProgram: function () { return state.program = undefined; },
            getCompilerOptions: function () { return state.compilerOptions; },
            getSourceFile: function (fileName) { return getProgram().getSourceFile(fileName); },
            getSourceFiles: function () { return getProgram().getSourceFiles(); },
            getOptionsDiagnostics: function (cancellationToken) { return getProgram().getOptionsDiagnostics(cancellationToken); },
            getGlobalDiagnostics: function (cancellationToken) { return getProgram().getGlobalDiagnostics(cancellationToken); },
            getConfigFileParsingDiagnostics: function () { return configFileParsingDiagnostics; },
            getSyntacticDiagnostics: function (sourceFile, cancellationToken) { return getProgram().getSyntacticDiagnostics(sourceFile, cancellationToken); },
            getDeclarationDiagnostics: function (sourceFile, cancellationToken) { return getProgram().getDeclarationDiagnostics(sourceFile, cancellationToken); },
            getSemanticDiagnostics: function (sourceFile, cancellationToken) { return getProgram().getSemanticDiagnostics(sourceFile, cancellationToken); },
            emit: function (sourceFile, writeFile, cancellationToken, emitOnlyDts, customTransformers) { return getProgram().emit(sourceFile, writeFile, cancellationToken, emitOnlyDts, customTransformers); },
            getAllDependencies: ts.notImplemented,
            getCurrentDirectory: function () { return getProgram().getCurrentDirectory(); },
        };
        function getProgram() {
            return ts.Debug.assertDefined(state.program);
        }
    }
    ts.createRedirectedBuilderProgram = createRedirectedBuilderProgram;
})(ts || (ts = {}));
(function (ts) {
    function createSemanticDiagnosticsBuilderProgram(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
        return ts.createBuilderProgram(ts.BuilderProgramKind.SemanticDiagnosticsBuilderProgram, ts.getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences));
    }
    ts.createSemanticDiagnosticsBuilderProgram = createSemanticDiagnosticsBuilderProgram;
    function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
        return ts.createBuilderProgram(ts.BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, ts.getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences));
    }
    ts.createEmitAndSemanticDiagnosticsBuilderProgram = createEmitAndSemanticDiagnosticsBuilderProgram;
    function createAbstractBuilder(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
        var _a = ts.getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences), newProgram = _a.newProgram, newConfigFileParsingDiagnostics = _a.configFileParsingDiagnostics;
        return ts.createRedirectedBuilderProgram({ program: newProgram, compilerOptions: newProgram.getCompilerOptions() }, newConfigFileParsingDiagnostics);
    }
    ts.createAbstractBuilder = createAbstractBuilder;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function isPathIgnored(path) {
        return ts.some(ts.ignoredPaths, function (searchPath) { return ts.stringContains(path, searchPath); });
    }
    ts.isPathIgnored = isPathIgnored;
    ts.maxNumberOfFilesToIterateForInvalidation = 256;
    function createResolutionCache(resolutionHost, rootDirForResolution, logChangesWhenResolvingModule) {
        var filesWithChangedSetOfUnresolvedImports;
        var filesWithInvalidatedResolutions;
        var filesWithInvalidatedNonRelativeUnresolvedImports;
        var allFilesHaveInvalidatedResolution = false;
        var nonRelativeExternalModuleResolutions = ts.createMultiMap();
        var getCurrentDirectory = ts.memoize(function () { return resolutionHost.getCurrentDirectory(); }); // TODO: GH#18217
        var cachedDirectoryStructureHost = resolutionHost.getCachedDirectoryStructureHost();
        // The resolvedModuleNames and resolvedTypeReferenceDirectives are the cache of resolutions per file.
        // The key in the map is source file's path.
        // The values are Map of resolutions with key being name lookedup.
        var resolvedModuleNames = ts.createMap();
        var perDirectoryResolvedModuleNames = ts.createCacheWithRedirects();
        var nonRelativeModuleNameCache = ts.createCacheWithRedirects();
        var moduleResolutionCache = ts.createModuleResolutionCacheWithMaps(perDirectoryResolvedModuleNames, nonRelativeModuleNameCache, getCurrentDirectory(), resolutionHost.getCanonicalFileName);
        var resolvedTypeReferenceDirectives = ts.createMap();
        var perDirectoryResolvedTypeReferenceDirectives = ts.createCacheWithRedirects();
        /**
         * These are the extensions that failed lookup files will have by default,
         * any other extension of failed lookup will be store that path in custom failed lookup path
         * This helps in not having to comb through all resolutions when files are added/removed
         * Note that .d.ts file also has .d.ts extension hence will be part of default extensions
         */
        var failedLookupDefaultExtensions = [".ts" /* Ts */, ".tsx" /* Tsx */, ".js" /* Js */, ".jsx" /* Jsx */, ".json" /* Json */];
        var customFailedLookupPaths = ts.createMap();
        var directoryWatchesOfFailedLookups = ts.createMap();
        var rootDir = rootDirForResolution && ts.removeTrailingDirectorySeparator(ts.getNormalizedAbsolutePath(rootDirForResolution, getCurrentDirectory()));
        var rootPath = (rootDir && resolutionHost.toPath(rootDir)); // TODO: GH#18217
        // TypeRoot watches for the types that get added as part of getAutomaticTypeDirectiveNames
        var typeRootsWatches = ts.createMap();
        return {
            startRecordingFilesWithChangedResolutions: startRecordingFilesWithChangedResolutions,
            finishRecordingFilesWithChangedResolutions: finishRecordingFilesWithChangedResolutions,
            // perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
            // (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution)
            startCachingPerDirectoryResolution: clearPerDirectoryResolutions,
            finishCachingPerDirectoryResolution: finishCachingPerDirectoryResolution,
            resolveModuleNames: resolveModuleNames,
            getResolvedModuleWithFailedLookupLocationsFromCache: getResolvedModuleWithFailedLookupLocationsFromCache,
            resolveTypeReferenceDirectives: resolveTypeReferenceDirectives,
            removeResolutionsFromProjectReferenceRedirects: removeResolutionsFromProjectReferenceRedirects,
            removeResolutionsOfFile: removeResolutionsOfFile,
            invalidateResolutionOfFile: invalidateResolutionOfFile,
            setFilesWithInvalidatedNonRelativeUnresolvedImports: setFilesWithInvalidatedNonRelativeUnresolvedImports,
            createHasInvalidatedResolution: createHasInvalidatedResolution,
            updateTypeRootsWatch: updateTypeRootsWatch,
            closeTypeRootsWatch: closeTypeRootsWatch,
            clear: clear
        };
        function getResolvedModule(resolution) {
            return resolution.resolvedModule;
        }
        function getResolvedTypeReferenceDirective(resolution) {
            return resolution.resolvedTypeReferenceDirective;
        }
        function isInDirectoryPath(dir, file) {
            if (dir === undefined || file.length <= dir.length) {
                return false;
            }
            return ts.startsWith(file, dir) && file[dir.length] === ts.directorySeparator;
        }
        function clear() {
            ts.clearMap(directoryWatchesOfFailedLookups, ts.closeFileWatcherOf);
            customFailedLookupPaths.clear();
            nonRelativeExternalModuleResolutions.clear();
            closeTypeRootsWatch();
            resolvedModuleNames.clear();
            resolvedTypeReferenceDirectives.clear();
            allFilesHaveInvalidatedResolution = false;
            // perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
            // (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution)
            clearPerDirectoryResolutions();
        }
        function startRecordingFilesWithChangedResolutions() {
            filesWithChangedSetOfUnresolvedImports = [];
        }
        function finishRecordingFilesWithChangedResolutions() {
            var collected = filesWithChangedSetOfUnresolvedImports;
            filesWithChangedSetOfUnresolvedImports = undefined;
            return collected;
        }
        function isFileWithInvalidatedNonRelativeUnresolvedImports(path) {
            if (!filesWithInvalidatedNonRelativeUnresolvedImports) {
                return false;
            }
            // Invalidated if file has unresolved imports
            var value = filesWithInvalidatedNonRelativeUnresolvedImports.get(path);
            return !!value && !!value.length;
        }
        function createHasInvalidatedResolution(forceAllFilesAsInvalidated) {
            if (allFilesHaveInvalidatedResolution || forceAllFilesAsInvalidated) {
                // Any file asked would have invalidated resolution
                filesWithInvalidatedResolutions = undefined;
                return ts.returnTrue;
            }
            var collected = filesWithInvalidatedResolutions;
            filesWithInvalidatedResolutions = undefined;
            return function (path) { return (!!collected && collected.has(path)) ||
                isFileWithInvalidatedNonRelativeUnresolvedImports(path); };
        }
        function clearPerDirectoryResolutions() {
            perDirectoryResolvedModuleNames.clear();
            nonRelativeModuleNameCache.clear();
            perDirectoryResolvedTypeReferenceDirectives.clear();
            nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions);
            nonRelativeExternalModuleResolutions.clear();
        }
        function finishCachingPerDirectoryResolution() {
            allFilesHaveInvalidatedResolution = false;
            filesWithInvalidatedNonRelativeUnresolvedImports = undefined;
            clearPerDirectoryResolutions();
            directoryWatchesOfFailedLookups.forEach(function (watcher, path) {
                if (watcher.refCount === 0) {
                    directoryWatchesOfFailedLookups.delete(path);
                    watcher.watcher.close();
                }
            });
        }
        function resolveModuleName(moduleName, containingFile, compilerOptions, host, redirectedReference) {
            var primaryResult = ts.resolveModuleName(moduleName, containingFile, compilerOptions, host, moduleResolutionCache, redirectedReference);
            // return result immediately only if global cache support is not enabled or if it is .ts, .tsx or .d.ts
            if (!resolutionHost.getGlobalCache) {
                return primaryResult;
            }
            // otherwise try to load typings from @types
            var globalCache = resolutionHost.getGlobalCache();
            if (globalCache !== undefined && !ts.isExternalModuleNameRelative(moduleName) && !(primaryResult.resolvedModule && ts.extensionIsTS(primaryResult.resolvedModule.extension))) {
                // create different collection of failed lookup locations for second pass
                // if it will fail and we've already found something during the first pass - we don't want to pollute its results
                var _a = ts.loadModuleFromGlobalCache(moduleName, resolutionHost.projectName, compilerOptions, host, globalCache), resolvedModule = _a.resolvedModule, failedLookupLocations = _a.failedLookupLocations;
                if (resolvedModule) {
                    return { resolvedModule: resolvedModule, failedLookupLocations: ts.addRange(primaryResult.failedLookupLocations, failedLookupLocations) };
                }
            }
            // Default return the result from the first pass
            return primaryResult;
        }
        function resolveNamesWithLocalCache(names, containingFile, redirectedReference, cache, perDirectoryCacheWithRedirects, loader, getResolutionWithResolvedFileName, shouldRetryResolution, reusedNames, logChanges) {
            var path = resolutionHost.toPath(containingFile);
            var resolutionsInFile = cache.get(path) || cache.set(path, ts.createMap()).get(path);
            var dirPath = ts.getDirectoryPath(path);
            var perDirectoryCache = perDirectoryCacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference);
            var perDirectoryResolution = perDirectoryCache.get(dirPath);
            if (!perDirectoryResolution) {
                perDirectoryResolution = ts.createMap();
                perDirectoryCache.set(dirPath, perDirectoryResolution);
            }
            var resolvedModules = [];
            var compilerOptions = resolutionHost.getCompilationSettings();
            var hasInvalidatedNonRelativeUnresolvedImport = logChanges && isFileWithInvalidatedNonRelativeUnresolvedImports(path);
            // All the resolutions in this file are invalidated if this file wasnt resolved using same redirect
            var program = resolutionHost.getCurrentProgram();
            var oldRedirect = program && program.getResolvedProjectReferenceToRedirect(containingFile);
            var unmatchedRedirects = oldRedirect ?
                !redirectedReference || redirectedReference.sourceFile.path !== oldRedirect.sourceFile.path :
                !!redirectedReference;
            var seenNamesInFile = ts.createMap();
            for (var _i = 0, names_2 = names; _i < names_2.length; _i++) {
                var name = names_2[_i];
                var resolution = resolutionsInFile.get(name);
                // Resolution is valid if it is present and not invalidated
                if (!seenNamesInFile.has(name) &&
                    allFilesHaveInvalidatedResolution || unmatchedRedirects || !resolution || resolution.isInvalidated ||
                    // If the name is unresolved import that was invalidated, recalculate
                    (hasInvalidatedNonRelativeUnresolvedImport && !ts.isExternalModuleNameRelative(name) && shouldRetryResolution(resolution))) {
                    var existingResolution = resolution;
                    var resolutionInDirectory = perDirectoryResolution.get(name);
                    if (resolutionInDirectory) {
                        resolution = resolutionInDirectory;
                    }
                    else {
                        resolution = loader(name, containingFile, compilerOptions, resolutionHost, redirectedReference);
                        perDirectoryResolution.set(name, resolution);
                    }
                    resolutionsInFile.set(name, resolution);
                    watchFailedLookupLocationsOfExternalModuleResolutions(name, resolution);
                    if (existingResolution) {
                        stopWatchFailedLookupLocationOfResolution(existingResolution);
                    }
                    if (logChanges && filesWithChangedSetOfUnresolvedImports && !resolutionIsEqualTo(existingResolution, resolution)) {
                        filesWithChangedSetOfUnresolvedImports.push(path);
                        // reset log changes to avoid recording the same file multiple times
                        logChanges = false;
                    }
                }
                ts.Debug.assert(resolution !== undefined && !resolution.isInvalidated);
                seenNamesInFile.set(name, true);
                resolvedModules.push(getResolutionWithResolvedFileName(resolution));
            }
            // Stop watching and remove the unused name
            resolutionsInFile.forEach(function (resolution, name) {
                if (!seenNamesInFile.has(name) && !ts.contains(reusedNames, name)) {
                    stopWatchFailedLookupLocationOfResolution(resolution);
                    resolutionsInFile.delete(name);
                }
            });
            return resolvedModules;
            function resolutionIsEqualTo(oldResolution, newResolution) {
                if (oldResolution === newResolution) {
                    return true;
                }
                if (!oldResolution || !newResolution) {
                    return false;
                }
                var oldResult = getResolutionWithResolvedFileName(oldResolution);
                var newResult = getResolutionWithResolvedFileName(newResolution);
                if (oldResult === newResult) {
                    return true;
                }
                if (!oldResult || !newResult) {
                    return false;
                }
                return oldResult.resolvedFileName === newResult.resolvedFileName;
            }
        }
        function resolveTypeReferenceDirectives(typeDirectiveNames, containingFile, redirectedReference) {
            return resolveNamesWithLocalCache(typeDirectiveNames, containingFile, redirectedReference, resolvedTypeReferenceDirectives, perDirectoryResolvedTypeReferenceDirectives, ts.resolveTypeReferenceDirective, getResolvedTypeReferenceDirective, 
            /*shouldRetryResolution*/ function (resolution) { return resolution.resolvedTypeReferenceDirective === undefined; }, 
            /*reusedNames*/ undefined, /*logChanges*/ false);
        }
        function resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference) {
            return resolveNamesWithLocalCache(moduleNames, containingFile, redirectedReference, resolvedModuleNames, perDirectoryResolvedModuleNames, resolveModuleName, getResolvedModule, 
            /*shouldRetryResolution*/ function (resolution) { return !resolution.resolvedModule || !ts.resolutionExtensionIsTSOrJson(resolution.resolvedModule.extension); }, reusedNames, logChangesWhenResolvingModule);
        }
        function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName, containingFile) {
            var cache = resolvedModuleNames.get(resolutionHost.toPath(containingFile));
            return cache && cache.get(moduleName);
        }
        function isNodeModulesDirectory(dirPath) {
            return ts.endsWith(dirPath, "/node_modules");
        }
        function isNodeModulesAtTypesDirectory(dirPath) {
            return ts.endsWith(dirPath, "/node_modules/@types");
        }
        /**
         * Filter out paths like
         * "/", "/user", "/user/username", "/user/username/folderAtRoot",
         * "c:/", "c:/users", "c:/users/username", "c:/users/username/folderAtRoot", "c:/folderAtRoot"
         * @param dirPath
         */
        function canWatchDirectory(dirPath) {
            var rootLength = ts.getRootLength(dirPath);
            if (dirPath.length === rootLength) {
                // Ignore "/", "c:/"
                return false;
            }
            var nextDirectorySeparator = dirPath.indexOf(ts.directorySeparator, rootLength);
            if (nextDirectorySeparator === -1) {
                // ignore "/user", "c:/users" or "c:/folderAtRoot"
                return false;
            }
            if (dirPath.charCodeAt(0) !== 47 /* slash */ &&
                dirPath.substr(rootLength, nextDirectorySeparator).search(/users/i) === -1) {
                // Paths like c:/folderAtRoot/subFolder are allowed
                return true;
            }
            for (var searchIndex = nextDirectorySeparator + 1, searchLevels = 2; searchLevels > 0; searchLevels--) {
                searchIndex = dirPath.indexOf(ts.directorySeparator, searchIndex) + 1;
                if (searchIndex === 0) {
                    // Folder isnt at expected minimun levels
                    return false;
                }
            }
            return true;
        }
        function getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath) {
            if (isInDirectoryPath(rootPath, failedLookupLocationPath)) {
                // Ensure failed look up is normalized path
                failedLookupLocation = ts.isRootedDiskPath(failedLookupLocation) ? ts.normalizePath(failedLookupLocation) : ts.getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory());
                ts.Debug.assert(failedLookupLocation.length === failedLookupLocationPath.length, "FailedLookup: " + failedLookupLocation + " failedLookupLocationPath: " + failedLookupLocationPath); // tslint:disable-line
                var subDirectoryInRoot = failedLookupLocationPath.indexOf(ts.directorySeparator, rootPath.length + 1);
                if (subDirectoryInRoot !== -1) {
                    // Instead of watching root, watch directory in root to avoid watching excluded directories not needed for module resolution
                    return { dir: failedLookupLocation.substr(0, subDirectoryInRoot), dirPath: failedLookupLocationPath.substr(0, subDirectoryInRoot) };
                }
                else {
                    // Always watch root directory non recursively
                    return { dir: rootDir, dirPath: rootPath, nonRecursive: false }; // TODO: GH#18217
                }
            }
            return getDirectoryToWatchFromFailedLookupLocationDirectory(ts.getDirectoryPath(ts.getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory())), ts.getDirectoryPath(failedLookupLocationPath));
        }
        function getDirectoryToWatchFromFailedLookupLocationDirectory(dir, dirPath) {
            // If directory path contains node module, get the most parent node_modules directory for watching
            while (ts.pathContainsNodeModules(dirPath)) {
                dir = ts.getDirectoryPath(dir);
                dirPath = ts.getDirectoryPath(dirPath);
            }
            // If the directory is node_modules use it to watch, always watch it recursively
            if (isNodeModulesDirectory(dirPath)) {
                return canWatchDirectory(ts.getDirectoryPath(dirPath)) ? { dir: dir, dirPath: dirPath } : undefined;
            }
            var nonRecursive = true;
            // Use some ancestor of the root directory
            var subDirectoryPath, subDirectory;
            if (rootPath !== undefined) {
                while (!isInDirectoryPath(dirPath, rootPath)) {
                    var parentPath = ts.getDirectoryPath(dirPath);
                    if (parentPath === dirPath) {
                        break;
                    }
                    nonRecursive = false;
                    subDirectoryPath = dirPath;
                    subDirectory = dir;
                    dirPath = parentPath;
                    dir = ts.getDirectoryPath(dir);
                }
            }
            return canWatchDirectory(dirPath) ? { dir: subDirectory || dir, dirPath: subDirectoryPath || dirPath, nonRecursive: nonRecursive } : undefined;
        }
        function isPathWithDefaultFailedLookupExtension(path) {
            return ts.fileExtensionIsOneOf(path, failedLookupDefaultExtensions);
        }
        function watchFailedLookupLocationsOfExternalModuleResolutions(name, resolution) {
            // No need to set the resolution refCount
            if (resolution.failedLookupLocations && resolution.failedLookupLocations.length) {
                if (resolution.refCount) {
                    resolution.refCount++;
                }
                else {
                    resolution.refCount = 1;
                    if (ts.isExternalModuleNameRelative(name)) {
                        watchFailedLookupLocationOfResolution(resolution);
                    }
                    else {
                        nonRelativeExternalModuleResolutions.add(name, resolution);
                    }
                }
            }
        }
        function watchFailedLookupLocationOfResolution(resolution) {
            ts.Debug.assert(!!resolution.refCount);
            var failedLookupLocations = resolution.failedLookupLocations;
            var setAtRoot = false;
            for (var _i = 0, failedLookupLocations_1 = failedLookupLocations; _i < failedLookupLocations_1.length; _i++) {
                var failedLookupLocation = failedLookupLocations_1[_i];
                var failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
                var toWatch = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
                if (toWatch) {
                    var dir = toWatch.dir, dirPath = toWatch.dirPath, nonRecursive = toWatch.nonRecursive;
                    // If the failed lookup location path is not one of the supported extensions,
                    // store it in the custom path
                    if (!isPathWithDefaultFailedLookupExtension(failedLookupLocationPath)) {
                        var refCount = customFailedLookupPaths.get(failedLookupLocationPath) || 0;
                        customFailedLookupPaths.set(failedLookupLocationPath, refCount + 1);
                    }
                    if (dirPath === rootPath) {
                        ts.Debug.assert(!nonRecursive);
                        setAtRoot = true;
                    }
                    else {
                        setDirectoryWatcher(dir, dirPath, nonRecursive);
                    }
                }
            }
            if (setAtRoot) {
                // This is always non recursive
                setDirectoryWatcher(rootDir, rootPath, /*nonRecursive*/ true); // TODO: GH#18217
            }
        }
        function setRefCountToUndefined(resolution) {
            resolution.refCount = undefined;
        }
        function watchFailedLookupLocationOfNonRelativeModuleResolutions(resolutions, name) {
            var program = resolutionHost.getCurrentProgram();
            var updateResolution = program && program.getTypeChecker().tryFindAmbientModuleWithoutAugmentations(name) ?
                setRefCountToUndefined : watchFailedLookupLocationOfResolution;
            resolutions.forEach(updateResolution);
        }
        function setDirectoryWatcher(dir, dirPath, nonRecursive) {
            var dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
            if (dirWatcher) {
                ts.Debug.assert(!!nonRecursive === !!dirWatcher.nonRecursive);
                dirWatcher.refCount++;
            }
            else {
                directoryWatchesOfFailedLookups.set(dirPath, { watcher: createDirectoryWatcher(dir, dirPath, nonRecursive), refCount: 1, nonRecursive: nonRecursive });
            }
        }
        function stopWatchFailedLookupLocationOfResolution(resolution) {
            if (!resolution.refCount) {
                return;
            }
            resolution.refCount--;
            if (resolution.refCount) {
                return;
            }
            var failedLookupLocations = resolution.failedLookupLocations;
            var removeAtRoot = false;
            for (var _i = 0, failedLookupLocations_2 = failedLookupLocations; _i < failedLookupLocations_2.length; _i++) {
                var failedLookupLocation = failedLookupLocations_2[_i];
                var failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
                var toWatch = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
                if (toWatch) {
                    var dirPath = toWatch.dirPath;
                    var refCount = customFailedLookupPaths.get(failedLookupLocationPath);
                    if (refCount) {
                        if (refCount === 1) {
                            customFailedLookupPaths.delete(failedLookupLocationPath);
                        }
                        else {
                            ts.Debug.assert(refCount > 1);
                            customFailedLookupPaths.set(failedLookupLocationPath, refCount - 1);
                        }
                    }
                    if (dirPath === rootPath) {
                        removeAtRoot = true;
                    }
                    else {
                        removeDirectoryWatcher(dirPath);
                    }
                }
            }
            if (removeAtRoot) {
                removeDirectoryWatcher(rootPath);
            }
        }
        function removeDirectoryWatcher(dirPath) {
            var dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
            // Do not close the watcher yet since it might be needed by other failed lookup locations.
            dirWatcher.refCount--;
        }
        function createDirectoryWatcher(directory, dirPath, nonRecursive) {
            return resolutionHost.watchDirectoryOfFailedLookupLocation(directory, function (fileOrDirectory) {
                var fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory);
                if (cachedDirectoryStructureHost) {
                    // Since the file existence changed, update the sourceFiles cache
                    cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
                }
                if (!allFilesHaveInvalidatedResolution && invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, dirPath === fileOrDirectoryPath)) {
                    resolutionHost.onInvalidatedResolution();
                }
            }, nonRecursive ? 0 /* None */ : 1 /* Recursive */);
        }
        function removeResolutionsOfFileFromCache(cache, filePath) {
            // Deleted file, stop watching failed lookups for all the resolutions in the file
            var resolutions = cache.get(filePath);
            if (resolutions) {
                resolutions.forEach(stopWatchFailedLookupLocationOfResolution);
                cache.delete(filePath);
            }
        }
        function removeResolutionsFromProjectReferenceRedirects(filePath) {
            if (!ts.fileExtensionIs(filePath, ".json" /* Json */)) {
                return;
            }
            var program = resolutionHost.getCurrentProgram();
            if (!program) {
                return;
            }
            // If this file is input file for the referenced project, get it
            var resolvedProjectReference = program.getResolvedProjectReferenceByPath(filePath);
            if (!resolvedProjectReference) {
                return;
            }
            // filePath is for the projectReference and the containing file is from this project reference, invalidate the resolution
            resolvedProjectReference.commandLine.fileNames.forEach(function (f) { return removeResolutionsOfFile(resolutionHost.toPath(f)); });
        }
        function removeResolutionsOfFile(filePath) {
            removeResolutionsOfFileFromCache(resolvedModuleNames, filePath);
            removeResolutionsOfFileFromCache(resolvedTypeReferenceDirectives, filePath);
        }
        function invalidateResolutionCache(cache, isInvalidatedResolution, getResolutionWithResolvedFileName) {
            var seen = ts.createMap();
            cache.forEach(function (resolutions, containingFilePath) {
                var dirPath = ts.getDirectoryPath(containingFilePath);
                var seenInDir = seen.get(dirPath);
                if (!seenInDir) {
                    seenInDir = ts.createMap();
                    seen.set(dirPath, seenInDir);
                }
                resolutions.forEach(function (resolution, name) {
                    if (seenInDir.has(name)) {
                        return;
                    }
                    seenInDir.set(name, true);
                    if (!resolution.isInvalidated && isInvalidatedResolution(resolution, getResolutionWithResolvedFileName)) {
                        // Mark the file as needing re-evaluation of module resolution instead of using it blindly.
                        resolution.isInvalidated = true;
                        (filesWithInvalidatedResolutions || (filesWithInvalidatedResolutions = ts.createMap())).set(containingFilePath, true);
                    }
                });
            });
        }
        function hasReachedResolutionIterationLimit() {
            var maxSize = resolutionHost.maxNumberOfFilesToIterateForInvalidation || ts.maxNumberOfFilesToIterateForInvalidation;
            return resolvedModuleNames.size > maxSize || resolvedTypeReferenceDirectives.size > maxSize;
        }
        function invalidateResolutions(isInvalidatedResolution) {
            // If more than maxNumberOfFilesToIterateForInvalidation present,
            // just invalidated all files and recalculate the resolutions for files instead
            if (hasReachedResolutionIterationLimit()) {
                allFilesHaveInvalidatedResolution = true;
                return;
            }
            invalidateResolutionCache(resolvedModuleNames, isInvalidatedResolution, getResolvedModule);
            invalidateResolutionCache(resolvedTypeReferenceDirectives, isInvalidatedResolution, getResolvedTypeReferenceDirective);
        }
        function invalidateResolutionOfFile(filePath) {
            removeResolutionsOfFile(filePath);
            invalidateResolutions(
            // Resolution is invalidated if the resulting file name is same as the deleted file path
            function (resolution, getResolutionWithResolvedFileName) {
                var result = getResolutionWithResolvedFileName(resolution);
                return !!result && resolutionHost.toPath(result.resolvedFileName) === filePath; // TODO: GH#18217
            });
        }
        function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap) {
            ts.Debug.assert(filesWithInvalidatedNonRelativeUnresolvedImports === filesMap || filesWithInvalidatedNonRelativeUnresolvedImports === undefined);
            filesWithInvalidatedNonRelativeUnresolvedImports = filesMap;
        }
        function invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, isCreatingWatchedDirectory) {
            var isChangedFailedLookupLocation;
            if (isCreatingWatchedDirectory) {
                // Watching directory is created
                // Invalidate any resolution has failed lookup in this directory
                isChangedFailedLookupLocation = function (location) { return isInDirectoryPath(fileOrDirectoryPath, resolutionHost.toPath(location)); };
            }
            else {
                // If something to do with folder/file starting with "." in node_modules folder, skip it
                if (isPathIgnored(fileOrDirectoryPath))
                    return false;
                // prevent saving an open file from over-eagerly triggering invalidation
                if (resolutionHost.fileIsOpen(fileOrDirectoryPath)) {
                    return false;
                }
                // Some file or directory in the watching directory is created
                // Return early if it does not have any of the watching extension or not the custom failed lookup path
                var dirOfFileOrDirectory = ts.getDirectoryPath(fileOrDirectoryPath);
                if (isNodeModulesAtTypesDirectory(fileOrDirectoryPath) || isNodeModulesDirectory(fileOrDirectoryPath) ||
                    isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) {
                    // Invalidate any resolution from this directory
                    isChangedFailedLookupLocation = function (location) {
                        var locationPath = resolutionHost.toPath(location);
                        return locationPath === fileOrDirectoryPath || ts.startsWith(resolutionHost.toPath(location), fileOrDirectoryPath);
                    };
                }
                else {
                    if (!isPathWithDefaultFailedLookupExtension(fileOrDirectoryPath) && !customFailedLookupPaths.has(fileOrDirectoryPath)) {
                        return false;
                    }
                    // Ignore emits from the program
                    if (ts.isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectoryPath)) {
                        return false;
                    }
                    // Resolution need to be invalidated if failed lookup location is same as the file or directory getting created
                    isChangedFailedLookupLocation = function (location) { return resolutionHost.toPath(location) === fileOrDirectoryPath; };
                }
            }
            var hasChangedFailedLookupLocation = function (resolution) { return ts.some(resolution.failedLookupLocations, isChangedFailedLookupLocation); };
            var invalidatedFilesCount = filesWithInvalidatedResolutions && filesWithInvalidatedResolutions.size;
            invalidateResolutions(
            // Resolution is invalidated if the resulting file name is same as the deleted file path
            hasChangedFailedLookupLocation);
            return allFilesHaveInvalidatedResolution || filesWithInvalidatedResolutions && filesWithInvalidatedResolutions.size !== invalidatedFilesCount;
        }
        function closeTypeRootsWatch() {
            ts.clearMap(typeRootsWatches, ts.closeFileWatcher);
        }
        function getDirectoryToWatchFailedLookupLocationFromTypeRoot(typeRoot, typeRootPath) {
            if (allFilesHaveInvalidatedResolution) {
                return undefined;
            }
            if (isInDirectoryPath(rootPath, typeRootPath)) {
                return rootPath;
            }
            var toWatch = getDirectoryToWatchFromFailedLookupLocationDirectory(typeRoot, typeRootPath);
            return toWatch && directoryWatchesOfFailedLookups.has(toWatch.dirPath) ? toWatch.dirPath : undefined;
        }
        function createTypeRootsWatch(typeRootPath, typeRoot) {
            // Create new watch and recursive info
            return resolutionHost.watchTypeRootsDirectory(typeRoot, function (fileOrDirectory) {
                var fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory);
                if (cachedDirectoryStructureHost) {
                    // Since the file existence changed, update the sourceFiles cache
                    cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
                }
                // For now just recompile
                // We could potentially store more data here about whether it was/would be really be used or not
                // and with that determine to trigger compilation but for now this is enough
                resolutionHost.onChangedAutomaticTypeDirectiveNames();
                // Since directory watchers invoked are flaky, the failed lookup location events might not be triggered
                // So handle to failed lookup locations here as well to ensure we are invalidating resolutions
                var dirPath = getDirectoryToWatchFailedLookupLocationFromTypeRoot(typeRoot, typeRootPath);
                if (dirPath && invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, dirPath === fileOrDirectoryPath)) {
                    resolutionHost.onInvalidatedResolution();
                }
            }, 1 /* Recursive */);
        }
        /**
         * Watches the types that would get added as part of getAutomaticTypeDirectiveNames
         * To be called when compiler options change
         */
        function updateTypeRootsWatch() {
            var options = resolutionHost.getCompilationSettings();
            if (options.types) {
                // No need to do any watch since resolution cache is going to handle the failed lookups
                // for the types added by this
                closeTypeRootsWatch();
                return;
            }
            // we need to assume the directories exist to ensure that we can get all the type root directories that get included
            // But filter directories that are at root level to say directory doesnt exist, so that we arent watching them
            var typeRoots = ts.getEffectiveTypeRoots(options, { directoryExists: directoryExistsForTypeRootWatch, getCurrentDirectory: getCurrentDirectory });
            if (typeRoots) {
                ts.mutateMap(typeRootsWatches, ts.arrayToMap(typeRoots, function (tr) { return resolutionHost.toPath(tr); }), {
                    createNewValue: createTypeRootsWatch,
                    onDeleteValue: ts.closeFileWatcher
                });
            }
            else {
                closeTypeRootsWatch();
            }
        }
        /**
         * Use this function to return if directory exists to get type roots to watch
         * If we return directory exists then only the paths will be added to type roots
         * Hence return true for all directories except root directories which are filtered from watching
         */
        function directoryExistsForTypeRootWatch(nodeTypesDirectory) {
            var dir = ts.getDirectoryPath(ts.getDirectoryPath(nodeTypesDirectory));
            var dirPath = resolutionHost.toPath(dir);
            return dirPath === rootPath || canWatchDirectory(dirPath);
        }
    }
    ts.createResolutionCache = createResolutionCache;
})(ts || (ts = {}));
// Used by importFixes, getEditsForFileRename, and declaration emit to synthesize import module specifiers.
/* @internal */
var ts;
(function (ts) {
    var moduleSpecifiers;
    (function (moduleSpecifiers) {
        var RelativePreference;
        (function (RelativePreference) {
            RelativePreference[RelativePreference["Relative"] = 0] = "Relative";
            RelativePreference[RelativePreference["NonRelative"] = 1] = "NonRelative";
            RelativePreference[RelativePreference["Auto"] = 2] = "Auto";
        })(RelativePreference || (RelativePreference = {}));
        // See UserPreferences#importPathEnding
        var Ending;
        (function (Ending) {
            Ending[Ending["Minimal"] = 0] = "Minimal";
            Ending[Ending["Index"] = 1] = "Index";
            Ending[Ending["JsExtension"] = 2] = "JsExtension";
        })(Ending || (Ending = {}));
        function getPreferences(_a, compilerOptions, importingSourceFile) {
            var importModuleSpecifierPreference = _a.importModuleSpecifierPreference, importModuleSpecifierEnding = _a.importModuleSpecifierEnding;
            return {
                relativePreference: importModuleSpecifierPreference === "relative" ? 0 /* Relative */ : importModuleSpecifierPreference === "non-relative" ? 1 /* NonRelative */ : 2 /* Auto */,
                ending: getEnding(),
            };
            function getEnding() {
                switch (importModuleSpecifierEnding) {
                    case "minimal": return 0 /* Minimal */;
                    case "index": return 1 /* Index */;
                    case "js": return 2 /* JsExtension */;
                    default: return usesJsExtensionOnImports(importingSourceFile) ? 2 /* JsExtension */
                        : ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.NodeJs ? 1 /* Index */ : 0 /* Minimal */;
                }
            }
        }
        function getPreferencesForUpdate(compilerOptions, oldImportSpecifier) {
            return {
                relativePreference: ts.isExternalModuleNameRelative(oldImportSpecifier) ? 0 /* Relative */ : 1 /* NonRelative */,
                ending: ts.hasJSOrJsonFileExtension(oldImportSpecifier) ? 2 /* JsExtension */
                    : ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.NodeJs || ts.endsWith(oldImportSpecifier, "index") ? 1 /* Index */ : 0 /* Minimal */,
            };
        }
        function updateModuleSpecifier(compilerOptions, importingSourceFileName, toFileName, host, files, redirectTargetsMap, oldImportSpecifier) {
            var res = getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, files, redirectTargetsMap, getPreferencesForUpdate(compilerOptions, oldImportSpecifier));
            if (res === oldImportSpecifier)
                return undefined;
            return res;
        }
        moduleSpecifiers.updateModuleSpecifier = updateModuleSpecifier;
        // Note: importingSourceFile is just for usesJsExtensionOnImports
        function getModuleSpecifier(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, files, preferences, redirectTargetsMap) {
            if (preferences === void 0) { preferences = {}; }
            return getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, files, redirectTargetsMap, getPreferences(preferences, compilerOptions, importingSourceFile));
        }
        moduleSpecifiers.getModuleSpecifier = getModuleSpecifier;
        function getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, files, redirectTargetsMap, preferences) {
            var info = getInfo(importingSourceFileName, host);
            var modulePaths = getAllModulePaths(files, importingSourceFileName, toFileName, info.getCanonicalFileName, host, redirectTargetsMap);
            return ts.firstDefined(modulePaths, function (moduleFileName) { return tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions); }) ||
                getLocalModuleSpecifier(toFileName, info, compilerOptions, preferences);
        }
        // Returns an import for each symlink and for the realpath.
        function getModuleSpecifiers(moduleSymbol, compilerOptions, importingSourceFile, host, files, userPreferences, redirectTargetsMap) {
            var ambient = tryGetModuleNameFromAmbientModule(moduleSymbol);
            if (ambient)
                return [ambient];
            var info = getInfo(importingSourceFile.path, host);
            var moduleSourceFile = ts.getSourceFileOfNode(moduleSymbol.valueDeclaration || ts.getNonAugmentationDeclaration(moduleSymbol));
            var modulePaths = getAllModulePaths(files, importingSourceFile.path, moduleSourceFile.fileName, info.getCanonicalFileName, host, redirectTargetsMap);
            var preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile);
            var global = ts.mapDefined(modulePaths, function (moduleFileName) { return tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions); });
            return global.length ? global : modulePaths.map(function (moduleFileName) { return getLocalModuleSpecifier(moduleFileName, info, compilerOptions, preferences); });
        }
        moduleSpecifiers.getModuleSpecifiers = getModuleSpecifiers;
        // importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path
        function getInfo(importingSourceFileName, host) {
            var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : true);
            var sourceDirectory = ts.getDirectoryPath(importingSourceFileName);
            return { getCanonicalFileName: getCanonicalFileName, sourceDirectory: sourceDirectory };
        }
        function getLocalModuleSpecifier(moduleFileName, _a, compilerOptions, _b) {
            var getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory;
            var ending = _b.ending, relativePreference = _b.relativePreference;
            var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths, rootDirs = compilerOptions.rootDirs;
            var relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) ||
                removeExtensionAndIndexPostFix(ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions);
            if (!baseUrl || relativePreference === 0 /* Relative */) {
                return relativePath;
            }
            var relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName);
            if (!relativeToBaseUrl) {
                return relativePath;
            }
            var importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions);
            var fromPaths = paths && tryGetModuleNameFromPaths(ts.removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths);
            var nonRelative = fromPaths === undefined ? importRelativeToBaseUrl : fromPaths;
            if (relativePreference === 1 /* NonRelative */) {
                return nonRelative;
            }
            if (relativePreference !== 2 /* Auto */)
                ts.Debug.assertNever(relativePreference);
            // Prefer a relative import over a baseUrl import if it has fewer components.
            return isPathRelativeToParent(nonRelative) || countPathComponents(relativePath) < countPathComponents(nonRelative) ? relativePath : nonRelative;
        }
        function countPathComponents(path) {
            var count = 0;
            for (var i = ts.startsWith(path, "./") ? 2 : 0; i < path.length; i++) {
                if (path.charCodeAt(i) === 47 /* slash */)
                    count++;
            }
            return count;
        }
        moduleSpecifiers.countPathComponents = countPathComponents;
        function usesJsExtensionOnImports(_a) {
            var imports = _a.imports;
            return ts.firstDefined(imports, function (_a) {
                var text = _a.text;
                return ts.pathIsRelative(text) ? ts.hasJSOrJsonFileExtension(text) : undefined;
            }) || false;
        }
        function stringsEqual(a, b, getCanonicalFileName) {
            return getCanonicalFileName(a) === getCanonicalFileName(b);
        }
        // KLUDGE: Don't assume one 'node_modules' links to another. More likely a single directory inside the node_modules is the symlink.
        // ALso, don't assume that an `@foo` directory is linked. More likely the contents of that are linked.
        function isNodeModulesOrScopedPackageDirectory(s, getCanonicalFileName) {
            return getCanonicalFileName(s) === "node_modules" || ts.startsWith(s, "@");
        }
        function guessDirectorySymlink(a, b, cwd, getCanonicalFileName) {
            var aParts = ts.getPathComponents(ts.toPath(a, cwd, getCanonicalFileName));
            var bParts = ts.getPathComponents(ts.toPath(b, cwd, getCanonicalFileName));
            while (!isNodeModulesOrScopedPackageDirectory(aParts[aParts.length - 2], getCanonicalFileName) &&
                !isNodeModulesOrScopedPackageDirectory(bParts[bParts.length - 2], getCanonicalFileName) &&
                stringsEqual(aParts[aParts.length - 1], bParts[bParts.length - 1], getCanonicalFileName)) {
                aParts.pop();
                bParts.pop();
            }
            return [ts.getPathFromPathComponents(aParts), ts.getPathFromPathComponents(bParts)];
        }
        function discoverProbableSymlinks(files, getCanonicalFileName, cwd) {
            var result = ts.createMap();
            var symlinks = ts.flatten(ts.mapDefined(files, function (sf) {
                return sf.resolvedModules && ts.compact(ts.arrayFrom(ts.mapIterator(sf.resolvedModules.values(), function (res) {
                    return res && res.originalPath && res.resolvedFileName !== res.originalPath ? [res.resolvedFileName, res.originalPath] : undefined;
                })));
            }));
            for (var _i = 0, symlinks_1 = symlinks; _i < symlinks_1.length; _i++) {
                var _a = symlinks_1[_i], resolvedPath = _a[0], originalPath = _a[1];
                var _b = guessDirectorySymlink(resolvedPath, originalPath, cwd, getCanonicalFileName), commonResolved = _b[0], commonOriginal = _b[1];
                result.set(commonOriginal, commonResolved);
            }
            return result;
        }
        /**
         * Looks for existing imports that use symlinks to this module.
         * Symlinks will be returned first so they are preferred over the real path.
         */
        function getAllModulePaths(files, importingFileName, importedFileName, getCanonicalFileName, host, redirectTargetsMap) {
            var redirects = redirectTargetsMap.get(importedFileName);
            var importedFileNames = redirects ? redirects.concat([importedFileName]) : [importedFileName];
            var cwd = host.getCurrentDirectory ? host.getCurrentDirectory() : "";
            var targets = importedFileNames.map(function (f) { return ts.getNormalizedAbsolutePath(f, cwd); });
            var links = discoverProbableSymlinks(files, getCanonicalFileName, cwd);
            var result = [];
            var compareStrings = (!host.useCaseSensitiveFileNames || host.useCaseSensitiveFileNames()) ? ts.compareStringsCaseSensitive : ts.compareStringsCaseInsensitive;
            links.forEach(function (resolved, path) {
                if (ts.startsWithDirectory(importingFileName, resolved, getCanonicalFileName)) {
                    return; // Don't want to a package to globally import from itself
                }
                var target = ts.find(targets, function (t) { return compareStrings(t.slice(0, resolved.length + 1), resolved + "/") === 0 /* EqualTo */; });
                if (target === undefined)
                    return;
                var relative = ts.getRelativePathFromDirectory(resolved, target, getCanonicalFileName);
                var option = ts.resolvePath(path, relative);
                if (!host.fileExists || host.fileExists(option)) {
                    result.push(option);
                }
            });
            result.push.apply(result, targets);
            return result;
        }
        function tryGetModuleNameFromAmbientModule(moduleSymbol) {
            var decl = ts.find(moduleSymbol.declarations, function (d) { return ts.isNonGlobalAmbientModule(d) && (!ts.isExternalModuleAugmentation(d) || !ts.isExternalModuleNameRelative(ts.getTextOfIdentifierOrLiteral(d.name))); });
            if (decl) {
                return decl.name.text;
            }
        }
        function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex, relativeToBaseUrl, paths) {
            for (var key in paths) {
                for (var _i = 0, _a = paths[key]; _i < _a.length; _i++) {
                    var patternText_1 = _a[_i];
                    var pattern = ts.removeFileExtension(ts.normalizePath(patternText_1));
                    var indexOfStar = pattern.indexOf("*");
                    if (indexOfStar !== -1) {
                        var prefix = pattern.substr(0, indexOfStar);
                        var suffix = pattern.substr(indexOfStar + 1);
                        if (relativeToBaseUrl.length >= prefix.length + suffix.length &&
                            ts.startsWith(relativeToBaseUrl, prefix) &&
                            ts.endsWith(relativeToBaseUrl, suffix) ||
                            !suffix && relativeToBaseUrl === ts.removeTrailingDirectorySeparator(prefix)) {
                            var matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length);
                            return key.replace("*", matchedStar);
                        }
                    }
                    else if (pattern === relativeToBaseUrl || pattern === relativeToBaseUrlWithIndex) {
                        return key;
                    }
                }
            }
        }
        function tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) {
            var normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName);
            if (normalizedTargetPath === undefined) {
                return undefined;
            }
            var normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName);
            var relativePath = normalizedSourcePath !== undefined ? ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath;
            return ts.removeFileExtension(relativePath);
        }
        function tryGetModuleNameAsNodeModule(moduleFileName, _a, host, options) {
            var getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory;
            if (!host.fileExists || !host.readFile) {
                return undefined;
            }
            var parts = getNodeModulePathParts(moduleFileName);
            if (!parts) {
                return undefined;
            }
            var packageRootPath = moduleFileName.substring(0, parts.packageRootIndex);
            var packageJsonPath = ts.combinePaths(packageRootPath, "package.json");
            var packageJsonContent = host.fileExists(packageJsonPath)
                ? JSON.parse(host.readFile(packageJsonPath))
                : undefined;
            var versionPaths = packageJsonContent && packageJsonContent.typesVersions
                ? ts.getPackageJsonTypesVersionsPaths(packageJsonContent.typesVersions)
                : undefined;
            if (versionPaths) {
                var subModuleName = moduleFileName.slice(parts.packageRootIndex + 1);
                var fromPaths = tryGetModuleNameFromPaths(ts.removeFileExtension(subModuleName), removeExtensionAndIndexPostFix(subModuleName, 0 /* Minimal */, options), versionPaths.paths);
                if (fromPaths !== undefined) {
                    moduleFileName = ts.combinePaths(moduleFileName.slice(0, parts.packageRootIndex), fromPaths);
                }
            }
            // Simplify the full file path to something that can be resolved by Node.
            // If the module could be imported by a directory name, use that directory's name
            var moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName);
            // Get a path that's relative to node_modules or the importing file's path
            // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
            if (!ts.startsWith(sourceDirectory, getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex))))
                return undefined;
            // If the module was found in @types, get the actual Node package name
            var nodeModulesDirectoryName = moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
            var packageName = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
            // For classic resolution, only allow importing from node_modules/@types, not other node_modules
            return ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && packageName === nodeModulesDirectoryName ? undefined : packageName;
            function getDirectoryOrExtensionlessFileName(path) {
                // If the file is the main module, it can be imported by the package name
                if (packageJsonContent) {
                    var mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main;
                    if (mainFileRelative) {
                        var mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName);
                        if (ts.removeFileExtension(mainExportFile) === ts.removeFileExtension(getCanonicalFileName(path))) {
                            return packageRootPath;
                        }
                    }
                }
                // We still have a file name - remove the extension
                var fullModulePathWithoutExtension = ts.removeFileExtension(path);
                // If the file is /index, it can be imported by its directory name
                // IFF there is not _also_ a file by the same name
                if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index" && !tryGetAnyFileFromPath(host, fullModulePathWithoutExtension.substring(0, parts.fileNameIndex))) {
                    return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex);
                }
                return fullModulePathWithoutExtension;
            }
        }
        function tryGetAnyFileFromPath(host, path) {
            if (!host.fileExists)
                return;
            // We check all js, `node` and `json` extensions in addition to TS, since node module resolution would also choose those over the directory
            var extensions = ts.getSupportedExtensions({ allowJs: true }, [{ extension: "node", isMixedContent: false }, { extension: "json", isMixedContent: false, scriptKind: 6 /* JSON */ }]);
            for (var _i = 0, extensions_3 = extensions; _i < extensions_3.length; _i++) {
                var e = extensions_3[_i];
                var fullPath = path + e;
                if (host.fileExists(fullPath)) {
                    return fullPath;
                }
            }
        }
        function getNodeModulePathParts(fullPath) {
            // If fullPath can't be valid module file within node_modules, returns undefined.
            // Example of expected pattern: /base/path/node_modules/[@scope/otherpackage/@otherscope/node_modules/]package/[subdirectory/]file.js
            // Returns indices:                       ^            ^                                                      ^             ^
            var topLevelNodeModulesIndex = 0;
            var topLevelPackageNameIndex = 0;
            var packageRootIndex = 0;
            var fileNameIndex = 0;
            var States;
            (function (States) {
                States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules";
                States[States["NodeModules"] = 1] = "NodeModules";
                States[States["Scope"] = 2] = "Scope";
                States[States["PackageContent"] = 3] = "PackageContent";
            })(States || (States = {}));
            var partStart = 0;
            var partEnd = 0;
            var state = 0 /* BeforeNodeModules */;
            while (partEnd >= 0) {
                partStart = partEnd;
                partEnd = fullPath.indexOf("/", partStart + 1);
                switch (state) {
                    case 0 /* BeforeNodeModules */:
                        if (fullPath.indexOf(ts.nodeModulesPathPart, partStart) === partStart) {
                            topLevelNodeModulesIndex = partStart;
                            topLevelPackageNameIndex = partEnd;
                            state = 1 /* NodeModules */;
                        }
                        break;
                    case 1 /* NodeModules */:
                    case 2 /* Scope */:
                        if (state === 1 /* NodeModules */ && fullPath.charAt(partStart + 1) === "@") {
                            state = 2 /* Scope */;
                        }
                        else {
                            packageRootIndex = partEnd;
                            state = 3 /* PackageContent */;
                        }
                        break;
                    case 3 /* PackageContent */:
                        if (fullPath.indexOf(ts.nodeModulesPathPart, partStart) === partStart) {
                            state = 1 /* NodeModules */;
                        }
                        else {
                            state = 3 /* PackageContent */;
                        }
                        break;
                }
            }
            fileNameIndex = partStart;
            return state > 1 /* NodeModules */ ? { topLevelNodeModulesIndex: topLevelNodeModulesIndex, topLevelPackageNameIndex: topLevelPackageNameIndex, packageRootIndex: packageRootIndex, fileNameIndex: fileNameIndex } : undefined;
        }
        function getPathRelativeToRootDirs(path, rootDirs, getCanonicalFileName) {
            return ts.firstDefined(rootDirs, function (rootDir) {
                var relativePath = getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); // TODO: GH#18217
                return isPathRelativeToParent(relativePath) ? undefined : relativePath;
            });
        }
        function removeExtensionAndIndexPostFix(fileName, ending, options) {
            if (ts.fileExtensionIs(fileName, ".json" /* Json */))
                return fileName;
            var noExtension = ts.removeFileExtension(fileName);
            switch (ending) {
                case 0 /* Minimal */:
                    return ts.removeSuffix(noExtension, "/index");
                case 1 /* Index */:
                    return noExtension;
                case 2 /* JsExtension */:
                    return noExtension + getJSExtensionForFile(fileName, options);
                default:
                    return ts.Debug.assertNever(ending);
            }
        }
        function getJSExtensionForFile(fileName, options) {
            var ext = ts.extensionFromPath(fileName);
            switch (ext) {
                case ".ts" /* Ts */:
                case ".d.ts" /* Dts */:
                    return ".js" /* Js */;
                case ".tsx" /* Tsx */:
                    return options.jsx === 1 /* Preserve */ ? ".jsx" /* Jsx */ : ".js" /* Js */;
                case ".js" /* Js */:
                case ".jsx" /* Jsx */:
                case ".json" /* Json */:
                    return ext;
                case ".tsbuildinfo" /* TsBuildInfo */:
                    return ts.Debug.fail("Extension " + ".tsbuildinfo" /* TsBuildInfo */ + " is unsupported:: FileName:: " + fileName);
                default:
                    return ts.Debug.assertNever(ext);
            }
        }
        function getRelativePathIfInDirectory(path, directoryPath, getCanonicalFileName) {
            var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
            return ts.isRootedDiskPath(relativePath) ? undefined : relativePath;
        }
        function isPathRelativeToParent(path) {
            return ts.startsWith(path, "..");
        }
    })(moduleSpecifiers = ts.moduleSpecifiers || (ts.moduleSpecifiers = {}));
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var sysFormatDiagnosticsHost = ts.sys ? {
        getCurrentDirectory: function () { return ts.sys.getCurrentDirectory(); },
        getNewLine: function () { return ts.sys.newLine; },
        getCanonicalFileName: ts.createGetCanonicalFileName(ts.sys.useCaseSensitiveFileNames)
    } : undefined; // TODO: GH#18217
    /**
     * Create a function that reports error by writing to the system and handles the formating of the diagnostic
     */
    function createDiagnosticReporter(system, pretty) {
        var host = system === ts.sys ? sysFormatDiagnosticsHost : {
            getCurrentDirectory: function () { return system.getCurrentDirectory(); },
            getNewLine: function () { return system.newLine; },
            getCanonicalFileName: ts.createGetCanonicalFileName(system.useCaseSensitiveFileNames),
        };
        if (!pretty) {
            return function (diagnostic) { return system.write(ts.formatDiagnostic(diagnostic, host)); };
        }
        var diagnostics = new Array(1);
        return function (diagnostic) {
            diagnostics[0] = diagnostic;
            system.write(ts.formatDiagnosticsWithColorAndContext(diagnostics, host) + host.getNewLine());
            diagnostics[0] = undefined; // TODO: GH#18217
        };
    }
    ts.createDiagnosticReporter = createDiagnosticReporter;
    /**
     * @returns Whether the screen was cleared.
     */
    function clearScreenIfNotWatchingForFileChanges(system, diagnostic, options) {
        if (system.clearScreen &&
            !options.preserveWatchOutput &&
            !options.extendedDiagnostics &&
            !options.diagnostics &&
            ts.contains(ts.screenStartingMessageCodes, diagnostic.code)) {
            system.clearScreen();
            return true;
        }
        return false;
    }
    ts.screenStartingMessageCodes = [
        ts.Diagnostics.Starting_compilation_in_watch_mode.code,
        ts.Diagnostics.File_change_detected_Starting_incremental_compilation.code,
    ];
    function getPlainDiagnosticFollowingNewLines(diagnostic, newLine) {
        return ts.contains(ts.screenStartingMessageCodes, diagnostic.code)
            ? newLine + newLine
            : newLine;
    }
    /**
     * Create a function that reports watch status by writing to the system and handles the formating of the diagnostic
     */
    function createWatchStatusReporter(system, pretty) {
        return pretty ?
            function (diagnostic, newLine, options) {
                clearScreenIfNotWatchingForFileChanges(system, diagnostic, options);
                var output = "[" + ts.formatColorAndReset(new Date().toLocaleTimeString(), ts.ForegroundColorEscapeSequences.Grey) + "] ";
                output += "" + ts.flattenDiagnosticMessageText(diagnostic.messageText, system.newLine) + (newLine + newLine);
                system.write(output);
            } :
            function (diagnostic, newLine, options) {
                var output = "";
                if (!clearScreenIfNotWatchingForFileChanges(system, diagnostic, options)) {
                    output += newLine;
                }
                output += new Date().toLocaleTimeString() + " - ";
                output += "" + ts.flattenDiagnosticMessageText(diagnostic.messageText, system.newLine) + getPlainDiagnosticFollowingNewLines(diagnostic, newLine);
                system.write(output);
            };
    }
    ts.createWatchStatusReporter = createWatchStatusReporter;
    /** Parses config file using System interface */
    function parseConfigFileWithSystem(configFileName, optionsToExtend, system, reportDiagnostic) {
        var host = system;
        host.onUnRecoverableConfigFileDiagnostic = function (diagnostic) { return reportUnrecoverableDiagnostic(ts.sys, reportDiagnostic, diagnostic); };
        var result = ts.getParsedCommandLineOfConfigFile(configFileName, optionsToExtend, host);
        host.onUnRecoverableConfigFileDiagnostic = undefined; // TODO: GH#18217
        return result;
    }
    ts.parseConfigFileWithSystem = parseConfigFileWithSystem;
    function getErrorCountForSummary(diagnostics) {
        return ts.countWhere(diagnostics, function (diagnostic) { return diagnostic.category === ts.DiagnosticCategory.Error; });
    }
    ts.getErrorCountForSummary = getErrorCountForSummary;
    function getWatchErrorSummaryDiagnosticMessage(errorCount) {
        return errorCount === 1 ?
            ts.Diagnostics.Found_1_error_Watching_for_file_changes :
            ts.Diagnostics.Found_0_errors_Watching_for_file_changes;
    }
    ts.getWatchErrorSummaryDiagnosticMessage = getWatchErrorSummaryDiagnosticMessage;
    function getErrorSummaryText(errorCount, newLine) {
        if (errorCount === 0)
            return "";
        var d = ts.createCompilerDiagnostic(errorCount === 1 ? ts.Diagnostics.Found_1_error : ts.Diagnostics.Found_0_errors, errorCount);
        return "" + newLine + ts.flattenDiagnosticMessageText(d.messageText, newLine) + newLine + newLine;
    }
    ts.getErrorSummaryText = getErrorSummaryText;
    function listFiles(program, writeFileName) {
        if (program.getCompilerOptions().listFiles) {
            ts.forEach(program.getSourceFiles(), function (file) {
                writeFileName(file.fileName);
            });
        }
    }
    ts.listFiles = listFiles;
    /**
     * Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options
     */
    function emitFilesAndReportErrors(program, reportDiagnostic, writeFileName, reportSummary, writeFile) {
        // First get and report any syntactic errors.
        var diagnostics = program.getConfigFileParsingDiagnostics().slice();
        var configFileParsingDiagnosticsLength = diagnostics.length;
        ts.addRange(diagnostics, program.getSyntacticDiagnostics());
        // If we didn't have any syntactic errors, then also try getting the global and
        // semantic errors.
        if (diagnostics.length === configFileParsingDiagnosticsLength) {
            ts.addRange(diagnostics, program.getOptionsDiagnostics());
            ts.addRange(diagnostics, program.getGlobalDiagnostics());
            if (diagnostics.length === configFileParsingDiagnosticsLength) {
                ts.addRange(diagnostics, program.getSemanticDiagnostics());
            }
        }
        // Emit and report any errors we ran into.
        var _a = program.emit(/*targetSourceFile*/ undefined, writeFile), emittedFiles = _a.emittedFiles, emitSkipped = _a.emitSkipped, emitDiagnostics = _a.diagnostics;
        ts.addRange(diagnostics, emitDiagnostics);
        ts.sortAndDeduplicateDiagnostics(diagnostics).forEach(reportDiagnostic);
        if (writeFileName) {
            var currentDir_1 = program.getCurrentDirectory();
            ts.forEach(emittedFiles, function (file) {
                var filepath = ts.getNormalizedAbsolutePath(file, currentDir_1);
                writeFileName("TSFILE: " + filepath);
            });
            listFiles(program, writeFileName);
        }
        if (reportSummary) {
            reportSummary(getErrorCountForSummary(diagnostics));
        }
        if (emitSkipped && diagnostics.length > 0) {
            // If the emitter didn't emit anything, then pass that value along.
            return ts.ExitStatus.DiagnosticsPresent_OutputsSkipped;
        }
        else if (diagnostics.length > 0) {
            // The emitter emitted something, inform the caller if that happened in the presence
            // of diagnostics or not.
            return ts.ExitStatus.DiagnosticsPresent_OutputsGenerated;
        }
        return ts.ExitStatus.Success;
    }
    ts.emitFilesAndReportErrors = emitFilesAndReportErrors;
    var noopFileWatcher = { close: ts.noop };
    function createWatchHost(system, reportWatchStatus) {
        if (system === void 0) { system = ts.sys; }
        var onWatchStatusChange = reportWatchStatus || createWatchStatusReporter(system);
        return {
            onWatchStatusChange: onWatchStatusChange,
            watchFile: ts.maybeBind(system, system.watchFile) || (function () { return noopFileWatcher; }),
            watchDirectory: ts.maybeBind(system, system.watchDirectory) || (function () { return noopFileWatcher; }),
            setTimeout: ts.maybeBind(system, system.setTimeout) || ts.noop,
            clearTimeout: ts.maybeBind(system, system.clearTimeout) || ts.noop
        };
    }
    ts.createWatchHost = createWatchHost;
    var WatchType;
    (function (WatchType) {
        WatchType["ConfigFile"] = "Config file";
        WatchType["SourceFile"] = "Source file";
        WatchType["MissingFile"] = "Missing file";
        WatchType["WildcardDirectory"] = "Wild card directory";
        WatchType["FailedLookupLocations"] = "Failed Lookup Locations";
        WatchType["TypeRoots"] = "Type roots";
    })(WatchType = ts.WatchType || (ts.WatchType = {}));
    function createWatchFactory(host, options) {
        var watchLogLevel = host.trace ? options.extendedDiagnostics ? ts.WatchLogLevel.Verbose : options.diagnostics ? ts.WatchLogLevel.TriggerOnly : ts.WatchLogLevel.None : ts.WatchLogLevel.None;
        var writeLog = watchLogLevel !== ts.WatchLogLevel.None ? (function (s) { return host.trace(s); }) : ts.noop;
        var result = ts.getWatchFactory(watchLogLevel, writeLog);
        result.writeLog = writeLog;
        return result;
    }
    ts.createWatchFactory = createWatchFactory;
    function createCompilerHostFromProgramHost(host, getCompilerOptions, directoryStructureHost) {
        if (directoryStructureHost === void 0) { directoryStructureHost = host; }
        var useCaseSensitiveFileNames = host.useCaseSensitiveFileNames();
        var hostGetNewLine = ts.memoize(function () { return host.getNewLine(); });
        return {
            getSourceFile: function (fileName, languageVersion, onError) {
                var text;
                try {
                    ts.performance.mark("beforeIORead");
                    text = host.readFile(fileName, getCompilerOptions().charset);
                    ts.performance.mark("afterIORead");
                    ts.performance.measure("I/O Read", "beforeIORead", "afterIORead");
                }
                catch (e) {
                    if (onError) {
                        onError(e.message);
                    }
                    text = "";
                }
                return text !== undefined ? ts.createSourceFile(fileName, text, languageVersion) : undefined;
            },
            getDefaultLibLocation: ts.maybeBind(host, host.getDefaultLibLocation),
            getDefaultLibFileName: function (options) { return host.getDefaultLibFileName(options); },
            writeFile: writeFile,
            getCurrentDirectory: ts.memoize(function () { return host.getCurrentDirectory(); }),
            useCaseSensitiveFileNames: function () { return useCaseSensitiveFileNames; },
            getCanonicalFileName: ts.createGetCanonicalFileName(useCaseSensitiveFileNames),
            getNewLine: function () { return ts.getNewLineCharacter(getCompilerOptions(), hostGetNewLine); },
            fileExists: function (f) { return host.fileExists(f); },
            readFile: function (f) { return host.readFile(f); },
            trace: ts.maybeBind(host, host.trace),
            directoryExists: ts.maybeBind(directoryStructureHost, directoryStructureHost.directoryExists),
            getDirectories: ts.maybeBind(directoryStructureHost, directoryStructureHost.getDirectories),
            realpath: ts.maybeBind(host, host.realpath),
            getEnvironmentVariable: ts.maybeBind(host, host.getEnvironmentVariable) || (function () { return ""; }),
            createHash: ts.maybeBind(host, host.createHash),
            readDirectory: ts.maybeBind(host, host.readDirectory),
        };
        function ensureDirectoriesExist(directoryPath) {
            if (directoryPath.length > ts.getRootLength(directoryPath) && !host.directoryExists(directoryPath)) {
                var parentDirectory = ts.getDirectoryPath(directoryPath);
                ensureDirectoriesExist(parentDirectory);
                if (host.createDirectory)
                    host.createDirectory(directoryPath);
            }
        }
        function writeFile(fileName, text, writeByteOrderMark, onError) {
            try {
                ts.performance.mark("beforeIOWrite");
                ensureDirectoriesExist(ts.getDirectoryPath(ts.normalizePath(fileName)));
                host.writeFile(fileName, text, writeByteOrderMark);
                ts.performance.mark("afterIOWrite");
                ts.performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
            }
            catch (e) {
                if (onError) {
                    onError(e.message);
                }
            }
        }
    }
    ts.createCompilerHostFromProgramHost = createCompilerHostFromProgramHost;
    function setGetSourceFileAsHashVersioned(compilerHost, host) {
        var originalGetSourceFile = compilerHost.getSourceFile;
        var computeHash = host.createHash || ts.generateDjb2Hash;
        compilerHost.getSourceFile = function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            var result = originalGetSourceFile.call.apply(originalGetSourceFile, [compilerHost].concat(args));
            if (result) {
                result.version = computeHash.call(host, result.text);
            }
            return result;
        };
    }
    ts.setGetSourceFileAsHashVersioned = setGetSourceFileAsHashVersioned;
    /**
     * Creates the watch compiler host that can be extended with config file or root file names and options host
     */
    function createProgramHost(system, createProgram) {
        var getDefaultLibLocation = ts.memoize(function () { return ts.getDirectoryPath(ts.normalizePath(system.getExecutingFilePath())); });
        var host = system;
        host; // tslint:disable-line no-unused-expression (TODO: `host` is unused!)
        return {
            useCaseSensitiveFileNames: function () { return system.useCaseSensitiveFileNames; },
            getNewLine: function () { return system.newLine; },
            getCurrentDirectory: ts.memoize(function () { return system.getCurrentDirectory(); }),
            getDefaultLibLocation: getDefaultLibLocation,
            getDefaultLibFileName: function (options) { return ts.combinePaths(getDefaultLibLocation(), ts.getDefaultLibFileName(options)); },
            fileExists: function (path) { return system.fileExists(path); },
            readFile: function (path, encoding) { return system.readFile(path, encoding); },
            directoryExists: function (path) { return system.directoryExists(path); },
            getDirectories: function (path) { return system.getDirectories(path); },
            readDirectory: function (path, extensions, exclude, include, depth) { return system.readDirectory(path, extensions, exclude, include, depth); },
            realpath: ts.maybeBind(system, system.realpath),
            getEnvironmentVariable: ts.maybeBind(system, system.getEnvironmentVariable),
            trace: function (s) { return system.write(s + system.newLine); },
            createDirectory: function (path) { return system.createDirectory(path); },
            writeFile: function (path, data, writeByteOrderMark) { return system.writeFile(path, data, writeByteOrderMark); },
            onCachedDirectoryStructureHostCreate: function (cacheHost) { return host = cacheHost || system; },
            createHash: ts.maybeBind(system, system.createHash),
            createProgram: createProgram || ts.createEmitAndSemanticDiagnosticsBuilderProgram
        };
    }
    ts.createProgramHost = createProgramHost;
    /**
     * Creates the watch compiler host that can be extended with config file or root file names and options host
     */
    function createWatchCompilerHost(system, createProgram, reportDiagnostic, reportWatchStatus) {
        if (system === void 0) { system = ts.sys; }
        var writeFileName = function (s) { return system.write(s + system.newLine); };
        var result = createProgramHost(system, createProgram);
        ts.copyProperties(result, createWatchHost(system, reportWatchStatus));
        result.afterProgramCreate = function (builderProgram) {
            var compilerOptions = builderProgram.getCompilerOptions();
            var newLine = ts.getNewLineCharacter(compilerOptions, function () { return system.newLine; });
            emitFilesAndReportErrors(builderProgram, reportDiagnostic, writeFileName, function (errorCount) { return result.onWatchStatusChange(ts.createCompilerDiagnostic(getWatchErrorSummaryDiagnosticMessage(errorCount), errorCount), newLine, compilerOptions); });
        };
        return result;
    }
    /**
     * Report error and exit
     */
    function reportUnrecoverableDiagnostic(system, reportDiagnostic, diagnostic) {
        reportDiagnostic(diagnostic);
        system.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped);
    }
    /**
     * Creates the watch compiler host from system for config file in watch mode
     */
    function createWatchCompilerHostOfConfigFile(configFileName, optionsToExtend, system, createProgram, reportDiagnostic, reportWatchStatus) {
        var diagnosticReporter = reportDiagnostic || createDiagnosticReporter(system);
        var host = createWatchCompilerHost(system, createProgram, diagnosticReporter, reportWatchStatus);
        host.onUnRecoverableConfigFileDiagnostic = function (diagnostic) { return reportUnrecoverableDiagnostic(system, diagnosticReporter, diagnostic); };
        host.configFileName = configFileName;
        host.optionsToExtend = optionsToExtend;
        return host;
    }
    ts.createWatchCompilerHostOfConfigFile = createWatchCompilerHostOfConfigFile;
    /**
     * Creates the watch compiler host from system for compiling root files and options in watch mode
     */
    function createWatchCompilerHostOfFilesAndCompilerOptions(rootFiles, options, system, createProgram, reportDiagnostic, reportWatchStatus, projectReferences) {
        var host = createWatchCompilerHost(system, createProgram, reportDiagnostic || createDiagnosticReporter(system), reportWatchStatus);
        host.rootFiles = rootFiles;
        host.options = options;
        host.projectReferences = projectReferences;
        return host;
    }
    ts.createWatchCompilerHostOfFilesAndCompilerOptions = createWatchCompilerHostOfFilesAndCompilerOptions;
    function readBuilderProgram(compilerOptions, readFile) {
        if (compilerOptions.out || compilerOptions.outFile)
            return undefined;
        var buildInfoPath = ts.getOutputPathForBuildInfo(compilerOptions);
        if (!buildInfoPath)
            return undefined;
        var content = readFile(buildInfoPath);
        if (!content)
            return undefined;
        var buildInfo = ts.getBuildInfo(content);
        if (buildInfo.version !== ts.version)
            return undefined;
        if (!buildInfo.program)
            return undefined;
        return ts.createBuildProgramUsingProgramBuildInfo(buildInfo.program);
    }
    ts.readBuilderProgram = readBuilderProgram;
    function createIncrementalCompilerHost(options, system) {
        if (system === void 0) { system = ts.sys; }
        var host = ts.createCompilerHostWorker(options, /*setParentNodes*/ undefined, system);
        host.createHash = ts.maybeBind(system, system.createHash);
        setGetSourceFileAsHashVersioned(host, system);
        ts.changeCompilerHostLikeToUseCache(host, function (fileName) { return ts.toPath(fileName, host.getCurrentDirectory(), host.getCanonicalFileName); });
        return host;
    }
    ts.createIncrementalCompilerHost = createIncrementalCompilerHost;
    function createIncrementalProgram(_a) {
        var rootNames = _a.rootNames, options = _a.options, configFileParsingDiagnostics = _a.configFileParsingDiagnostics, projectReferences = _a.projectReferences, host = _a.host, createProgram = _a.createProgram;
        host = host || createIncrementalCompilerHost(options);
        createProgram = createProgram || ts.createEmitAndSemanticDiagnosticsBuilderProgram;
        var oldProgram = readBuilderProgram(options, function (path) { return host.readFile(path); });
        return createProgram(rootNames, options, host, oldProgram, configFileParsingDiagnostics, projectReferences);
    }
    function performIncrementalCompilation(input) {
        var system = input.system || ts.sys;
        var host = input.host || (input.host = createIncrementalCompilerHost(input.options, system));
        var builderProgram = createIncrementalProgram(input);
        var exitStatus = emitFilesAndReportErrors(builderProgram, input.reportDiagnostic || createDiagnosticReporter(system), function (s) { return host.trace && host.trace(s); }, input.reportErrorSummary || input.options.pretty ? function (errorCount) { return system.write(getErrorSummaryText(errorCount, system.newLine)); } : undefined);
        if (input.afterProgramEmitAndDiagnostics)
            input.afterProgramEmitAndDiagnostics(builderProgram);
        return exitStatus;
    }
    ts.performIncrementalCompilation = performIncrementalCompilation;
})(ts || (ts = {}));
(function (ts) {
    function createWatchCompilerHost(rootFilesOrConfigFileName, options, system, createProgram, reportDiagnostic, reportWatchStatus, projectReferences) {
        if (ts.isArray(rootFilesOrConfigFileName)) {
            return ts.createWatchCompilerHostOfFilesAndCompilerOptions(rootFilesOrConfigFileName, options, system, createProgram, reportDiagnostic, reportWatchStatus, projectReferences); // TODO: GH#18217
        }
        else {
            return ts.createWatchCompilerHostOfConfigFile(rootFilesOrConfigFileName, options, system, createProgram, reportDiagnostic, reportWatchStatus);
        }
    }
    ts.createWatchCompilerHost = createWatchCompilerHost;
    function createWatchProgram(host) {
        var builderProgram;
        var reloadLevel; // level to indicate if the program needs to be reloaded from config file/just filenames etc
        var missingFilesMap; // Map of file watchers for the missing files
        var watchedWildcardDirectories; // map of watchers for the wild card directories in the config file
        var timerToUpdateProgram; // timer callback to recompile the program
        var sourceFilesCache = ts.createMap(); // Cache that stores the source file and version info
        var missingFilePathsRequestedForRelease; // These paths are held temparirly so that we can remove the entry from source file cache if the file is not tracked by missing files
        var hasChangedCompilerOptions = false; // True if the compiler options have changed between compilations
        var hasChangedAutomaticTypeDirectiveNames = false; // True if the automatic type directives have changed
        var useCaseSensitiveFileNames = host.useCaseSensitiveFileNames();
        var currentDirectory = host.getCurrentDirectory();
        var configFileName = host.configFileName, _a = host.optionsToExtend, optionsToExtendForConfigFile = _a === void 0 ? {} : _a, createProgram = host.createProgram;
        var rootFileNames = host.rootFiles, compilerOptions = host.options, projectReferences = host.projectReferences;
        var configFileSpecs;
        var configFileParsingDiagnostics;
        var canConfigFileJsonReportNoInputFiles = false;
        var hasChangedConfigFileParsingErrors = false;
        var cachedDirectoryStructureHost = configFileName === undefined ? undefined : ts.createCachedDirectoryStructureHost(host, currentDirectory, useCaseSensitiveFileNames);
        if (cachedDirectoryStructureHost && host.onCachedDirectoryStructureHostCreate) {
            host.onCachedDirectoryStructureHostCreate(cachedDirectoryStructureHost);
        }
        var directoryStructureHost = cachedDirectoryStructureHost || host;
        var parseConfigFileHost = ts.parseConfigHostFromCompilerHostLike(host, directoryStructureHost);
        // From tsc we want to get already parsed result and hence check for rootFileNames
        var newLine = updateNewLine();
        if (configFileName && host.configFileParsingResult) {
            setConfigFileParsingResult(host.configFileParsingResult);
            newLine = updateNewLine();
        }
        reportWatchDiagnostic(ts.Diagnostics.Starting_compilation_in_watch_mode);
        if (configFileName && !host.configFileParsingResult) {
            newLine = ts.getNewLineCharacter(optionsToExtendForConfigFile, function () { return host.getNewLine(); });
            ts.Debug.assert(!rootFileNames);
            parseConfigFile();
            newLine = updateNewLine();
        }
        var _b = ts.createWatchFactory(host, compilerOptions), watchFile = _b.watchFile, watchFilePath = _b.watchFilePath, watchDirectory = _b.watchDirectory, writeLog = _b.writeLog;
        var getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        writeLog("Current directory: " + currentDirectory + " CaseSensitiveFileNames: " + useCaseSensitiveFileNames);
        var configFileWatcher;
        if (configFileName) {
            configFileWatcher = watchFile(host, configFileName, scheduleProgramReload, ts.PollingInterval.High, "Config file" /* ConfigFile */);
        }
        var compilerHost = ts.createCompilerHostFromProgramHost(host, function () { return compilerOptions; }, directoryStructureHost);
        ts.setGetSourceFileAsHashVersioned(compilerHost, host);
        // Members for CompilerHost
        var getNewSourceFile = compilerHost.getSourceFile;
        compilerHost.getSourceFile = function (fileName) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            return getVersionedSourceFileByPath.apply(void 0, [fileName, toPath(fileName)].concat(args));
        };
        compilerHost.getSourceFileByPath = getVersionedSourceFileByPath;
        compilerHost.getNewLine = function () { return newLine; };
        compilerHost.fileExists = fileExists;
        compilerHost.onReleaseOldSourceFile = onReleaseOldSourceFile;
        // Members for ResolutionCacheHost
        compilerHost.toPath = toPath;
        compilerHost.getCompilationSettings = function () { return compilerOptions; };
        compilerHost.watchDirectoryOfFailedLookupLocation = function (dir, cb, flags) { return watchDirectory(host, dir, cb, flags, "Failed Lookup Locations" /* FailedLookupLocations */); };
        compilerHost.watchTypeRootsDirectory = function (dir, cb, flags) { return watchDirectory(host, dir, cb, flags, "Type roots" /* TypeRoots */); };
        compilerHost.getCachedDirectoryStructureHost = function () { return cachedDirectoryStructureHost; };
        compilerHost.onInvalidatedResolution = scheduleProgramUpdate;
        compilerHost.onChangedAutomaticTypeDirectiveNames = function () {
            hasChangedAutomaticTypeDirectiveNames = true;
            scheduleProgramUpdate();
        };
        compilerHost.fileIsOpen = ts.returnFalse;
        compilerHost.maxNumberOfFilesToIterateForInvalidation = host.maxNumberOfFilesToIterateForInvalidation;
        compilerHost.getCurrentProgram = getCurrentProgram;
        compilerHost.writeLog = writeLog;
        // Cache for the module resolution
        var resolutionCache = ts.createResolutionCache(compilerHost, configFileName ?
            ts.getDirectoryPath(ts.getNormalizedAbsolutePath(configFileName, currentDirectory)) :
            currentDirectory, 
        /*logChangesWhenResolvingModule*/ false);
        // Resolve module using host module resolution strategy if provided otherwise use resolution cache to resolve module names
        compilerHost.resolveModuleNames = host.resolveModuleNames ?
            (function (moduleNames, containingFile, reusedNames, redirectedReference) { return host.resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference); }) :
            (function (moduleNames, containingFile, reusedNames, redirectedReference) { return resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference); });
        compilerHost.resolveTypeReferenceDirectives = host.resolveTypeReferenceDirectives ?
            (function (typeDirectiveNames, containingFile, redirectedReference) { return host.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile, redirectedReference); }) :
            (function (typeDirectiveNames, containingFile, redirectedReference) { return resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile, redirectedReference); });
        var userProvidedResolution = !!host.resolveModuleNames || !!host.resolveTypeReferenceDirectives;
        builderProgram = ts.readBuilderProgram(compilerOptions, function (path) { return compilerHost.readFile(path); });
        synchronizeProgram();
        // Update the wild card directory watch
        watchConfigFileWildCardDirectories();
        return configFileName ?
            { getCurrentProgram: getCurrentBuilderProgram, getProgram: synchronizeProgram, close: close } :
            { getCurrentProgram: getCurrentBuilderProgram, getProgram: synchronizeProgram, updateRootFileNames: updateRootFileNames, close: close };
        function close() {
            resolutionCache.clear();
            ts.clearMap(sourceFilesCache, function (value) {
                if (value && value.fileWatcher) {
                    value.fileWatcher.close();
                    value.fileWatcher = undefined;
                }
            });
            if (configFileWatcher) {
                configFileWatcher.close();
                configFileWatcher = undefined;
            }
            if (watchedWildcardDirectories) {
                ts.clearMap(watchedWildcardDirectories, ts.closeFileWatcherOf);
                watchedWildcardDirectories = undefined;
            }
            if (missingFilesMap) {
                ts.clearMap(missingFilesMap, ts.closeFileWatcher);
                missingFilesMap = undefined;
            }
        }
        function getCurrentBuilderProgram() {
            return builderProgram;
        }
        function getCurrentProgram() {
            return builderProgram && builderProgram.getProgramOrUndefined();
        }
        function synchronizeProgram() {
            writeLog("Synchronizing program");
            var program = getCurrentBuilderProgram();
            if (hasChangedCompilerOptions) {
                newLine = updateNewLine();
                if (program && ts.changesAffectModuleResolution(program.getCompilerOptions(), compilerOptions)) {
                    resolutionCache.clear();
                }
            }
            // All resolutions are invalid if user provided resolutions
            var hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution);
            if (ts.isProgramUptoDate(getCurrentProgram(), rootFileNames, compilerOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, projectReferences)) {
                if (hasChangedConfigFileParsingErrors) {
                    builderProgram = createProgram(/*rootNames*/ undefined, /*options*/ undefined, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
                    hasChangedConfigFileParsingErrors = false;
                }
            }
            else {
                createNewProgram(hasInvalidatedResolution);
            }
            if (host.afterProgramCreate) {
                host.afterProgramCreate(builderProgram);
            }
            return builderProgram;
        }
        function createNewProgram(hasInvalidatedResolution) {
            // Compile the program
            writeLog("CreatingProgramWith::");
            writeLog("  roots: " + JSON.stringify(rootFileNames));
            writeLog("  options: " + JSON.stringify(compilerOptions));
            var needsUpdateInTypeRootWatch = hasChangedCompilerOptions || !getCurrentProgram();
            hasChangedCompilerOptions = false;
            hasChangedConfigFileParsingErrors = false;
            resolutionCache.startCachingPerDirectoryResolution();
            compilerHost.hasInvalidatedResolution = hasInvalidatedResolution;
            compilerHost.hasChangedAutomaticTypeDirectiveNames = hasChangedAutomaticTypeDirectiveNames;
            builderProgram = createProgram(rootFileNames, compilerOptions, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
            resolutionCache.finishCachingPerDirectoryResolution();
            // Update watches
            ts.updateMissingFilePathsWatch(builderProgram.getProgram(), missingFilesMap || (missingFilesMap = ts.createMap()), watchMissingFilePath);
            if (needsUpdateInTypeRootWatch) {
                resolutionCache.updateTypeRootsWatch();
            }
            if (missingFilePathsRequestedForRelease) {
                // These are the paths that program creater told us as not in use any more but were missing on the disk.
                // We didnt remove the entry for them from sourceFiles cache so that we dont have to do File IO,
                // if there is already watcher for it (for missing files)
                // At this point our watches were updated, hence now we know that these paths are not tracked and need to be removed
                // so that at later time we have correct result of their presence
                for (var _i = 0, missingFilePathsRequestedForRelease_1 = missingFilePathsRequestedForRelease; _i < missingFilePathsRequestedForRelease_1.length; _i++) {
                    var missingFilePath = missingFilePathsRequestedForRelease_1[_i];
                    if (!missingFilesMap.has(missingFilePath)) {
                        sourceFilesCache.delete(missingFilePath);
                    }
                }
                missingFilePathsRequestedForRelease = undefined;
            }
        }
        function updateRootFileNames(files) {
            ts.Debug.assert(!configFileName, "Cannot update root file names with config file watch mode");
            rootFileNames = files;
            scheduleProgramUpdate();
        }
        function updateNewLine() {
            return ts.getNewLineCharacter(compilerOptions || optionsToExtendForConfigFile, function () { return host.getNewLine(); });
        }
        function toPath(fileName) {
            return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
        }
        function isFileMissingOnHost(hostSourceFile) {
            return typeof hostSourceFile === "boolean";
        }
        function isFilePresenceUnknownOnHost(hostSourceFile) {
            return typeof hostSourceFile.version === "boolean";
        }
        function fileExists(fileName) {
            var path = toPath(fileName);
            // If file is missing on host from cache, we can definitely say file doesnt exist
            // otherwise we need to ensure from the disk
            if (isFileMissingOnHost(sourceFilesCache.get(path))) {
                return true;
            }
            return directoryStructureHost.fileExists(fileName);
        }
        function getVersionedSourceFileByPath(fileName, path, languageVersion, onError, shouldCreateNewSourceFile) {
            var hostSourceFile = sourceFilesCache.get(path);
            // No source file on the host
            if (isFileMissingOnHost(hostSourceFile)) {
                return undefined;
            }
            // Create new source file if requested or the versions dont match
            if (hostSourceFile === undefined || shouldCreateNewSourceFile || isFilePresenceUnknownOnHost(hostSourceFile)) {
                var sourceFile = getNewSourceFile(fileName, languageVersion, onError);
                if (hostSourceFile) {
                    if (sourceFile) {
                        // Set the source file and create file watcher now that file was present on the disk
                        hostSourceFile.sourceFile = sourceFile;
                        hostSourceFile.version = sourceFile.version;
                        if (!hostSourceFile.fileWatcher) {
                            hostSourceFile.fileWatcher = watchFilePath(host, fileName, onSourceFileChange, ts.PollingInterval.Low, path, "Source file" /* SourceFile */);
                        }
                    }
                    else {
                        // There is no source file on host any more, close the watch, missing file paths will track it
                        if (hostSourceFile.fileWatcher) {
                            hostSourceFile.fileWatcher.close();
                        }
                        sourceFilesCache.set(path, false);
                    }
                }
                else {
                    if (sourceFile) {
                        var fileWatcher = watchFilePath(host, fileName, onSourceFileChange, ts.PollingInterval.Low, path, "Source file" /* SourceFile */);
                        sourceFilesCache.set(path, { sourceFile: sourceFile, version: sourceFile.version, fileWatcher: fileWatcher });
                    }
                    else {
                        sourceFilesCache.set(path, false);
                    }
                }
                return sourceFile;
            }
            return hostSourceFile.sourceFile;
        }
        function nextSourceFileVersion(path) {
            var hostSourceFile = sourceFilesCache.get(path);
            if (hostSourceFile !== undefined) {
                if (isFileMissingOnHost(hostSourceFile)) {
                    // The next version, lets set it as presence unknown file
                    sourceFilesCache.set(path, { version: false });
                }
                else {
                    hostSourceFile.version = false;
                }
            }
        }
        function getSourceVersion(path) {
            var hostSourceFile = sourceFilesCache.get(path);
            return !hostSourceFile || !hostSourceFile.version ? undefined : hostSourceFile.version;
        }
        function onReleaseOldSourceFile(oldSourceFile, _oldOptions, hasSourceFileByPath) {
            var hostSourceFileInfo = sourceFilesCache.get(oldSourceFile.resolvedPath);
            // If this is the source file thats in the cache and new program doesnt need it,
            // remove the cached entry.
            // Note we arent deleting entry if file became missing in new program or
            // there was version update and new source file was created.
            if (hostSourceFileInfo !== undefined) {
                // record the missing file paths so they can be removed later if watchers arent tracking them
                if (isFileMissingOnHost(hostSourceFileInfo)) {
                    (missingFilePathsRequestedForRelease || (missingFilePathsRequestedForRelease = [])).push(oldSourceFile.path);
                }
                else if (hostSourceFileInfo.sourceFile === oldSourceFile) {
                    if (hostSourceFileInfo.fileWatcher) {
                        hostSourceFileInfo.fileWatcher.close();
                    }
                    sourceFilesCache.delete(oldSourceFile.resolvedPath);
                    if (!hasSourceFileByPath) {
                        resolutionCache.removeResolutionsOfFile(oldSourceFile.path);
                    }
                }
            }
        }
        function reportWatchDiagnostic(message) {
            if (host.onWatchStatusChange) {
                host.onWatchStatusChange(ts.createCompilerDiagnostic(message), newLine, compilerOptions || optionsToExtendForConfigFile);
            }
        }
        // Upon detecting a file change, wait for 250ms and then perform a recompilation. This gives batch
        // operations (such as saving all modified files in an editor) a chance to complete before we kick
        // off a new compilation.
        function scheduleProgramUpdate() {
            if (!host.setTimeout || !host.clearTimeout) {
                return;
            }
            if (timerToUpdateProgram) {
                host.clearTimeout(timerToUpdateProgram);
            }
            writeLog("Scheduling update");
            timerToUpdateProgram = host.setTimeout(updateProgram, 250);
        }
        function scheduleProgramReload() {
            ts.Debug.assert(!!configFileName);
            reloadLevel = ts.ConfigFileProgramReloadLevel.Full;
            scheduleProgramUpdate();
        }
        function updateProgram() {
            timerToUpdateProgram = undefined;
            reportWatchDiagnostic(ts.Diagnostics.File_change_detected_Starting_incremental_compilation);
            switch (reloadLevel) {
                case ts.ConfigFileProgramReloadLevel.Partial:
                    return reloadFileNamesFromConfigFile();
                case ts.ConfigFileProgramReloadLevel.Full:
                    return reloadConfigFile();
                default:
                    synchronizeProgram();
                    return;
            }
        }
        function reloadFileNamesFromConfigFile() {
            writeLog("Reloading new file names and options");
            var result = ts.getFileNamesFromConfigSpecs(configFileSpecs, ts.getDirectoryPath(configFileName), compilerOptions, parseConfigFileHost);
            if (ts.updateErrorForNoInputFiles(result, configFileName, configFileSpecs, configFileParsingDiagnostics, canConfigFileJsonReportNoInputFiles)) {
                hasChangedConfigFileParsingErrors = true;
            }
            rootFileNames = result.fileNames;
            // Update the program
            synchronizeProgram();
        }
        function reloadConfigFile() {
            writeLog("Reloading config file: " + configFileName);
            reloadLevel = ts.ConfigFileProgramReloadLevel.None;
            if (cachedDirectoryStructureHost) {
                cachedDirectoryStructureHost.clearCache();
            }
            parseConfigFile();
            hasChangedCompilerOptions = true;
            synchronizeProgram();
            // Update the wild card directory watch
            watchConfigFileWildCardDirectories();
        }
        function parseConfigFile() {
            setConfigFileParsingResult(ts.getParsedCommandLineOfConfigFile(configFileName, optionsToExtendForConfigFile, parseConfigFileHost)); // TODO: GH#18217
        }
        function setConfigFileParsingResult(configFileParseResult) {
            rootFileNames = configFileParseResult.fileNames;
            compilerOptions = configFileParseResult.options;
            configFileSpecs = configFileParseResult.configFileSpecs; // TODO: GH#18217
            projectReferences = configFileParseResult.projectReferences;
            configFileParsingDiagnostics = ts.getConfigFileParsingDiagnostics(configFileParseResult).slice();
            canConfigFileJsonReportNoInputFiles = ts.canJsonReportNoInutFiles(configFileParseResult.raw);
            hasChangedConfigFileParsingErrors = true;
        }
        function onSourceFileChange(fileName, eventKind, path) {
            updateCachedSystemWithFile(fileName, path, eventKind);
            // Update the source file cache
            if (eventKind === ts.FileWatcherEventKind.Deleted && sourceFilesCache.has(path)) {
                resolutionCache.invalidateResolutionOfFile(path);
            }
            resolutionCache.removeResolutionsFromProjectReferenceRedirects(path);
            nextSourceFileVersion(path);
            // Update the program
            scheduleProgramUpdate();
        }
        function updateCachedSystemWithFile(fileName, path, eventKind) {
            if (cachedDirectoryStructureHost) {
                cachedDirectoryStructureHost.addOrDeleteFile(fileName, path, eventKind);
            }
        }
        function watchMissingFilePath(missingFilePath) {
            return watchFilePath(host, missingFilePath, onMissingFileChange, ts.PollingInterval.Medium, missingFilePath, "Missing file" /* MissingFile */);
        }
        function onMissingFileChange(fileName, eventKind, missingFilePath) {
            updateCachedSystemWithFile(fileName, missingFilePath, eventKind);
            if (eventKind === ts.FileWatcherEventKind.Created && missingFilesMap.has(missingFilePath)) {
                missingFilesMap.get(missingFilePath).close();
                missingFilesMap.delete(missingFilePath);
                // Delete the entry in the source files cache so that new source file is created
                nextSourceFileVersion(missingFilePath);
                // When a missing file is created, we should update the graph.
                scheduleProgramUpdate();
            }
        }
        function watchConfigFileWildCardDirectories() {
            if (configFileSpecs) {
                ts.updateWatchingWildcardDirectories(watchedWildcardDirectories || (watchedWildcardDirectories = ts.createMap()), ts.createMapFromTemplate(configFileSpecs.wildcardDirectories), watchWildcardDirectory);
            }
            else if (watchedWildcardDirectories) {
                ts.clearMap(watchedWildcardDirectories, ts.closeFileWatcherOf);
            }
        }
        function watchWildcardDirectory(directory, flags) {
            return watchDirectory(host, directory, function (fileOrDirectory) {
                ts.Debug.assert(!!configFileName);
                var fileOrDirectoryPath = toPath(fileOrDirectory);
                // Since the file existance changed, update the sourceFiles cache
                if (cachedDirectoryStructureHost) {
                    cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
                }
                nextSourceFileVersion(fileOrDirectoryPath);
                if (ts.isPathIgnored(fileOrDirectoryPath))
                    return;
                // If the the added or created file or directory is not supported file name, ignore the file
                // But when watched directory is added/removed, we need to reload the file list
                if (fileOrDirectoryPath !== directory && ts.hasExtension(fileOrDirectoryPath) && !ts.isSupportedSourceFileName(fileOrDirectory, compilerOptions)) {
                    writeLog("Project: " + configFileName + " Detected file add/remove of non supported extension: " + fileOrDirectory);
                    return;
                }
                // Reload is pending, do the reload
                if (reloadLevel !== ts.ConfigFileProgramReloadLevel.Full) {
                    reloadLevel = ts.ConfigFileProgramReloadLevel.Partial;
                    // Schedule Update the program
                    scheduleProgramUpdate();
                }
            }, flags, "Wild card directory" /* WildcardDirectory */);
        }
    }
    ts.createWatchProgram = createWatchProgram;
})(ts || (ts = {}));
// Currently we do not want to expose API for build, we should work out the API, and then expose it just like we did for builder/watch
/*@internal*/
var ts;
(function (ts) {
    var minimumDate = new Date(-8640000000000000);
    var maximumDate = new Date(8640000000000000);
    var BuildResultFlags;
    (function (BuildResultFlags) {
        BuildResultFlags[BuildResultFlags["None"] = 0] = "None";
        /**
         * No errors of any kind occurred during build
         */
        BuildResultFlags[BuildResultFlags["Success"] = 1] = "Success";
        /**
         * None of the .d.ts files emitted by this build were
         * different from the existing files on disk
         */
        BuildResultFlags[BuildResultFlags["DeclarationOutputUnchanged"] = 2] = "DeclarationOutputUnchanged";
        BuildResultFlags[BuildResultFlags["ConfigFileErrors"] = 4] = "ConfigFileErrors";
        BuildResultFlags[BuildResultFlags["SyntaxErrors"] = 8] = "SyntaxErrors";
        BuildResultFlags[BuildResultFlags["TypeErrors"] = 16] = "TypeErrors";
        BuildResultFlags[BuildResultFlags["DeclarationEmitErrors"] = 32] = "DeclarationEmitErrors";
        BuildResultFlags[BuildResultFlags["EmitErrors"] = 64] = "EmitErrors";
        BuildResultFlags[BuildResultFlags["AnyErrors"] = 124] = "AnyErrors";
    })(BuildResultFlags || (BuildResultFlags = {}));
    var UpToDateStatusType;
    (function (UpToDateStatusType) {
        UpToDateStatusType[UpToDateStatusType["Unbuildable"] = 0] = "Unbuildable";
        UpToDateStatusType[UpToDateStatusType["UpToDate"] = 1] = "UpToDate";
        /**
         * The project appears out of date because its upstream inputs are newer than its outputs,
         * but all of its outputs are actually newer than the previous identical outputs of its (.d.ts) inputs.
         * This means we can Pseudo-build (just touch timestamps), as if we had actually built this project.
         */
        UpToDateStatusType[UpToDateStatusType["UpToDateWithUpstreamTypes"] = 2] = "UpToDateWithUpstreamTypes";
        /**
         * The project appears out of date because its upstream inputs are newer than its outputs,
         * but all of its outputs are actually newer than the previous identical outputs of its (.d.ts) inputs.
         * This means we can Pseudo-build (just manipulate outputs), as if we had actually built this project.
         */
        UpToDateStatusType[UpToDateStatusType["OutOfDateWithPrepend"] = 3] = "OutOfDateWithPrepend";
        UpToDateStatusType[UpToDateStatusType["OutputMissing"] = 4] = "OutputMissing";
        UpToDateStatusType[UpToDateStatusType["OutOfDateWithSelf"] = 5] = "OutOfDateWithSelf";
        UpToDateStatusType[UpToDateStatusType["OutOfDateWithUpstream"] = 6] = "OutOfDateWithUpstream";
        UpToDateStatusType[UpToDateStatusType["UpstreamOutOfDate"] = 7] = "UpstreamOutOfDate";
        UpToDateStatusType[UpToDateStatusType["UpstreamBlocked"] = 8] = "UpstreamBlocked";
        UpToDateStatusType[UpToDateStatusType["ComputingUpstream"] = 9] = "ComputingUpstream";
        UpToDateStatusType[UpToDateStatusType["TsVersionOutputOfDate"] = 10] = "TsVersionOutputOfDate";
        /**
         * Projects with no outputs (i.e. "solution" files)
         */
        UpToDateStatusType[UpToDateStatusType["ContainerOnly"] = 11] = "ContainerOnly";
    })(UpToDateStatusType = ts.UpToDateStatusType || (ts.UpToDateStatusType = {}));
    function createFileMap(toPath) {
        // tslint:disable-next-line:no-null-keyword
        var lookup = ts.createMap();
        return {
            setValue: setValue,
            getValue: getValue,
            removeKey: removeKey,
            forEach: forEach,
            hasKey: hasKey,
            getSize: getSize,
            clear: clear
        };
        function forEach(action) {
            lookup.forEach(action);
        }
        function hasKey(fileName) {
            return lookup.has(toPath(fileName));
        }
        function removeKey(fileName) {
            lookup.delete(toPath(fileName));
        }
        function setValue(fileName, value) {
            lookup.set(toPath(fileName), value);
        }
        function getValue(fileName) {
            return lookup.get(toPath(fileName));
        }
        function getSize() {
            return lookup.size;
        }
        function clear() {
            lookup.clear();
        }
    }
    function getOrCreateValueFromConfigFileMap(configFileMap, resolved, createT) {
        var existingValue = configFileMap.getValue(resolved);
        var newValue;
        if (!existingValue) {
            newValue = createT();
            configFileMap.setValue(resolved, newValue);
        }
        return existingValue || newValue;
    }
    function getOrCreateValueMapFromConfigFileMap(configFileMap, resolved) {
        return getOrCreateValueFromConfigFileMap(configFileMap, resolved, ts.createMap);
    }
    function newer(date1, date2) {
        return date2 > date1 ? date2 : date1;
    }
    function isDeclarationFile(fileName) {
        return ts.fileExtensionIs(fileName, ".d.ts" /* Dts */);
    }
    /**
     * Create a function that reports watch status by writing to the system and handles the formating of the diagnostic
     */
    function createBuilderStatusReporter(system, pretty) {
        return function (diagnostic) {
            var output = pretty ? "[" + ts.formatColorAndReset(new Date().toLocaleTimeString(), ts.ForegroundColorEscapeSequences.Grey) + "] " : new Date().toLocaleTimeString() + " - ";
            output += "" + ts.flattenDiagnosticMessageText(diagnostic.messageText, system.newLine) + (system.newLine + system.newLine);
            system.write(output);
        };
    }
    ts.createBuilderStatusReporter = createBuilderStatusReporter;
    function createSolutionBuilderHostBase(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus) {
        var host = ts.createProgramHost(system, createProgram);
        host.getModifiedTime = system.getModifiedTime ? function (path) { return system.getModifiedTime(path); } : ts.returnUndefined;
        host.setModifiedTime = system.setModifiedTime ? function (path, date) { return system.setModifiedTime(path, date); } : ts.noop;
        host.deleteFile = system.deleteFile ? function (path) { return system.deleteFile(path); } : ts.noop;
        host.reportDiagnostic = reportDiagnostic || ts.createDiagnosticReporter(system);
        host.reportSolutionBuilderStatus = reportSolutionBuilderStatus || createBuilderStatusReporter(system);
        return host;
    }
    function createSolutionBuilderHost(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus, reportErrorSummary) {
        if (system === void 0) { system = ts.sys; }
        var host = createSolutionBuilderHostBase(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus);
        host.reportErrorSummary = reportErrorSummary;
        return host;
    }
    ts.createSolutionBuilderHost = createSolutionBuilderHost;
    function createSolutionBuilderWithWatchHost(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus, reportWatchStatus) {
        if (system === void 0) { system = ts.sys; }
        var host = createSolutionBuilderHostBase(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus);
        var watchHost = ts.createWatchHost(system, reportWatchStatus);
        ts.copyProperties(host, watchHost);
        return host;
    }
    ts.createSolutionBuilderWithWatchHost = createSolutionBuilderWithWatchHost;
    function getCompilerOptionsOfBuildOptions(buildOptions) {
        var result = {};
        ts.commonOptionsWithBuild.forEach(function (option) {
            if (ts.hasProperty(buildOptions, option.name))
                result[option.name] = buildOptions[option.name];
        });
        return result;
    }
    function createSolutionBuilder(host, rootNames, defaultOptions) {
        var hostWithWatch = host;
        var currentDirectory = host.getCurrentDirectory();
        var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames());
        var parseConfigFileHost = ts.parseConfigHostFromCompilerHostLike(host);
        // State of the solution
        var options = defaultOptions;
        var baseCompilerOptions = getCompilerOptionsOfBuildOptions(options);
        var configFileCache = createFileMap(toPath);
        /** Map from output file name to its pre-build timestamp */
        var unchangedOutputs = createFileMap(toPath);
        /** Map from config file name to up-to-date status */
        var projectStatus = createFileMap(toPath);
        var missingRoots = ts.createMap();
        var globalDependencyGraph;
        var writeFileName = host.trace ? function (s) { return host.trace(s); } : undefined;
        var readFileWithCache = function (f) { return host.readFile(f); };
        var projectCompilerOptions = baseCompilerOptions;
        var compilerHost = ts.createCompilerHostFromProgramHost(host, function () { return projectCompilerOptions; });
        ts.setGetSourceFileAsHashVersioned(compilerHost, host);
        compilerHost.getParsedCommandLine = parseConfigFile;
        compilerHost.resolveModuleNames = ts.maybeBind(host, host.resolveModuleNames);
        compilerHost.resolveTypeReferenceDirectives = ts.maybeBind(host, host.resolveTypeReferenceDirectives);
        var moduleResolutionCache = !compilerHost.resolveModuleNames ? ts.createModuleResolutionCache(currentDirectory, getCanonicalFileName) : undefined;
        var cacheState;
        var buildInfoChecked = createFileMap(toPath);
        var extendedConfigCache = ts.createMap();
        // Watch state
        var builderPrograms = createFileMap(toPath);
        var diagnostics = createFileMap(toPath);
        var projectPendingBuild = createFileMap(toPath);
        var projectErrorsReported = createFileMap(toPath);
        var invalidatedProjectQueue = [];
        var nextProjectToBuild = 0;
        var timerToBuildInvalidatedProject;
        var reportFileChangeDetected = false;
        var _a = ts.createWatchFactory(host, options), watchFile = _a.watchFile, watchFilePath = _a.watchFilePath, watchDirectory = _a.watchDirectory, writeLog = _a.writeLog;
        // Watches for the solution
        var allWatchedWildcardDirectories = createFileMap(toPath);
        var allWatchedInputFiles = createFileMap(toPath);
        var allWatchedConfigFiles = createFileMap(toPath);
        return {
            buildAllProjects: buildAllProjects,
            getUpToDateStatusOfFile: getUpToDateStatusOfFile,
            cleanAllProjects: cleanAllProjects,
            resetBuildContext: resetBuildContext,
            getBuildGraph: getBuildGraph,
            invalidateProject: invalidateProject,
            buildInvalidatedProject: buildInvalidatedProject,
            resolveProjectName: resolveProjectName,
            startWatching: startWatching
        };
        function toPath(fileName) {
            return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
        }
        function resetBuildContext(opts) {
            if (opts === void 0) { opts = defaultOptions; }
            options = opts;
            baseCompilerOptions = getCompilerOptionsOfBuildOptions(options);
            configFileCache.clear();
            unchangedOutputs.clear();
            projectStatus.clear();
            missingRoots.clear();
            globalDependencyGraph = undefined;
            buildInfoChecked.clear();
            diagnostics.clear();
            projectPendingBuild.clear();
            projectErrorsReported.clear();
            invalidatedProjectQueue.length = 0;
            nextProjectToBuild = 0;
            if (timerToBuildInvalidatedProject) {
                clearTimeout(timerToBuildInvalidatedProject);
                timerToBuildInvalidatedProject = undefined;
            }
            reportFileChangeDetected = false;
            ts.clearMap(allWatchedWildcardDirectories, function (wildCardWatches) { return ts.clearMap(wildCardWatches, ts.closeFileWatcherOf); });
            ts.clearMap(allWatchedInputFiles, function (inputFileWatches) { return ts.clearMap(inputFileWatches, ts.closeFileWatcher); });
            ts.clearMap(allWatchedConfigFiles, ts.closeFileWatcher);
            builderPrograms.clear();
        }
        function isParsedCommandLine(entry) {
            return !!entry.options;
        }
        function parseConfigFile(configFilePath) {
            var value = configFileCache.getValue(configFilePath);
            if (value) {
                return isParsedCommandLine(value) ? value : undefined;
            }
            var diagnostic;
            parseConfigFileHost.onUnRecoverableConfigFileDiagnostic = function (d) { return diagnostic = d; };
            var parsed = ts.getParsedCommandLineOfConfigFile(configFilePath, baseCompilerOptions, parseConfigFileHost, extendedConfigCache);
            parseConfigFileHost.onUnRecoverableConfigFileDiagnostic = ts.noop;
            configFileCache.setValue(configFilePath, parsed || diagnostic);
            return parsed;
        }
        function reportStatus(message) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            host.reportSolutionBuilderStatus(ts.createCompilerDiagnostic.apply(void 0, [message].concat(args)));
        }
        function reportWatchStatus(message) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            if (hostWithWatch.onWatchStatusChange) {
                hostWithWatch.onWatchStatusChange(ts.createCompilerDiagnostic.apply(void 0, [message].concat(args)), host.getNewLine(), baseCompilerOptions);
            }
        }
        function startWatching() {
            var graph = getGlobalDependencyGraph();
            for (var _i = 0, _a = graph.buildQueue; _i < _a.length; _i++) {
                var resolved = _a[_i];
                // Watch this file
                watchConfigFile(resolved);
                var cfg = parseConfigFile(resolved);
                if (cfg) {
                    // Update watchers for wildcard directories
                    watchWildCardDirectories(resolved, cfg);
                    // Watch input files
                    watchInputFiles(resolved, cfg);
                }
            }
        }
        function watchConfigFile(resolved) {
            if (options.watch && !allWatchedConfigFiles.hasKey(resolved)) {
                allWatchedConfigFiles.setValue(resolved, watchFile(hostWithWatch, resolved, function () {
                    invalidateProjectAndScheduleBuilds(resolved, ts.ConfigFileProgramReloadLevel.Full);
                }, ts.PollingInterval.High, "Config file" /* ConfigFile */, resolved));
            }
        }
        function watchWildCardDirectories(resolved, parsed) {
            if (!options.watch)
                return;
            ts.updateWatchingWildcardDirectories(getOrCreateValueMapFromConfigFileMap(allWatchedWildcardDirectories, resolved), ts.createMapFromTemplate(parsed.configFileSpecs.wildcardDirectories), function (dir, flags) {
                return watchDirectory(hostWithWatch, dir, function (fileOrDirectory) {
                    var fileOrDirectoryPath = toPath(fileOrDirectory);
                    if (fileOrDirectoryPath !== toPath(dir) && ts.hasExtension(fileOrDirectoryPath) && !ts.isSupportedSourceFileName(fileOrDirectory, parsed.options)) {
                        writeLog("Project: " + resolved + " Detected file add/remove of non supported extension: " + fileOrDirectory);
                        return;
                    }
                    if (isOutputFile(fileOrDirectory, parsed)) {
                        writeLog(fileOrDirectory + " is output file");
                        return;
                    }
                    invalidateProjectAndScheduleBuilds(resolved, ts.ConfigFileProgramReloadLevel.Partial);
                }, flags, "Wild card directory" /* WildcardDirectory */, resolved);
            });
        }
        function watchInputFiles(resolved, parsed) {
            if (!options.watch)
                return;
            ts.mutateMap(getOrCreateValueMapFromConfigFileMap(allWatchedInputFiles, resolved), ts.arrayToMap(parsed.fileNames, toPath), {
                createNewValue: function (path, input) { return watchFilePath(hostWithWatch, input, function () { return invalidateProjectAndScheduleBuilds(resolved, ts.ConfigFileProgramReloadLevel.None); }, ts.PollingInterval.Low, path, "Source file" /* SourceFile */, resolved); },
                onDeleteValue: ts.closeFileWatcher,
            });
        }
        function isOutputFile(fileName, configFile) {
            if (configFile.options.noEmit)
                return false;
            // ts or tsx files are not output
            if (!ts.fileExtensionIs(fileName, ".d.ts" /* Dts */) &&
                (ts.fileExtensionIs(fileName, ".ts" /* Ts */) || ts.fileExtensionIs(fileName, ".tsx" /* Tsx */))) {
                return false;
            }
            // If options have --outFile or --out, check if its that
            var out = configFile.options.outFile || configFile.options.out;
            if (out && (isSameFile(fileName, out) || isSameFile(fileName, ts.removeFileExtension(out) + ".d.ts" /* Dts */))) {
                return true;
            }
            // If declarationDir is specified, return if its a file in that directory
            if (configFile.options.declarationDir && ts.containsPath(configFile.options.declarationDir, fileName, currentDirectory, !host.useCaseSensitiveFileNames())) {
                return true;
            }
            // If --outDir, check if file is in that directory
            if (configFile.options.outDir && ts.containsPath(configFile.options.outDir, fileName, currentDirectory, !host.useCaseSensitiveFileNames())) {
                return true;
            }
            return !ts.forEach(configFile.fileNames, function (inputFile) { return isSameFile(fileName, inputFile); });
        }
        function isSameFile(file1, file2) {
            return ts.comparePaths(file1, file2, currentDirectory, !host.useCaseSensitiveFileNames()) === 0 /* EqualTo */;
        }
        function invalidateProjectAndScheduleBuilds(resolved, reloadLevel) {
            reportFileChangeDetected = true;
            invalidateResolvedProject(resolved, reloadLevel);
            scheduleBuildInvalidatedProject();
        }
        function getUpToDateStatusOfFile(configFileName) {
            return getUpToDateStatus(parseConfigFile(configFileName));
        }
        function getBuildGraph(configFileNames) {
            return createDependencyGraph(resolveProjectNames(configFileNames));
        }
        function getGlobalDependencyGraph() {
            return globalDependencyGraph || (globalDependencyGraph = getBuildGraph(rootNames));
        }
        function getUpToDateStatus(project) {
            if (project === undefined) {
                return { type: UpToDateStatusType.Unbuildable, reason: "File deleted mid-build" };
            }
            var prior = projectStatus.getValue(project.options.configFilePath);
            if (prior !== undefined) {
                return prior;
            }
            var actual = getUpToDateStatusWorker(project);
            projectStatus.setValue(project.options.configFilePath, actual);
            return actual;
        }
        function getUpToDateStatusWorker(project) {
            var newestInputFileName = undefined;
            var newestInputFileTime = minimumDate;
            // Get timestamps of input files
            for (var _i = 0, _a = project.fileNames; _i < _a.length; _i++) {
                var inputFile = _a[_i];
                if (!host.fileExists(inputFile)) {
                    return {
                        type: UpToDateStatusType.Unbuildable,
                        reason: inputFile + " does not exist"
                    };
                }
                var inputTime = host.getModifiedTime(inputFile) || ts.missingFileModifiedTime;
                if (inputTime > newestInputFileTime) {
                    newestInputFileName = inputFile;
                    newestInputFileTime = inputTime;
                }
            }
            // Container if no files are specified in the project
            if (!project.fileNames.length && !ts.canJsonReportNoInutFiles(project.raw)) {
                return {
                    type: UpToDateStatusType.ContainerOnly
                };
            }
            // Collect the expected outputs of this project
            var outputs = ts.getAllProjectOutputs(project, !host.useCaseSensitiveFileNames());
            // Now see if all outputs are newer than the newest input
            var oldestOutputFileName = "(none)";
            var oldestOutputFileTime = maximumDate;
            var newestOutputFileName = "(none)";
            var newestOutputFileTime = minimumDate;
            var missingOutputFileName;
            var newestDeclarationFileContentChangedTime = minimumDate;
            var isOutOfDateWithInputs = false;
            for (var _b = 0, outputs_1 = outputs; _b < outputs_1.length; _b++) {
                var output = outputs_1[_b];
                // Output is missing; can stop checking
                // Don't immediately return because we can still be upstream-blocked, which is a higher-priority status
                if (!host.fileExists(output)) {
                    missingOutputFileName = output;
                    break;
                }
                var outputTime = host.getModifiedTime(output) || ts.missingFileModifiedTime;
                if (outputTime < oldestOutputFileTime) {
                    oldestOutputFileTime = outputTime;
                    oldestOutputFileName = output;
                }
                // If an output is older than the newest input, we can stop checking
                // Don't immediately return because we can still be upstream-blocked, which is a higher-priority status
                if (outputTime < newestInputFileTime) {
                    isOutOfDateWithInputs = true;
                    break;
                }
                if (outputTime > newestOutputFileTime) {
                    newestOutputFileTime = outputTime;
                    newestOutputFileName = output;
                }
                // Keep track of when the most recent time a .d.ts file was changed.
                // In addition to file timestamps, we also keep track of when a .d.ts file
                // had its file touched but not had its contents changed - this allows us
                // to skip a downstream typecheck
                if (isDeclarationFile(output)) {
                    var unchangedTime = unchangedOutputs.getValue(output);
                    if (unchangedTime !== undefined) {
                        newestDeclarationFileContentChangedTime = newer(unchangedTime, newestDeclarationFileContentChangedTime);
                    }
                    else {
                        var outputModifiedTime = host.getModifiedTime(output) || ts.missingFileModifiedTime;
                        newestDeclarationFileContentChangedTime = newer(newestDeclarationFileContentChangedTime, outputModifiedTime);
                    }
                }
            }
            var pseudoUpToDate = false;
            var usesPrepend = false;
            var upstreamChangedProject;
            if (project.projectReferences) {
                projectStatus.setValue(project.options.configFilePath, { type: UpToDateStatusType.ComputingUpstream });
                for (var _c = 0, _d = project.projectReferences; _c < _d.length; _c++) {
                    var ref = _d[_c];
                    usesPrepend = usesPrepend || !!(ref.prepend);
                    var resolvedRef = ts.resolveProjectReferencePath(ref);
                    var refStatus = getUpToDateStatus(parseConfigFile(resolvedRef));
                    // Its a circular reference ignore the status of this project
                    if (refStatus.type === UpToDateStatusType.ComputingUpstream) {
                        continue;
                    }
                    // An upstream project is blocked
                    if (refStatus.type === UpToDateStatusType.Unbuildable) {
                        return {
                            type: UpToDateStatusType.UpstreamBlocked,
                            upstreamProjectName: ref.path
                        };
                    }
                    // If the upstream project is out of date, then so are we (someone shouldn't have asked, though?)
                    if (refStatus.type !== UpToDateStatusType.UpToDate) {
                        return {
                            type: UpToDateStatusType.UpstreamOutOfDate,
                            upstreamProjectName: ref.path
                        };
                    }
                    // Check oldest output file name only if there is no missing output file name
                    if (!missingOutputFileName) {
                        // If the upstream project's newest file is older than our oldest output, we
                        // can't be out of date because of it
                        if (refStatus.newestInputFileTime && refStatus.newestInputFileTime <= oldestOutputFileTime) {
                            continue;
                        }
                        // If the upstream project has only change .d.ts files, and we've built
                        // *after* those files, then we're "psuedo up to date" and eligible for a fast rebuild
                        if (refStatus.newestDeclarationFileContentChangedTime && refStatus.newestDeclarationFileContentChangedTime <= oldestOutputFileTime) {
                            pseudoUpToDate = true;
                            upstreamChangedProject = ref.path;
                            continue;
                        }
                        // We have an output older than an upstream output - we are out of date
                        ts.Debug.assert(oldestOutputFileName !== undefined, "Should have an oldest output filename here");
                        return {
                            type: UpToDateStatusType.OutOfDateWithUpstream,
                            outOfDateOutputFileName: oldestOutputFileName,
                            newerProjectName: ref.path
                        };
                    }
                }
            }
            if (missingOutputFileName !== undefined) {
                return {
                    type: UpToDateStatusType.OutputMissing,
                    missingOutputFileName: missingOutputFileName
                };
            }
            if (isOutOfDateWithInputs) {
                return {
                    type: UpToDateStatusType.OutOfDateWithSelf,
                    outOfDateOutputFileName: oldestOutputFileName,
                    newerInputFileName: newestInputFileName
                };
            }
            else {
                // Check tsconfig time
                var configStatus = checkConfigFileUpToDateStatus(project.options.configFilePath, oldestOutputFileTime, oldestOutputFileName);
                if (configStatus)
                    return configStatus;
                // Check extended config time
                var extendedConfigStatus = ts.forEach(project.options.configFile.extendedSourceFiles || ts.emptyArray, function (configFile) { return checkConfigFileUpToDateStatus(configFile, oldestOutputFileTime, oldestOutputFileName); });
                if (extendedConfigStatus)
                    return extendedConfigStatus;
            }
            if (!buildInfoChecked.hasKey(project.options.configFilePath)) {
                buildInfoChecked.setValue(project.options.configFilePath, true);
                var buildInfoPath = ts.getOutputPathForBuildInfo(project.options);
                if (buildInfoPath) {
                    var value = readFileWithCache(buildInfoPath);
                    var buildInfo = value && ts.getBuildInfo(value);
                    if (buildInfo && buildInfo.version !== ts.version) {
                        return {
                            type: UpToDateStatusType.TsVersionOutputOfDate,
                            version: buildInfo.version
                        };
                    }
                }
            }
            if (usesPrepend && pseudoUpToDate) {
                return {
                    type: UpToDateStatusType.OutOfDateWithPrepend,
                    outOfDateOutputFileName: oldestOutputFileName,
                    newerProjectName: upstreamChangedProject
                };
            }
            // Up to date
            return {
                type: pseudoUpToDate ? UpToDateStatusType.UpToDateWithUpstreamTypes : UpToDateStatusType.UpToDate,
                newestDeclarationFileContentChangedTime: newestDeclarationFileContentChangedTime,
                newestInputFileTime: newestInputFileTime,
                newestOutputFileTime: newestOutputFileTime,
                newestInputFileName: newestInputFileName,
                newestOutputFileName: newestOutputFileName,
                oldestOutputFileName: oldestOutputFileName
            };
        }
        function checkConfigFileUpToDateStatus(configFile, oldestOutputFileTime, oldestOutputFileName) {
            // Check tsconfig time
            var tsconfigTime = host.getModifiedTime(configFile) || ts.missingFileModifiedTime;
            if (oldestOutputFileTime < tsconfigTime) {
                return {
                    type: UpToDateStatusType.OutOfDateWithSelf,
                    outOfDateOutputFileName: oldestOutputFileName,
                    newerInputFileName: configFile
                };
            }
        }
        function invalidateProject(configFileName, reloadLevel) {
            invalidateResolvedProject(resolveProjectName(configFileName), reloadLevel);
        }
        function invalidateResolvedProject(resolved, reloadLevel) {
            if (reloadLevel === ts.ConfigFileProgramReloadLevel.Full) {
                configFileCache.removeKey(resolved);
                globalDependencyGraph = undefined;
            }
            projectStatus.removeKey(resolved);
            diagnostics.removeKey(resolved);
            addProjToQueue(resolved, reloadLevel);
            enableCache();
        }
        /**
         * return true if new addition
         */
        function addProjToQueue(proj, reloadLevel) {
            var value = projectPendingBuild.getValue(proj);
            if (value === undefined) {
                projectPendingBuild.setValue(proj, reloadLevel || ts.ConfigFileProgramReloadLevel.None);
                invalidatedProjectQueue.push(proj);
            }
            else if (value < (reloadLevel || ts.ConfigFileProgramReloadLevel.None)) {
                projectPendingBuild.setValue(proj, reloadLevel || ts.ConfigFileProgramReloadLevel.None);
            }
        }
        function getNextInvalidatedProject() {
            if (nextProjectToBuild < invalidatedProjectQueue.length) {
                var project = invalidatedProjectQueue[nextProjectToBuild];
                nextProjectToBuild++;
                var reloadLevel = projectPendingBuild.getValue(project);
                projectPendingBuild.removeKey(project);
                if (!projectPendingBuild.getSize()) {
                    invalidatedProjectQueue.length = 0;
                    nextProjectToBuild = 0;
                }
                return { project: project, reloadLevel: reloadLevel };
            }
        }
        function hasPendingInvalidatedProjects() {
            return !!projectPendingBuild.getSize();
        }
        function scheduleBuildInvalidatedProject() {
            if (!hostWithWatch.setTimeout || !hostWithWatch.clearTimeout) {
                return;
            }
            if (timerToBuildInvalidatedProject) {
                hostWithWatch.clearTimeout(timerToBuildInvalidatedProject);
            }
            timerToBuildInvalidatedProject = hostWithWatch.setTimeout(buildInvalidatedProject, 250);
        }
        function buildInvalidatedProject() {
            timerToBuildInvalidatedProject = undefined;
            if (reportFileChangeDetected) {
                reportFileChangeDetected = false;
                projectErrorsReported.clear();
                reportWatchStatus(ts.Diagnostics.File_change_detected_Starting_incremental_compilation);
            }
            var buildProject = getNextInvalidatedProject();
            if (buildProject) {
                buildSingleInvalidatedProject(buildProject.project, buildProject.reloadLevel);
                if (hasPendingInvalidatedProjects()) {
                    if (options.watch && !timerToBuildInvalidatedProject) {
                        scheduleBuildInvalidatedProject();
                    }
                }
                else {
                    disableCache();
                    reportErrorSummary();
                }
            }
        }
        function reportErrorSummary() {
            if (options.watch || host.reportErrorSummary) {
                // Report errors from the other projects
                getGlobalDependencyGraph().buildQueue.forEach(function (project) {
                    if (!projectErrorsReported.hasKey(project)) {
                        reportErrors(diagnostics.getValue(project) || ts.emptyArray);
                    }
                });
                var totalErrors_1 = 0;
                diagnostics.forEach(function (singleProjectErrors) { return totalErrors_1 += ts.getErrorCountForSummary(singleProjectErrors); });
                if (options.watch) {
                    reportWatchStatus(ts.getWatchErrorSummaryDiagnosticMessage(totalErrors_1), totalErrors_1);
                }
                else {
                    host.reportErrorSummary(totalErrors_1);
                }
            }
        }
        function buildSingleInvalidatedProject(resolved, reloadLevel) {
            var proj = parseConfigFile(resolved);
            if (!proj) {
                reportParseConfigFileDiagnostic(resolved);
                return;
            }
            if (reloadLevel === ts.ConfigFileProgramReloadLevel.Full) {
                watchConfigFile(resolved);
                watchWildCardDirectories(resolved, proj);
                watchInputFiles(resolved, proj);
            }
            else if (reloadLevel === ts.ConfigFileProgramReloadLevel.Partial) {
                // Update file names
                var result = ts.getFileNamesFromConfigSpecs(proj.configFileSpecs, ts.getDirectoryPath(resolved), proj.options, parseConfigFileHost);
                ts.updateErrorForNoInputFiles(result, resolved, proj.configFileSpecs, proj.errors, ts.canJsonReportNoInutFiles(proj.raw));
                proj.fileNames = result.fileNames;
                watchInputFiles(resolved, proj);
            }
            var status = getUpToDateStatus(proj);
            verboseReportProjectStatus(resolved, status);
            if (status.type === UpToDateStatusType.UpstreamBlocked) {
                if (options.verbose)
                    reportStatus(ts.Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, resolved, status.upstreamProjectName);
                return;
            }
            if (status.type === UpToDateStatusType.UpToDateWithUpstreamTypes) {
                // Fake that files have been built by updating output file stamps
                updateOutputTimestamps(proj);
                return;
            }
            var buildResult = needsBuild(status, resolved) ?
                buildSingleProject(resolved) : // Actual build
                updateBundle(resolved); // Fake that files have been built by manipulating prepend and existing output
            if (buildResult & BuildResultFlags.AnyErrors)
                return;
            var _a = getGlobalDependencyGraph(), referencingProjectsMap = _a.referencingProjectsMap, buildQueue = _a.buildQueue;
            var referencingProjects = referencingProjectsMap.getValue(resolved);
            if (!referencingProjects)
                return;
            // Always use build order to queue projects
            for (var index = buildQueue.indexOf(resolved) + 1; index < buildQueue.length; index++) {
                var project = buildQueue[index];
                var prepend = referencingProjects.getValue(project);
                if (prepend !== undefined) {
                    // If the project is referenced with prepend, always build downstream projects,
                    // If declaration output is changed, build the project
                    // otherwise mark the project UpToDateWithUpstreamTypes so it updates output time stamps
                    var status_1 = projectStatus.getValue(project);
                    if (!(buildResult & BuildResultFlags.DeclarationOutputUnchanged)) {
                        if (status_1 && (status_1.type === UpToDateStatusType.UpToDate || status_1.type === UpToDateStatusType.UpToDateWithUpstreamTypes || status_1.type === UpToDateStatusType.OutOfDateWithPrepend)) {
                            projectStatus.setValue(project, {
                                type: UpToDateStatusType.OutOfDateWithUpstream,
                                outOfDateOutputFileName: status_1.type === UpToDateStatusType.OutOfDateWithPrepend ? status_1.outOfDateOutputFileName : status_1.oldestOutputFileName,
                                newerProjectName: resolved
                            });
                        }
                    }
                    else if (status_1 && status_1.type === UpToDateStatusType.UpToDate) {
                        if (prepend) {
                            projectStatus.setValue(project, {
                                type: UpToDateStatusType.OutOfDateWithPrepend,
                                outOfDateOutputFileName: status_1.oldestOutputFileName,
                                newerProjectName: resolved
                            });
                        }
                        else {
                            status_1.type = UpToDateStatusType.UpToDateWithUpstreamTypes;
                        }
                    }
                    addProjToQueue(project);
                }
            }
        }
        function createDependencyGraph(roots) {
            var temporaryMarks = createFileMap(toPath);
            var permanentMarks = createFileMap(toPath);
            var circularityReportStack = [];
            var buildOrder = [];
            var referencingProjectsMap = createFileMap(toPath);
            for (var _i = 0, roots_1 = roots; _i < roots_1.length; _i++) {
                var root = roots_1[_i];
                visit(root);
            }
            return {
                buildQueue: buildOrder,
                referencingProjectsMap: referencingProjectsMap
            };
            function visit(projPath, inCircularContext) {
                // Already visited
                if (permanentMarks.hasKey(projPath))
                    return;
                // Circular
                if (temporaryMarks.hasKey(projPath)) {
                    if (!inCircularContext) {
                        // TODO:: Do we report this as error?
                        reportStatus(ts.Diagnostics.Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0, circularityReportStack.join("\r\n"));
                    }
                    return;
                }
                temporaryMarks.setValue(projPath, true);
                circularityReportStack.push(projPath);
                var parsed = parseConfigFile(projPath);
                if (parsed && parsed.projectReferences) {
                    for (var _i = 0, _a = parsed.projectReferences; _i < _a.length; _i++) {
                        var ref = _a[_i];
                        var resolvedRefPath = resolveProjectName(ref.path);
                        visit(resolvedRefPath, inCircularContext || ref.circular);
                        // Get projects referencing resolvedRefPath and add projPath to it
                        var referencingProjects = getOrCreateValueFromConfigFileMap(referencingProjectsMap, resolvedRefPath, function () { return createFileMap(toPath); });
                        referencingProjects.setValue(projPath, !!ref.prepend);
                    }
                }
                circularityReportStack.pop();
                permanentMarks.setValue(projPath, true);
                buildOrder.push(projPath);
            }
        }
        function buildSingleProject(proj) {
            if (options.dry) {
                reportStatus(ts.Diagnostics.A_non_dry_build_would_build_project_0, proj);
                return BuildResultFlags.Success;
            }
            if (options.verbose)
                reportStatus(ts.Diagnostics.Building_project_0, proj);
            var resultFlags = BuildResultFlags.DeclarationOutputUnchanged;
            var configFile = parseConfigFile(proj);
            if (!configFile) {
                // Failed to read the config file
                resultFlags |= BuildResultFlags.ConfigFileErrors;
                reportParseConfigFileDiagnostic(proj);
                projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Config file errors" });
                return resultFlags;
            }
            if (configFile.fileNames.length === 0) {
                reportAndStoreErrors(proj, configFile.errors);
                // Nothing to build - must be a solution file, basically
                return BuildResultFlags.None;
            }
            // TODO: handle resolve module name to cache result in project reference redirect
            projectCompilerOptions = configFile.options;
            // Update module resolution cache if needed
            if (moduleResolutionCache) {
                var projPath = toPath(proj);
                if (moduleResolutionCache.directoryToModuleNameMap.redirectsMap.size === 0) {
                    // The own map will be for projectCompilerOptions
                    ts.Debug.assert(moduleResolutionCache.moduleNameToDirectoryMap.redirectsMap.size === 0);
                    moduleResolutionCache.directoryToModuleNameMap.redirectsMap.set(projPath, moduleResolutionCache.directoryToModuleNameMap.ownMap);
                    moduleResolutionCache.moduleNameToDirectoryMap.redirectsMap.set(projPath, moduleResolutionCache.moduleNameToDirectoryMap.ownMap);
                }
                else {
                    // Set correct own map
                    ts.Debug.assert(moduleResolutionCache.moduleNameToDirectoryMap.redirectsMap.size > 0);
                    var ref = {
                        sourceFile: projectCompilerOptions.configFile,
                        commandLine: configFile
                    };
                    moduleResolutionCache.directoryToModuleNameMap.setOwnMap(moduleResolutionCache.directoryToModuleNameMap.getOrCreateMapOfCacheRedirects(ref));
                    moduleResolutionCache.moduleNameToDirectoryMap.setOwnMap(moduleResolutionCache.moduleNameToDirectoryMap.getOrCreateMapOfCacheRedirects(ref));
                }
                moduleResolutionCache.directoryToModuleNameMap.setOwnOptions(projectCompilerOptions);
                moduleResolutionCache.moduleNameToDirectoryMap.setOwnOptions(projectCompilerOptions);
            }
            var program = host.createProgram(configFile.fileNames, configFile.options, compilerHost, getOldProgram(proj, configFile), configFile.errors, configFile.projectReferences);
            // Don't emit anything in the presence of syntactic errors or options diagnostics
            var syntaxDiagnostics = program.getConfigFileParsingDiagnostics().concat(program.getOptionsDiagnostics(), program.getGlobalDiagnostics(), program.getSyntacticDiagnostics());
            if (syntaxDiagnostics.length) {
                return buildErrors(syntaxDiagnostics, BuildResultFlags.SyntaxErrors, "Syntactic");
            }
            // Same as above but now for semantic diagnostics
            var semanticDiagnostics = program.getSemanticDiagnostics();
            if (semanticDiagnostics.length) {
                return buildErrors(semanticDiagnostics, BuildResultFlags.TypeErrors, "Semantic");
            }
            // Before emitting lets backup state, so we can revert it back if there are declaration errors to handle emit and declaration errors correctly
            program.backupState();
            var newestDeclarationFileContentChangedTime = minimumDate;
            var anyDtsChanged = false;
            var declDiagnostics;
            var reportDeclarationDiagnostics = function (d) { return (declDiagnostics || (declDiagnostics = [])).push(d); };
            var outputFiles = [];
            ts.emitFilesAndReportErrors(program, reportDeclarationDiagnostics, /*writeFileName*/ undefined, /*reportSummary*/ undefined, function (name, text, writeByteOrderMark) { return outputFiles.push({ name: name, text: text, writeByteOrderMark: writeByteOrderMark }); });
            // Don't emit .d.ts if there are decl file errors
            if (declDiagnostics) {
                program.restoreState();
                return buildErrors(declDiagnostics, BuildResultFlags.DeclarationEmitErrors, "Declaration file");
            }
            // Actual Emit
            var emitterDiagnostics = ts.createDiagnosticCollection();
            var emittedOutputs = createFileMap(toPath);
            outputFiles.forEach(function (_a) {
                var name = _a.name, text = _a.text, writeByteOrderMark = _a.writeByteOrderMark;
                var priorChangeTime;
                if (!anyDtsChanged && isDeclarationFile(name)) {
                    // Check for unchanged .d.ts files
                    if (host.fileExists(name) && readFileWithCache(name) === text) {
                        priorChangeTime = host.getModifiedTime(name);
                    }
                    else {
                        resultFlags &= ~BuildResultFlags.DeclarationOutputUnchanged;
                        anyDtsChanged = true;
                    }
                }
                emittedOutputs.setValue(name, name);
                ts.writeFile(compilerHost, emitterDiagnostics, name, text, writeByteOrderMark);
                if (priorChangeTime !== undefined) {
                    newestDeclarationFileContentChangedTime = newer(priorChangeTime, newestDeclarationFileContentChangedTime);
                    unchangedOutputs.setValue(name, priorChangeTime);
                }
            });
            var emitDiagnostics = emitterDiagnostics.getDiagnostics();
            if (emitDiagnostics.length) {
                return buildErrors(emitDiagnostics, BuildResultFlags.EmitErrors, "Emit");
            }
            if (writeFileName) {
                emittedOutputs.forEach(function (name) { return listEmittedFile(configFile, name); });
                ts.listFiles(program, writeFileName);
            }
            // Update time stamps for rest of the outputs
            newestDeclarationFileContentChangedTime = updateOutputTimestampsWorker(configFile, newestDeclarationFileContentChangedTime, ts.Diagnostics.Updating_unchanged_output_timestamps_of_project_0, emittedOutputs);
            var status = {
                type: UpToDateStatusType.UpToDate,
                newestDeclarationFileContentChangedTime: anyDtsChanged ? maximumDate : newestDeclarationFileContentChangedTime,
                oldestOutputFileName: outputFiles.length ? outputFiles[0].name : ts.getFirstProjectOutput(configFile, !host.useCaseSensitiveFileNames())
            };
            diagnostics.removeKey(proj);
            projectStatus.setValue(proj, status);
            afterProgramCreate(proj, program);
            projectCompilerOptions = baseCompilerOptions;
            return resultFlags;
            function buildErrors(diagnostics, errorFlags, errorType) {
                resultFlags |= errorFlags;
                reportAndStoreErrors(proj, diagnostics);
                // List files if any other build error using program (emit errors already report files)
                if (writeFileName)
                    ts.listFiles(program, writeFileName);
                projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: errorType + " errors" });
                afterProgramCreate(proj, program);
                projectCompilerOptions = baseCompilerOptions;
                return resultFlags;
            }
        }
        function listEmittedFile(proj, file) {
            if (writeFileName && proj.options.listEmittedFiles) {
                writeFileName("TSFILE: " + file);
            }
        }
        function afterProgramCreate(proj, program) {
            if (host.afterProgramEmitAndDiagnostics) {
                host.afterProgramEmitAndDiagnostics(program);
            }
            if (options.watch) {
                program.releaseProgram();
                builderPrograms.setValue(proj, program);
            }
        }
        function getOldProgram(proj, parsed) {
            if (options.force)
                return undefined;
            var value = builderPrograms.getValue(proj);
            if (value)
                return value;
            return ts.readBuilderProgram(parsed.options, readFileWithCache);
        }
        function updateBundle(proj) {
            if (options.dry) {
                reportStatus(ts.Diagnostics.A_non_dry_build_would_update_output_of_project_0, proj);
                return BuildResultFlags.Success;
            }
            if (options.verbose)
                reportStatus(ts.Diagnostics.Updating_output_of_project_0, proj);
            // Update js, and source map
            var config = ts.Debug.assertDefined(parseConfigFile(proj));
            projectCompilerOptions = config.options;
            var outputFiles = ts.emitUsingBuildInfo(config, compilerHost, function (ref) { return parseConfigFile(resolveProjectName(ref.path)); });
            if (ts.isString(outputFiles)) {
                reportStatus(ts.Diagnostics.Cannot_update_output_of_project_0_because_there_was_error_reading_file_1, proj, relName(outputFiles));
                return buildSingleProject(proj);
            }
            // Actual Emit
            ts.Debug.assert(!!outputFiles.length);
            var emitterDiagnostics = ts.createDiagnosticCollection();
            var emittedOutputs = createFileMap(toPath);
            outputFiles.forEach(function (_a) {
                var name = _a.name, text = _a.text, writeByteOrderMark = _a.writeByteOrderMark;
                emittedOutputs.setValue(name, name);
                ts.writeFile(compilerHost, emitterDiagnostics, name, text, writeByteOrderMark);
            });
            var emitDiagnostics = emitterDiagnostics.getDiagnostics();
            if (emitDiagnostics.length) {
                reportAndStoreErrors(proj, emitDiagnostics);
                projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Emit errors" });
                projectCompilerOptions = baseCompilerOptions;
                return BuildResultFlags.DeclarationOutputUnchanged | BuildResultFlags.EmitErrors;
            }
            if (writeFileName) {
                emittedOutputs.forEach(function (name) { return listEmittedFile(config, name); });
            }
            // Update timestamps for dts
            var newestDeclarationFileContentChangedTime = updateOutputTimestampsWorker(config, minimumDate, ts.Diagnostics.Updating_unchanged_output_timestamps_of_project_0, emittedOutputs);
            var status = {
                type: UpToDateStatusType.UpToDate,
                newestDeclarationFileContentChangedTime: newestDeclarationFileContentChangedTime,
                oldestOutputFileName: outputFiles[0].name
            };
            diagnostics.removeKey(proj);
            projectStatus.setValue(proj, status);
            projectCompilerOptions = baseCompilerOptions;
            return BuildResultFlags.DeclarationOutputUnchanged;
        }
        function updateOutputTimestamps(proj) {
            if (options.dry) {
                return reportStatus(ts.Diagnostics.A_non_dry_build_would_update_timestamps_for_output_of_project_0, proj.options.configFilePath);
            }
            var priorNewestUpdateTime = updateOutputTimestampsWorker(proj, minimumDate, ts.Diagnostics.Updating_output_timestamps_of_project_0);
            var status = {
                type: UpToDateStatusType.UpToDate,
                newestDeclarationFileContentChangedTime: priorNewestUpdateTime,
                oldestOutputFileName: ts.getFirstProjectOutput(proj, !host.useCaseSensitiveFileNames())
            };
            projectStatus.setValue(proj.options.configFilePath, status);
        }
        function updateOutputTimestampsWorker(proj, priorNewestUpdateTime, verboseMessage, skipOutputs) {
            var outputs = ts.getAllProjectOutputs(proj, !host.useCaseSensitiveFileNames());
            if (!skipOutputs || outputs.length !== skipOutputs.getSize()) {
                if (options.verbose) {
                    reportStatus(verboseMessage, proj.options.configFilePath);
                }
                var now = host.now ? host.now() : new Date();
                for (var _i = 0, outputs_2 = outputs; _i < outputs_2.length; _i++) {
                    var file = outputs_2[_i];
                    if (skipOutputs && skipOutputs.hasKey(file)) {
                        continue;
                    }
                    if (isDeclarationFile(file)) {
                        priorNewestUpdateTime = newer(priorNewestUpdateTime, host.getModifiedTime(file) || ts.missingFileModifiedTime);
                    }
                    host.setModifiedTime(file, now);
                    listEmittedFile(proj, file);
                }
            }
            return priorNewestUpdateTime;
        }
        function getFilesToClean() {
            // Get the same graph for cleaning we'd use for building
            var graph = getGlobalDependencyGraph();
            var filesToDelete = [];
            for (var _i = 0, _a = graph.buildQueue; _i < _a.length; _i++) {
                var proj = _a[_i];
                var parsed = parseConfigFile(proj);
                if (parsed === undefined) {
                    // File has gone missing; fine to ignore here
                    reportParseConfigFileDiagnostic(proj);
                    continue;
                }
                var outputs = ts.getAllProjectOutputs(parsed, !host.useCaseSensitiveFileNames());
                for (var _b = 0, outputs_3 = outputs; _b < outputs_3.length; _b++) {
                    var output = outputs_3[_b];
                    if (host.fileExists(output)) {
                        filesToDelete.push(output);
                    }
                }
            }
            return filesToDelete;
        }
        function cleanAllProjects() {
            var filesToDelete = getFilesToClean();
            if (options.dry) {
                reportStatus(ts.Diagnostics.A_non_dry_build_would_delete_the_following_files_Colon_0, filesToDelete.map(function (f) { return "\r\n * " + f; }).join(""));
                return ts.ExitStatus.Success;
            }
            for (var _i = 0, filesToDelete_1 = filesToDelete; _i < filesToDelete_1.length; _i++) {
                var output = filesToDelete_1[_i];
                host.deleteFile(output);
            }
            return ts.ExitStatus.Success;
        }
        function resolveProjectName(name) {
            return resolveConfigFileProjectName(ts.resolvePath(host.getCurrentDirectory(), name));
        }
        function resolveProjectNames(configFileNames) {
            return configFileNames.map(resolveProjectName);
        }
        function enableCache() {
            if (cacheState) {
                disableCache();
            }
            var originalReadFileWithCache = readFileWithCache;
            var originalGetSourceFile = compilerHost.getSourceFile;
            var _a = ts.changeCompilerHostLikeToUseCache(host, toPath, function () {
                var args = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    args[_i] = arguments[_i];
                }
                return originalGetSourceFile.call.apply(originalGetSourceFile, [compilerHost].concat(args));
            }), originalReadFile = _a.originalReadFile, originalFileExists = _a.originalFileExists, originalDirectoryExists = _a.originalDirectoryExists, originalCreateDirectory = _a.originalCreateDirectory, originalWriteFile = _a.originalWriteFile, getSourceFileWithCache = _a.getSourceFileWithCache, newReadFileWithCache = _a.readFileWithCache;
            readFileWithCache = newReadFileWithCache;
            compilerHost.getSourceFile = getSourceFileWithCache;
            var originalResolveModuleNames = compilerHost.resolveModuleNames;
            if (!compilerHost.resolveModuleNames) {
                var loader_3 = function (moduleName, containingFile, redirectedReference) { return ts.resolveModuleName(moduleName, containingFile, projectCompilerOptions, compilerHost, moduleResolutionCache, redirectedReference).resolvedModule; };
                compilerHost.resolveModuleNames = function (moduleNames, containingFile, _reusedNames, redirectedReference) {
                    return ts.loadWithLocalCache(ts.Debug.assertEachDefined(moduleNames), containingFile, redirectedReference, loader_3);
                };
            }
            cacheState = {
                originalReadFile: originalReadFile,
                originalFileExists: originalFileExists,
                originalDirectoryExists: originalDirectoryExists,
                originalCreateDirectory: originalCreateDirectory,
                originalWriteFile: originalWriteFile,
                originalReadFileWithCache: originalReadFileWithCache,
                originalGetSourceFile: originalGetSourceFile,
                originalResolveModuleNames: originalResolveModuleNames
            };
        }
        function disableCache() {
            if (!cacheState)
                return;
            host.readFile = cacheState.originalReadFile;
            host.fileExists = cacheState.originalFileExists;
            host.directoryExists = cacheState.originalDirectoryExists;
            host.createDirectory = cacheState.originalCreateDirectory;
            host.writeFile = cacheState.originalWriteFile;
            compilerHost.getSourceFile = cacheState.originalGetSourceFile;
            readFileWithCache = cacheState.originalReadFileWithCache;
            compilerHost.resolveModuleNames = cacheState.originalResolveModuleNames;
            extendedConfigCache.clear();
            if (moduleResolutionCache) {
                moduleResolutionCache.directoryToModuleNameMap.clear();
                moduleResolutionCache.moduleNameToDirectoryMap.clear();
            }
            cacheState = undefined;
        }
        function buildAllProjects() {
            if (options.watch) {
                reportWatchStatus(ts.Diagnostics.Starting_compilation_in_watch_mode);
            }
            enableCache();
            var graph = getGlobalDependencyGraph();
            reportBuildQueue(graph);
            var anyFailed = false;
            for (var _i = 0, _a = graph.buildQueue; _i < _a.length; _i++) {
                var next = _a[_i];
                var proj = parseConfigFile(next);
                if (proj === undefined) {
                    reportParseConfigFileDiagnostic(next);
                    anyFailed = true;
                    break;
                }
                // report errors early when using continue or break statements
                var errors = proj.errors;
                var status = getUpToDateStatus(proj);
                verboseReportProjectStatus(next, status);
                var projName = proj.options.configFilePath;
                if (status.type === UpToDateStatusType.UpToDate && !options.force) {
                    reportAndStoreErrors(next, errors);
                    // Up to date, skip
                    if (defaultOptions.dry) {
                        // In a dry build, inform the user of this fact
                        reportStatus(ts.Diagnostics.Project_0_is_up_to_date, projName);
                    }
                    continue;
                }
                if (status.type === UpToDateStatusType.UpToDateWithUpstreamTypes && !options.force) {
                    reportAndStoreErrors(next, errors);
                    // Fake build
                    updateOutputTimestamps(proj);
                    continue;
                }
                if (status.type === UpToDateStatusType.UpstreamBlocked) {
                    reportAndStoreErrors(next, errors);
                    if (options.verbose)
                        reportStatus(ts.Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, projName, status.upstreamProjectName);
                    continue;
                }
                if (status.type === UpToDateStatusType.ContainerOnly) {
                    reportAndStoreErrors(next, errors);
                    // Do nothing
                    continue;
                }
                var buildResult = needsBuild(status, next) ?
                    buildSingleProject(next) : // Actual build
                    updateBundle(next); // Fake that files have been built by manipulating prepend and existing output
                anyFailed = anyFailed || !!(buildResult & BuildResultFlags.AnyErrors);
            }
            reportErrorSummary();
            disableCache();
            return anyFailed ? ts.ExitStatus.DiagnosticsPresent_OutputsSkipped : ts.ExitStatus.Success;
        }
        function needsBuild(status, configFile) {
            if (status.type !== UpToDateStatusType.OutOfDateWithPrepend || options.force)
                return true;
            var config = parseConfigFile(configFile);
            return !config ||
                config.fileNames.length === 0 ||
                !!config.errors.length ||
                !ts.isIncrementalCompilation(config.options);
        }
        function reportParseConfigFileDiagnostic(proj) {
            reportAndStoreErrors(proj, [configFileCache.getValue(proj)]);
        }
        function reportAndStoreErrors(proj, errors) {
            reportErrors(errors);
            projectErrorsReported.setValue(proj, true);
            diagnostics.setValue(proj, errors);
        }
        function reportErrors(errors) {
            errors.forEach(function (err) { return host.reportDiagnostic(err); });
        }
        /**
         * Report the build ordering inferred from the current project graph if we're in verbose mode
         */
        function reportBuildQueue(graph) {
            if (options.verbose) {
                reportStatus(ts.Diagnostics.Projects_in_this_build_Colon_0, graph.buildQueue.map(function (s) { return "\r\n    * " + relName(s); }).join(""));
            }
        }
        function relName(path) {
            return ts.convertToRelativePath(path, host.getCurrentDirectory(), function (f) { return compilerHost.getCanonicalFileName(f); });
        }
        /**
         * Report the up-to-date status of a project if we're in verbose mode
         */
        function verboseReportProjectStatus(configFileName, status) {
            if (!options.verbose)
                return;
            return formatUpToDateStatus(configFileName, status, relName, reportStatus);
        }
    }
    ts.createSolutionBuilder = createSolutionBuilder;
    function resolveConfigFileProjectName(project) {
        if (ts.fileExtensionIs(project, ".json" /* Json */)) {
            return project;
        }
        return ts.combinePaths(project, "tsconfig.json");
    }
    ts.resolveConfigFileProjectName = resolveConfigFileProjectName;
    function formatUpToDateStatus(configFileName, status, relName, formatMessage) {
        switch (status.type) {
            case UpToDateStatusType.OutOfDateWithSelf:
                return formatMessage(ts.Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, relName(configFileName), relName(status.outOfDateOutputFileName), relName(status.newerInputFileName));
            case UpToDateStatusType.OutOfDateWithUpstream:
                return formatMessage(ts.Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, relName(configFileName), relName(status.outOfDateOutputFileName), relName(status.newerProjectName));
            case UpToDateStatusType.OutputMissing:
                return formatMessage(ts.Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, relName(configFileName), relName(status.missingOutputFileName));
            case UpToDateStatusType.UpToDate:
                if (status.newestInputFileTime !== undefined) {
                    return formatMessage(ts.Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, relName(configFileName), relName(status.newestInputFileName || ""), relName(status.oldestOutputFileName || ""));
                }
                // Don't report anything for "up to date because it was already built" -- too verbose
                break;
            case UpToDateStatusType.OutOfDateWithPrepend:
                return formatMessage(ts.Diagnostics.Project_0_is_out_of_date_because_output_of_its_dependency_1_has_changed, relName(configFileName), relName(status.newerProjectName));
            case UpToDateStatusType.UpToDateWithUpstreamTypes:
                return formatMessage(ts.Diagnostics.Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies, relName(configFileName));
            case UpToDateStatusType.UpstreamOutOfDate:
                return formatMessage(ts.Diagnostics.Project_0_is_out_of_date_because_its_dependency_1_is_out_of_date, relName(configFileName), relName(status.upstreamProjectName));
            case UpToDateStatusType.UpstreamBlocked:
                return formatMessage(ts.Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors, relName(configFileName), relName(status.upstreamProjectName));
            case UpToDateStatusType.Unbuildable:
                return formatMessage(ts.Diagnostics.Failed_to_parse_file_0_Colon_1, relName(configFileName), status.reason);
            case UpToDateStatusType.TsVersionOutputOfDate:
                return formatMessage(ts.Diagnostics.Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2, relName(configFileName), status.version, ts.version);
            case UpToDateStatusType.ContainerOnly:
            // Don't report status on "solution" projects
            case UpToDateStatusType.ComputingUpstream:
                // Should never leak from getUptoDateStatusWorker
                break;
            default:
                ts.assertType(status);
        }
    }
    ts.formatUpToDateStatus = formatUpToDateStatus;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var server;
    (function (server) {
        // tslint:disable variable-name
        server.ActionSet = "action::set";
        server.ActionInvalidate = "action::invalidate";
        server.ActionPackageInstalled = "action::packageInstalled";
        server.EventTypesRegistry = "event::typesRegistry";
        server.EventBeginInstallTypes = "event::beginInstallTypes";
        server.EventEndInstallTypes = "event::endInstallTypes";
        server.EventInitializationFailed = "event::initializationFailed";
        var Arguments;
        (function (Arguments) {
            Arguments.GlobalCacheLocation = "--globalTypingsCacheLocation";
            Arguments.LogFile = "--logFile";
            Arguments.EnableTelemetry = "--enableTelemetry";
            Arguments.TypingSafeListLocation = "--typingSafeListLocation";
            Arguments.TypesMapLocation = "--typesMapLocation";
            /**
             * This argument specifies the location of the NPM executable.
             * typingsInstaller will run the command with `${npmLocation} install ...`.
             */
            Arguments.NpmLocation = "--npmLocation";
            /**
             * Flag indicating that the typings installer should try to validate the default npm location.
             * If the default npm is not found when this flag is enabled, fallback to `npm install`
             */
            Arguments.ValidateDefaultNpmLocation = "--validateDefaultNpmLocation";
        })(Arguments = server.Arguments || (server.Arguments = {}));
        function hasArgument(argumentName) {
            return ts.sys.args.indexOf(argumentName) >= 0;
        }
        server.hasArgument = hasArgument;
        function findArgument(argumentName) {
            var index = ts.sys.args.indexOf(argumentName);
            return index >= 0 && index < ts.sys.args.length - 1
                ? ts.sys.args[index + 1]
                : undefined;
        }
        server.findArgument = findArgument;
        function nowString() {
            // E.g. "12:34:56.789"
            var d = new Date();
            return d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + "." + d.getMilliseconds();
        }
        server.nowString = nowString;
    })(server = ts.server || (ts.server = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var JsTyping;
    (function (JsTyping) {
        function isTypingUpToDate(cachedTyping, availableTypingVersions) {
            var availableVersion = new ts.Version(ts.getProperty(availableTypingVersions, "ts" + ts.versionMajorMinor) || ts.getProperty(availableTypingVersions, "latest"));
            return availableVersion.compareTo(cachedTyping.version) <= 0;
        }
        JsTyping.isTypingUpToDate = isTypingUpToDate;
        JsTyping.nodeCoreModuleList = [
            "assert",
            "async_hooks",
            "buffer",
            "child_process",
            "cluster",
            "console",
            "constants",
            "crypto",
            "dgram",
            "dns",
            "domain",
            "events",
            "fs",
            "http",
            "https",
            "http2",
            "inspector",
            "net",
            "os",
            "path",
            "perf_hooks",
            "process",
            "punycode",
            "querystring",
            "readline",
            "repl",
            "stream",
            "string_decoder",
            "timers",
            "tls",
            "tty",
            "url",
            "util",
            "v8",
            "vm",
            "zlib"
        ];
        JsTyping.nodeCoreModules = ts.arrayToSet(JsTyping.nodeCoreModuleList);
        function loadSafeList(host, safeListPath) {
            var result = ts.readConfigFile(safeListPath, function (path) { return host.readFile(path); });
            return ts.createMapFromTemplate(result.config);
        }
        JsTyping.loadSafeList = loadSafeList;
        function loadTypesMap(host, typesMapPath) {
            var result = ts.readConfigFile(typesMapPath, function (path) { return host.readFile(path); });
            if (result.config) {
                return ts.createMapFromTemplate(result.config.simpleMap);
            }
            return undefined;
        }
        JsTyping.loadTypesMap = loadTypesMap;
        /**
         * @param host is the object providing I/O related operations.
         * @param fileNames are the file names that belong to the same project
         * @param projectRootPath is the path to the project root directory
         * @param safeListPath is the path used to retrieve the safe list
         * @param packageNameToTypingLocation is the map of package names to their cached typing locations and installed versions
         * @param typeAcquisition is used to customize the typing acquisition process
         * @param compilerOptions are used as a source for typing inference
         */
        function discoverTypings(host, log, fileNames, projectRootPath, safeList, packageNameToTypingLocation, typeAcquisition, unresolvedImports, typesRegistry) {
            if (!typeAcquisition || !typeAcquisition.enable) {
                return { cachedTypingPaths: [], newTypingNames: [], filesToWatch: [] };
            }
            // A typing name to typing file path mapping
            var inferredTypings = ts.createMap();
            // Only infer typings for .js and .jsx files
            fileNames = ts.mapDefined(fileNames, function (fileName) {
                var path = ts.normalizePath(fileName);
                if (ts.hasJSFileExtension(path)) {
                    return path;
                }
            });
            var filesToWatch = [];
            if (typeAcquisition.include)
                addInferredTypings(typeAcquisition.include, "Explicitly included types");
            var exclude = typeAcquisition.exclude || [];
            // Directories to search for package.json, bower.json and other typing information
            var possibleSearchDirs = ts.arrayToSet(fileNames, ts.getDirectoryPath);
            possibleSearchDirs.set(projectRootPath, true);
            possibleSearchDirs.forEach(function (_true, searchDir) {
                var packageJsonPath = ts.combinePaths(searchDir, "package.json");
                getTypingNamesFromJson(packageJsonPath, filesToWatch);
                var bowerJsonPath = ts.combinePaths(searchDir, "bower.json");
                getTypingNamesFromJson(bowerJsonPath, filesToWatch);
                var bowerComponentsPath = ts.combinePaths(searchDir, "bower_components");
                getTypingNamesFromPackagesFolder(bowerComponentsPath, filesToWatch);
                var nodeModulesPath = ts.combinePaths(searchDir, "node_modules");
                getTypingNamesFromPackagesFolder(nodeModulesPath, filesToWatch);
            });
            getTypingNamesFromSourceFileNames(fileNames);
            // add typings for unresolved imports
            if (unresolvedImports) {
                var module_1 = ts.deduplicate(unresolvedImports.map(function (moduleId) { return JsTyping.nodeCoreModules.has(moduleId) ? "node" : moduleId; }), ts.equateStringsCaseSensitive, ts.compareStringsCaseSensitive);
                addInferredTypings(module_1, "Inferred typings from unresolved imports");
            }
            // Add the cached typing locations for inferred typings that are already installed
            packageNameToTypingLocation.forEach(function (typing, name) {
                var registryEntry = typesRegistry.get(name);
                if (inferredTypings.has(name) && inferredTypings.get(name) === undefined && registryEntry !== undefined && isTypingUpToDate(typing, registryEntry)) {
                    inferredTypings.set(name, typing.typingLocation);
                }
            });
            // Remove typings that the user has added to the exclude list
            for (var _i = 0, exclude_1 = exclude; _i < exclude_1.length; _i++) {
                var excludeTypingName = exclude_1[_i];
                var didDelete = inferredTypings.delete(excludeTypingName);
                if (didDelete && log)
                    log("Typing for " + excludeTypingName + " is in exclude list, will be ignored.");
            }
            var newTypingNames = [];
            var cachedTypingPaths = [];
            inferredTypings.forEach(function (inferred, typing) {
                if (inferred !== undefined) {
                    cachedTypingPaths.push(inferred);
                }
                else {
                    newTypingNames.push(typing);
                }
            });
            var result = { cachedTypingPaths: cachedTypingPaths, newTypingNames: newTypingNames, filesToWatch: filesToWatch };
            if (log)
                log("Result: " + JSON.stringify(result));
            return result;
            function addInferredTyping(typingName) {
                if (!inferredTypings.has(typingName)) {
                    inferredTypings.set(typingName, undefined); // TODO: GH#18217
                }
            }
            function addInferredTypings(typingNames, message) {
                if (log)
                    log(message + ": " + JSON.stringify(typingNames));
                ts.forEach(typingNames, addInferredTyping);
            }
            /**
             * Get the typing info from common package manager json files like package.json or bower.json
             */
            function getTypingNamesFromJson(jsonPath, filesToWatch) {
                if (!host.fileExists(jsonPath)) {
                    return;
                }
                filesToWatch.push(jsonPath);
                var jsonConfig = ts.readConfigFile(jsonPath, function (path) { return host.readFile(path); }).config;
                var jsonTypingNames = ts.flatMap([jsonConfig.dependencies, jsonConfig.devDependencies, jsonConfig.optionalDependencies, jsonConfig.peerDependencies], ts.getOwnKeys);
                addInferredTypings(jsonTypingNames, "Typing names in '" + jsonPath + "' dependencies");
            }
            /**
             * Infer typing names from given file names. For example, the file name "jquery-min.2.3.4.js"
             * should be inferred to the 'jquery' typing name; and "angular-route.1.2.3.js" should be inferred
             * to the 'angular-route' typing name.
             * @param fileNames are the names for source files in the project
             */
            function getTypingNamesFromSourceFileNames(fileNames) {
                var fromFileNames = ts.mapDefined(fileNames, function (j) {
                    if (!ts.hasJSFileExtension(j))
                        return undefined;
                    var inferredTypingName = ts.removeFileExtension(ts.getBaseFileName(j.toLowerCase()));
                    var cleanedTypingName = ts.removeMinAndVersionNumbers(inferredTypingName);
                    return safeList.get(cleanedTypingName);
                });
                if (fromFileNames.length) {
                    addInferredTypings(fromFileNames, "Inferred typings from file names");
                }
                var hasJsxFile = ts.some(fileNames, function (f) { return ts.fileExtensionIs(f, ".jsx" /* Jsx */); });
                if (hasJsxFile) {
                    if (log)
                        log("Inferred 'react' typings due to presence of '.jsx' extension");
                    addInferredTyping("react");
                }
            }
            /**
             * Infer typing names from packages folder (ex: node_module, bower_components)
             * @param packagesFolderPath is the path to the packages folder
             */
            function getTypingNamesFromPackagesFolder(packagesFolderPath, filesToWatch) {
                filesToWatch.push(packagesFolderPath);
                // Todo: add support for ModuleResolutionHost too
                if (!host.directoryExists(packagesFolderPath)) {
                    return;
                }
                // depth of 2, so we access `node_modules/foo` but not `node_modules/foo/bar`
                var fileNames = host.readDirectory(packagesFolderPath, [".json" /* Json */], /*excludes*/ undefined, /*includes*/ undefined, /*depth*/ 2);
                if (log)
                    log("Searching for typing names in " + packagesFolderPath + "; all files: " + JSON.stringify(fileNames));
                var packageNames = [];
                for (var _i = 0, fileNames_1 = fileNames; _i < fileNames_1.length; _i++) {
                    var fileName = fileNames_1[_i];
                    var normalizedFileName = ts.normalizePath(fileName);
                    var baseFileName = ts.getBaseFileName(normalizedFileName);
                    if (baseFileName !== "package.json" && baseFileName !== "bower.json") {
                        continue;
                    }
                    var result_1 = ts.readConfigFile(normalizedFileName, function (path) { return host.readFile(path); });
                    var packageJson = result_1.config;
                    // npm 3's package.json contains a "_requiredBy" field
                    // we should include all the top level module names for npm 2, and only module names whose
                    // "_requiredBy" field starts with "#" or equals "/" for npm 3.
                    if (baseFileName === "package.json" && packageJson._requiredBy &&
                        ts.filter(packageJson._requiredBy, function (r) { return r[0] === "#" || r === "/"; }).length === 0) {
                        continue;
                    }
                    // If the package has its own d.ts typings, those will take precedence. Otherwise the package name will be used
                    // to download d.ts files from DefinitelyTyped
                    if (!packageJson.name) {
                        continue;
                    }
                    var ownTypes = packageJson.types || packageJson.typings;
                    if (ownTypes) {
                        var absolutePath = ts.getNormalizedAbsolutePath(ownTypes, ts.getDirectoryPath(normalizedFileName));
                        if (log)
                            log("    Package '" + packageJson.name + "' provides its own types.");
                        inferredTypings.set(packageJson.name, absolutePath);
                    }
                    else {
                        packageNames.push(packageJson.name);
                    }
                }
                addInferredTypings(packageNames, "    Found package names");
            }
        }
        JsTyping.discoverTypings = discoverTypings;
        var PackageNameValidationResult;
        (function (PackageNameValidationResult) {
            PackageNameValidationResult[PackageNameValidationResult["Ok"] = 0] = "Ok";
            PackageNameValidationResult[PackageNameValidationResult["ScopedPackagesNotSupported"] = 1] = "ScopedPackagesNotSupported";
            PackageNameValidationResult[PackageNameValidationResult["EmptyName"] = 2] = "EmptyName";
            PackageNameValidationResult[PackageNameValidationResult["NameTooLong"] = 3] = "NameTooLong";
            PackageNameValidationResult[PackageNameValidationResult["NameStartsWithDot"] = 4] = "NameStartsWithDot";
            PackageNameValidationResult[PackageNameValidationResult["NameStartsWithUnderscore"] = 5] = "NameStartsWithUnderscore";
            PackageNameValidationResult[PackageNameValidationResult["NameContainsNonURISafeCharacters"] = 6] = "NameContainsNonURISafeCharacters";
        })(PackageNameValidationResult = JsTyping.PackageNameValidationResult || (JsTyping.PackageNameValidationResult = {}));
        var maxPackageNameLength = 214;
        /**
         * Validates package name using rules defined at https://docs.npmjs.com/files/package.json
         */
        function validatePackageName(packageName) {
            if (!packageName) {
                return 2 /* EmptyName */;
            }
            if (packageName.length > maxPackageNameLength) {
                return 3 /* NameTooLong */;
            }
            if (packageName.charCodeAt(0) === 46 /* dot */) {
                return 4 /* NameStartsWithDot */;
            }
            if (packageName.charCodeAt(0) === 95 /* _ */) {
                return 5 /* NameStartsWithUnderscore */;
            }
            // check if name is scope package like: starts with @ and has one '/' in the middle
            // scoped packages are not currently supported
            // TODO: when support will be added we'll need to split and check both scope and package name
            if (/^@[^/]+\/[^/]+$/.test(packageName)) {
                return 1 /* ScopedPackagesNotSupported */;
            }
            if (encodeURIComponent(packageName) !== packageName) {
                return 6 /* NameContainsNonURISafeCharacters */;
            }
            return 0 /* Ok */;
        }
        JsTyping.validatePackageName = validatePackageName;
        function renderPackageNameValidationFailure(result, typing) {
            switch (result) {
                case 2 /* EmptyName */:
                    return "Package name '" + typing + "' cannot be empty";
                case 3 /* NameTooLong */:
                    return "Package name '" + typing + "' should be less than " + maxPackageNameLength + " characters";
                case 4 /* NameStartsWithDot */:
                    return "Package name '" + typing + "' cannot start with '.'";
                case 5 /* NameStartsWithUnderscore */:
                    return "Package name '" + typing + "' cannot start with '_'";
                case 1 /* ScopedPackagesNotSupported */:
                    return "Package '" + typing + "' is scoped and currently is not supported";
                case 6 /* NameContainsNonURISafeCharacters */:
                    return "Package name '" + typing + "' contains non URI safe characters";
                case 0 /* Ok */:
                    return ts.Debug.fail(); // Shouldn't have called this.
                default:
                    throw ts.Debug.assertNever(result);
            }
        }
        JsTyping.renderPackageNameValidationFailure = renderPackageNameValidationFailure;
    })(JsTyping = ts.JsTyping || (ts.JsTyping = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    var ScriptSnapshot;
    (function (ScriptSnapshot) {
        var StringScriptSnapshot = /** @class */ (function () {
            function StringScriptSnapshot(text) {
                this.text = text;
            }
            StringScriptSnapshot.prototype.getText = function (start, end) {
                return start === 0 && end === this.text.length
                    ? this.text
                    : this.text.substring(start, end);
            };
            StringScriptSnapshot.prototype.getLength = function () {
                return this.text.length;
            };
            StringScriptSnapshot.prototype.getChangeRange = function () {
                // Text-based snapshots do not support incremental parsing. Return undefined
                // to signal that to the caller.
                return undefined;
            };
            return StringScriptSnapshot;
        }());
        function fromString(text) {
            return new StringScriptSnapshot(text);
        }
        ScriptSnapshot.fromString = fromString;
    })(ScriptSnapshot = ts.ScriptSnapshot || (ts.ScriptSnapshot = {}));
    /* @internal */
    ts.emptyOptions = {};
    var HighlightSpanKind;
    (function (HighlightSpanKind) {
        HighlightSpanKind["none"] = "none";
        HighlightSpanKind["definition"] = "definition";
        HighlightSpanKind["reference"] = "reference";
        HighlightSpanKind["writtenReference"] = "writtenReference";
    })(HighlightSpanKind = ts.HighlightSpanKind || (ts.HighlightSpanKind = {}));
    var IndentStyle;
    (function (IndentStyle) {
        IndentStyle[IndentStyle["None"] = 0] = "None";
        IndentStyle[IndentStyle["Block"] = 1] = "Block";
        IndentStyle[IndentStyle["Smart"] = 2] = "Smart";
    })(IndentStyle = ts.IndentStyle || (ts.IndentStyle = {}));
    function getDefaultFormatCodeSettings(newLineCharacter) {
        return {
            indentSize: 4,
            tabSize: 4,
            newLineCharacter: newLineCharacter || "\n",
            convertTabsToSpaces: true,
            indentStyle: IndentStyle.Smart,
            insertSpaceAfterConstructor: false,
            insertSpaceAfterCommaDelimiter: true,
            insertSpaceAfterSemicolonInForStatements: true,
            insertSpaceBeforeAndAfterBinaryOperators: true,
            insertSpaceAfterKeywordsInControlFlowStatements: true,
            insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
            insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
            insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
            insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true,
            insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
            insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
            insertSpaceBeforeFunctionParenthesis: false,
            placeOpenBraceOnNewLineForFunctions: false,
            placeOpenBraceOnNewLineForControlBlocks: false,
        };
    }
    ts.getDefaultFormatCodeSettings = getDefaultFormatCodeSettings;
    /* @internal */
    ts.testFormatSettings = getDefaultFormatCodeSettings("\n");
    var SymbolDisplayPartKind;
    (function (SymbolDisplayPartKind) {
        SymbolDisplayPartKind[SymbolDisplayPartKind["aliasName"] = 0] = "aliasName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["className"] = 1] = "className";
        SymbolDisplayPartKind[SymbolDisplayPartKind["enumName"] = 2] = "enumName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["fieldName"] = 3] = "fieldName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["interfaceName"] = 4] = "interfaceName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["keyword"] = 5] = "keyword";
        SymbolDisplayPartKind[SymbolDisplayPartKind["lineBreak"] = 6] = "lineBreak";
        SymbolDisplayPartKind[SymbolDisplayPartKind["numericLiteral"] = 7] = "numericLiteral";
        SymbolDisplayPartKind[SymbolDisplayPartKind["stringLiteral"] = 8] = "stringLiteral";
        SymbolDisplayPartKind[SymbolDisplayPartKind["localName"] = 9] = "localName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["methodName"] = 10] = "methodName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["moduleName"] = 11] = "moduleName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["operator"] = 12] = "operator";
        SymbolDisplayPartKind[SymbolDisplayPartKind["parameterName"] = 13] = "parameterName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["propertyName"] = 14] = "propertyName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["punctuation"] = 15] = "punctuation";
        SymbolDisplayPartKind[SymbolDisplayPartKind["space"] = 16] = "space";
        SymbolDisplayPartKind[SymbolDisplayPartKind["text"] = 17] = "text";
        SymbolDisplayPartKind[SymbolDisplayPartKind["typeParameterName"] = 18] = "typeParameterName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["enumMemberName"] = 19] = "enumMemberName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["functionName"] = 20] = "functionName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["regularExpressionLiteral"] = 21] = "regularExpressionLiteral";
    })(SymbolDisplayPartKind = ts.SymbolDisplayPartKind || (ts.SymbolDisplayPartKind = {}));
    var OutliningSpanKind;
    (function (OutliningSpanKind) {
        /** Single or multi-line comments */
        OutliningSpanKind["Comment"] = "comment";
        /** Sections marked by '// #region' and '// #endregion' comments */
        OutliningSpanKind["Region"] = "region";
        /** Declarations and expressions */
        OutliningSpanKind["Code"] = "code";
        /** Contiguous blocks of import declarations */
        OutliningSpanKind["Imports"] = "imports";
    })(OutliningSpanKind = ts.OutliningSpanKind || (ts.OutliningSpanKind = {}));
    var OutputFileType;
    (function (OutputFileType) {
        OutputFileType[OutputFileType["JavaScript"] = 0] = "JavaScript";
        OutputFileType[OutputFileType["SourceMap"] = 1] = "SourceMap";
        OutputFileType[OutputFileType["Declaration"] = 2] = "Declaration";
    })(OutputFileType = ts.OutputFileType || (ts.OutputFileType = {}));
    var EndOfLineState;
    (function (EndOfLineState) {
        EndOfLineState[EndOfLineState["None"] = 0] = "None";
        EndOfLineState[EndOfLineState["InMultiLineCommentTrivia"] = 1] = "InMultiLineCommentTrivia";
        EndOfLineState[EndOfLineState["InSingleQuoteStringLiteral"] = 2] = "InSingleQuoteStringLiteral";
        EndOfLineState[EndOfLineState["InDoubleQuoteStringLiteral"] = 3] = "InDoubleQuoteStringLiteral";
        EndOfLineState[EndOfLineState["InTemplateHeadOrNoSubstitutionTemplate"] = 4] = "InTemplateHeadOrNoSubstitutionTemplate";
        EndOfLineState[EndOfLineState["InTemplateMiddleOrTail"] = 5] = "InTemplateMiddleOrTail";
        EndOfLineState[EndOfLineState["InTemplateSubstitutionPosition"] = 6] = "InTemplateSubstitutionPosition";
    })(EndOfLineState = ts.EndOfLineState || (ts.EndOfLineState = {}));
    var TokenClass;
    (function (TokenClass) {
        TokenClass[TokenClass["Punctuation"] = 0] = "Punctuation";
        TokenClass[TokenClass["Keyword"] = 1] = "Keyword";
        TokenClass[TokenClass["Operator"] = 2] = "Operator";
        TokenClass[TokenClass["Comment"] = 3] = "Comment";
        TokenClass[TokenClass["Whitespace"] = 4] = "Whitespace";
        TokenClass[TokenClass["Identifier"] = 5] = "Identifier";
        TokenClass[TokenClass["NumberLiteral"] = 6] = "NumberLiteral";
        TokenClass[TokenClass["BigIntLiteral"] = 7] = "BigIntLiteral";
        TokenClass[TokenClass["StringLiteral"] = 8] = "StringLiteral";
        TokenClass[TokenClass["RegExpLiteral"] = 9] = "RegExpLiteral";
    })(TokenClass = ts.TokenClass || (ts.TokenClass = {}));
    var ScriptElementKind;
    (function (ScriptElementKind) {
        ScriptElementKind["unknown"] = "";
        ScriptElementKind["warning"] = "warning";
        /** predefined type (void) or keyword (class) */
        ScriptElementKind["keyword"] = "keyword";
        /** top level script node */
        ScriptElementKind["scriptElement"] = "script";
        /** module foo {} */
        ScriptElementKind["moduleElement"] = "module";
        /** class X {} */
        ScriptElementKind["classElement"] = "class";
        /** var x = class X {} */
        ScriptElementKind["localClassElement"] = "local class";
        /** interface Y {} */
        ScriptElementKind["interfaceElement"] = "interface";
        /** type T = ... */
        ScriptElementKind["typeElement"] = "type";
        /** enum E */
        ScriptElementKind["enumElement"] = "enum";
        ScriptElementKind["enumMemberElement"] = "enum member";
        /**
         * Inside module and script only
         * const v = ..
         */
        ScriptElementKind["variableElement"] = "var";
        /** Inside function */
        ScriptElementKind["localVariableElement"] = "local var";
        /**
         * Inside module and script only
         * function f() { }
         */
        ScriptElementKind["functionElement"] = "function";
        /** Inside function */
        ScriptElementKind["localFunctionElement"] = "local function";
        /** class X { [public|private]* foo() {} } */
        ScriptElementKind["memberFunctionElement"] = "method";
        /** class X { [public|private]* [get|set] foo:number; } */
        ScriptElementKind["memberGetAccessorElement"] = "getter";
        ScriptElementKind["memberSetAccessorElement"] = "setter";
        /**
         * class X { [public|private]* foo:number; }
         * interface Y { foo:number; }
         */
        ScriptElementKind["memberVariableElement"] = "property";
        /** class X { constructor() { } } */
        ScriptElementKind["constructorImplementationElement"] = "constructor";
        /** interface Y { ():number; } */
        ScriptElementKind["callSignatureElement"] = "call";
        /** interface Y { []:number; } */
        ScriptElementKind["indexSignatureElement"] = "index";
        /** interface Y { new():Y; } */
        ScriptElementKind["constructSignatureElement"] = "construct";
        /** function foo(*Y*: string) */
        ScriptElementKind["parameterElement"] = "parameter";
        ScriptElementKind["typeParameterElement"] = "type parameter";
        ScriptElementKind["primitiveType"] = "primitive type";
        ScriptElementKind["label"] = "label";
        ScriptElementKind["alias"] = "alias";
        ScriptElementKind["constElement"] = "const";
        ScriptElementKind["letElement"] = "let";
        ScriptElementKind["directory"] = "directory";
        ScriptElementKind["externalModuleName"] = "external module name";
        /**
         * <JsxTagName attribute1 attribute2={0} />
         */
        ScriptElementKind["jsxAttribute"] = "JSX attribute";
        /** String literal */
        ScriptElementKind["string"] = "string";
    })(ScriptElementKind = ts.ScriptElementKind || (ts.ScriptElementKind = {}));
    var ScriptElementKindModifier;
    (function (ScriptElementKindModifier) {
        ScriptElementKindModifier["none"] = "";
        ScriptElementKindModifier["publicMemberModifier"] = "public";
        ScriptElementKindModifier["privateMemberModifier"] = "private";
        ScriptElementKindModifier["protectedMemberModifier"] = "protected";
        ScriptElementKindModifier["exportedModifier"] = "export";
        ScriptElementKindModifier["ambientModifier"] = "declare";
        ScriptElementKindModifier["staticModifier"] = "static";
        ScriptElementKindModifier["abstractModifier"] = "abstract";
        ScriptElementKindModifier["optionalModifier"] = "optional";
        ScriptElementKindModifier["dtsModifier"] = ".d.ts";
        ScriptElementKindModifier["tsModifier"] = ".ts";
        ScriptElementKindModifier["tsxModifier"] = ".tsx";
        ScriptElementKindModifier["jsModifier"] = ".js";
        ScriptElementKindModifier["jsxModifier"] = ".jsx";
        ScriptElementKindModifier["jsonModifier"] = ".json";
    })(ScriptElementKindModifier = ts.ScriptElementKindModifier || (ts.ScriptElementKindModifier = {}));
    var ClassificationTypeNames;
    (function (ClassificationTypeNames) {
        ClassificationTypeNames["comment"] = "comment";
        ClassificationTypeNames["identifier"] = "identifier";
        ClassificationTypeNames["keyword"] = "keyword";
        ClassificationTypeNames["numericLiteral"] = "number";
        ClassificationTypeNames["bigintLiteral"] = "bigint";
        ClassificationTypeNames["operator"] = "operator";
        ClassificationTypeNames["stringLiteral"] = "string";
        ClassificationTypeNames["whiteSpace"] = "whitespace";
        ClassificationTypeNames["text"] = "text";
        ClassificationTypeNames["punctuation"] = "punctuation";
        ClassificationTypeNames["className"] = "class name";
        ClassificationTypeNames["enumName"] = "enum name";
        ClassificationTypeNames["interfaceName"] = "interface name";
        ClassificationTypeNames["moduleName"] = "module name";
        ClassificationTypeNames["typeParameterName"] = "type parameter name";
        ClassificationTypeNames["typeAliasName"] = "type alias name";
        ClassificationTypeNames["parameterName"] = "parameter name";
        ClassificationTypeNames["docCommentTagName"] = "doc comment tag name";
        ClassificationTypeNames["jsxOpenTagName"] = "jsx open tag name";
        ClassificationTypeNames["jsxCloseTagName"] = "jsx close tag name";
        ClassificationTypeNames["jsxSelfClosingTagName"] = "jsx self closing tag name";
        ClassificationTypeNames["jsxAttribute"] = "jsx attribute";
        ClassificationTypeNames["jsxText"] = "jsx text";
        ClassificationTypeNames["jsxAttributeStringLiteralValue"] = "jsx attribute string literal value";
    })(ClassificationTypeNames = ts.ClassificationTypeNames || (ts.ClassificationTypeNames = {}));
    var ClassificationType;
    (function (ClassificationType) {
        ClassificationType[ClassificationType["comment"] = 1] = "comment";
        ClassificationType[ClassificationType["identifier"] = 2] = "identifier";
        ClassificationType[ClassificationType["keyword"] = 3] = "keyword";
        ClassificationType[ClassificationType["numericLiteral"] = 4] = "numericLiteral";
        ClassificationType[ClassificationType["operator"] = 5] = "operator";
        ClassificationType[ClassificationType["stringLiteral"] = 6] = "stringLiteral";
        ClassificationType[ClassificationType["regularExpressionLiteral"] = 7] = "regularExpressionLiteral";
        ClassificationType[ClassificationType["whiteSpace"] = 8] = "whiteSpace";
        ClassificationType[ClassificationType["text"] = 9] = "text";
        ClassificationType[ClassificationType["punctuation"] = 10] = "punctuation";
        ClassificationType[ClassificationType["className"] = 11] = "className";
        ClassificationType[ClassificationType["enumName"] = 12] = "enumName";
        ClassificationType[ClassificationType["interfaceName"] = 13] = "interfaceName";
        ClassificationType[ClassificationType["moduleName"] = 14] = "moduleName";
        ClassificationType[ClassificationType["typeParameterName"] = 15] = "typeParameterName";
        ClassificationType[ClassificationType["typeAliasName"] = 16] = "typeAliasName";
        ClassificationType[ClassificationType["parameterName"] = 17] = "parameterName";
        ClassificationType[ClassificationType["docCommentTagName"] = 18] = "docCommentTagName";
        ClassificationType[ClassificationType["jsxOpenTagName"] = 19] = "jsxOpenTagName";
        ClassificationType[ClassificationType["jsxCloseTagName"] = 20] = "jsxCloseTagName";
        ClassificationType[ClassificationType["jsxSelfClosingTagName"] = 21] = "jsxSelfClosingTagName";
        ClassificationType[ClassificationType["jsxAttribute"] = 22] = "jsxAttribute";
        ClassificationType[ClassificationType["jsxText"] = 23] = "jsxText";
        ClassificationType[ClassificationType["jsxAttributeStringLiteralValue"] = 24] = "jsxAttributeStringLiteralValue";
        ClassificationType[ClassificationType["bigintLiteral"] = 25] = "bigintLiteral";
    })(ClassificationType = ts.ClassificationType || (ts.ClassificationType = {}));
})(ts || (ts = {}));
// These utilities are common to multiple language service features.
/* @internal */
var ts;
(function (ts) {
    ts.scanner = ts.createScanner(8 /* Latest */, /*skipTrivia*/ true);
    var SemanticMeaning;
    (function (SemanticMeaning) {
        SemanticMeaning[SemanticMeaning["None"] = 0] = "None";
        SemanticMeaning[SemanticMeaning["Value"] = 1] = "Value";
        SemanticMeaning[SemanticMeaning["Type"] = 2] = "Type";
        SemanticMeaning[SemanticMeaning["Namespace"] = 4] = "Namespace";
        SemanticMeaning[SemanticMeaning["All"] = 7] = "All";
    })(SemanticMeaning = ts.SemanticMeaning || (ts.SemanticMeaning = {}));
    function getMeaningFromDeclaration(node) {
        switch (node.kind) {
            case 238 /* VariableDeclaration */:
                return ts.isInJSFile(node) && ts.getJSDocEnumTag(node) ? 7 /* All */ : 1 /* Value */;
            case 152 /* Parameter */:
            case 187 /* BindingElement */:
            case 155 /* PropertyDeclaration */:
            case 154 /* PropertySignature */:
            case 276 /* PropertyAssignment */:
            case 277 /* ShorthandPropertyAssignment */:
            case 157 /* MethodDeclaration */:
            case 156 /* MethodSignature */:
            case 158 /* Constructor */:
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
            case 240 /* FunctionDeclaration */:
            case 197 /* FunctionExpression */:
            case 198 /* ArrowFunction */:
            case 275 /* CatchClause */:
            case 268 /* JsxAttribute */:
                return 1 /* Value */;
            case 151 /* TypeParameter */:
            case 242 /* InterfaceDeclaration */:
            case 243 /* TypeAliasDeclaration */:
            case 169 /* TypeLiteral */:
                return 2 /* Type */;
            case 310 /* JSDocTypedefTag */:
                // If it has no name node, it shares the name with the value declaration below it.
                return node.name === undefined ? 1 /* Value */ | 2 /* Type */ : 2 /* Type */;
            case 279 /* EnumMember */:
            case 241 /* ClassDeclaration */:
                return 1 /* Value */ | 2 /* Type */;
            case 245 /* ModuleDeclaration */:
                if (ts.isAmbientModule(node)) {
                    return 4 /* Namespace */ | 1 /* Value */;
                }
                else if (ts.getModuleInstanceState(node) === 1 /* Instantiated */) {
                    return 4 /* Namespace */ | 1 /* Value */;
                }
                else {
                    return 4 /* Namespace */;
                }
            case 244 /* EnumDeclaration */:
            case 253 /* NamedImports */:
            case 254 /* ImportSpecifier */:
            case 249 /* ImportEqualsDeclaration */:
            case 250 /* ImportDeclaration */:
            case 255 /* ExportAssignment */:
            case 256 /* ExportDeclaration */:
                return 7 /* All */;
            // An external module can be a Value
            case 285 /* SourceFile */:
                return 4 /* Namespace */ | 1 /* Value */;
        }
        return 7 /* All */;
    }
    ts.getMeaningFromDeclaration = getMeaningFromDeclaration;
    function getMeaningFromLocation(node) {
        if (node.kind === 285 /* SourceFile */) {
            return 1 /* Value */;
        }
        else if (node.parent.kind === 255 /* ExportAssignment */ || node.parent.kind === 260 /* ExternalModuleReference */) {
            return 7 /* All */;
        }
        else if (isInRightSideOfInternalImportEqualsDeclaration(node)) {
            return getMeaningFromRightHandSideOfImportEquals(node);
        }
        else if (ts.isDeclarationName(node)) {
            return getMeaningFromDeclaration(node.parent);
        }
        else if (isTypeReference(node)) {
            return 2 /* Type */;
        }
        else if (isNamespaceReference(node)) {
            return 4 /* Namespace */;
        }
        else if (ts.isTypeParameterDeclaration(node.parent)) {
            ts.Debug.assert(ts.isJSDocTemplateTag(node.parent.parent)); // Else would be handled by isDeclarationName
            return 2 /* Type */;
        }
        else if (ts.isLiteralTypeNode(node.parent)) {
            // This might be T["name"], which is actually referencing a property and not a type. So allow both meanings.
            return 2 /* Type */ | 1 /* Value */;
        }
        else {
            return 1 /* Value */;
        }
    }
    ts.getMeaningFromLocation = getMeaningFromLocation;
    function getMeaningFromRightHandSideOfImportEquals(node) {
        //     import a = |b|; // Namespace
        //     import a = |b.c|; // Value, type, namespace
        //     import a = |b.c|.d; // Namespace
        var name = node.kind === 149 /* QualifiedName */ ? node : ts.isQualifiedName(node.parent) && node.parent.right === node ? node.parent : undefined;
        return name && name.parent.kind === 249 /* ImportEqualsDeclaration */ ? 7 /* All */ : 4 /* Namespace */;
    }
    function isInRightSideOfInternalImportEqualsDeclaration(node) {
        while (node.parent.kind === 149 /* QualifiedName */) {
            node = node.parent;
        }
        return ts.isInternalModuleImportEqualsDeclaration(node.parent) && node.parent.moduleReference === node;
    }
    ts.isInRightSideOfInternalImportEqualsDeclaration = isInRightSideOfInternalImportEqualsDeclaration;
    function isNamespaceReference(node) {
        return isQualifiedNameNamespaceReference(node) || isPropertyAccessNamespaceReference(node);
    }
    function isQualifiedNameNamespaceReference(node) {
        var root = node;
        var isLastClause = true;
        if (root.parent.kind === 149 /* QualifiedName */) {
            while (root.parent && root.parent.kind === 149 /* QualifiedName */) {
                root = root.parent;
            }
            isLastClause = root.right === node;
        }
        return root.parent.kind === 165 /* TypeReference */ && !isLastClause;
    }
    function isPropertyAccessNamespaceReference(node) {
        var root = node;
        var isLastClause = true;
        if (root.parent.kind === 190 /* PropertyAccessExpression */) {
            while (root.parent && root.parent.kind === 190 /* PropertyAccessExpression */) {
                root = root.parent;
            }
            isLastClause = root.name === node;
        }
        if (!isLastClause && root.parent.kind === 212 /* ExpressionWithTypeArguments */ && root.parent.parent.kind === 274 /* HeritageClause */) {
            var decl = root.parent.parent.parent;
            return (decl.kind === 241 /* ClassDeclaration */ && root.parent.parent.token === 110 /* ImplementsKeyword */) ||
                (decl.kind === 242 /* InterfaceDeclaration */ && root.parent.parent.token === 87 /* ExtendsKeyword */);
        }
        return false;
    }
    function isTypeReference(node) {
        if (ts.isRightSideOfQualifiedNameOrPropertyAccess(node)) {
            node = node.parent;
        }
        switch (node.kind) {
            case 101 /* ThisKeyword */:
                return !ts.isExpressionNode(node);
            case 179 /* ThisType */:
                return true;
        }
        switch (node.parent.kind) {
            case 165 /* TypeReference */:
                return true;
            case 184 /* ImportType */:
                return !node.parent.isTypeOf;
            case 212 /* ExpressionWithTypeArguments */:
                return !ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent);
        }
        return false;
    }
    function isCallExpressionTarget(node) {
        return isCallOrNewExpressionTargetWorker(node, ts.isCallExpression);
    }
    ts.isCallExpressionTarget = isCallExpressionTarget;
    function isNewExpressionTarget(node) {
        return isCallOrNewExpressionTargetWorker(node, ts.isNewExpression);
    }
    ts.isNewExpressionTarget = isNewExpressionTarget;
    function isCallOrNewExpressionTarget(node) {
        return isCallOrNewExpressionTargetWorker(node, ts.isCallOrNewExpression);
    }
    ts.isCallOrNewExpressionTarget = isCallOrNewExpressionTarget;
    function isCallOrNewExpressionTargetWorker(node, pred) {
        var target = climbPastPropertyAccess(node);
        return !!target && !!target.parent && pred(target.parent) && target.parent.expression === target;
    }
    function climbPastPropertyAccess(node) {
        return isRightSideOfPropertyAccess(node) ? node.parent : node;
    }
    ts.climbPastPropertyAccess = climbPastPropertyAccess;
    function getTargetLabel(referenceNode, labelName) {
        while (referenceNode) {
            if (referenceNode.kind === 234 /* LabeledStatement */ && referenceNode.label.escapedText === labelName) {
                return referenceNode.label;
            }
            referenceNode = referenceNode.parent;
        }
        return undefined;
    }
    ts.getTargetLabel = getTargetLabel;
    function hasPropertyAccessExpressionWithName(node, funcName) {
        if (!ts.isPropertyAccessExpression(node.expression)) {
            return false;
        }
        return node.expression.name.text === funcName;
    }
    ts.hasPropertyAccessExpressionWithName = hasPropertyAccessExpressionWithName;
    function isJumpStatementTarget(node) {
        return node.kind === 73 /* Identifier */ && ts.isBreakOrContinueStatement(node.parent) && node.parent.label === node;
    }
    ts.isJumpStatementTarget = isJumpStatementTarget;
    function isLabelOfLabeledStatement(node) {
        return node.kind === 73 /* Identifier */ && ts.isLabeledStatement(node.parent) && node.parent.label === node;
    }
    ts.isLabelOfLabeledStatement = isLabelOfLabeledStatement;
    function isLabelName(node) {
        return isLabelOfLabeledStatement(node) || isJumpStatementTarget(node);
    }
    ts.isLabelName = isLabelName;
    function isTagName(node) {
        return ts.isJSDocTag(node.parent) && node.parent.tagName === node;
    }
    ts.isTagName = isTagName;
    function isRightSideOfQualifiedName(node) {
        return node.parent.kind === 149 /* QualifiedName */ && node.parent.right === node;
    }
    ts.isRightSideOfQualifiedName = isRightSideOfQualifiedName;
    function isRightSideOfPropertyAccess(node) {
        return node && node.parent && node.parent.kind === 190 /* PropertyAccessExpression */ && node.parent.name === node;
    }
    ts.isRightSideOfPropertyAccess = isRightSideOfPropertyAccess;
    function isNameOfModuleDeclaration(node) {
        return node.parent.kind === 245 /* ModuleDeclaration */ && node.parent.name === node;
    }
    ts.isNameOfModuleDeclaration = isNameOfModuleDeclaration;
    function isNameOfFunctionDeclaration(node) {
        return node.kind === 73 /* Identifier */ &&
            ts.isFunctionLike(node.parent) && node.parent.name === node;
    }
    ts.isNameOfFunctionDeclaration = isNameOfFunctionDeclaration;
    function isLiteralNameOfPropertyDeclarationOrIndexAccess(node) {
        switch (node.parent.kind) {
            case 155 /* PropertyDeclaration */:
            case 154 /* PropertySignature */:
            case 276 /* PropertyAssignment */:
            case 279 /* EnumMember */:
            case 157 /* MethodDeclaration */:
            case 156 /* MethodSignature */:
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
            case 245 /* ModuleDeclaration */:
                return ts.getNameOfDeclaration(node.parent) === node;
            case 191 /* ElementAccessExpression */:
                return node.parent.argumentExpression === node;
            case 150 /* ComputedPropertyName */:
                return true;
            case 183 /* LiteralType */:
                return node.parent.parent.kind === 181 /* IndexedAccessType */;
            default:
                return false;
        }
    }
    ts.isLiteralNameOfPropertyDeclarationOrIndexAccess = isLiteralNameOfPropertyDeclarationOrIndexAccess;
    function isExpressionOfExternalModuleImportEqualsDeclaration(node) {
        return ts.isExternalModuleImportEqualsDeclaration(node.parent.parent) &&
            ts.getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node;
    }
    ts.isExpressionOfExternalModuleImportEqualsDeclaration = isExpressionOfExternalModuleImportEqualsDeclaration;
    function getContainerNode(node) {
        if (ts.isJSDocTypeAlias(node)) {
            // This doesn't just apply to the node immediately under the comment, but to everything in its parent's scope.
            // node.parent = the JSDoc comment, node.parent.parent = the node having the comment.
            // Then we get parent again in the loop.
            node = node.parent.parent;
        }
        while (true) {
            node = node.parent;
            if (!node) {
                return undefined;
            }
            switch (node.kind) {
                case 285 /* SourceFile */:
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                case 240 /* FunctionDeclaration */:
                case 197 /* FunctionExpression */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                case 241 /* ClassDeclaration */:
                case 242 /* InterfaceDeclaration */:
                case 244 /* EnumDeclaration */:
                case 245 /* ModuleDeclaration */:
                    return node;
            }
        }
    }
    ts.getContainerNode = getContainerNode;
    function getNodeKind(node) {
        switch (node.kind) {
            case 285 /* SourceFile */:
                return ts.isExternalModule(node) ? "module" /* moduleElement */ : "script" /* scriptElement */;
            case 245 /* ModuleDeclaration */:
                return "module" /* moduleElement */;
            case 241 /* ClassDeclaration */:
            case 210 /* ClassExpression */:
                return "class" /* classElement */;
            case 242 /* InterfaceDeclaration */: return "interface" /* interfaceElement */;
            case 243 /* TypeAliasDeclaration */:
            case 303 /* JSDocCallbackTag */:
            case 310 /* JSDocTypedefTag */:
                return "type" /* typeElement */;
            case 244 /* EnumDeclaration */: return "enum" /* enumElement */;
            case 238 /* VariableDeclaration */:
                return getKindOfVariableDeclaration(node);
            case 187 /* BindingElement */:
                return getKindOfVariableDeclaration(ts.getRootDeclaration(node));
            case 198 /* ArrowFunction */:
            case 240 /* FunctionDeclaration */:
            case 197 /* FunctionExpression */:
                return "function" /* functionElement */;
            case 159 /* GetAccessor */: return "getter" /* memberGetAccessorElement */;
            case 160 /* SetAccessor */: return "setter" /* memberSetAccessorElement */;
            case 157 /* MethodDeclaration */:
            case 156 /* MethodSignature */:
                return "method" /* memberFunctionElement */;
            case 155 /* PropertyDeclaration */:
            case 154 /* PropertySignature */:
                return "property" /* memberVariableElement */;
            case 163 /* IndexSignature */: return "index" /* indexSignatureElement */;
            case 162 /* ConstructSignature */: return "construct" /* constructSignatureElement */;
            case 161 /* CallSignature */: return "call" /* callSignatureElement */;
            case 158 /* Constructor */: return "constructor" /* constructorImplementationElement */;
            case 151 /* TypeParameter */: return "type parameter" /* typeParameterElement */;
            case 279 /* EnumMember */: return "enum member" /* enumMemberElement */;
            case 152 /* Parameter */: return ts.hasModifier(node, 92 /* ParameterPropertyModifier */) ? "property" /* memberVariableElement */ : "parameter" /* parameterElement */;
            case 249 /* ImportEqualsDeclaration */:
            case 254 /* ImportSpecifier */:
            case 258 /* ExportSpecifier */:
            case 252 /* NamespaceImport */:
                return "alias" /* alias */;
            case 205 /* BinaryExpression */:
                var kind = ts.getAssignmentDeclarationKind(node);
                var right = node.right;
                switch (kind) {
                    case 7 /* ObjectDefinePropertyValue */:
                    case 8 /* ObjectDefinePropertyExports */:
                    case 9 /* ObjectDefinePrototypeProperty */:
                    case 0 /* None */:
                        return "" /* unknown */;
                    case 1 /* ExportsProperty */:
                    case 2 /* ModuleExports */:
                        var rightKind = getNodeKind(right);
                        return rightKind === "" /* unknown */ ? "const" /* constElement */ : rightKind;
                    case 3 /* PrototypeProperty */:
                        return ts.isFunctionExpression(right) ? "method" /* memberFunctionElement */ : "property" /* memberVariableElement */;
                    case 4 /* ThisProperty */:
                        return "property" /* memberVariableElement */; // property
                    case 5 /* Property */:
                        // static method / property
                        return ts.isFunctionExpression(right) ? "method" /* memberFunctionElement */ : "property" /* memberVariableElement */;
                    case 6 /* Prototype */:
                        return "local class" /* localClassElement */;
                    default: {
                        ts.assertType(kind);
                        return "" /* unknown */;
                    }
                }
            case 73 /* Identifier */:
                return ts.isImportClause(node.parent) ? "alias" /* alias */ : "" /* unknown */;
            default:
                return "" /* unknown */;
        }
        function getKindOfVariableDeclaration(v) {
            return ts.isVarConst(v)
                ? "const" /* constElement */
                : ts.isLet(v)
                    ? "let" /* letElement */
                    : "var" /* variableElement */;
        }
    }
    ts.getNodeKind = getNodeKind;
    function isThis(node) {
        switch (node.kind) {
            case 101 /* ThisKeyword */:
                // case SyntaxKind.ThisType: TODO: GH#9267
                return true;
            case 73 /* Identifier */:
                // 'this' as a parameter
                return ts.identifierIsThisKeyword(node) && node.parent.kind === 152 /* Parameter */;
            default:
                return false;
        }
    }
    ts.isThis = isThis;
    // Matches the beginning of a triple slash directive
    var tripleSlashDirectivePrefixRegex = /^\/\/\/\s*</;
    function getLineStartPositionForPosition(position, sourceFile) {
        var lineStarts = ts.getLineStarts(sourceFile);
        var line = sourceFile.getLineAndCharacterOfPosition(position).line;
        return lineStarts[line];
    }
    ts.getLineStartPositionForPosition = getLineStartPositionForPosition;
    function rangeContainsRange(r1, r2) {
        return startEndContainsRange(r1.pos, r1.end, r2);
    }
    ts.rangeContainsRange = rangeContainsRange;
    function rangeContainsRangeExclusive(r1, r2) {
        return rangeContainsPositionExclusive(r1, r2.pos) && rangeContainsPositionExclusive(r1, r2.end);
    }
    ts.rangeContainsRangeExclusive = rangeContainsRangeExclusive;
    function rangeContainsPosition(r, pos) {
        return r.pos <= pos && pos <= r.end;
    }
    ts.rangeContainsPosition = rangeContainsPosition;
    function rangeContainsPositionExclusive(r, pos) {
        return r.pos < pos && pos < r.end;
    }
    ts.rangeContainsPositionExclusive = rangeContainsPositionExclusive;
    function startEndContainsRange(start, end, range) {
        return start <= range.pos && end >= range.end;
    }
    ts.startEndContainsRange = startEndContainsRange;
    function rangeContainsStartEnd(range, start, end) {
        return range.pos <= start && range.end >= end;
    }
    ts.rangeContainsStartEnd = rangeContainsStartEnd;
    function rangeOverlapsWithStartEnd(r1, start, end) {
        return startEndOverlapsWithStartEnd(r1.pos, r1.end, start, end);
    }
    ts.rangeOverlapsWithStartEnd = rangeOverlapsWithStartEnd;
    function nodeOverlapsWithStartEnd(node, sourceFile, start, end) {
        return startEndOverlapsWithStartEnd(node.getStart(sourceFile), node.end, start, end);
    }
    ts.nodeOverlapsWithStartEnd = nodeOverlapsWithStartEnd;
    function startEndOverlapsWithStartEnd(start1, end1, start2, end2) {
        var start = Math.max(start1, start2);
        var end = Math.min(end1, end2);
        return start < end;
    }
    ts.startEndOverlapsWithStartEnd = startEndOverlapsWithStartEnd;
    /**
     * Assumes `candidate.start <= position` holds.
     */
    function positionBelongsToNode(candidate, position, sourceFile) {
        ts.Debug.assert(candidate.pos <= position);
        return position < candidate.end || !isCompletedNode(candidate, sourceFile);
    }
    ts.positionBelongsToNode = positionBelongsToNode;
    function isCompletedNode(n, sourceFile) {
        if (n === undefined || ts.nodeIsMissing(n)) {
            return false;
        }
        switch (n.kind) {
            case 241 /* ClassDeclaration */:
            case 242 /* InterfaceDeclaration */:
            case 244 /* EnumDeclaration */:
            case 189 /* ObjectLiteralExpression */:
            case 185 /* ObjectBindingPattern */:
            case 169 /* TypeLiteral */:
            case 219 /* Block */:
            case 246 /* ModuleBlock */:
            case 247 /* CaseBlock */:
            case 253 /* NamedImports */:
            case 257 /* NamedExports */:
                return nodeEndsWith(n, 19 /* CloseBraceToken */, sourceFile);
            case 275 /* CatchClause */:
                return isCompletedNode(n.block, sourceFile);
            case 193 /* NewExpression */:
                if (!n.arguments) {
                    return true;
                }
            // falls through
            case 192 /* CallExpression */:
            case 196 /* ParenthesizedExpression */:
            case 178 /* ParenthesizedType */:
                return nodeEndsWith(n, 21 /* CloseParenToken */, sourceFile);
            case 166 /* FunctionType */:
            case 167 /* ConstructorType */:
                return isCompletedNode(n.type, sourceFile);
            case 158 /* Constructor */:
            case 159 /* GetAccessor */:
            case 160 /* SetAccessor */:
            case 240 /* FunctionDeclaration */:
            case 197 /* FunctionExpression */:
            case 157 /* MethodDeclaration */:
            case 156 /* MethodSignature */:
            case 162 /* ConstructSignature */:
            case 161 /* CallSignature */:
            case 198 /* ArrowFunction */:
                if (n.body) {
                    return isCompletedNode(n.body, sourceFile);
                }
                if (n.type) {
                    return isCompletedNode(n.type, sourceFile);
                }
                // Even though type parameters can be unclosed, we can get away with
                // having at least a closing paren.
                return hasChildOfKind(n, 21 /* CloseParenToken */, sourceFile);
            case 245 /* ModuleDeclaration */:
                return !!n.body && isCompletedNode(n.body, sourceFile);
            case 223 /* IfStatement */:
                if (n.elseStatement) {
                    return isCompletedNode(n.elseStatement, sourceFile);
                }
                return isCompletedNode(n.thenStatement, sourceFile);
            case 222 /* ExpressionStatement */:
                return isCompletedNode(n.expression, sourceFile) ||
                    hasChildOfKind(n, 26 /* SemicolonToken */, sourceFile);
            case 188 /* ArrayLiteralExpression */:
            case 186 /* ArrayBindingPattern */:
            case 191 /* ElementAccessExpression */:
            case 150 /* ComputedPropertyName */:
            case 171 /* TupleType */:
                return nodeEndsWith(n, 23 /* CloseBracketToken */, sourceFile);
            case 163 /* IndexSignature */:
                if (n.type) {
                    return isCompletedNode(n.type, sourceFile);
                }
                return hasChildOfKind(n, 23 /* CloseBracketToken */, sourceFile);
            case 272 /* CaseClause */:
            case 273 /* DefaultClause */:
                // there is no such thing as terminator token for CaseClause/DefaultClause so for simplicity always consider them non-completed
                return false;
            case 226 /* ForStatement */:
            case 227 /* ForInStatement */:
            case 228 /* ForOfStatement */:
            case 225 /* WhileStatement */:
                return isCompletedNode(n.statement, sourceFile);
            case 224 /* DoStatement */:
                // rough approximation: if DoStatement has While keyword - then if node is completed is checking the presence of ')';
                return hasChildOfKind(n, 108 /* WhileKeyword */, sourceFile)
                    ? nodeEndsWith(n, 21 /* CloseParenToken */, sourceFile)
                    : isCompletedNode(n.statement, sourceFile);
            case 168 /* TypeQuery */:
                return isCompletedNode(n.exprName, sourceFile);
            case 200 /* TypeOfExpression */:
            case 199 /* DeleteExpression */:
            case 201 /* VoidExpression */:
            case 208 /* YieldExpression */:
            case 209 /* SpreadElement */:
                var unaryWordExpression = n;
                return isCompletedNode(unaryWordExpression.expression, sourceFile);
            case 194 /* TaggedTemplateExpression */:
                return isCompletedNode(n.template, sourceFile);
            case 207 /* TemplateExpression */:
                var lastSpan = ts.lastOrUndefined(n.templateSpans);
                return isCompletedNode(lastSpan, sourceFile);
            case 217 /* TemplateSpan */:
                return ts.nodeIsPresent(n.literal);
            case 256 /* ExportDeclaration */:
            case 250 /* ImportDeclaration */:
                return ts.nodeIsPresent(n.moduleSpecifier);
            case 203 /* PrefixUnaryExpression */:
                return isCompletedNode(n.operand, sourceFile);
            case 205 /* BinaryExpression */:
                return isCompletedNode(n.right, sourceFile);
            case 206 /* ConditionalExpression */:
                return isCompletedNode(n.whenFalse, sourceFile);
            default:
                return true;
        }
    }
    /*
     * Checks if node ends with 'expectedLastToken'.
     * If child at position 'length - 1' is 'SemicolonToken' it is skipped and 'expectedLastToken' is compared with child at position 'length - 2'.
     */
    function nodeEndsWith(n, expectedLastToken, sourceFile) {
        var children = n.getChildren(sourceFile);
        if (children.length) {
            var lastChild = ts.last(children);
            if (lastChild.kind === expectedLastToken) {
                return true;
            }
            else if (lastChild.kind === 26 /* SemicolonToken */ && children.length !== 1) {
                return children[children.length - 2].kind === expectedLastToken;
            }
        }
        return false;
    }
    function findListItemInfo(node) {
        var list = findContainingList(node);
        // It is possible at this point for syntaxList to be undefined, either if
        // node.parent had no list child, or if none of its list children contained
        // the span of node. If this happens, return undefined. The caller should
        // handle this case.
        if (!list) {
            return undefined;
        }
        var children = list.getChildren();
        var listItemIndex = ts.indexOfNode(children, node);
        return {
            listItemIndex: listItemIndex,
            list: list
        };
    }
    ts.findListItemInfo = findListItemInfo;
    function hasChildOfKind(n, kind, sourceFile) {
        return !!findChildOfKind(n, kind, sourceFile);
    }
    ts.hasChildOfKind = hasChildOfKind;
    function findChildOfKind(n, kind, sourceFile) {
        return ts.find(n.getChildren(sourceFile), function (c) { return c.kind === kind; });
    }
    ts.findChildOfKind = findChildOfKind;
    function findContainingList(node) {
        // The node might be a list element (nonsynthetic) or a comma (synthetic). Either way, it will
        // be parented by the container of the SyntaxList, not the SyntaxList itself.
        // In order to find the list item index, we first need to locate SyntaxList itself and then search
        // for the position of the relevant node (or comma).
        var syntaxList = ts.find(node.parent.getChildren(), function (c) { return ts.isSyntaxList(c) && rangeContainsRange(c, node); });
        // Either we didn't find an appropriate list, or the list must contain us.
        ts.Debug.assert(!syntaxList || ts.contains(syntaxList.getChildren(), node));
        return syntaxList;
    }
    ts.findContainingList = findContainingList;
    /**
     * Gets the token whose text has range [start, end) and
     * position >= start and (position < end or (position === end && token is literal or keyword or identifier))
     */
    function getTouchingPropertyName(sourceFile, position) {
        return getTouchingToken(sourceFile, position, function (n) { return ts.isPropertyNameLiteral(n) || ts.isKeyword(n.kind); });
    }
    ts.getTouchingPropertyName = getTouchingPropertyName;
    /**
     * Returns the token if position is in [start, end).
     * If position === end, returns the preceding token if includeItemAtEndPosition(previousToken) === true
     */
    function getTouchingToken(sourceFile, position, includePrecedingTokenAtEndPosition) {
        return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ false, includePrecedingTokenAtEndPosition, /*includeEndPosition*/ false);
    }
    ts.getTouchingToken = getTouchingToken;
    /** Returns a token if position is in [start-of-leading-trivia, end) */
    function getTokenAtPosition(sourceFile, position) {
        return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ true, /*includePrecedingTokenAtEndPosition*/ undefined, /*includeEndPosition*/ false);
    }
    ts.getTokenAtPosition = getTokenAtPosition;
    /** Get the token whose text contains the position */
    function getTokenAtPositionWorker(sourceFile, position, allowPositionInLeadingTrivia, includePrecedingTokenAtEndPosition, includeEndPosition) {
        var current = sourceFile;
        outer: while (true) {
            // find the child that contains 'position'
            for (var _i = 0, _a = current.getChildren(sourceFile); _i < _a.length; _i++) {
                var child = _a[_i];
                var start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, /*includeJsDoc*/ true);
                if (start > position) {
                    // If this child begins after position, then all subsequent children will as well.
                    break;
                }
                var end = child.getEnd();
                if (position < end || (position === end && (child.kind === 1 /* EndOfFileToken */ || includeEndPosition))) {
                    current = child;
                    continue outer;
                }
                else if (includePrecedingTokenAtEndPosition && end === position) {
                    var previousToken = findPrecedingToken(position, sourceFile, child);
                    if (previousToken && includePrecedingTokenAtEndPosition(previousToken)) {
                        return previousToken;
                    }
                }
            }
            return current;
        }
    }
    /**
     * The token on the left of the position is the token that strictly includes the position
     * or sits to the left of the cursor if it is on a boundary. For example
     *
     *   fo|o               -> will return foo
     *   foo <comment> |bar -> will return foo
     *
     */
    function findTokenOnLeftOfPosition(file, position) {
        // Ideally, getTokenAtPosition should return a token. However, it is currently
        // broken, so we do a check to make sure the result was indeed a token.
        var tokenAtPosition = getTokenAtPosition(file, position);
        if (ts.isToken(tokenAtPosition) && position > tokenAtPosition.getStart(file) && position < tokenAtPosition.getEnd()) {
            return tokenAtPosition;
        }
        return findPrecedingToken(position, file);
    }
    ts.findTokenOnLeftOfPosition = findTokenOnLeftOfPosition;
    function findNextToken(previousToken, parent, sourceFile) {
        return find(parent);
        function find(n) {
            if (ts.isToken(n) && n.pos === previousToken.end) {
                // this is token that starts at the end of previous token - return it
                return n;
            }
            return ts.firstDefined(n.getChildren(), function (child) {
                var shouldDiveInChildNode = 
                // previous token is enclosed somewhere in the child
                (child.pos <= previousToken.pos && child.end > previousToken.end) ||
                    // previous token ends exactly at the beginning of child
                    (child.pos === previousToken.end);
                return shouldDiveInChildNode && nodeHasTokens(child, sourceFile) ? find(child) : undefined;
            });
        }
    }
    ts.findNextToken = findNextToken;
    /**
     * Finds the rightmost token satisfying `token.end <= position`,
     * excluding `JsxText` tokens containing only whitespace.
     */
    function findPrecedingToken(position, sourceFile, startNode, excludeJsdoc) {
        var result = find(startNode || sourceFile);
        ts.Debug.assert(!(result && isWhiteSpaceOnlyJsxText(result)));
        return result;
        function find(n) {
            if (isNonWhitespaceToken(n) && n.kind !== 1 /* EndOfFileToken */) {
                return n;
            }
            var children = n.getChildren(sourceFile);
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                // Note that the span of a node's tokens is [node.getStart(...), node.end).
                // Given that `position < child.end` and child has constituent tokens, we distinguish these cases:
                // 1) `position` precedes `child`'s tokens or `child` has no tokens (ie: in a comment or whitespace preceding `child`):
                // we need to find the last token in a previous child.
                // 2) `position` is within the same span: we recurse on `child`.
                if (position < child.end) {
                    var start = child.getStart(sourceFile, /*includeJsDoc*/ !excludeJsdoc);
                    var lookInPreviousChild = (start >= position) || // cursor in the leading trivia
                        !nodeHasTokens(child, sourceFile) ||
                        isWhiteSpaceOnlyJsxText(child);
                    if (lookInPreviousChild) {
                        // actual start of the node is past the position - previous token should be at the end of previous child
                        var candidate_1 = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ i, sourceFile);
                        return candidate_1 && findRightmostToken(candidate_1, sourceFile);
                    }
                    else {
                        // candidate should be in this node
                        return find(child);
                    }
                }
            }
            ts.Debug.assert(startNode !== undefined || n.kind === 285 /* SourceFile */ || n.kind === 1 /* EndOfFileToken */ || ts.isJSDocCommentContainingNode(n));
            // Here we know that none of child token nodes embrace the position,
            // the only known case is when position is at the end of the file.
            // Try to find the rightmost token in the file without filtering.
            // Namely we are skipping the check: 'position < node.end'
            var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length, sourceFile);
            return candidate && findRightmostToken(candidate, sourceFile);
        }
    }
    ts.findPrecedingToken = findPrecedingToken;
    function isNonWhitespaceToken(n) {
        return ts.isToken(n) && !isWhiteSpaceOnlyJsxText(n);
    }
    function findRightmostToken(n, sourceFile) {
        if (isNonWhitespaceToken(n)) {
            return n;
        }
        var children = n.getChildren(sourceFile);
        var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length, sourceFile);
        return candidate && findRightmostToken(candidate, sourceFile);
    }
    /**
     * Finds the rightmost child to the left of `children[exclusiveStartPosition]` which is a non-all-whitespace token or has constituent tokens.
     */
    function findRightmostChildNodeWithTokens(children, exclusiveStartPosition, sourceFile) {
        for (var i = exclusiveStartPosition - 1; i >= 0; i--) {
            var child = children[i];
            if (isWhiteSpaceOnlyJsxText(child)) {
                ts.Debug.assert(i > 0, "`JsxText` tokens should not be the first child of `JsxElement | JsxSelfClosingElement`");
            }
            else if (nodeHasTokens(children[i], sourceFile)) {
                return children[i];
            }
        }
    }
    function isInString(sourceFile, position, previousToken) {
        if (previousToken === void 0) { previousToken = findPrecedingToken(position, sourceFile); }
        if (previousToken && ts.isStringTextContainingNode(previousToken)) {
            var start = previousToken.getStart(sourceFile);
            var end = previousToken.getEnd();
            // To be "in" one of these literals, the position has to be:
            //   1. entirely within the token text.
            //   2. at the end position of an unterminated token.
            //   3. at the end of a regular expression (due to trailing flags like '/foo/g').
            if (start < position && position < end) {
                return true;
            }
            if (position === end) {
                return !!previousToken.isUnterminated;
            }
        }
        return false;
    }
    ts.isInString = isInString;
    /**
     * returns true if the position is in between the open and close elements of an JSX expression.
     */
    function isInsideJsxElementOrAttribute(sourceFile, position) {
        var token = getTokenAtPosition(sourceFile, position);
        if (!token) {
            return false;
        }
        if (token.kind === 11 /* JsxText */) {
            return true;
        }
        // <div>Hello |</div>
        if (token.kind === 28 /* LessThanToken */ && token.parent.kind === 11 /* JsxText */) {
            return true;
        }
        // <div> { | </div> or <div a={| </div>
        if (token.kind === 28 /* LessThanToken */ && token.parent.kind === 271 /* JsxExpression */) {
            return true;
        }
        // <div> {
        // |
        // } < /div>
        if (token && token.kind === 19 /* CloseBraceToken */ && token.parent.kind === 271 /* JsxExpression */) {
            return true;
        }
        // <div>|</div>
        if (token.kind === 28 /* LessThanToken */ && token.parent.kind === 264 /* JsxClosingElement */) {
            return true;
        }
        return false;
    }
    ts.isInsideJsxElementOrAttribute = isInsideJsxElementOrAttribute;
    function isWhiteSpaceOnlyJsxText(node) {
        return ts.isJsxText(node) && node.containsOnlyTriviaWhiteSpaces;
    }
    function isInTemplateString(sourceFile, position) {
        var token = getTokenAtPosition(sourceFile, position);
        return ts.isTemplateLiteralKind(token.kind) && position > token.getStart(sourceFile);
    }
    ts.isInTemplateString = isInTemplateString;
    function isInJSXText(sourceFile, position) {
        var token = getTokenAtPosition(sourceFile, position);
        if (ts.isJsxText(token)) {
            return true;
        }
        if (token.kind === 18 /* OpenBraceToken */ && ts.isJsxExpression(token.parent) && ts.isJsxElement(token.parent.parent)) {
            return true;
        }
        if (token.kind === 28 /* LessThanToken */ && ts.isJsxOpeningLikeElement(token.parent) && ts.isJsxElement(token.parent.parent)) {
            return true;
        }
        return false;
    }
    ts.isInJSXText = isInJSXText;
    function findPrecedingMatchingToken(token, matchingTokenKind, sourceFile) {
        var tokenKind = token.kind;
        var remainingMatchingTokens = 0;
        while (true) {
            var preceding = findPrecedingToken(token.getFullStart(), sourceFile);
            if (!preceding) {
                return undefined;
            }
            token = preceding;
            if (token.kind === matchingTokenKind) {
                if (remainingMatchingTokens === 0) {
                    return token;
                }
                remainingMatchingTokens--;
            }
            else if (token.kind === tokenKind) {
                remainingMatchingTokens++;
            }
        }
    }
    ts.findPrecedingMatchingToken = findPrecedingMatchingToken;
    function isPossiblyTypeArgumentPosition(token, sourceFile, checker) {
        var info = getPossibleTypeArgumentsInfo(token, sourceFile);
        return info !== undefined && (ts.isPartOfTypeNode(info.called) ||
            getPossibleGenericSignatures(info.called, info.nTypeArguments, checker).length !== 0 ||
            isPossiblyTypeArgumentPosition(info.called, sourceFile, checker));
    }
    ts.isPossiblyTypeArgumentPosition = isPossiblyTypeArgumentPosition;
    function getPossibleGenericSignatures(called, typeArgumentCount, checker) {
        var type = checker.getTypeAtLocation(called);
        var signatures = ts.isNewExpression(called.parent) ? type.getConstructSignatures() : type.getCallSignatures();
        return signatures.filter(function (candidate) { return !!candidate.typeParameters && candidate.typeParameters.length >= typeArgumentCount; });
    }
    ts.getPossibleGenericSignatures = getPossibleGenericSignatures;
    // Get info for an expression like `f <` that may be the start of type arguments.
    function getPossibleTypeArgumentsInfo(tokenIn, sourceFile) {
        var token = tokenIn;
        // This function determines if the node could be type argument position
        // Since during editing, when type argument list is not complete,
        // the tree could be of any shape depending on the tokens parsed before current node,
        // scanning of the previous identifier followed by "<" before current node would give us better result
        // Note that we also balance out the already provided type arguments, arrays, object literals while doing so
        var remainingLessThanTokens = 0;
        var nTypeArguments = 0;
        while (token) {
            switch (token.kind) {
                case 28 /* LessThanToken */:
                    // Found the beginning of the generic argument expression
                    token = findPrecedingToken(token.getFullStart(), sourceFile);
                    if (!token || !ts.isIdentifier(token))
                        return undefined;
                    if (!remainingLessThanTokens) {
                        return ts.isDeclarationName(token) ? undefined : { called: token, nTypeArguments: nTypeArguments };
                    }
                    remainingLessThanTokens--;
                    break;
                case 48 /* GreaterThanGreaterThanGreaterThanToken */:
                    remainingLessThanTokens = +3;
                    break;
                case 47 /* GreaterThanGreaterThanToken */:
                    remainingLessThanTokens = +2;
                    break;
                case 30 /* GreaterThanToken */:
                    remainingLessThanTokens++;
                    break;
                case 19 /* CloseBraceToken */:
                    // This can be object type, skip until we find the matching open brace token
                    // Skip until the matching open brace token
                    token = findPrecedingMatchingToken(token, 18 /* OpenBraceToken */, sourceFile);
                    if (!token)
                        return undefined;
                    break;
                case 21 /* CloseParenToken */:
                    // This can be object type, skip until we find the matching open brace token
                    // Skip until the matching open brace token
                    token = findPrecedingMatchingToken(token, 20 /* OpenParenToken */, sourceFile);
                    if (!token)
                        return undefined;
                    break;
                case 23 /* CloseBracketToken */:
                    // This can be object type, skip until we find the matching open brace token
                    // Skip until the matching open brace token
                    token = findPrecedingMatchingToken(token, 22 /* OpenBracketToken */, sourceFile);
                    if (!token)
                        return undefined;
                    break;
                // Valid tokens in a type name. Skip.
                case 27 /* CommaToken */:
                    nTypeArguments++;
                    break;
                case 37 /* EqualsGreaterThanToken */:
                case 73 /* Identifier */:
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 103 /* TrueKeyword */:
                case 88 /* FalseKeyword */:
                case 105 /* TypeOfKeyword */:
                case 87 /* ExtendsKeyword */:
                case 130 /* KeyOfKeyword */:
                case 24 /* DotToken */:
                case 50 /* BarToken */:
                case 56 /* QuestionToken */:
                case 57 /* ColonToken */:
                    break;
                default:
                    if (ts.isTypeNode(token)) {
                        break;
                    }
                    // Invalid token in type
                    return undefined;
            }
            token = findPrecedingToken(token.getFullStart(), sourceFile);
        }
        return undefined;
    }
    ts.getPossibleTypeArgumentsInfo = getPossibleTypeArgumentsInfo;
    /**
     * Returns true if the cursor at position in sourceFile is within a comment.
     *
     * @param tokenAtPosition Must equal `getTokenAtPosition(sourceFile, position)
     * @param predicate Additional predicate to test on the comment range.
     */
    function isInComment(sourceFile, position, tokenAtPosition) {
        return ts.formatting.getRangeOfEnclosingComment(sourceFile, position, /*precedingToken*/ undefined, tokenAtPosition);
    }
    ts.isInComment = isInComment;
    function hasDocComment(sourceFile, position) {
        var token = getTokenAtPosition(sourceFile, position);
        return !!ts.findAncestor(token, ts.isJSDoc);
    }
    ts.hasDocComment = hasDocComment;
    function nodeHasTokens(n, sourceFile) {
        // If we have a token or node that has a non-zero width, it must have tokens.
        // Note: getWidth() does not take trivia into account.
        return n.kind === 1 /* EndOfFileToken */ ? !!n.jsDoc : n.getWidth(sourceFile) !== 0;
    }
    function getNodeModifiers(node) {
        var flags = ts.isDeclaration(node) ? ts.getCombinedModifierFlags(node) : 0 /* None */;
        var result = [];
        if (flags & 8 /* Private */)
            result.push("private" /* privateMemberModifier */);
        if (flags & 16 /* Protected */)
            result.push("protected" /* protectedMemberModifier */);
        if (flags & 4 /* Public */)
            result.push("public" /* publicMemberModifier */);
        if (flags & 32 /* Static */)
            result.push("static" /* staticModifier */);
        if (flags & 128 /* Abstract */)
            result.push("abstract" /* abstractModifier */);
        if (flags & 1 /* Export */)
            result.push("export" /* exportedModifier */);
        if (node.flags & 4194304 /* Ambient */)
            result.push("declare" /* ambientModifier */);
        return result.length > 0 ? result.join(",") : "" /* none */;
    }
    ts.getNodeModifiers = getNodeModifiers;
    function getTypeArgumentOrTypeParameterList(node) {
        if (node.kind === 165 /* TypeReference */ || node.kind === 192 /* CallExpression */) {
            return node.typeArguments;
        }
        if (ts.isFunctionLike(node) || node.kind === 241 /* ClassDeclaration */ || node.kind === 242 /* InterfaceDeclaration */) {
            return node.typeParameters;
        }
        return undefined;
    }
    ts.getTypeArgumentOrTypeParameterList = getTypeArgumentOrTypeParameterList;
    function isComment(kind) {
        return kind === 2 /* SingleLineCommentTrivia */ || kind === 3 /* MultiLineCommentTrivia */;
    }
    ts.isComment = isComment;
    function isStringOrRegularExpressionOrTemplateLiteral(kind) {
        if (kind === 10 /* StringLiteral */
            || kind === 13 /* RegularExpressionLiteral */
            || ts.isTemplateLiteralKind(kind)) {
            return true;
        }
        return false;
    }
    ts.isStringOrRegularExpressionOrTemplateLiteral = isStringOrRegularExpressionOrTemplateLiteral;
    function isPunctuation(kind) {
        return 18 /* FirstPunctuation */ <= kind && kind <= 72 /* LastPunctuation */;
    }
    ts.isPunctuation = isPunctuation;
    function isInsideTemplateLiteral(node, position, sourceFile) {
        return ts.isTemplateLiteralKind(node.kind)
            && (node.getStart(sourceFile) < position && position < node.end) || (!!node.isUnterminated && position === node.end);
    }
    ts.isInsideTemplateLiteral = isInsideTemplateLiteral;
    function isAccessibilityModifier(kind) {
        switch (kind) {
            case 116 /* PublicKeyword */:
            case 114 /* PrivateKeyword */:
            case 115 /* ProtectedKeyword */:
                return true;
        }
        return false;
    }
    ts.isAccessibilityModifier = isAccessibilityModifier;
    function cloneCompilerOptions(options) {
        var result = ts.clone(options);
        ts.setConfigFileInOptions(result, options && options.configFile);
        return result;
    }
    ts.cloneCompilerOptions = cloneCompilerOptions;
    function isArrayLiteralOrObjectLiteralDestructuringPattern(node) {
        if (node.kind === 188 /* ArrayLiteralExpression */ ||
            node.kind === 189 /* ObjectLiteralExpression */) {
            // [a,b,c] from:
            // [a, b, c] = someExpression;
            if (node.parent.kind === 205 /* BinaryExpression */ &&
                node.parent.left === node &&
                node.parent.operatorToken.kind === 60 /* EqualsToken */) {
                return true;
            }
            // [a, b, c] from:
            // for([a, b, c] of expression)
            if (node.parent.kind === 228 /* ForOfStatement */ &&
                node.parent.initializer === node) {
                return true;
            }
            // [a, b, c] of
            // [x, [a, b, c] ] = someExpression
            // or
            // {x, a: {a, b, c} } = someExpression
            if (isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent.kind === 276 /* PropertyAssignment */ ? node.parent.parent : node.parent)) {
                return true;
            }
        }
        return false;
    }
    ts.isArrayLiteralOrObjectLiteralDestructuringPattern = isArrayLiteralOrObjectLiteralDestructuringPattern;
    function isInReferenceComment(sourceFile, position) {
        return isInReferenceCommentWorker(sourceFile, position, /*shouldBeReference*/ true);
    }
    ts.isInReferenceComment = isInReferenceComment;
    function isInNonReferenceComment(sourceFile, position) {
        return isInReferenceCommentWorker(sourceFile, position, /*shouldBeReference*/ false);
    }
    ts.isInNonReferenceComment = isInNonReferenceComment;
    function isInReferenceCommentWorker(sourceFile, position, shouldBeReference) {
        var range = isInComment(sourceFile, position, /*tokenAtPosition*/ undefined);
        return !!range && shouldBeReference === tripleSlashDirectivePrefixRegex.test(sourceFile.text.substring(range.pos, range.end));
    }
    function createTextSpanFromNode(node, sourceFile) {
        return ts.createTextSpanFromBounds(node.getStart(sourceFile), node.getEnd());
    }
    ts.createTextSpanFromNode = createTextSpanFromNode;
    function createTextRangeFromNode(node, sourceFile) {
        return ts.createRange(node.getStart(sourceFile), node.end);
    }
    ts.createTextRangeFromNode = createTextRangeFromNode;
    function createTextSpanFromRange(range) {
        return ts.createTextSpanFromBounds(range.pos, range.end);
    }
    ts.createTextSpanFromRange = createTextSpanFromRange;
    function createTextRangeFromSpan(span) {
        return ts.createRange(span.start, span.start + span.length);
    }
    ts.createTextRangeFromSpan = createTextRangeFromSpan;
    function createTextChangeFromStartLength(start, length, newText) {
        return createTextChange(ts.createTextSpan(start, length), newText);
    }
    ts.createTextChangeFromStartLength = createTextChangeFromStartLength;
    function createTextChange(span, newText) {
        return { span: span, newText: newText };
    }
    ts.createTextChange = createTextChange;
    ts.typeKeywords = [
        121 /* AnyKeyword */,
        147 /* BigIntKeyword */,
        124 /* BooleanKeyword */,
        88 /* FalseKeyword */,
        130 /* KeyOfKeyword */,
        133 /* NeverKeyword */,
        97 /* NullKeyword */,
        136 /* NumberKeyword */,
        137 /* ObjectKeyword */,
        139 /* StringKeyword */,
        140 /* SymbolKeyword */,
        103 /* TrueKeyword */,
        107 /* VoidKeyword */,
        142 /* UndefinedKeyword */,
        143 /* UniqueKeyword */,
        144 /* UnknownKeyword */,
    ];
    function isTypeKeyword(kind) {
        return ts.contains(ts.typeKeywords, kind);
    }
    ts.isTypeKeyword = isTypeKeyword;
    /** True if the symbol is for an external module, as opposed to a namespace. */
    function isExternalModuleSymbol(moduleSymbol) {
        return !!(moduleSymbol.flags & 1536 /* Module */) && moduleSymbol.name.charCodeAt(0) === 34 /* doubleQuote */;
    }
    ts.isExternalModuleSymbol = isExternalModuleSymbol;
    function nodeSeenTracker() {
        var seen = [];
        return function (node) {
            var id = ts.getNodeId(node);
            return !seen[id] && (seen[id] = true);
        };
    }
    ts.nodeSeenTracker = nodeSeenTracker;
    function getSnapshotText(snap) {
        return snap.getText(0, snap.getLength());
    }
    ts.getSnapshotText = getSnapshotText;
    function repeatString(str, count) {
        var result = "";
        for (var i = 0; i < count; i++) {
            result += str;
        }
        return result;
    }
    ts.repeatString = repeatString;
    function skipConstraint(type) {
        return type.isTypeParameter() ? type.getConstraint() || type : type;
    }
    ts.skipConstraint = skipConstraint;
    function getNameFromPropertyName(name) {
        return name.kind === 150 /* ComputedPropertyName */
            // treat computed property names where expression is string/numeric literal as just string/numeric literal
            ? ts.isStringOrNumericLiteralLike(name.expression) ? name.expression.text : undefined
            : ts.getTextOfIdentifierOrLiteral(name);
    }
    ts.getNameFromPropertyName = getNameFromPropertyName;
    function programContainsEs6Modules(program) {
        return program.getSourceFiles().some(function (s) { return !s.isDeclarationFile && !program.isSourceFileFromExternalLibrary(s) && !!s.externalModuleIndicator; });
    }
    ts.programContainsEs6Modules = programContainsEs6Modules;
    function compilerOptionsIndicateEs6Modules(compilerOptions) {
        return !!compilerOptions.module || compilerOptions.target >= 2 /* ES2015 */ || !!compilerOptions.noEmit;
    }
    ts.compilerOptionsIndicateEs6Modules = compilerOptionsIndicateEs6Modules;
    function hostUsesCaseSensitiveFileNames(host) {
        return host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : false;
    }
    ts.hostUsesCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames;
    function hostGetCanonicalFileName(host) {
        return ts.createGetCanonicalFileName(hostUsesCaseSensitiveFileNames(host));
    }
    ts.hostGetCanonicalFileName = hostGetCanonicalFileName;
    function makeImportIfNecessary(defaultImport, namedImports, moduleSpecifier, quotePreference) {
        return defaultImport || namedImports && namedImports.length ? makeImport(defaultImport, namedImports, moduleSpecifier, quotePreference) : undefined;
    }
    ts.makeImportIfNecessary = makeImportIfNecessary;
    function makeImport(defaultImport, namedImports, moduleSpecifier, quotePreference) {
        return ts.createImportDeclaration(
        /*decorators*/ undefined, 
        /*modifiers*/ undefined, defaultImport || namedImports
            ? ts.createImportClause(defaultImport, namedImports && namedImports.length ? ts.createNamedImports(namedImports) : undefined)
            : undefined, typeof moduleSpecifier === "string" ? makeStringLiteral(moduleSpecifier, quotePreference) : moduleSpecifier);
    }
    ts.makeImport = makeImport;
    function makeStringLiteral(text, quotePreference) {
        return ts.createLiteral(text, quotePreference === 0 /* Single */);
    }
    ts.makeStringLiteral = makeStringLiteral;
    var QuotePreference;
    (function (QuotePreference) {
        QuotePreference[QuotePreference["Single"] = 0] = "Single";
        QuotePreference[QuotePreference["Double"] = 1] = "Double";
    })(QuotePreference = ts.QuotePreference || (ts.QuotePreference = {}));
    function quotePreferenceFromString(str, sourceFile) {
        return ts.isStringDoubleQuoted(str, sourceFile) ? 1 /* Double */ : 0 /* Single */;
    }
    ts.quotePreferenceFromString = quotePreferenceFromString;
    function getQuotePreference(sourceFile, preferences) {
        if (preferences.quotePreference && preferences.quotePreference !== "auto") {
            return preferences.quotePreference === "single" ? 0 /* Single */ : 1 /* Double */;
        }
        else {
            var firstModuleSpecifier = sourceFile.imports && ts.find(sourceFile.imports, ts.isStringLiteral);
            return firstModuleSpecifier ? quotePreferenceFromString(firstModuleSpecifier, sourceFile) : 1 /* Double */;
        }
    }
    ts.getQuotePreference = getQuotePreference;
    function getQuoteFromPreference(qp) {
        switch (qp) {
            case 0 /* Single */: return "'";
            case 1 /* Double */: return '"';
            default: return ts.Debug.assertNever(qp);
        }
    }
    ts.getQuoteFromPreference = getQuoteFromPreference;
    function symbolNameNoDefault(symbol) {
        var escaped = symbolEscapedNameNoDefault(symbol);
        return escaped === undefined ? undefined : ts.unescapeLeadingUnderscores(escaped);
    }
    ts.symbolNameNoDefault = symbolNameNoDefault;
    function symbolEscapedNameNoDefault(symbol) {
        if (symbol.escapedName !== "default" /* Default */) {
            return symbol.escapedName;
        }
        return ts.firstDefined(symbol.declarations, function (decl) {
            var name = ts.getNameOfDeclaration(decl);
            return name && name.kind === 73 /* Identifier */ ? name.escapedText : undefined;
        });
    }
    ts.symbolEscapedNameNoDefault = symbolEscapedNameNoDefault;
    function isObjectBindingElementWithoutPropertyName(bindingElement) {
        return ts.isBindingElement(bindingElement) &&
            ts.isObjectBindingPattern(bindingElement.parent) &&
            ts.isIdentifier(bindingElement.name) &&
            !bindingElement.propertyName;
    }
    ts.isObjectBindingElementWithoutPropertyName = isObjectBindingElementWithoutPropertyName;
    function getPropertySymbolFromBindingElement(checker, bindingElement) {
        var typeOfPattern = checker.getTypeAtLocation(bindingElement.parent);
        return typeOfPattern && checker.getPropertyOfType(typeOfPattern, bindingElement.name.text);
    }
    ts.getPropertySymbolFromBindingElement = getPropertySymbolFromBindingElement;
    /**
     * Find symbol of the given property-name and add the symbol to the given result array
     * @param symbol a symbol to start searching for the given propertyName
     * @param propertyName a name of property to search for
     * @param result an array of symbol of found property symbols
     * @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisiting of the same symbol.
     *                                The value of previousIterationSymbol is undefined when the function is first called.
     */
    function getPropertySymbolsFromBaseTypes(symbol, propertyName, checker, cb) {
        var seen = ts.createMap();
        return recur(symbol);
        function recur(symbol) {
            // Use `addToSeen` to ensure we don't infinitely recurse in this situation:
            //      interface C extends C {
            //          /*findRef*/propName: string;
            //      }
            if (!(symbol.flags & (32 /* Class */ | 64 /* Interface */)) || !ts.addToSeen(seen, ts.getSymbolId(symbol)))
                return;
            return ts.firstDefined(symbol.declarations, function (declaration) { return ts.firstDefined(ts.getAllSuperTypeNodes(declaration), function (typeReference) {
                var type = checker.getTypeAtLocation(typeReference);
                var propertySymbol = type && type.symbol && checker.getPropertyOfType(type, propertyName);
                // Visit the typeReference as well to see if it directly or indirectly uses that property
                return type && propertySymbol && (ts.firstDefined(checker.getRootSymbols(propertySymbol), cb) || recur(type.symbol));
            }); });
        }
    }
    ts.getPropertySymbolsFromBaseTypes = getPropertySymbolsFromBaseTypes;
    function isMemberSymbolInBaseType(memberSymbol, checker) {
        return getPropertySymbolsFromBaseTypes(memberSymbol.parent, memberSymbol.name, checker, function (_) { return true; }) || false;
    }
    ts.isMemberSymbolInBaseType = isMemberSymbolInBaseType;
    function getParentNodeInSpan(node, file, span) {
        if (!node)
            return undefined;
        while (node.parent) {
            if (ts.isSourceFile(node.parent) || !spanContainsNode(span, node.parent, file)) {
                return node;
            }
            node = node.parent;
        }
    }
    ts.getParentNodeInSpan = getParentNodeInSpan;
    function spanContainsNode(span, node, file) {
        return ts.textSpanContainsPosition(span, node.getStart(file)) &&
            node.getEnd() <= ts.textSpanEnd(span);
    }
    function findModifier(node, kind) {
        return node.modifiers && ts.find(node.modifiers, function (m) { return m.kind === kind; });
    }
    ts.findModifier = findModifier;
    function insertImport(changes, sourceFile, importDecl) {
        var lastImportDeclaration = ts.findLast(sourceFile.statements, ts.isAnyImportSyntax);
        if (lastImportDeclaration) {
            changes.insertNodeAfter(sourceFile, lastImportDeclaration, importDecl);
        }
        else {
            changes.insertNodeAtTopOfFile(sourceFile, importDecl, /*blankLineBetween*/ true);
        }
    }
    ts.insertImport = insertImport;
    function textSpansEqual(a, b) {
        return !!a && !!b && a.start === b.start && a.length === b.length;
    }
    ts.textSpansEqual = textSpansEqual;
    function documentSpansEqual(a, b) {
        return a.fileName === b.fileName && textSpansEqual(a.textSpan, b.textSpan);
    }
    ts.documentSpansEqual = documentSpansEqual;
})(ts || (ts = {}));
// Display-part writer helpers
/* @internal */
(function (ts) {
    function isFirstDeclarationOfSymbolParameter(symbol) {
        return symbol.declarations && symbol.declarations.length > 0 && symbol.declarations[0].kind === 152 /* Parameter */;
    }
    ts.isFirstDeclarationOfSymbolParameter = isFirstDeclarationOfSymbolParameter;
    var displayPartWriter = getDisplayPartWriter();
    function getDisplayPartWriter() {
        var absoluteMaximumLength = ts.defaultMaximumTruncationLength * 10; // A hard cutoff to avoid overloading the messaging channel in worst-case scenarios
        var displayParts;
        var lineStart;
        var indent;
        var length;
        resetWriter();
        var unknownWrite = function (text) { return writeKind(text, ts.SymbolDisplayPartKind.text); };
        return {
            displayParts: function () {
                var finalText = displayParts.length && displayParts[displayParts.length - 1].text;
                if (length > absoluteMaximumLength && finalText && finalText !== "...") {
                    if (!ts.isWhiteSpaceLike(finalText.charCodeAt(finalText.length - 1))) {
                        displayParts.push(displayPart(" ", ts.SymbolDisplayPartKind.space));
                    }
                    displayParts.push(displayPart("...", ts.SymbolDisplayPartKind.punctuation));
                }
                return displayParts;
            },
            writeKeyword: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.keyword); },
            writeOperator: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.operator); },
            writePunctuation: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.punctuation); },
            writeTrailingSemicolon: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.punctuation); },
            writeSpace: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.space); },
            writeStringLiteral: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.stringLiteral); },
            writeParameter: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.parameterName); },
            writeProperty: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.propertyName); },
            writeLiteral: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.stringLiteral); },
            writeSymbol: writeSymbol,
            writeLine: writeLine,
            write: unknownWrite,
            writeComment: unknownWrite,
            getText: function () { return ""; },
            getTextPos: function () { return 0; },
            getColumn: function () { return 0; },
            getLine: function () { return 0; },
            isAtStartOfLine: function () { return false; },
            rawWrite: ts.notImplemented,
            getIndent: function () { return indent; },
            increaseIndent: function () { indent++; },
            decreaseIndent: function () { indent--; },
            clear: resetWriter,
            trackSymbol: ts.noop,
            reportInaccessibleThisError: ts.noop,
            reportInaccessibleUniqueSymbolError: ts.noop,
            reportPrivateInBaseOfClassExpression: ts.noop,
        };
        function writeIndent() {
            if (length > absoluteMaximumLength)
                return;
            if (lineStart) {
                var indentString = ts.getIndentString(indent);
                if (indentString) {
                    length += indentString.length;
                    displayParts.push(displayPart(indentString, ts.SymbolDisplayPartKind.space));
                }
                lineStart = false;
            }
        }
        function writeKind(text, kind) {
            if (length > absoluteMaximumLength)
                return;
            writeIndent();
            length += text.length;
            displayParts.push(displayPart(text, kind));
        }
        function writeSymbol(text, symbol) {
            if (length > absoluteMaximumLength)
                return;
            writeIndent();
            length += text.length;
            displayParts.push(symbolPart(text, symbol));
        }
        function writeLine() {
            if (length > absoluteMaximumLength)
                return;
            length += 1;
            displayParts.push(lineBreakPart());
            lineStart = true;
        }
        function resetWriter() {
            displayParts = [];
            lineStart = true;
            indent = 0;
            length = 0;
        }
    }
    function symbolPart(text, symbol) {
        return displayPart(text, displayPartKind(symbol));
        function displayPartKind(symbol) {
            var flags = symbol.flags;
            if (flags & 3 /* Variable */) {
                return isFirstDeclarationOfSymbolParameter(symbol) ? ts.SymbolDisplayPartKind.parameterName : ts.SymbolDisplayPartKind.localName;
            }
            else if (flags & 4 /* Property */) {
                return ts.SymbolDisplayPartKind.propertyName;
            }
            else if (flags & 32768 /* GetAccessor */) {
                return ts.SymbolDisplayPartKind.propertyName;
            }
            else if (flags & 65536 /* SetAccessor */) {
                return ts.SymbolDisplayPartKind.propertyName;
            }
            else if (flags & 8 /* EnumMember */) {
                return ts.SymbolDisplayPartKind.enumMemberName;
            }
            else if (flags & 16 /* Function */) {
                return ts.SymbolDisplayPartKind.functionName;
            }
            else if (flags & 32 /* Class */) {
                return ts.SymbolDisplayPartKind.className;
            }
            else if (flags & 64 /* Interface */) {
                return ts.SymbolDisplayPartKind.interfaceName;
            }
            else if (flags & 384 /* Enum */) {
                return ts.SymbolDisplayPartKind.enumName;
            }
            else if (flags & 1536 /* Module */) {
                return ts.SymbolDisplayPartKind.moduleName;
            }
            else if (flags & 8192 /* Method */) {
                return ts.SymbolDisplayPartKind.methodName;
            }
            else if (flags & 262144 /* TypeParameter */) {
                return ts.SymbolDisplayPartKind.typeParameterName;
            }
            else if (flags & 524288 /* TypeAlias */) {
                return ts.SymbolDisplayPartKind.aliasName;
            }
            else if (flags & 2097152 /* Alias */) {
                return ts.SymbolDisplayPartKind.aliasName;
            }
            return ts.SymbolDisplayPartKind.text;
        }
    }
    ts.symbolPart = symbolPart;
    function displayPart(text, kind) {
        return { text: text, kind: ts.SymbolDisplayPartKind[kind] };
    }
    ts.displayPart = displayPart;
    function spacePart() {
        return displayPart(" ", ts.SymbolDisplayPartKind.space);
    }
    ts.spacePart = spacePart;
    function keywordPart(kind) {
        return displayPart(ts.tokenToString(kind), ts.SymbolDisplayPartKind.keyword);
    }
    ts.keywordPart = keywordPart;
    function punctuationPart(kind) {
        return displayPart(ts.tokenToString(kind), ts.SymbolDisplayPartKind.punctuation);
    }
    ts.punctuationPart = punctuationPart;
    function operatorPart(kind) {
        return displayPart(ts.tokenToString(kind), ts.SymbolDisplayPartKind.operator);
    }
    ts.operatorPart = operatorPart;
    function textOrKeywordPart(text) {
        var kind = ts.stringToToken(text);
        return kind === undefined
            ? textPart(text)
            : keywordPart(kind);
    }
    ts.textOrKeywordPart = textOrKeywordPart;
    function textPart(text) {
        return displayPart(text, ts.SymbolDisplayPartKind.text);
    }
    ts.textPart = textPart;
    var carriageReturnLineFeed = "\r\n";
    /**
     * The default is CRLF.
     */
    function getNewLineOrDefaultFromHost(host, formatSettings) {
        return (formatSettings && formatSettings.newLineCharacter) ||
            (host.getNewLine && host.getNewLine()) ||
            carriageReturnLineFeed;
    }
    ts.getNewLineOrDefaultFromHost = getNewLineOrDefaultFromHost;
    function lineBreakPart() {
        return displayPart("\n", ts.SymbolDisplayPartKind.lineBreak);
    }
    ts.lineBreakPart = lineBreakPart;
    function mapToDisplayParts(writeDisplayParts) {
        try {
            writeDisplayParts(displayPartWriter);
            return displayPartWriter.displayParts();
        }
        finally {
            displayPartWriter.clear();
        }
    }
    ts.mapToDisplayParts = mapToDisplayParts;
    function typeToDisplayParts(typechecker, type, enclosingDeclaration, flags) {
        if (flags === void 0) { flags = 0 /* None */; }
        return mapToDisplayParts(function (writer) {
            typechecker.writeType(type, enclosingDeclaration, flags | 1024 /* MultilineObjectLiterals */ | 16384 /* UseAliasDefinedOutsideCurrentScope */, writer);
        });
    }
    ts.typeToDisplayParts = typeToDisplayParts;
    function symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration, meaning, flags) {
        if (flags === void 0) { flags = 0 /* None */; }
        return mapToDisplayParts(function (writer) {
            typeChecker.writeSymbol(symbol, enclosingDeclaration, meaning, flags | 8 /* UseAliasDefinedOutsideCurrentScope */, writer);
        });
    }
    ts.symbolToDisplayParts = symbolToDisplayParts;
    function signatureToDisplayParts(typechecker, signature, enclosingDeclaration, flags) {
        if (flags === void 0) { flags = 0 /* None */; }
        flags |= 16384 /* UseAliasDefinedOutsideCurrentScope */ | 1024 /* MultilineObjectLiterals */ | 32 /* WriteTypeArgumentsOfSignature */ | 8192 /* OmitParameterModifiers */;
        return mapToDisplayParts(function (writer) {
            typechecker.writeSignature(signature, enclosingDeclaration, flags, /*signatureKind*/ undefined, writer);
        });
    }
    ts.signatureToDisplayParts = signatureToDisplayParts;
    function isImportOrExportSpecifierName(location) {
        return !!location.parent && ts.isImportOrExportSpecifier(location.parent) && location.parent.propertyName === location;
    }
    ts.isImportOrExportSpecifierName = isImportOrExportSpecifierName;
    /**
     * Strip off existed single quotes or double quotes from a given string
     *
     * @return non-quoted string
     */
    function stripQuotes(name) {
        var length = name.length;
        if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && startsWithQuote(name)) {
            return name.substring(1, length - 1);
        }
        return name;
    }
    ts.stripQuotes = stripQuotes;
    function startsWithQuote(name) {
        return ts.isSingleOrDoubleQuote(name.charCodeAt(0));
    }
    ts.startsWithQuote = startsWithQuote;
    function scriptKindIs(fileName, host) {
        var scriptKinds = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            scriptKinds[_i - 2] = arguments[_i];
        }
        var scriptKind = getScriptKind(fileName, host);
        return ts.some(scriptKinds, function (k) { return k === scriptKind; });
    }
    ts.scriptKindIs = scriptKindIs;
    function getScriptKind(fileName, host) {
        // First check to see if the script kind was specified by the host. Chances are the host
        // may override the default script kind for the file extension.
        return ts.ensureScriptKind(fileName, host && host.getScriptKind && host.getScriptKind(fileName));
    }
    ts.getScriptKind = getScriptKind;
    function getSymbolTarget(symbol, checker) {
        var next = symbol;
        while (isAliasSymbol(next) || (isTransientSymbol(next) && next.target)) {
            if (isTransientSymbol(next) && next.target) {
                next = next.target;
            }
            else {
                next = ts.skipAlias(next, checker);
            }
        }
        return next;
    }
    ts.getSymbolTarget = getSymbolTarget;
    function isTransientSymbol(symbol) {
        return (symbol.flags & 33554432 /* Transient */) !== 0;
    }
    function isAliasSymbol(symbol) {
        return (symbol.flags & 2097152 /* Alias */) !== 0;
    }
    function getUniqueSymbolId(symbol, checker) {
        return ts.getSymbolId(ts.skipAlias(symbol, checker));
    }
    ts.getUniqueSymbolId = getUniqueSymbolId;
    function getFirstNonSpaceCharacterPosition(text, position) {
        while (ts.isWhiteSpaceLike(text.charCodeAt(position))) {
            position += 1;
        }
        return position;
    }
    ts.getFirstNonSpaceCharacterPosition = getFirstNonSpaceCharacterPosition;
    function getPrecedingNonSpaceCharacterPosition(text, position) {
        while (position > -1 && ts.isWhiteSpaceSingleLine(text.charCodeAt(position))) {
            position -= 1;
        }
        return position + 1;
    }
    ts.getPrecedingNonSpaceCharacterPosition = getPrecedingNonSpaceCharacterPosition;
    /**
     * Creates a deep, memberwise clone of a node with no source map location.
     *
     * WARNING: This is an expensive operation and is only intended to be used in refactorings
     * and code fixes (because those are triggered by explicit user actions).
     */
    function getSynthesizedDeepClone(node, includeTrivia) {
        if (includeTrivia === void 0) { includeTrivia = true; }
        var clone = node && getSynthesizedDeepCloneWorker(node);
        if (clone && !includeTrivia)
            suppressLeadingAndTrailingTrivia(clone);
        return clone;
    }
    ts.getSynthesizedDeepClone = getSynthesizedDeepClone;
    function getSynthesizedDeepCloneWithRenames(node, includeTrivia, renameMap, checker, callback) {
        if (includeTrivia === void 0) { includeTrivia = true; }
        var clone;
        if (renameMap && checker && ts.isBindingElement(node) && ts.isIdentifier(node.name) && ts.isObjectBindingPattern(node.parent)) {
            var symbol = checker.getSymbolAtLocation(node.name);
            var renameInfo = symbol && renameMap.get(String(ts.getSymbolId(symbol)));
            if (renameInfo && renameInfo.text !== (node.name || node.propertyName).getText()) {
                clone = ts.createBindingElement(node.dotDotDotToken, node.propertyName || node.name, renameInfo, node.initializer);
            }
        }
        else if (renameMap && checker && ts.isIdentifier(node)) {
            var symbol = checker.getSymbolAtLocation(node);
            var renameInfo = symbol && renameMap.get(String(ts.getSymbolId(symbol)));
            if (renameInfo) {
                clone = ts.createIdentifier(renameInfo.text);
            }
        }
        if (!clone) {
            clone = getSynthesizedDeepCloneWorker(node, renameMap, checker, callback);
        }
        if (clone && !includeTrivia)
            suppressLeadingAndTrailingTrivia(clone);
        if (callback && clone)
            callback(node, clone);
        return clone;
    }
    ts.getSynthesizedDeepCloneWithRenames = getSynthesizedDeepCloneWithRenames;
    function getSynthesizedDeepCloneWorker(node, renameMap, checker, callback) {
        var visited = (renameMap || checker || callback) ?
            ts.visitEachChild(node, wrapper, ts.nullTransformationContext) :
            ts.visitEachChild(node, getSynthesizedDeepClone, ts.nullTransformationContext);
        if (visited === node) {
            // This only happens for leaf nodes - internal nodes always see their children change.
            var clone_1 = ts.getSynthesizedClone(node);
            if (ts.isStringLiteral(clone_1)) {
                clone_1.textSourceNode = node;
            }
            else if (ts.isNumericLiteral(clone_1)) {
                clone_1.numericLiteralFlags = node.numericLiteralFlags;
            }
            return ts.setTextRange(clone_1, node);
        }
        // PERF: As an optimization, rather than calling getSynthesizedClone, we'll update
        // the new node created by visitEachChild with the extra changes getSynthesizedClone
        // would have made.
        visited.parent = undefined;
        return visited;
        function wrapper(node) {
            return getSynthesizedDeepCloneWithRenames(node, /*includeTrivia*/ true, renameMap, checker, callback);
        }
    }
    function getSynthesizedDeepClones(nodes, includeTrivia) {
        if (includeTrivia === void 0) { includeTrivia = true; }
        return nodes && ts.createNodeArray(nodes.map(function (n) { return getSynthesizedDeepClone(n, includeTrivia); }), nodes.hasTrailingComma);
    }
    ts.getSynthesizedDeepClones = getSynthesizedDeepClones;
    /**
     * Sets EmitFlags to suppress leading and trailing trivia on the node.
     */
    function suppressLeadingAndTrailingTrivia(node) {
        suppressLeadingTrivia(node);
        suppressTrailingTrivia(node);
    }
    ts.suppressLeadingAndTrailingTrivia = suppressLeadingAndTrailingTrivia;
    /**
     * Sets EmitFlags to suppress leading trivia on the node.
     */
    function suppressLeadingTrivia(node) {
        addEmitFlagsRecursively(node, 512 /* NoLeadingComments */, getFirstChild);
    }
    ts.suppressLeadingTrivia = suppressLeadingTrivia;
    /**
     * Sets EmitFlags to suppress trailing trivia on the node.
     */
    function suppressTrailingTrivia(node) {
        addEmitFlagsRecursively(node, 1024 /* NoTrailingComments */, ts.getLastChild);
    }
    ts.suppressTrailingTrivia = suppressTrailingTrivia;
    function addEmitFlagsRecursively(node, flag, getChild) {
        ts.addEmitFlags(node, flag);
        var child = getChild(node);
        if (child)
            addEmitFlagsRecursively(child, flag, getChild);
    }
    function getFirstChild(node) {
        return node.forEachChild(function (child) { return child; });
    }
    function getUniqueName(baseName, sourceFile) {
        var nameText = baseName;
        for (var i = 1; !ts.isFileLevelUniqueName(sourceFile, nameText); i++) {
            nameText = baseName + "_" + i;
        }
        return nameText;
    }
    ts.getUniqueName = getUniqueName;
    /**
     * @return The index of the (only) reference to the extracted symbol.  We want the cursor
     * to be on the reference, rather than the declaration, because it's closer to where the
     * user was before extracting it.
     */
    function getRenameLocation(edits, renameFilename, name, preferLastLocation) {
        var delta = 0;
        var lastPos = -1;
        for (var _i = 0, edits_1 = edits; _i < edits_1.length; _i++) {
            var _a = edits_1[_i], fileName = _a.fileName, textChanges_2 = _a.textChanges;
            ts.Debug.assert(fileName === renameFilename);
            for (var _b = 0, textChanges_1 = textChanges_2; _b < textChanges_1.length; _b++) {
                var change = textChanges_1[_b];
                var span = change.span, newText = change.newText;
                var index = indexInTextChange(newText, name);
                if (index !== -1) {
                    lastPos = span.start + delta + index;
                    // If the reference comes first, return immediately.
                    if (!preferLastLocation) {
                        return lastPos;
                    }
                }
                delta += newText.length - span.length;
            }
        }
        // If the declaration comes first, return the position of the last occurrence.
        ts.Debug.assert(preferLastLocation);
        ts.Debug.assert(lastPos >= 0);
        return lastPos;
    }
    ts.getRenameLocation = getRenameLocation;
    function copyLeadingComments(sourceNode, targetNode, sourceFile, commentKind, hasTrailingNewLine) {
        ts.forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, ts.addSyntheticLeadingComment));
    }
    ts.copyLeadingComments = copyLeadingComments;
    function copyTrailingComments(sourceNode, targetNode, sourceFile, commentKind, hasTrailingNewLine) {
        ts.forEachTrailingCommentRange(sourceFile.text, sourceNode.end, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, ts.addSyntheticTrailingComment));
    }
    ts.copyTrailingComments = copyTrailingComments;
    /**
     * This function copies the trailing comments for the token that comes before `sourceNode`, as leading comments of `targetNode`.
     * This is useful because sometimes a comment that refers to `sourceNode` will be a leading comment for `sourceNode`, according to the
     * notion of trivia ownership, and instead will be a trailing comment for the token before `sourceNode`, e.g.:
     * `function foo(\* not leading comment for a *\ a: string) {}`
     * The comment refers to `a` but belongs to the `(` token, but we might want to copy it.
     */
    function copyTrailingAsLeadingComments(sourceNode, targetNode, sourceFile, commentKind, hasTrailingNewLine) {
        ts.forEachTrailingCommentRange(sourceFile.text, sourceNode.pos, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, ts.addSyntheticLeadingComment));
    }
    ts.copyTrailingAsLeadingComments = copyTrailingAsLeadingComments;
    function getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, cb) {
        return function (pos, end, kind, htnl) {
            if (kind === 3 /* MultiLineCommentTrivia */) {
                // Remove leading /*
                pos += 2;
                // Remove trailing */
                end -= 2;
            }
            else {
                // Remove leading //
                pos += 2;
            }
            cb(targetNode, commentKind || kind, sourceFile.text.slice(pos, end), hasTrailingNewLine !== undefined ? hasTrailingNewLine : htnl);
        };
    }
    function indexInTextChange(change, name) {
        if (ts.startsWith(change, name))
            return 0;
        // Add a " " to avoid references inside words
        var idx = change.indexOf(" " + name);
        if (idx === -1)
            idx = change.indexOf("." + name);
        if (idx === -1)
            idx = change.indexOf('"' + name);
        return idx === -1 ? -1 : idx + 1;
    }
    function getContextualTypeFromParent(node, checker) {
        var parent = node.parent;
        switch (parent.kind) {
            case 193 /* NewExpression */:
                return checker.getContextualType(parent);
            case 205 /* BinaryExpression */: {
                var _a = parent, left = _a.left, operatorToken = _a.operatorToken, right = _a.right;
                return isEqualityOperatorKind(operatorToken.kind)
                    ? checker.getTypeAtLocation(node === right ? left : right)
                    : checker.getContextualType(node);
            }
            case 272 /* CaseClause */:
                return parent.expression === node ? getSwitchedType(parent, checker) : undefined;
            default:
                return checker.getContextualType(node);
        }
    }
    ts.getContextualTypeFromParent = getContextualTypeFromParent;
    function quote(text, preferences) {
        if (/^\d+$/.test(text)) {
            return text;
        }
        // Editors can pass in undefined or empty string - we want to infer the preference in those cases.
        var quotePreference = preferences.quotePreference || "auto";
        var quoted = JSON.stringify(text);
        switch (quotePreference) {
            // TODO use getQuotePreference to infer the actual quote style.
            case "auto":
            case "double":
                return quoted;
            case "single":
                return "'" + stripQuotes(quoted).replace("'", "\\'").replace('\\"', '"') + "'";
            default:
                return ts.Debug.assertNever(quotePreference);
        }
    }
    ts.quote = quote;
    function isEqualityOperatorKind(kind) {
        switch (kind) {
            case 35 /* EqualsEqualsEqualsToken */:
            case 33 /* EqualsEqualsToken */:
            case 36 /* ExclamationEqualsEqualsToken */:
            case 34 /* ExclamationEqualsToken */:
                return true;
            default:
                return false;
        }
    }
    ts.isEqualityOperatorKind = isEqualityOperatorKind;
    function isStringLiteralOrTemplate(node) {
        switch (node.kind) {
            case 10 /* StringLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 207 /* TemplateExpression */:
            case 194 /* TaggedTemplateExpression */:
                return true;
            default:
                return false;
        }
    }
    ts.isStringLiteralOrTemplate = isStringLiteralOrTemplate;
    function hasIndexSignature(type) {
        return !!type.getStringIndexType() || !!type.getNumberIndexType();
    }
    ts.hasIndexSignature = hasIndexSignature;
    function getSwitchedType(caseClause, checker) {
        return checker.getTypeAtLocation(caseClause.parent.parent.expression);
    }
    ts.getSwitchedType = getSwitchedType;
    function getTypeNodeIfAccessible(type, enclosingScope, program, host) {
        var checker = program.getTypeChecker();
        var typeIsAccessible = true;
        var notAccessible = function () { typeIsAccessible = false; };
        var res = checker.typeToTypeNode(type, enclosingScope, /*flags*/ undefined, {
            trackSymbol: function (symbol, declaration, meaning) {
                // TODO: GH#18217
                typeIsAccessible = typeIsAccessible && checker.isSymbolAccessible(symbol, declaration, meaning, /*shouldComputeAliasToMarkVisible*/ false).accessibility === 0 /* Accessible */;
            },
            reportInaccessibleThisError: notAccessible,
            reportPrivateInBaseOfClassExpression: notAccessible,
            reportInaccessibleUniqueSymbolError: notAccessible,
            moduleResolverHost: {
                readFile: host.readFile,
                fileExists: host.fileExists,
                directoryExists: host.directoryExists,
                getSourceFiles: program.getSourceFiles,
                getCurrentDirectory: program.getCurrentDirectory,
                getCommonSourceDirectory: program.getCommonSourceDirectory,
            }
        });
        return typeIsAccessible ? res : undefined;
    }
    ts.getTypeNodeIfAccessible = getTypeNodeIfAccessible;
})(ts || (ts = {}));
var ts;
(function (ts) {
    function createClassifier() {
        var scanner = ts.createScanner(8 /* Latest */, /*skipTrivia*/ false);
        function getClassificationsForLine(text, lexState, syntacticClassifierAbsent) {
            return convertClassificationsToResult(getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent), text);
        }
        // If there is a syntactic classifier ('syntacticClassifierAbsent' is false),
        // we will be more conservative in order to avoid conflicting with the syntactic classifier.
        function getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent) {
            var token = 0 /* Unknown */;
            var lastNonTriviaToken = 0 /* Unknown */;
            // Just a stack of TemplateHeads and OpenCurlyBraces, used to perform rudimentary (inexact)
            // classification on template strings. Because of the context free nature of templates,
            // the only precise way to classify a template portion would be by propagating the stack across
            // lines, just as we do with the end-of-line state. However, this is a burden for implementers,
            // and the behavior is entirely subsumed by the syntactic classifier anyway, so we instead
            // flatten any nesting when the template stack is non-empty and encode it in the end-of-line state.
            // Situations in which this fails are
            //  1) When template strings are nested across different lines:
            //          `hello ${ `world
            //          ` }`
            //
            //     Where on the second line, you will get the closing of a template,
            //     a closing curly, and a new template.
            //
            //  2) When substitution expressions have curly braces and the curly brace falls on the next line:
            //          `hello ${ () => {
            //          return "world" } } `
            //
            //     Where on the second line, you will get the 'return' keyword,
            //     a string literal, and a template end consisting of '} } `'.
            var templateStack = [];
            var _a = getPrefixFromLexState(lexState), prefix = _a.prefix, pushTemplate = _a.pushTemplate;
            text = prefix + text;
            var offset = prefix.length;
            if (pushTemplate) {
                templateStack.push(15 /* TemplateHead */);
            }
            scanner.setText(text);
            var endOfLineState = 0 /* None */;
            var spans = [];
            // We can run into an unfortunate interaction between the lexical and syntactic classifier
            // when the user is typing something generic.  Consider the case where the user types:
            //
            //      Foo<number
            //
            // From the lexical classifier's perspective, 'number' is a keyword, and so the word will
            // be classified as such.  However, from the syntactic classifier's tree-based perspective
            // this is simply an expression with the identifier 'number' on the RHS of the less than
            // token.  So the classification will go back to being an identifier.  The moment the user
            // types again, number will become a keyword, then an identifier, etc. etc.
            //
            // To try to avoid this problem, we avoid classifying contextual keywords as keywords
            // when the user is potentially typing something generic.  We just can't do a good enough
            // job at the lexical level, and so well leave it up to the syntactic classifier to make
            // the determination.
            //
            // In order to determine if the user is potentially typing something generic, we use a
            // weak heuristic where we track < and > tokens.  It's a weak heuristic, but should
            // work well enough in practice.
            var angleBracketStack = 0;
            do {
                token = scanner.scan();
                if (!ts.isTrivia(token)) {
                    handleToken();
                    lastNonTriviaToken = token;
                }
                var end = scanner.getTextPos();
                pushEncodedClassification(scanner.getTokenPos(), end, offset, classFromKind(token), spans);
                if (end >= text.length) {
                    var end_1 = getNewEndOfLineState(scanner, token, ts.lastOrUndefined(templateStack));
                    if (end_1 !== undefined) {
                        endOfLineState = end_1;
                    }
                }
            } while (token !== 1 /* EndOfFileToken */);
            function handleToken() {
                switch (token) {
                    case 42 /* SlashToken */:
                    case 65 /* SlashEqualsToken */:
                        if (!noRegexTable[lastNonTriviaToken] && scanner.reScanSlashToken() === 13 /* RegularExpressionLiteral */) {
                            token = 13 /* RegularExpressionLiteral */;
                        }
                        break;
                    case 28 /* LessThanToken */:
                        if (lastNonTriviaToken === 73 /* Identifier */) {
                            // Could be the start of something generic.  Keep track of that by bumping
                            // up the current count of generic contexts we may be in.
                            angleBracketStack++;
                        }
                        break;
                    case 30 /* GreaterThanToken */:
                        if (angleBracketStack > 0) {
                            // If we think we're currently in something generic, then mark that that
                            // generic entity is complete.
                            angleBracketStack--;
                        }
                        break;
                    case 121 /* AnyKeyword */:
                    case 139 /* StringKeyword */:
                    case 136 /* NumberKeyword */:
                    case 124 /* BooleanKeyword */:
                    case 140 /* SymbolKeyword */:
                        if (angleBracketStack > 0 && !syntacticClassifierAbsent) {
                            // If it looks like we're could be in something generic, don't classify this
                            // as a keyword.  We may just get overwritten by the syntactic classifier,
                            // causing a noisy experience for the user.
                            token = 73 /* Identifier */;
                        }
                        break;
                    case 15 /* TemplateHead */:
                        templateStack.push(token);
                        break;
                    case 18 /* OpenBraceToken */:
                        // If we don't have anything on the template stack,
                        // then we aren't trying to keep track of a previously scanned template head.
                        if (templateStack.length > 0) {
                            templateStack.push(token);
                        }
                        break;
                    case 19 /* CloseBraceToken */:
                        // If we don't have anything on the template stack,
                        // then we aren't trying to keep track of a previously scanned template head.
                        if (templateStack.length > 0) {
                            var lastTemplateStackToken = ts.lastOrUndefined(templateStack);
                            if (lastTemplateStackToken === 15 /* TemplateHead */) {
                                token = scanner.reScanTemplateToken();
                                // Only pop on a TemplateTail; a TemplateMiddle indicates there is more for us.
                                if (token === 17 /* TemplateTail */) {
                                    templateStack.pop();
                                }
                                else {
                                    ts.Debug.assertEqual(token, 16 /* TemplateMiddle */, "Should have been a template middle.");
                                }
                            }
                            else {
                                ts.Debug.assertEqual(lastTemplateStackToken, 18 /* OpenBraceToken */, "Should have been an open brace");
                                templateStack.pop();
                            }
                        }
                        break;
                    default:
                        if (!ts.isKeyword(token)) {
                            break;
                        }
                        if (lastNonTriviaToken === 24 /* DotToken */) {
                            token = 73 /* Identifier */;
                        }
                        else if (ts.isKeyword(lastNonTriviaToken) && ts.isKeyword(token) && !canFollow(lastNonTriviaToken, token)) {
                            // We have two keywords in a row.  Only treat the second as a keyword if
                            // it's a sequence that could legally occur in the language.  Otherwise
                            // treat it as an identifier.  This way, if someone writes "private var"
                            // we recognize that 'var' is actually an identifier here.
                            token = 73 /* Identifier */;
                        }
                }
            }
            return { endOfLineState: endOfLineState, spans: spans };
        }
        return { getClassificationsForLine: getClassificationsForLine, getEncodedLexicalClassifications: getEncodedLexicalClassifications };
    }
    ts.createClassifier = createClassifier;
    /// We do not have a full parser support to know when we should parse a regex or not
    /// If we consider every slash token to be a regex, we could be missing cases like "1/2/3", where
    /// we have a series of divide operator. this list allows us to be more accurate by ruling out
    /// locations where a regexp cannot exist.
    var noRegexTable = ts.arrayToNumericMap([
        73 /* Identifier */,
        10 /* StringLiteral */,
        8 /* NumericLiteral */,
        9 /* BigIntLiteral */,
        13 /* RegularExpressionLiteral */,
        101 /* ThisKeyword */,
        44 /* PlusPlusToken */,
        45 /* MinusMinusToken */,
        21 /* CloseParenToken */,
        23 /* CloseBracketToken */,
        19 /* CloseBraceToken */,
        103 /* TrueKeyword */,
        88 /* FalseKeyword */,
    ], function (token) { return token; }, function () { return true; });
    function getNewEndOfLineState(scanner, token, lastOnTemplateStack) {
        switch (token) {
            case 10 /* StringLiteral */: {
                // Check to see if we finished up on a multiline string literal.
                if (!scanner.isUnterminated())
                    return undefined;
                var tokenText = scanner.getTokenText();
                var lastCharIndex = tokenText.length - 1;
                var numBackslashes = 0;
                while (tokenText.charCodeAt(lastCharIndex - numBackslashes) === 92 /* backslash */) {
                    numBackslashes++;
                }
                // If we have an odd number of backslashes, then the multiline string is unclosed
                if ((numBackslashes & 1) === 0)
                    return undefined;
                return tokenText.charCodeAt(0) === 34 /* doubleQuote */ ? 3 /* InDoubleQuoteStringLiteral */ : 2 /* InSingleQuoteStringLiteral */;
            }
            case 3 /* MultiLineCommentTrivia */:
                // Check to see if the multiline comment was unclosed.
                return scanner.isUnterminated() ? 1 /* InMultiLineCommentTrivia */ : undefined;
            default:
                if (ts.isTemplateLiteralKind(token)) {
                    if (!scanner.isUnterminated()) {
                        return undefined;
                    }
                    switch (token) {
                        case 17 /* TemplateTail */:
                            return 5 /* InTemplateMiddleOrTail */;
                        case 14 /* NoSubstitutionTemplateLiteral */:
                            return 4 /* InTemplateHeadOrNoSubstitutionTemplate */;
                        default:
                            return ts.Debug.fail("Only 'NoSubstitutionTemplateLiteral's and 'TemplateTail's can be unterminated; got SyntaxKind #" + token);
                    }
                }
                return lastOnTemplateStack === 15 /* TemplateHead */ ? 6 /* InTemplateSubstitutionPosition */ : undefined;
        }
    }
    function pushEncodedClassification(start, end, offset, classification, result) {
        if (classification === 8 /* whiteSpace */) {
            // Don't bother with whitespace classifications.  They're not needed.
            return;
        }
        if (start === 0 && offset > 0) {
            // We're classifying the first token, and this was a case where we prepended text.
            // We should consider the start of this token to be at the start of the original text.
            start += offset;
        }
        var length = end - start;
        if (length > 0) {
            // All our tokens are in relation to the augmented text.  Move them back to be
            // relative to the original text.
            result.push(start - offset, length, classification);
        }
    }
    function convertClassificationsToResult(classifications, text) {
        var entries = [];
        var dense = classifications.spans;
        var lastEnd = 0;
        for (var i = 0; i < dense.length; i += 3) {
            var start = dense[i];
            var length_1 = dense[i + 1];
            var type = dense[i + 2];
            // Make a whitespace entry between the last item and this one.
            if (lastEnd >= 0) {
                var whitespaceLength_1 = start - lastEnd;
                if (whitespaceLength_1 > 0) {
                    entries.push({ length: whitespaceLength_1, classification: ts.TokenClass.Whitespace });
                }
            }
            entries.push({ length: length_1, classification: convertClassification(type) });
            lastEnd = start + length_1;
        }
        var whitespaceLength = text.length - lastEnd;
        if (whitespaceLength > 0) {
            entries.push({ length: whitespaceLength, classification: ts.TokenClass.Whitespace });
        }
        return { entries: entries, finalLexState: classifications.endOfLineState };
    }
    function convertClassification(type) {
        switch (type) {
            case 1 /* comment */: return ts.TokenClass.Comment;
            case 3 /* keyword */: return ts.TokenClass.Keyword;
            case 4 /* numericLiteral */: return ts.TokenClass.NumberLiteral;
            case 25 /* bigintLiteral */: return ts.TokenClass.BigIntLiteral;
            case 5 /* operator */: return ts.TokenClass.Operator;
            case 6 /* stringLiteral */: return ts.TokenClass.StringLiteral;
            case 8 /* whiteSpace */: return ts.TokenClass.Whitespace;
            case 10 /* punctuation */: return ts.TokenClass.Punctuation;
            case 2 /* identifier */:
            case 11 /* className */:
            case 12 /* enumName */:
            case 13 /* interfaceName */:
            case 14 /* moduleName */:
            case 15 /* typeParameterName */:
            case 16 /* typeAliasName */:
            case 9 /* text */:
            case 17 /* parameterName */:
                return ts.TokenClass.Identifier;
            default:
                return undefined; // TODO: GH#18217 Debug.assertNever(type);
        }
    }
    /** Returns true if 'keyword2' can legally follow 'keyword1' in any language construct. */
    function canFollow(keyword1, keyword2) {
        if (!ts.isAccessibilityModifier(keyword1)) {
            // Assume any other keyword combination is legal.
            // This can be refined in the future if there are more cases we want the classifier to be better at.
            return true;
        }
        switch (keyword2) {
            case 127 /* GetKeyword */:
            case 138 /* SetKeyword */:
            case 125 /* ConstructorKeyword */:
            case 117 /* StaticKeyword */:
                return true; // Allow things like "public get", "public constructor" and "public static".
            default:
                return false; // Any other keyword following "public" is actually an identifier, not a real keyword.
        }
    }
    function getPrefixFromLexState(lexState) {
        // If we're in a string literal, then prepend: "\
        // (and a newline).  That way when we lex we'll think we're still in a string literal.
        //
        // If we're in a multiline comment, then prepend: /*
        // (and a newline).  That way when we lex we'll think we're still in a multiline comment.
        switch (lexState) {
            case 3 /* InDoubleQuoteStringLiteral */:
                return { prefix: "\"\\\n" };
            case 2 /* InSingleQuoteStringLiteral */:
                return { prefix: "'\\\n" };
            case 1 /* InMultiLineCommentTrivia */:
                return { prefix: "/*\n" };
            case 4 /* InTemplateHeadOrNoSubstitutionTemplate */:
                return { prefix: "`\n" };
            case 5 /* InTemplateMiddleOrTail */:
                return { prefix: "}\n", pushTemplate: true };
            case 6 /* InTemplateSubstitutionPosition */:
                return { prefix: "", pushTemplate: true };
            case 0 /* None */:
                return { prefix: "" };
            default:
                return ts.Debug.assertNever(lexState);
        }
    }
    function isBinaryExpressionOperatorToken(token) {
        switch (token) {
            case 40 /* AsteriskToken */:
            case 42 /* SlashToken */:
            case 43 /* PercentToken */:
            case 38 /* PlusToken */:
            case 39 /* MinusToken */:
            case 46 /* LessThanLessThanToken */:
            case 47 /* GreaterThanGreaterThanToken */:
            case 48 /* GreaterThanGreaterThanGreaterThanToken */:
            case 28 /* LessThanToken */:
            case 30 /* GreaterThanToken */:
            case 31 /* LessThanEqualsToken */:
            case 32 /* GreaterThanEqualsToken */:
            case 95 /* InstanceOfKeyword */:
            case 94 /* InKeyword */:
            case 120 /* AsKeyword */:
            case 33 /* EqualsEqualsToken */:
            case 34 /* ExclamationEqualsToken */:
            case 35 /* EqualsEqualsEqualsToken */:
            case 36 /* ExclamationEqualsEqualsToken */:
            case 49 /* AmpersandToken */:
            case 51 /* CaretToken */:
            case 50 /* BarToken */:
            case 54 /* AmpersandAmpersandToken */:
            case 55 /* BarBarToken */:
            case 71 /* BarEqualsToken */:
            case 70 /* AmpersandEqualsToken */:
            case 72 /* CaretEqualsToken */:
            case 67 /* LessThanLessThanEqualsToken */:
            case 68 /* GreaterThanGreaterThanEqualsToken */:
            case 69 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
            case 61 /* PlusEqualsToken */:
            case 62 /* MinusEqualsToken */:
            case 63 /* AsteriskEqualsToken */:
            case 65 /* SlashEqualsToken */:
            case 66 /* PercentEqualsToken */:
            case 60 /* EqualsToken */:
            case 27 /* CommaToken */:
                return true;
            default:
                return false;
        }
    }
    function isPrefixUnaryExpressionOperatorToken(token) {
        switch (token) {
            case 38 /* PlusToken */:
            case 39 /* MinusToken */:
            case 53 /* TildeToken */:
            case 52 /* ExclamationToken */:
            case 44 /* PlusPlusToken */:
            case 45 /* MinusMinusToken */:
                return true;
            default:
                return false;
        }
    }
    function classFromKind(token) {
        if (ts.isKeyword(token)) {
            return 3 /* keyword */;
        }
        else if (isBinaryExpressionOperatorToken(token) || isPrefixUnaryExpressionOperatorToken(token)) {
            return 5 /* operator */;
        }
        else if (token >= 18 /* FirstPunctuation */ && token <= 72 /* LastPunctuation */) {
            return 10 /* punctuation */;
        }
        switch (token) {
            case 8 /* NumericLiteral */:
                return 4 /* numericLiteral */;
            case 9 /* BigIntLiteral */:
                return 25 /* bigintLiteral */;
            case 10 /* StringLiteral */:
                return 6 /* stringLiteral */;
            case 13 /* RegularExpressionLiteral */:
                return 7 /* regularExpressionLiteral */;
            case 7 /* ConflictMarkerTrivia */:
            case 3 /* MultiLineCommentTrivia */:
            case 2 /* SingleLineCommentTrivia */:
                return 1 /* comment */;
            case 5 /* WhitespaceTrivia */:
            case 4 /* NewLineTrivia */:
                return 8 /* whiteSpace */;
            case 73 /* Identifier */:
            default:
                if (ts.isTemplateLiteralKind(token)) {
                    return 6 /* stringLiteral */;
                }
                return 2 /* identifier */;
        }
    }
    /* @internal */
    function getSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span) {
        return convertClassificationsToSpans(getEncodedSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span));
    }
    ts.getSemanticClassifications = getSemanticClassifications;
    function checkForClassificationCancellation(cancellationToken, kind) {
        // We don't want to actually call back into our host on every node to find out if we've
        // been canceled.  That would be an enormous amount of chattyness, along with the all
        // the overhead of marshalling the data to/from the host.  So instead we pick a few
        // reasonable node kinds to bother checking on.  These node kinds represent high level
        // constructs that we would expect to see commonly, but just at a far less frequent
        // interval.
        //
        // For example, in checker.ts (around 750k) we only have around 600 of these constructs.
        // That means we're calling back into the host around every 1.2k of the file we process.
        // Lib.d.ts has similar numbers.
        switch (kind) {
            case 245 /* ModuleDeclaration */:
            case 241 /* ClassDeclaration */:
            case 242 /* InterfaceDeclaration */:
            case 240 /* FunctionDeclaration */:
                cancellationToken.throwIfCancellationRequested();
        }
    }
    /* @internal */
    function getEncodedSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span) {
        var spans = [];
        sourceFile.forEachChild(function cb(node) {
            // Only walk into nodes that intersect the requested span.
            if (!node || !ts.textSpanIntersectsWith(span, node.pos, node.getFullWidth())) {
                return;
            }
            checkForClassificationCancellation(cancellationToken, node.kind);
            // Only bother calling into the typechecker if this is an identifier that
            // could possibly resolve to a type name.  This makes classification run
            // in a third of the time it would normally take.
            if (ts.isIdentifier(node) && !ts.nodeIsMissing(node) && classifiableNames.has(node.escapedText)) {
                var symbol = typeChecker.getSymbolAtLocation(node);
                var type = symbol && classifySymbol(symbol, ts.getMeaningFromLocation(node), typeChecker);
                if (type) {
                    pushClassification(node.getStart(sourceFile), node.getEnd(), type);
                }
            }
            node.forEachChild(cb);
        });
        return { spans: spans, endOfLineState: 0 /* None */ };
        function pushClassification(start, end, type) {
            spans.push(start);
            spans.push(end - start);
            spans.push(type);
        }
    }
    ts.getEncodedSemanticClassifications = getEncodedSemanticClassifications;
    function classifySymbol(symbol, meaningAtPosition, checker) {
        var flags = symbol.getFlags();
        if ((flags & 2885600 /* Classifiable */) === 0 /* None */) {
            return undefined;
        }
        else if (flags & 32 /* Class */) {
            return 11 /* className */;
        }
        else if (flags & 384 /* Enum */) {
            return 12 /* enumName */;
        }
        else if (flags & 524288 /* TypeAlias */) {
            return 16 /* typeAliasName */;
        }
        else if (flags & 1536 /* Module */) {
            // Only classify a module as such if
            //  - It appears in a namespace context.
            //  - There exists a module declaration which actually impacts the value side.
            return meaningAtPosition & 4 /* Namespace */ || meaningAtPosition & 1 /* Value */ && hasValueSideModule(symbol) ? 14 /* moduleName */ : undefined;
        }
        else if (flags & 2097152 /* Alias */) {
            return classifySymbol(checker.getAliasedSymbol(symbol), meaningAtPosition, checker);
        }
        else if (meaningAtPosition & 2 /* Type */) {
            return flags & 64 /* Interface */ ? 13 /* interfaceName */ : flags & 262144 /* TypeParameter */ ? 15 /* typeParameterName */ : undefined;
        }
        else {
            return undefined;
        }
    }
    /** Returns true if there exists a module that introduces entities on the value side. */
    function hasValueSideModule(symbol) {
        return ts.some(symbol.declarations, function (declaration) {
            return ts.isModuleDeclaration(declaration) && ts.getModuleInstanceState(declaration) === 1 /* Instantiated */;
        });
    }
    function getClassificationTypeName(type) {
        switch (type) {
            case 1 /* comment */: return "comment" /* comment */;
            case 2 /* identifier */: return "identifier" /* identifier */;
            case 3 /* keyword */: return "keyword" /* keyword */;
            case 4 /* numericLiteral */: return "number" /* numericLiteral */;
            case 25 /* bigintLiteral */: return "bigint" /* bigintLiteral */;
            case 5 /* operator */: return "operator" /* operator */;
            case 6 /* stringLiteral */: return "string" /* stringLiteral */;
            case 8 /* whiteSpace */: return "whitespace" /* whiteSpace */;
            case 9 /* text */: return "text" /* text */;
            case 10 /* punctuation */: return "punctuation" /* punctuation */;
            case 11 /* className */: return "class name" /* className */;
            case 12 /* enumName */: return "enum name" /* enumName */;
            case 13 /* interfaceName */: return "interface name" /* interfaceName */;
            case 14 /* moduleName */: return "module name" /* moduleName */;
            case 15 /* typeParameterName */: return "type parameter name" /* typeParameterName */;
            case 16 /* typeAliasName */: return "type alias name" /* typeAliasName */;
            case 17 /* parameterName */: return "parameter name" /* parameterName */;
            case 18 /* docCommentTagName */: return "doc comment tag name" /* docCommentTagName */;
            case 19 /* jsxOpenTagName */: return "jsx open tag name" /* jsxOpenTagName */;
            case 20 /* jsxCloseTagName */: return "jsx close tag name" /* jsxCloseTagName */;
            case 21 /* jsxSelfClosingTagName */: return "jsx self closing tag name" /* jsxSelfClosingTagName */;
            case 22 /* jsxAttribute */: return "jsx attribute" /* jsxAttribute */;
            case 23 /* jsxText */: return "jsx text" /* jsxText */;
            case 24 /* jsxAttributeStringLiteralValue */: return "jsx attribute string literal value" /* jsxAttributeStringLiteralValue */;
            default: return undefined; // TODO: GH#18217 throw Debug.assertNever(type);
        }
    }
    function convertClassificationsToSpans(classifications) {
        ts.Debug.assert(classifications.spans.length % 3 === 0);
        var dense = classifications.spans;
        var result = [];
        for (var i = 0; i < dense.length; i += 3) {
            result.push({
                textSpan: ts.createTextSpan(dense[i], dense[i + 1]),
                classificationType: getClassificationTypeName(dense[i + 2])
            });
        }
        return result;
    }
    /* @internal */
    function getSyntacticClassifications(cancellationToken, sourceFile, span) {
        return convertClassificationsToSpans(getEncodedSyntacticClassifications(cancellationToken, sourceFile, span));
    }
    ts.getSyntacticClassifications = getSyntacticClassifications;
    /* @internal */
    function getEncodedSyntacticClassifications(cancellationToken, sourceFile, span) {
        var spanStart = span.start;
        var spanLength = span.length;
        // Make a scanner we can get trivia from.
        var triviaScanner = ts.createScanner(8 /* Latest */, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text);
        var mergeConflictScanner = ts.createScanner(8 /* Latest */, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text);
        var result = [];
        processElement(sourceFile);
        return { spans: result, endOfLineState: 0 /* None */ };
        function pushClassification(start, length, type) {
            result.push(start);
            result.push(length);
            result.push(type);
        }
        function classifyLeadingTriviaAndGetTokenStart(token) {
            triviaScanner.setTextPos(token.pos);
            while (true) {
                var start = triviaScanner.getTextPos();
                // only bother scanning if we have something that could be trivia.
                if (!ts.couldStartTrivia(sourceFile.text, start)) {
                    return start;
                }
                var kind = triviaScanner.scan();
                var end = triviaScanner.getTextPos();
                var width = end - start;
                // The moment we get something that isn't trivia, then stop processing.
                if (!ts.isTrivia(kind)) {
                    return start;
                }
                switch (kind) {
                    case 4 /* NewLineTrivia */:
                    case 5 /* WhitespaceTrivia */:
                        // Don't bother with newlines/whitespace.
                        continue;
                    case 2 /* SingleLineCommentTrivia */:
                    case 3 /* MultiLineCommentTrivia */:
                        // Only bother with the trivia if it at least intersects the span of interest.
                        classifyComment(token, kind, start, width);
                        // Classifying a comment might cause us to reuse the trivia scanner
                        // (because of jsdoc comments).  So after we classify the comment make
                        // sure we set the scanner position back to where it needs to be.
                        triviaScanner.setTextPos(end);
                        continue;
                    case 7 /* ConflictMarkerTrivia */:
                        var text = sourceFile.text;
                        var ch = text.charCodeAt(start);
                        // for the <<<<<<< and >>>>>>> markers, we just add them in as comments
                        // in the classification stream.
                        if (ch === 60 /* lessThan */ || ch === 62 /* greaterThan */) {
                            pushClassification(start, width, 1 /* comment */);
                            continue;
                        }
                        // for the ||||||| and ======== markers, add a comment for the first line,
                        // and then lex all subsequent lines up until the end of the conflict marker.
                        ts.Debug.assert(ch === 124 /* bar */ || ch === 61 /* equals */);
                        classifyDisabledMergeCode(text, start, end);
                        break;
                    case 6 /* ShebangTrivia */:
                        // TODO: Maybe we should classify these.
                        break;
                    default:
                        ts.Debug.assertNever(kind);
                }
            }
        }
        function classifyComment(token, kind, start, width) {
            if (kind === 3 /* MultiLineCommentTrivia */) {
                // See if this is a doc comment.  If so, we'll classify certain portions of it
                // specially.
                var docCommentAndDiagnostics = ts.parseIsolatedJSDocComment(sourceFile.text, start, width);
                if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDoc) {
                    // TODO: This should be predicated on `token["kind"]` being compatible with `HasJSDoc["kind"]`
                    docCommentAndDiagnostics.jsDoc.parent = token;
                    classifyJSDocComment(docCommentAndDiagnostics.jsDoc);
                    return;
                }
            }
            // Simple comment.  Just add as is.
            pushCommentRange(start, width);
        }
        function pushCommentRange(start, width) {
            pushClassification(start, width, 1 /* comment */);
        }
        function classifyJSDocComment(docComment) {
            var pos = docComment.pos;
            if (docComment.tags) {
                for (var _i = 0, _a = docComment.tags; _i < _a.length; _i++) {
                    var tag = _a[_i];
                    // As we walk through each tag, classify the portion of text from the end of
                    // the last tag (or the start of the entire doc comment) as 'comment'.
                    if (tag.pos !== pos) {
                        pushCommentRange(pos, tag.pos - pos);
                    }
                    pushClassification(tag.pos, 1, 10 /* punctuation */); // "@"
                    pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, 18 /* docCommentTagName */); // e.g. "param"
                    pos = tag.tagName.end;
                    switch (tag.kind) {
                        case 305 /* JSDocParameterTag */:
                            processJSDocParameterTag(tag);
                            break;
                        case 309 /* JSDocTemplateTag */:
                            processJSDocTemplateTag(tag);
                            pos = tag.end;
                            break;
                        case 308 /* JSDocTypeTag */:
                            processElement(tag.typeExpression);
                            pos = tag.end;
                            break;
                        case 306 /* JSDocReturnTag */:
                            processElement(tag.typeExpression);
                            pos = tag.end;
                            break;
                    }
                }
            }
            if (pos !== docComment.end) {
                pushCommentRange(pos, docComment.end - pos);
            }
            return;
            function processJSDocParameterTag(tag) {
                if (tag.isNameFirst) {
                    pushCommentRange(pos, tag.name.pos - pos);
                    pushClassification(tag.name.pos, tag.name.end - tag.name.pos, 17 /* parameterName */);
                    pos = tag.name.end;
                }
                if (tag.typeExpression) {
                    pushCommentRange(pos, tag.typeExpression.pos - pos);
                    processElement(tag.typeExpression);
                    pos = tag.typeExpression.end;
                }
                if (!tag.isNameFirst) {
                    pushCommentRange(pos, tag.name.pos - pos);
                    pushClassification(tag.name.pos, tag.name.end - tag.name.pos, 17 /* parameterName */);
                    pos = tag.name.end;
                }
            }
        }
        function processJSDocTemplateTag(tag) {
            for (var _i = 0, _a = tag.getChildren(); _i < _a.length; _i++) {
                var child = _a[_i];
                processElement(child);
            }
        }
        function classifyDisabledMergeCode(text, start, end) {
            // Classify the line that the ||||||| or ======= marker is on as a comment.
            // Then just lex all further tokens and add them to the result.
            var i;
            for (i = start; i < end; i++) {
                if (ts.isLineBreak(text.charCodeAt(i))) {
                    break;
                }
            }
            pushClassification(start, i - start, 1 /* comment */);
            mergeConflictScanner.setTextPos(i);
            while (mergeConflictScanner.getTextPos() < end) {
                classifyDisabledCodeToken();
            }
        }
        function classifyDisabledCodeToken() {
            var start = mergeConflictScanner.getTextPos();
            var tokenKind = mergeConflictScanner.scan();
            var end = mergeConflictScanner.getTextPos();
            var type = classifyTokenType(tokenKind);
            if (type) {
                pushClassification(start, end - start, type);
            }
        }
        /**
         * Returns true if node should be treated as classified and no further processing is required.
         * False will mean that node is not classified and traverse routine should recurse into node contents.
         */
        function tryClassifyNode(node) {
            if (ts.isJSDoc(node)) {
                return true;
            }
            if (ts.nodeIsMissing(node)) {
                return true;
            }
            var classifiedElementName = tryClassifyJsxElementName(node);
            if (!ts.isToken(node) && node.kind !== 11 /* JsxText */ && classifiedElementName === undefined) {
                return false;
            }
            var tokenStart = node.kind === 11 /* JsxText */ ? node.pos : classifyLeadingTriviaAndGetTokenStart(node);
            var tokenWidth = node.end - tokenStart;
            ts.Debug.assert(tokenWidth >= 0);
            if (tokenWidth > 0) {
                var type = classifiedElementName || classifyTokenType(node.kind, node);
                if (type) {
                    pushClassification(tokenStart, tokenWidth, type);
                }
            }
            return true;
        }
        function tryClassifyJsxElementName(token) {
            switch (token.parent && token.parent.kind) {
                case 263 /* JsxOpeningElement */:
                    if (token.parent.tagName === token) {
                        return 19 /* jsxOpenTagName */;
                    }
                    break;
                case 264 /* JsxClosingElement */:
                    if (token.parent.tagName === token) {
                        return 20 /* jsxCloseTagName */;
                    }
                    break;
                case 262 /* JsxSelfClosingElement */:
                    if (token.parent.tagName === token) {
                        return 21 /* jsxSelfClosingTagName */;
                    }
                    break;
                case 268 /* JsxAttribute */:
                    if (token.parent.name === token) {
                        return 22 /* jsxAttribute */;
                    }
                    break;
            }
            return undefined;
        }
        // for accurate classification, the actual token should be passed in.  however, for
        // cases like 'disabled merge code' classification, we just get the token kind and
        // classify based on that instead.
        function classifyTokenType(tokenKind, token) {
            if (ts.isKeyword(tokenKind)) {
                return 3 /* keyword */;
            }
            // Special case `<` and `>`: If they appear in a generic context they are punctuation,
            // not operators.
            if (tokenKind === 28 /* LessThanToken */ || tokenKind === 30 /* GreaterThanToken */) {
                // If the node owning the token has a type argument list or type parameter list, then
                // we can effectively assume that a '<' and '>' belong to those lists.
                if (token && ts.getTypeArgumentOrTypeParameterList(token.parent)) {
                    return 10 /* punctuation */;
                }
            }
            if (ts.isPunctuation(tokenKind)) {
                if (token) {
                    var parent = token.parent;
                    if (tokenKind === 60 /* EqualsToken */) {
                        // the '=' in a variable declaration is special cased here.
                        if (parent.kind === 238 /* VariableDeclaration */ ||
                            parent.kind === 155 /* PropertyDeclaration */ ||
                            parent.kind === 152 /* Parameter */ ||
                            parent.kind === 268 /* JsxAttribute */) {
                            return 5 /* operator */;
                        }
                    }
                    if (parent.kind === 205 /* BinaryExpression */ ||
                        parent.kind === 203 /* PrefixUnaryExpression */ ||
                        parent.kind === 204 /* PostfixUnaryExpression */ ||
                        parent.kind === 206 /* ConditionalExpression */) {
                        return 5 /* operator */;
                    }
                }
                return 10 /* punctuation */;
            }
            else if (tokenKind === 8 /* NumericLiteral */) {
                return 4 /* numericLiteral */;
            }
            else if (tokenKind === 9 /* BigIntLiteral */) {
                return 25 /* bigintLiteral */;
            }
            else if (tokenKind === 10 /* StringLiteral */) {
                // TODO: GH#18217
                return token.parent.kind === 268 /* JsxAttribute */ ? 24 /* jsxAttributeStringLiteralValue */ : 6 /* stringLiteral */;
            }
            else if (tokenKind === 13 /* RegularExpressionLiteral */) {
                // TODO: we should get another classification type for these literals.
                return 6 /* stringLiteral */;
            }
            else if (ts.isTemplateLiteralKind(tokenKind)) {
                // TODO (drosen): we should *also* get another classification type for these literals.
                return 6 /* stringLiteral */;
            }
            else if (tokenKind === 11 /* JsxText */) {
                return 23 /* jsxText */;
            }
            else if (tokenKind === 73 /* Identifier */) {
                if (token) {
                    switch (token.parent.kind) {
                        case 241 /* ClassDeclaration */:
                            if (token.parent.name === token) {
                                return 11 /* className */;
                            }
                            return;
                        case 151 /* TypeParameter */:
                            if (token.parent.name === token) {
                                return 15 /* typeParameterName */;
                            }
                            return;
                        case 242 /* InterfaceDeclaration */:
                            if (token.parent.name === token) {
                                return 13 /* interfaceName */;
                            }
                            return;
                        case 244 /* EnumDeclaration */:
                            if (token.parent.name === token) {
                                return 12 /* enumName */;
                            }
                            return;
                        case 245 /* ModuleDeclaration */:
                            if (token.parent.name === token) {
                                return 14 /* moduleName */;
                            }
                            return;
                        case 152 /* Parameter */:
                            if (token.parent.name === token) {
                                return ts.isThisIdentifier(token) ? 3 /* keyword */ : 17 /* parameterName */;
                            }
                            return;
                    }
                }
                return 2 /* identifier */;
            }
        }
        function processElement(element) {
            if (!element) {
                return;
            }
            // Ignore nodes that don't intersect the original span to classify.
            if (ts.decodedTextSpanIntersectsWith(spanStart, spanLength, element.pos, element.getFullWidth())) {
                checkForClassificationCancellation(cancellationToken, element.kind);
                for (var _i = 0, _a = element.getChildren(sourceFile); _i < _a.length; _i++) {
                    var child = _a[_i];
                    if (!tryClassifyNode(child)) {
                        // Recurse into our child nodes.
                        processElement(child);
                    }
                }
            }
        }
    }
    ts.getEncodedSyntacticClassifications = getEncodedSyntacticClassifications;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var Completions;
    (function (Completions) {
        var StringCompletions;
        (function (StringCompletions) {
            function getStringLiteralCompletions(sourceFile, position, contextToken, checker, options, host, log, preferences) {
                if (ts.isInReferenceComment(sourceFile, position)) {
                    var entries = getTripleSlashReferenceCompletion(sourceFile, position, options, host);
                    return entries && convertPathCompletions(entries);
                }
                if (ts.isInString(sourceFile, position, contextToken)) {
                    return !contextToken || !ts.isStringLiteralLike(contextToken)
                        ? undefined
                        : convertStringLiteralCompletions(getStringLiteralCompletionEntries(sourceFile, contextToken, position, checker, options, host), sourceFile, checker, log, preferences);
                }
            }
            StringCompletions.getStringLiteralCompletions = getStringLiteralCompletions;
            function convertStringLiteralCompletions(completion, sourceFile, checker, log, preferences) {
                if (completion === undefined) {
                    return undefined;
                }
                switch (completion.kind) {
                    case 0 /* Paths */:
                        return convertPathCompletions(completion.paths);
                    case 1 /* Properties */: {
                        var entries = [];
                        Completions.getCompletionEntriesFromSymbols(completion.symbols, entries, sourceFile, sourceFile, checker, 8 /* ESNext */, log, 4 /* String */, preferences); // Target will not be used, so arbitrary
                        return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: completion.hasIndexSignature, entries: entries };
                    }
                    case 2 /* Types */: {
                        var entries = completion.types.map(function (type) { return ({ name: type.value, kindModifiers: "" /* none */, kind: "string" /* string */, sortText: "0" }); });
                        return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: completion.isNewIdentifier, entries: entries };
                    }
                    default:
                        return ts.Debug.assertNever(completion);
                }
            }
            function getStringLiteralCompletionDetails(name, sourceFile, position, contextToken, checker, options, host, cancellationToken) {
                if (!contextToken || !ts.isStringLiteralLike(contextToken))
                    return undefined;
                var completions = getStringLiteralCompletionEntries(sourceFile, contextToken, position, checker, options, host);
                return completions && stringLiteralCompletionDetails(name, contextToken, completions, sourceFile, checker, cancellationToken);
            }
            StringCompletions.getStringLiteralCompletionDetails = getStringLiteralCompletionDetails;
            function stringLiteralCompletionDetails(name, location, completion, sourceFile, checker, cancellationToken) {
                switch (completion.kind) {
                    case 0 /* Paths */: {
                        var match = ts.find(completion.paths, function (p) { return p.name === name; });
                        return match && Completions.createCompletionDetails(name, kindModifiersFromExtension(match.extension), match.kind, [ts.textPart(name)]);
                    }
                    case 1 /* Properties */: {
                        var match = ts.find(completion.symbols, function (s) { return s.name === name; });
                        return match && Completions.createCompletionDetailsForSymbol(match, checker, sourceFile, location, cancellationToken);
                    }
                    case 2 /* Types */:
                        return ts.find(completion.types, function (t) { return t.value === name; }) ? Completions.createCompletionDetails(name, "" /* none */, "type" /* typeElement */, [ts.textPart(name)]) : undefined;
                    default:
                        return ts.Debug.assertNever(completion);
                }
            }
            function convertPathCompletions(pathCompletions) {
                var isGlobalCompletion = false; // We don't want the editor to offer any other completions, such as snippets, inside a comment.
                var isNewIdentifierLocation = true; // The user may type in a path that doesn't yet exist, creating a "new identifier" with respect to the collection of identifiers the server is aware of.
                var entries = pathCompletions.map(function (_a) {
                    var name = _a.name, kind = _a.kind, span = _a.span, extension = _a.extension;
                    return ({ name: name, kind: kind, kindModifiers: kindModifiersFromExtension(extension), sortText: Completions.SortText.LocationPriority, replacementSpan: span });
                });
                return { isGlobalCompletion: isGlobalCompletion, isMemberCompletion: false, isNewIdentifierLocation: isNewIdentifierLocation, entries: entries };
            }
            function kindModifiersFromExtension(extension) {
                switch (extension) {
                    case ".d.ts" /* Dts */: return ".d.ts" /* dtsModifier */;
                    case ".js" /* Js */: return ".js" /* jsModifier */;
                    case ".json" /* Json */: return ".json" /* jsonModifier */;
                    case ".jsx" /* Jsx */: return ".jsx" /* jsxModifier */;
                    case ".ts" /* Ts */: return ".ts" /* tsModifier */;
                    case ".tsx" /* Tsx */: return ".tsx" /* tsxModifier */;
                    case ".tsbuildinfo" /* TsBuildInfo */: return ts.Debug.fail("Extension " + ".tsbuildinfo" /* TsBuildInfo */ + " is unsupported.");
                    case undefined: return "" /* none */;
                    default:
                        return ts.Debug.assertNever(extension);
                }
            }
            var StringLiteralCompletionKind;
            (function (StringLiteralCompletionKind) {
                StringLiteralCompletionKind[StringLiteralCompletionKind["Paths"] = 0] = "Paths";
                StringLiteralCompletionKind[StringLiteralCompletionKind["Properties"] = 1] = "Properties";
                StringLiteralCompletionKind[StringLiteralCompletionKind["Types"] = 2] = "Types";
            })(StringLiteralCompletionKind || (StringLiteralCompletionKind = {}));
            function getStringLiteralCompletionEntries(sourceFile, node, position, typeChecker, compilerOptions, host) {
                var parent = node.parent;
                switch (parent.kind) {
                    case 183 /* LiteralType */:
                        switch (parent.parent.kind) {
                            case 165 /* TypeReference */:
                                return { kind: 2 /* Types */, types: getStringLiteralTypes(typeChecker.getTypeArgumentConstraint(parent)), isNewIdentifier: false };
                            case 181 /* IndexedAccessType */:
                                // Get all apparent property names
                                // i.e. interface Foo {
                                //          foo: string;
                                //          bar: string;
                                //      }
                                //      let x: Foo["/*completion position*/"]
                                return stringLiteralCompletionsFromProperties(typeChecker.getTypeFromTypeNode(parent.parent.objectType));
                            case 184 /* ImportType */:
                                return { kind: 0 /* Paths */, paths: getStringLiteralCompletionsFromModuleNames(sourceFile, node, compilerOptions, host, typeChecker) };
                            case 174 /* UnionType */: {
                                if (!ts.isTypeReferenceNode(parent.parent.parent))
                                    return undefined;
                                var alreadyUsedTypes_1 = getAlreadyUsedTypesInStringLiteralUnion(parent.parent, parent);
                                var types = getStringLiteralTypes(typeChecker.getTypeArgumentConstraint(parent.parent)).filter(function (t) { return !ts.contains(alreadyUsedTypes_1, t.value); });
                                return { kind: 2 /* Types */, types: types, isNewIdentifier: false };
                            }
                            default:
                                return undefined;
                        }
                    case 276 /* PropertyAssignment */:
                        if (ts.isObjectLiteralExpression(parent.parent) && parent.name === node) {
                            // Get quoted name of properties of the object literal expression
                            // i.e. interface ConfigFiles {
                            //          'jspm:dev': string
                            //      }
                            //      let files: ConfigFiles = {
                            //          '/*completion position*/'
                            //      }
                            //
                            //      function foo(c: ConfigFiles) {}
                            //      foo({
                            //          '/*completion position*/'
                            //      });
                            return stringLiteralCompletionsFromProperties(typeChecker.getContextualType(parent.parent));
                        }
                        return fromContextualType();
                    case 191 /* ElementAccessExpression */: {
                        var _a = parent, expression = _a.expression, argumentExpression = _a.argumentExpression;
                        if (node === argumentExpression) {
                            // Get all names of properties on the expression
                            // i.e. interface A {
                            //      'prop1': string
                            // }
                            // let a: A;
                            // a['/*completion position*/']
                            return stringLiteralCompletionsFromProperties(typeChecker.getTypeAtLocation(expression));
                        }
                        return undefined;
                    }
                    case 192 /* CallExpression */:
                    case 193 /* NewExpression */:
                        if (!ts.isRequireCall(parent, /*checkArgumentIsStringLiteralLike*/ false) && !ts.isImportCall(parent)) {
                            var argumentInfo = ts.SignatureHelp.getArgumentInfoForCompletions(node, position, sourceFile);
                            // Get string literal completions from specialized signatures of the target
                            // i.e. declare function f(a: 'A');
                            // f("/*completion position*/")
                            return argumentInfo ? getStringLiteralCompletionsFromSignature(argumentInfo, typeChecker) : fromContextualType();
                        }
                    // falls through (is `require("")` or `import("")`)
                    case 250 /* ImportDeclaration */:
                    case 256 /* ExportDeclaration */:
                    case 260 /* ExternalModuleReference */:
                        // Get all known external module names or complete a path to a module
                        // i.e. import * as ns from "/*completion position*/";
                        //      var y = import("/*completion position*/");
                        //      import x = require("/*completion position*/");
                        //      var y = require("/*completion position*/");
                        //      export * from "/*completion position*/";
                        return { kind: 0 /* Paths */, paths: getStringLiteralCompletionsFromModuleNames(sourceFile, node, compilerOptions, host, typeChecker) };
                    default:
                        return fromContextualType();
                }
                function fromContextualType() {
                    // Get completion for string literal from string literal type
                    // i.e. var x: "hi" | "hello" = "/*completion position*/"
                    return { kind: 2 /* Types */, types: getStringLiteralTypes(ts.getContextualTypeFromParent(node, typeChecker)), isNewIdentifier: false };
                }
            }
            function getAlreadyUsedTypesInStringLiteralUnion(union, current) {
                return ts.mapDefined(union.types, function (type) {
                    return type !== current && ts.isLiteralTypeNode(type) && ts.isStringLiteral(type.literal) ? type.literal.text : undefined;
                });
            }
            function getStringLiteralCompletionsFromSignature(argumentInfo, checker) {
                var isNewIdentifier = false;
                var uniques = ts.createMap();
                var candidates = [];
                checker.getResolvedSignature(argumentInfo.invocation, candidates, argumentInfo.argumentCount);
                var types = ts.flatMap(candidates, function (candidate) {
                    if (!candidate.hasRestParameter && argumentInfo.argumentCount > candidate.parameters.length)
                        return;
                    var type = checker.getParameterType(candidate, argumentInfo.argumentIndex);
                    isNewIdentifier = isNewIdentifier || !!(type.flags & 4 /* String */);
                    return getStringLiteralTypes(type, uniques);
                });
                return { kind: 2 /* Types */, types: types, isNewIdentifier: isNewIdentifier };
            }
            function stringLiteralCompletionsFromProperties(type) {
                return type && { kind: 1 /* Properties */, symbols: type.getApparentProperties(), hasIndexSignature: ts.hasIndexSignature(type) };
            }
            function getStringLiteralTypes(type, uniques) {
                if (uniques === void 0) { uniques = ts.createMap(); }
                if (!type)
                    return ts.emptyArray;
                type = ts.skipConstraint(type);
                return type.isUnion()
                    ? ts.flatMap(type.types, function (t) { return getStringLiteralTypes(t, uniques); })
                    : type.isStringLiteral() && !(type.flags & 1024 /* EnumLiteral */) && ts.addToSeen(uniques, type.value)
                        ? [type]
                        : ts.emptyArray;
            }
            function nameAndKind(name, kind, extension) {
                return { name: name, kind: kind, extension: extension };
            }
            function directoryResult(name) {
                return nameAndKind(name, "directory" /* directory */, /*extension*/ undefined);
            }
            function addReplacementSpans(text, textStart, names) {
                var span = getDirectoryFragmentTextSpan(text, textStart);
                return names.map(function (_a) {
                    var name = _a.name, kind = _a.kind, extension = _a.extension;
                    return ({ name: name, kind: kind, extension: extension, span: span });
                });
            }
            function getStringLiteralCompletionsFromModuleNames(sourceFile, node, compilerOptions, host, typeChecker) {
                return addReplacementSpans(node.text, node.getStart(sourceFile) + 1, getStringLiteralCompletionsFromModuleNamesWorker(sourceFile, node, compilerOptions, host, typeChecker));
            }
            function getStringLiteralCompletionsFromModuleNamesWorker(sourceFile, node, compilerOptions, host, typeChecker) {
                var literalValue = ts.normalizeSlashes(node.text);
                var scriptPath = sourceFile.path;
                var scriptDirectory = ts.getDirectoryPath(scriptPath);
                return isPathRelativeToScript(literalValue) || !compilerOptions.baseUrl && (ts.isRootedDiskPath(literalValue) || ts.isUrl(literalValue))
                    ? getCompletionEntriesForRelativeModules(literalValue, scriptDirectory, compilerOptions, host, scriptPath)
                    : getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, compilerOptions, host, typeChecker);
            }
            function getExtensionOptions(compilerOptions, includeExtensions) {
                if (includeExtensions === void 0) { includeExtensions = false; }
                return { extensions: getSupportedExtensionsForModuleResolution(compilerOptions), includeExtensions: includeExtensions };
            }
            function getCompletionEntriesForRelativeModules(literalValue, scriptDirectory, compilerOptions, host, scriptPath) {
                var extensionOptions = getExtensionOptions(compilerOptions);
                if (compilerOptions.rootDirs) {
                    return getCompletionEntriesForDirectoryFragmentWithRootDirs(compilerOptions.rootDirs, literalValue, scriptDirectory, extensionOptions, compilerOptions, host, scriptPath);
                }
                else {
                    return getCompletionEntriesForDirectoryFragment(literalValue, scriptDirectory, extensionOptions, host, scriptPath);
                }
            }
            function getSupportedExtensionsForModuleResolution(compilerOptions) {
                var extensions = ts.getSupportedExtensions(compilerOptions);
                return compilerOptions.resolveJsonModule && ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeJs ?
                    extensions.concat(".json" /* Json */) :
                    extensions;
            }
            /**
             * Takes a script path and returns paths for all potential folders that could be merged with its
             * containing folder via the "rootDirs" compiler option
             */
            function getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptDirectory, ignoreCase) {
                // Make all paths absolute/normalized if they are not already
                rootDirs = rootDirs.map(function (rootDirectory) { return ts.normalizePath(ts.isRootedDiskPath(rootDirectory) ? rootDirectory : ts.combinePaths(basePath, rootDirectory)); });
                // Determine the path to the directory containing the script relative to the root directory it is contained within
                var relativeDirectory = ts.firstDefined(rootDirs, function (rootDirectory) {
                    return ts.containsPath(rootDirectory, scriptDirectory, basePath, ignoreCase) ? scriptDirectory.substr(rootDirectory.length) : undefined;
                }); // TODO: GH#18217
                // Now find a path for each potential directory that is to be merged with the one containing the script
                return ts.deduplicate(rootDirs.map(function (rootDirectory) { return ts.combinePaths(rootDirectory, relativeDirectory); }).concat([scriptDirectory]), ts.equateStringsCaseSensitive, ts.compareStringsCaseSensitive);
            }
            function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs, fragment, scriptDirectory, extensionOptions, compilerOptions, host, exclude) {
                var basePath = compilerOptions.project || host.getCurrentDirectory();
                var ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
                var baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptDirectory, ignoreCase);
                return ts.flatMap(baseDirectories, function (baseDirectory) { return getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensionOptions, host, exclude); });
            }
            /**
             * Given a path ending at a directory, gets the completions for the path, and filters for those entries containing the basename.
             */
            function getCompletionEntriesForDirectoryFragment(fragment, scriptPath, _a, host, exclude, result) {
                var extensions = _a.extensions, includeExtensions = _a.includeExtensions;
                if (result === void 0) { result = []; }
                if (fragment === undefined) {
                    fragment = "";
                }
                fragment = ts.normalizeSlashes(fragment);
                /**
                 * Remove the basename from the path. Note that we don't use the basename to filter completions;
                 * the client is responsible for refining completions.
                 */
                if (!ts.hasTrailingDirectorySeparator(fragment)) {
                    fragment = ts.getDirectoryPath(fragment);
                }
                if (fragment === "") {
                    fragment = "." + ts.directorySeparator;
                }
                fragment = ts.ensureTrailingDirectorySeparator(fragment);
                // const absolutePath = normalizeAndPreserveTrailingSlash(isRootedDiskPath(fragment) ? fragment : combinePaths(scriptPath, fragment)); // TODO(rbuckton): should use resolvePaths
                var absolutePath = ts.resolvePath(scriptPath, fragment);
                var baseDirectory = ts.hasTrailingDirectorySeparator(absolutePath) ? absolutePath : ts.getDirectoryPath(absolutePath);
                var ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
                if (!tryDirectoryExists(host, baseDirectory))
                    return result;
                // Enumerate the available files if possible
                var files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/ undefined, /*include*/ ["./*"]);
                if (files) {
                    /**
                     * Multiple file entries might map to the same truncated name once we remove extensions
                     * (happens iff includeExtensions === false)so we use a set-like data structure. Eg:
                     *
                     * both foo.ts and foo.tsx become foo
                     */
                    var foundFiles = ts.createMap(); // maps file to its extension
                    for (var _i = 0, files_1 = files; _i < files_1.length; _i++) {
                        var filePath = files_1[_i];
                        filePath = ts.normalizePath(filePath);
                        if (exclude && ts.comparePaths(filePath, exclude, scriptPath, ignoreCase) === 0 /* EqualTo */) {
                            continue;
                        }
                        var foundFileName = includeExtensions || ts.fileExtensionIs(filePath, ".json" /* Json */) ? ts.getBaseFileName(filePath) : ts.removeFileExtension(ts.getBaseFileName(filePath));
                        foundFiles.set(foundFileName, ts.tryGetExtensionFromPath(filePath));
                    }
                    foundFiles.forEach(function (ext, foundFile) {
                        result.push(nameAndKind(foundFile, "script" /* scriptElement */, ext));
                    });
                }
                // If possible, get folder completion as well
                var directories = tryGetDirectories(host, baseDirectory);
                if (directories) {
                    for (var _b = 0, directories_1 = directories; _b < directories_1.length; _b++) {
                        var directory = directories_1[_b];
                        var directoryName = ts.getBaseFileName(ts.normalizePath(directory));
                        if (directoryName !== "@types") {
                            result.push(directoryResult(directoryName));
                        }
                    }
                }
                // check for a version redirect
                var packageJsonPath = findPackageJson(baseDirectory, host);
                if (packageJsonPath) {
                    var packageJson = ts.readJson(packageJsonPath, host);
                    var typesVersions = packageJson.typesVersions;
                    if (typeof typesVersions === "object") {
                        var versionResult = ts.getPackageJsonTypesVersionsPaths(typesVersions);
                        var versionPaths = versionResult && versionResult.paths;
                        var rest = absolutePath.slice(ts.ensureTrailingDirectorySeparator(baseDirectory).length);
                        if (versionPaths) {
                            addCompletionEntriesFromPaths(result, rest, baseDirectory, extensions, versionPaths, host);
                        }
                    }
                }
                return result;
            }
            function addCompletionEntriesFromPaths(result, fragment, baseDirectory, fileExtensions, paths, host) {
                for (var path in paths) {
                    if (!ts.hasProperty(paths, path))
                        continue;
                    var patterns = paths[path];
                    if (patterns) {
                        var _loop_1 = function (name, kind, extension) {
                            // Path mappings may provide a duplicate way to get to something we've already added, so don't add again.
                            if (!result.some(function (entry) { return entry.name === name; })) {
                                result.push(nameAndKind(name, kind, extension));
                            }
                        };
                        for (var _i = 0, _a = getCompletionsForPathMapping(path, patterns, fragment, baseDirectory, fileExtensions, host); _i < _a.length; _i++) {
                            var _b = _a[_i], name = _b.name, kind = _b.kind, extension = _b.extension;
                            _loop_1(name, kind, extension);
                        }
                    }
                }
            }
            /**
             * Check all of the declared modules and those in node modules. Possible sources of modules:
             *      Modules that are found by the type checker
             *      Modules found relative to "baseUrl" compliler options (including patterns from "paths" compiler option)
             *      Modules from node_modules (i.e. those listed in package.json)
             *          This includes all files that are found in node_modules/moduleName/ with acceptable file extensions
             */
            function getCompletionEntriesForNonRelativeModules(fragment, scriptPath, compilerOptions, host, typeChecker) {
                var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths;
                var result = [];
                var extensionOptions = getExtensionOptions(compilerOptions);
                if (baseUrl) {
                    var projectDir = compilerOptions.project || host.getCurrentDirectory();
                    var absolute = ts.normalizePath(ts.combinePaths(projectDir, baseUrl));
                    getCompletionEntriesForDirectoryFragment(fragment, absolute, extensionOptions, host, /*exclude*/ undefined, result);
                    if (paths) {
                        addCompletionEntriesFromPaths(result, fragment, absolute, extensionOptions.extensions, paths, host);
                    }
                }
                var fragmentDirectory = getFragmentDirectory(fragment);
                for (var _i = 0, _a = getAmbientModuleCompletions(fragment, fragmentDirectory, typeChecker); _i < _a.length; _i++) {
                    var ambientName = _a[_i];
                    result.push(nameAndKind(ambientName, "external module name" /* externalModuleName */, /*extension*/ undefined));
                }
                getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, fragmentDirectory, extensionOptions, result);
                if (ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeJs) {
                    // If looking for a global package name, don't just include everything in `node_modules` because that includes dependencies' own dependencies.
                    // (But do if we didn't find anything, e.g. 'package.json' missing.)
                    var foundGlobal = false;
                    if (fragmentDirectory === undefined) {
                        var _loop_2 = function (moduleName) {
                            if (!result.some(function (entry) { return entry.name === moduleName; })) {
                                foundGlobal = true;
                                result.push(nameAndKind(moduleName, "external module name" /* externalModuleName */, /*extension*/ undefined));
                            }
                        };
                        for (var _b = 0, _c = enumerateNodeModulesVisibleToScript(host, scriptPath); _b < _c.length; _b++) {
                            var moduleName = _c[_b];
                            _loop_2(moduleName);
                        }
                    }
                    if (!foundGlobal) {
                        ts.forEachAncestorDirectory(scriptPath, function (ancestor) {
                            var nodeModules = ts.combinePaths(ancestor, "node_modules");
                            if (tryDirectoryExists(host, nodeModules)) {
                                getCompletionEntriesForDirectoryFragment(fragment, nodeModules, extensionOptions, host, /*exclude*/ undefined, result);
                            }
                        });
                    }
                }
                return result;
            }
            function getFragmentDirectory(fragment) {
                return containsSlash(fragment) ? ts.hasTrailingDirectorySeparator(fragment) ? fragment : ts.getDirectoryPath(fragment) : undefined;
            }
            function getCompletionsForPathMapping(path, patterns, fragment, baseUrl, fileExtensions, host) {
                if (!ts.endsWith(path, "*")) {
                    // For a path mapping "foo": ["/x/y/z.ts"], add "foo" itself as a completion.
                    return !ts.stringContains(path, "*") ? justPathMappingName(path) : ts.emptyArray;
                }
                var pathPrefix = path.slice(0, path.length - 1);
                var remainingFragment = ts.tryRemovePrefix(fragment, pathPrefix);
                return remainingFragment === undefined ? justPathMappingName(pathPrefix) : ts.flatMap(patterns, function (pattern) {
                    return getModulesForPathsPattern(remainingFragment, baseUrl, pattern, fileExtensions, host);
                });
                function justPathMappingName(name) {
                    return ts.startsWith(name, fragment) ? [directoryResult(name)] : ts.emptyArray;
                }
            }
            function getModulesForPathsPattern(fragment, baseUrl, pattern, fileExtensions, host) {
                if (!host.readDirectory) {
                    return undefined;
                }
                var parsed = ts.hasZeroOrOneAsteriskCharacter(pattern) ? ts.tryParsePattern(pattern) : undefined;
                if (!parsed) {
                    return undefined;
                }
                // The prefix has two effective parts: the directory path and the base component after the filepath that is not a
                // full directory component. For example: directory/path/of/prefix/base*
                var normalizedPrefix = ts.resolvePath(parsed.prefix);
                var normalizedPrefixDirectory = ts.hasTrailingDirectorySeparator(parsed.prefix) ? normalizedPrefix : ts.getDirectoryPath(normalizedPrefix);
                var normalizedPrefixBase = ts.hasTrailingDirectorySeparator(parsed.prefix) ? "" : ts.getBaseFileName(normalizedPrefix);
                var fragmentHasPath = containsSlash(fragment);
                var fragmentDirectory = fragmentHasPath ? ts.hasTrailingDirectorySeparator(fragment) ? fragment : ts.getDirectoryPath(fragment) : undefined;
                // Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call
                var expandedPrefixDirectory = fragmentHasPath ? ts.combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + fragmentDirectory) : normalizedPrefixDirectory;
                var normalizedSuffix = ts.normalizePath(parsed.suffix);
                // Need to normalize after combining: If we combinePaths("a", "../b"), we want "b" and not "a/../b".
                var baseDirectory = ts.normalizePath(ts.combinePaths(baseUrl, expandedPrefixDirectory));
                var completePrefix = fragmentHasPath ? baseDirectory : ts.ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase;
                // If we have a suffix, then we need to read the directory all the way down. We could create a glob
                // that encodes the suffix, but we would have to escape the character "?" which readDirectory
                // doesn't support. For now, this is safer but slower
                var includeGlob = normalizedSuffix ? "**/*" : "./*";
                var matches = ts.mapDefined(tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]), function (match) {
                    var extension = ts.tryGetExtensionFromPath(match);
                    var name = trimPrefixAndSuffix(match);
                    return name === undefined ? undefined : nameAndKind(ts.removeFileExtension(name), "script" /* scriptElement */, extension);
                });
                var directories = ts.mapDefined(tryGetDirectories(host, baseDirectory).map(function (d) { return ts.combinePaths(baseDirectory, d); }), function (dir) {
                    var name = trimPrefixAndSuffix(dir);
                    return name === undefined ? undefined : directoryResult(name);
                });
                return matches.concat(directories);
                function trimPrefixAndSuffix(path) {
                    var inner = withoutStartAndEnd(ts.normalizePath(path), completePrefix, normalizedSuffix);
                    return inner === undefined ? undefined : removeLeadingDirectorySeparator(inner);
                }
            }
            function withoutStartAndEnd(s, start, end) {
                return ts.startsWith(s, start) && ts.endsWith(s, end) ? s.slice(start.length, s.length - end.length) : undefined;
            }
            function removeLeadingDirectorySeparator(path) {
                return path[0] === ts.directorySeparator ? path.slice(1) : path;
            }
            function getAmbientModuleCompletions(fragment, fragmentDirectory, checker) {
                // Get modules that the type checker picked up
                var ambientModules = checker.getAmbientModules().map(function (sym) { return ts.stripQuotes(sym.name); });
                var nonRelativeModuleNames = ambientModules.filter(function (moduleName) { return ts.startsWith(moduleName, fragment); });
                // Nested modules of the form "module-name/sub" need to be adjusted to only return the string
                // after the last '/' that appears in the fragment because that's where the replacement span
                // starts
                if (fragmentDirectory !== undefined) {
                    var moduleNameWithSeparator_1 = ts.ensureTrailingDirectorySeparator(fragmentDirectory);
                    return nonRelativeModuleNames.map(function (nonRelativeModuleName) { return ts.removePrefix(nonRelativeModuleName, moduleNameWithSeparator_1); });
                }
                return nonRelativeModuleNames;
            }
            function getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host) {
                var token = ts.getTokenAtPosition(sourceFile, position);
                var commentRanges = ts.getLeadingCommentRanges(sourceFile.text, token.pos);
                var range = commentRanges && ts.find(commentRanges, function (commentRange) { return position >= commentRange.pos && position <= commentRange.end; });
                if (!range) {
                    return undefined;
                }
                var text = sourceFile.text.slice(range.pos, position);
                var match = tripleSlashDirectiveFragmentRegex.exec(text);
                if (!match) {
                    return undefined;
                }
                var prefix = match[1], kind = match[2], toComplete = match[3];
                var scriptPath = ts.getDirectoryPath(sourceFile.path);
                var names = kind === "path" ? getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getExtensionOptions(compilerOptions, /*includeExtensions*/ true), host, sourceFile.path)
                    : kind === "types" ? getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, getFragmentDirectory(toComplete), getExtensionOptions(compilerOptions))
                        : ts.Debug.fail();
                return addReplacementSpans(toComplete, range.pos + prefix.length, names);
            }
            function getCompletionEntriesFromTypings(host, options, scriptPath, fragmentDirectory, extensionOptions, result) {
                if (result === void 0) { result = []; }
                // Check for typings specified in compiler options
                var seen = ts.createMap();
                var typeRoots = tryAndIgnoreErrors(function () { return ts.getEffectiveTypeRoots(options, host); }) || ts.emptyArray;
                for (var _i = 0, typeRoots_1 = typeRoots; _i < typeRoots_1.length; _i++) {
                    var root = typeRoots_1[_i];
                    getCompletionEntriesFromDirectories(root);
                }
                // Also get all @types typings installed in visible node_modules directories
                for (var _a = 0, _b = findPackageJsons(scriptPath, host); _a < _b.length; _a++) {
                    var packageJson = _b[_a];
                    var typesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules/@types");
                    getCompletionEntriesFromDirectories(typesDir);
                }
                return result;
                function getCompletionEntriesFromDirectories(directory) {
                    if (!tryDirectoryExists(host, directory))
                        return;
                    for (var _i = 0, _a = tryGetDirectories(host, directory); _i < _a.length; _i++) {
                        var typeDirectoryName = _a[_i];
                        var packageName = ts.unmangleScopedPackageName(typeDirectoryName);
                        if (options.types && !ts.contains(options.types, packageName))
                            continue;
                        if (fragmentDirectory === undefined) {
                            if (!seen.has(packageName)) {
                                result.push(nameAndKind(packageName, "external module name" /* externalModuleName */, /*extension*/ undefined));
                                seen.set(packageName, true);
                            }
                        }
                        else {
                            var baseDirectory = ts.combinePaths(directory, typeDirectoryName);
                            var remainingFragment = ts.tryRemoveDirectoryPrefix(fragmentDirectory, packageName, ts.hostGetCanonicalFileName(host));
                            if (remainingFragment !== undefined) {
                                getCompletionEntriesForDirectoryFragment(remainingFragment, baseDirectory, extensionOptions, host, /*exclude*/ undefined, result);
                            }
                        }
                    }
                }
            }
            function findPackageJsons(directory, host) {
                var paths = [];
                ts.forEachAncestorDirectory(directory, function (ancestor) {
                    var currentConfigPath = ts.findConfigFile(ancestor, function (f) { return tryFileExists(host, f); }, "package.json");
                    if (!currentConfigPath) {
                        return true; // break out
                    }
                    paths.push(currentConfigPath);
                });
                return paths;
            }
            function findPackageJson(directory, host) {
                var packageJson;
                ts.forEachAncestorDirectory(directory, function (ancestor) {
                    if (ancestor === "node_modules")
                        return true;
                    packageJson = ts.findConfigFile(ancestor, function (f) { return tryFileExists(host, f); }, "package.json");
                    if (packageJson) {
                        return true; // break out
                    }
                });
                return packageJson;
            }
            function enumerateNodeModulesVisibleToScript(host, scriptPath) {
                if (!host.readFile || !host.fileExists)
                    return ts.emptyArray;
                var result = [];
                for (var _i = 0, _a = findPackageJsons(scriptPath, host); _i < _a.length; _i++) {
                    var packageJson = _a[_i];
                    var contents = ts.readJson(packageJson, host); // Cast to assert that readFile is defined
                    // Provide completions for all non @types dependencies
                    for (var _b = 0, nodeModulesDependencyKeys_1 = nodeModulesDependencyKeys; _b < nodeModulesDependencyKeys_1.length; _b++) {
                        var key = nodeModulesDependencyKeys_1[_b];
                        var dependencies = contents[key];
                        if (!dependencies)
                            continue;
                        for (var dep in dependencies) {
                            if (dependencies.hasOwnProperty(dep) && !ts.startsWith(dep, "@types/")) {
                                result.push(dep);
                            }
                        }
                    }
                }
                return result;
            }
            // Replace everything after the last directory separator that appears
            function getDirectoryFragmentTextSpan(text, textStart) {
                var index = Math.max(text.lastIndexOf(ts.directorySeparator), text.lastIndexOf("\\"));
                var offset = index !== -1 ? index + 1 : 0;
                // If the range is an identifier, span is unnecessary.
                var length = text.length - offset;
                return length === 0 || ts.isIdentifierText(text.substr(offset, length), 8 /* ESNext */) ? undefined : ts.createTextSpan(textStart + offset, length);
            }
            // Returns true if the path is explicitly relative to the script (i.e. relative to . or ..)
            function isPathRelativeToScript(path) {
                if (path && path.length >= 2 && path.charCodeAt(0) === 46 /* dot */) {
                    var slashIndex = path.length >= 3 && path.charCodeAt(1) === 46 /* dot */ ? 2 : 1;
                    var slashCharCode = path.charCodeAt(slashIndex);
                    return slashCharCode === 47 /* slash */ || slashCharCode === 92 /* backslash */;
                }
                return false;
            }
            /**
             * Matches a triple slash reference directive with an incomplete string literal for its path. Used
             * to determine if the caret is currently within the string literal and capture the literal fragment
             * for completions.
             * For example, this matches
             *
             * /// <reference path="fragment
             *
             * but not
             *
             * /// <reference path="fragment"
             */
            var tripleSlashDirectiveFragmentRegex = /^(\/\/\/\s*<reference\s+(path|types)\s*=\s*(?:'|"))([^\3"]*)$/;
            var nodeModulesDependencyKeys = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
            function tryGetDirectories(host, directoryName) {
                return tryIOAndConsumeErrors(host, host.getDirectories, directoryName) || [];
            }
            function tryReadDirectory(host, path, extensions, exclude, include) {
                return tryIOAndConsumeErrors(host, host.readDirectory, path, extensions, exclude, include) || ts.emptyArray;
            }
            function tryFileExists(host, path) {
                return tryIOAndConsumeErrors(host, host.fileExists, path);
            }
            function tryDirectoryExists(host, path) {
                return tryAndIgnoreErrors(function () { return ts.directoryProbablyExists(path, host); }) || false;
            }
            function tryIOAndConsumeErrors(host, toApply) {
                var args = [];
                for (var _i = 2; _i < arguments.length; _i++) {
                    args[_i - 2] = arguments[_i];
                }
                return tryAndIgnoreErrors(function () { return toApply && toApply.apply(host, args); });
            }
            function tryAndIgnoreErrors(cb) {
                try {
                    return cb();
                }
                catch (_a) {
                    return undefined;
                }
            }
            function containsSlash(fragment) {
                return ts.stringContains(fragment, ts.directorySeparator);
            }
        })(StringCompletions = Completions.StringCompletions || (Completions.StringCompletions = {}));
    })(Completions = ts.Completions || (ts.Completions = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var Completions;
    (function (Completions) {
        var SortText;
        (function (SortText) {
            SortText["LocationPriority"] = "0";
            SortText["SuggestedClassMembers"] = "1";
            SortText["GlobalsOrKeywords"] = "2";
            SortText["AutoImportSuggestions"] = "3";
            SortText["JavascriptIdentifiers"] = "4";
        })(SortText = Completions.SortText || (Completions.SortText = {}));
        var SymbolOriginInfoKind;
        (function (SymbolOriginInfoKind) {
            SymbolOriginInfoKind[SymbolOriginInfoKind["ThisType"] = 0] = "ThisType";
            SymbolOriginInfoKind[SymbolOriginInfoKind["SymbolMemberNoExport"] = 1] = "SymbolMemberNoExport";
            SymbolOriginInfoKind[SymbolOriginInfoKind["SymbolMemberExport"] = 2] = "SymbolMemberExport";
            SymbolOriginInfoKind[SymbolOriginInfoKind["Export"] = 3] = "Export";
        })(SymbolOriginInfoKind || (SymbolOriginInfoKind = {}));
        function originIsSymbolMember(origin) {
            return origin.kind === 2 /* SymbolMemberExport */ || origin.kind === 1 /* SymbolMemberNoExport */;
        }
        function originIsExport(origin) {
            return origin.kind === 2 /* SymbolMemberExport */ || origin.kind === 3 /* Export */;
        }
        var KeywordCompletionFilters;
        (function (KeywordCompletionFilters) {
            KeywordCompletionFilters[KeywordCompletionFilters["None"] = 0] = "None";
            KeywordCompletionFilters[KeywordCompletionFilters["All"] = 1] = "All";
            KeywordCompletionFilters[KeywordCompletionFilters["ClassElementKeywords"] = 2] = "ClassElementKeywords";
            KeywordCompletionFilters[KeywordCompletionFilters["InterfaceElementKeywords"] = 3] = "InterfaceElementKeywords";
            KeywordCompletionFilters[KeywordCompletionFilters["ConstructorParameterKeywords"] = 4] = "ConstructorParameterKeywords";
            KeywordCompletionFilters[KeywordCompletionFilters["FunctionLikeBodyKeywords"] = 5] = "FunctionLikeBodyKeywords";
            KeywordCompletionFilters[KeywordCompletionFilters["TypeKeywords"] = 6] = "TypeKeywords";
            KeywordCompletionFilters[KeywordCompletionFilters["Last"] = 6] = "Last";
        })(KeywordCompletionFilters || (KeywordCompletionFilters = {}));
        var GlobalsSearch;
        (function (GlobalsSearch) {
            GlobalsSearch[GlobalsSearch["Continue"] = 0] = "Continue";
            GlobalsSearch[GlobalsSearch["Success"] = 1] = "Success";
            GlobalsSearch[GlobalsSearch["Fail"] = 2] = "Fail";
        })(GlobalsSearch || (GlobalsSearch = {}));
        function getCompletionsAtPosition(host, program, log, sourceFile, position, preferences, triggerCharacter) {
            var typeChecker = program.getTypeChecker();
            var compilerOptions = program.getCompilerOptions();
            var contextToken = ts.findPrecedingToken(position, sourceFile);
            if (triggerCharacter && !ts.isInString(sourceFile, position, contextToken) && !isValidTrigger(sourceFile, triggerCharacter, contextToken, position)) {
                return undefined;
            }
            var stringCompletions = Completions.StringCompletions.getStringLiteralCompletions(sourceFile, position, contextToken, typeChecker, compilerOptions, host, log, preferences);
            if (stringCompletions) {
                return stringCompletions;
            }
            if (contextToken && ts.isBreakOrContinueStatement(contextToken.parent)
                && (contextToken.kind === 74 /* BreakKeyword */ || contextToken.kind === 79 /* ContinueKeyword */ || contextToken.kind === 73 /* Identifier */)) {
                return getLabelCompletionAtPosition(contextToken.parent);
            }
            var completionData = getCompletionData(program, log, sourceFile, isUncheckedFile(sourceFile, compilerOptions), position, preferences, /*detailsEntryId*/ undefined);
            if (!completionData) {
                return undefined;
            }
            switch (completionData.kind) {
                case 0 /* Data */:
                    return completionInfoFromData(sourceFile, typeChecker, compilerOptions, log, completionData, preferences);
                case 1 /* JsDocTagName */:
                    // If the current position is a jsDoc tag name, only tag names should be provided for completion
                    return jsdocCompletionInfo(ts.JsDoc.getJSDocTagNameCompletions());
                case 2 /* JsDocTag */:
                    // If the current position is a jsDoc tag, only tags should be provided for completion
                    return jsdocCompletionInfo(ts.JsDoc.getJSDocTagCompletions());
                case 3 /* JsDocParameterName */:
                    return jsdocCompletionInfo(ts.JsDoc.getJSDocParameterNameCompletions(completionData.tag));
                default:
                    return ts.Debug.assertNever(completionData);
            }
        }
        Completions.getCompletionsAtPosition = getCompletionsAtPosition;
        function jsdocCompletionInfo(entries) {
            return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: entries };
        }
        function completionInfoFromData(sourceFile, typeChecker, compilerOptions, log, completionData, preferences) {
            var symbols = completionData.symbols, completionKind = completionData.completionKind, isInSnippetScope = completionData.isInSnippetScope, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, propertyAccessToConvert = completionData.propertyAccessToConvert, keywordFilters = completionData.keywordFilters, literals = completionData.literals, symbolToOriginInfoMap = completionData.symbolToOriginInfoMap, recommendedCompletion = completionData.recommendedCompletion, isJsxInitializer = completionData.isJsxInitializer, insideJsDocTagTypeExpression = completionData.insideJsDocTagTypeExpression, symbolToSortTextMap = completionData.symbolToSortTextMap;
            if (location && location.parent && ts.isJsxClosingElement(location.parent)) {
                // In the TypeScript JSX element, if such element is not defined. When users query for completion at closing tag,
                // instead of simply giving unknown value, the completion will return the tag-name of an associated opening-element.
                // For example:
                //     var x = <div> </ /*1*/
                // The completion list at "1" will contain "div>" with type any
                // And at `<div> </ /*1*/ >` (with a closing `>`), the completion list will contain "div".
                var tagName = location.parent.parent.openingElement.tagName;
                var hasClosingAngleBracket = !!ts.findChildOfKind(location.parent, 30 /* GreaterThanToken */, sourceFile);
                var entry = {
                    name: tagName.getFullText(sourceFile) + (hasClosingAngleBracket ? "" : ">"),
                    kind: "class" /* classElement */,
                    kindModifiers: undefined,
                    sortText: SortText.LocationPriority,
                };
                return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: false, entries: [entry] };
            }
            var entries = [];
            if (isUncheckedFile(sourceFile, compilerOptions)) {
                var uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, sourceFile, typeChecker, compilerOptions.target, log, completionKind, preferences, propertyAccessToConvert, isJsxInitializer, recommendedCompletion, symbolToOriginInfoMap, symbolToSortTextMap);
                getJSCompletionEntries(sourceFile, location.pos, uniqueNames, compilerOptions.target, entries); // TODO: GH#18217
            }
            else {
                if (!isNewIdentifierLocation && (!symbols || symbols.length === 0) && keywordFilters === 0 /* None */) {
                    return undefined;
                }
                getCompletionEntriesFromSymbols(symbols, entries, location, sourceFile, typeChecker, compilerOptions.target, log, completionKind, preferences, propertyAccessToConvert, isJsxInitializer, recommendedCompletion, symbolToOriginInfoMap, symbolToSortTextMap);
            }
            if (keywordFilters !== 0 /* None */) {
                var entryNames = ts.arrayToSet(entries, function (e) { return e.name; });
                for (var _i = 0, _a = getKeywordCompletions(keywordFilters, !insideJsDocTagTypeExpression && ts.isSourceFileJS(sourceFile)); _i < _a.length; _i++) {
                    var keywordEntry = _a[_i];
                    if (!entryNames.has(keywordEntry.name)) {
                        entries.push(keywordEntry);
                    }
                }
            }
            for (var _b = 0, literals_1 = literals; _b < literals_1.length; _b++) {
                var literal = literals_1[_b];
                entries.push(createCompletionEntryForLiteral(literal));
            }
            return { isGlobalCompletion: isInSnippetScope, isMemberCompletion: isMemberCompletionKind(completionKind), isNewIdentifierLocation: isNewIdentifierLocation, entries: entries };
        }
        function isUncheckedFile(sourceFile, compilerOptions) {
            return ts.isSourceFileJS(sourceFile) && !ts.isCheckJsEnabledForFile(sourceFile, compilerOptions);
        }
        function isMemberCompletionKind(kind) {
            switch (kind) {
                case 0 /* ObjectPropertyDeclaration */:
                case 3 /* MemberLike */:
                case 2 /* PropertyAccess */:
                    return true;
                default:
                    return false;
            }
        }
        function getJSCompletionEntries(sourceFile, position, uniqueNames, target, entries) {
            ts.getNameTable(sourceFile).forEach(function (pos, name) {
                // Skip identifiers produced only from the current location
                if (pos === position) {
                    return;
                }
                var realName = ts.unescapeLeadingUnderscores(name);
                if (ts.addToSeen(uniqueNames, realName) && ts.isIdentifierText(realName, target)) {
                    entries.push({
                        name: realName,
                        kind: "warning" /* warning */,
                        kindModifiers: "",
                        sortText: SortText.JavascriptIdentifiers
                    });
                }
            });
        }
        var completionNameForLiteral = function (literal) {
            return typeof literal === "object" ? ts.pseudoBigIntToString(literal) + "n" : JSON.stringify(literal);
        };
        function createCompletionEntryForLiteral(literal) {
            return { name: completionNameForLiteral(literal), kind: "string" /* string */, kindModifiers: "" /* none */, sortText: SortText.LocationPriority };
        }
        function createCompletionEntry(symbol, sortText, location, sourceFile, typeChecker, name, needsConvertPropertyAccess, origin, recommendedCompletion, propertyAccessToConvert, isJsxInitializer, preferences) {
            var insertText;
            var replacementSpan;
            if (origin && origin.kind === 0 /* ThisType */) {
                insertText = needsConvertPropertyAccess ? "this[" + ts.quote(name, preferences) + "]" : "this." + name;
            }
            // We should only have needsConvertPropertyAccess if there's a property access to convert. But see #21790.
            // Somehow there was a global with a non-identifier name. Hopefully someone will complain about getting a "foo bar" global completion and provide a repro.
            else if ((origin && originIsSymbolMember(origin) || needsConvertPropertyAccess) && propertyAccessToConvert) {
                insertText = needsConvertPropertyAccess ? "[" + ts.quote(name, preferences) + "]" : "[" + name + "]";
                var dot = ts.findChildOfKind(propertyAccessToConvert, 24 /* DotToken */, sourceFile);
                // If the text after the '.' starts with this name, write over it. Else, add new text.
                var end = ts.startsWith(name, propertyAccessToConvert.name.text) ? propertyAccessToConvert.name.end : dot.end;
                replacementSpan = ts.createTextSpanFromBounds(dot.getStart(sourceFile), end);
            }
            if (isJsxInitializer) {
                if (insertText === undefined)
                    insertText = name;
                insertText = "{" + insertText + "}";
                if (typeof isJsxInitializer !== "boolean") {
                    replacementSpan = ts.createTextSpanFromNode(isJsxInitializer, sourceFile);
                }
            }
            if (insertText !== undefined && !preferences.includeCompletionsWithInsertText) {
                return undefined;
            }
            // TODO(drosen): Right now we just permit *all* semantic meanings when calling
            // 'getSymbolKind' which is permissible given that it is backwards compatible; but
            // really we should consider passing the meaning for the node so that we don't report
            // that a suggestion for a value is an interface.  We COULD also just do what
            // 'getSymbolModifiers' does, which is to use the first declaration.
            // Use a 'sortText' of 0' so that all symbol completion entries come before any other
            // entries (like JavaScript identifier entries).
            return {
                name: name,
                kind: ts.SymbolDisplay.getSymbolKind(typeChecker, symbol, location),
                kindModifiers: ts.SymbolDisplay.getSymbolModifiers(symbol),
                sortText: sortText,
                source: getSourceFromOrigin(origin),
                hasAction: trueOrUndefined(!!origin && originIsExport(origin)),
                isRecommended: trueOrUndefined(isRecommendedCompletionMatch(symbol, recommendedCompletion, typeChecker)),
                insertText: insertText,
                replacementSpan: replacementSpan,
            };
        }
        function isRecommendedCompletionMatch(localSymbol, recommendedCompletion, checker) {
            return localSymbol === recommendedCompletion ||
                !!(localSymbol.flags & 1048576 /* ExportValue */) && checker.getExportSymbolOfSymbol(localSymbol) === recommendedCompletion;
        }
        function trueOrUndefined(b) {
            return b ? true : undefined;
        }
        function getSourceFromOrigin(origin) {
            return origin && originIsExport(origin) ? ts.stripQuotes(origin.moduleSymbol.name) : undefined;
        }
        function getCompletionEntriesFromSymbols(symbols, entries, location, sourceFile, typeChecker, target, log, kind, preferences, propertyAccessToConvert, isJsxInitializer, recommendedCompletion, symbolToOriginInfoMap, symbolToSortTextMap) {
            var start = ts.timestamp();
            // Tracks unique names.
            // We don't set this for global variables or completions from external module exports, because we can have multiple of those.
            // Based on the order we add things we will always see locals first, then globals, then module exports.
            // So adding a completion for a local will prevent us from adding completions for external module exports sharing the same name.
            var uniques = ts.createMap();
            for (var _i = 0, symbols_1 = symbols; _i < symbols_1.length; _i++) {
                var symbol = symbols_1[_i];
                var origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[ts.getSymbolId(symbol)] : undefined;
                var info = getCompletionEntryDisplayNameForSymbol(symbol, target, origin, kind);
                if (!info) {
                    continue;
                }
                var name = info.name, needsConvertPropertyAccess = info.needsConvertPropertyAccess;
                if (uniques.has(name)) {
                    continue;
                }
                var entry = createCompletionEntry(symbol, symbolToSortTextMap && symbolToSortTextMap[ts.getSymbolId(symbol)] || SortText.LocationPriority, location, sourceFile, typeChecker, name, needsConvertPropertyAccess, origin, recommendedCompletion, propertyAccessToConvert, isJsxInitializer, preferences);
                if (!entry) {
                    continue;
                }
                // Latter case tests whether this is a global variable.
                if (!origin && !(symbol.parent === undefined && !ts.some(symbol.declarations, function (d) { return d.getSourceFile() === location.getSourceFile(); }))) { // TODO: GH#18217
                    uniques.set(name, true);
                }
                entries.push(entry);
            }
            log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (ts.timestamp() - start));
            return uniques;
        }
        Completions.getCompletionEntriesFromSymbols = getCompletionEntriesFromSymbols;
        function getLabelCompletionAtPosition(node) {
            var entries = getLabelStatementCompletions(node);
            if (entries.length) {
                return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: entries };
            }
        }
        function getLabelStatementCompletions(node) {
            var entries = [];
            var uniques = ts.createMap();
            var current = node;
            while (current) {
                if (ts.isFunctionLike(current)) {
                    break;
                }
                if (ts.isLabeledStatement(current)) {
                    var name = current.label.text;
                    if (!uniques.has(name)) {
                        uniques.set(name, true);
                        entries.push({
                            name: name,
                            kindModifiers: "" /* none */,
                            kind: "label" /* label */,
                            sortText: SortText.LocationPriority
                        });
                    }
                }
                current = current.parent;
            }
            return entries;
        }
        function getSymbolCompletionFromEntryId(program, log, sourceFile, position, entryId) {
            var compilerOptions = program.getCompilerOptions();
            var completionData = getCompletionData(program, log, sourceFile, isUncheckedFile(sourceFile, compilerOptions), position, { includeCompletionsForModuleExports: true, includeCompletionsWithInsertText: true }, entryId);
            if (!completionData) {
                return { type: "none" };
            }
            if (completionData.kind !== 0 /* Data */) {
                return { type: "request", request: completionData };
            }
            var symbols = completionData.symbols, literals = completionData.literals, location = completionData.location, completionKind = completionData.completionKind, symbolToOriginInfoMap = completionData.symbolToOriginInfoMap, previousToken = completionData.previousToken, isJsxInitializer = completionData.isJsxInitializer;
            var literal = ts.find(literals, function (l) { return completionNameForLiteral(l) === entryId.name; });
            if (literal !== undefined)
                return { type: "literal", literal: literal };
            // Find the symbol with the matching entry name.
            // We don't need to perform character checks here because we're only comparing the
            // name against 'entryName' (which is known to be good), not building a new
            // completion entry.
            return ts.firstDefined(symbols, function (symbol) {
                var origin = symbolToOriginInfoMap[ts.getSymbolId(symbol)];
                var info = getCompletionEntryDisplayNameForSymbol(symbol, compilerOptions.target, origin, completionKind);
                return info && info.name === entryId.name && getSourceFromOrigin(origin) === entryId.source
                    ? { type: "symbol", symbol: symbol, location: location, symbolToOriginInfoMap: symbolToOriginInfoMap, previousToken: previousToken, isJsxInitializer: isJsxInitializer }
                    : undefined;
            }) || { type: "none" };
        }
        function getSymbolName(symbol, origin, target) {
            return origin && originIsExport(origin) && ((origin.isDefaultExport && symbol.escapedName === "default" /* Default */) ||
                (symbol.escapedName === "export=" /* ExportEquals */))
                // Name of "export default foo;" is "foo". Name of "export default 0" is the filename converted to camelCase.
                ? ts.firstDefined(symbol.declarations, function (d) { return ts.isExportAssignment(d) && ts.isIdentifier(d.expression) ? d.expression.text : undefined; })
                    || ts.codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target)
                : symbol.name;
        }
        function getCompletionEntryDetails(program, log, sourceFile, position, entryId, host, formatContext, preferences, cancellationToken) {
            var typeChecker = program.getTypeChecker();
            var compilerOptions = program.getCompilerOptions();
            var name = entryId.name;
            var contextToken = ts.findPrecedingToken(position, sourceFile);
            if (ts.isInString(sourceFile, position, contextToken)) {
                return Completions.StringCompletions.getStringLiteralCompletionDetails(name, sourceFile, position, contextToken, typeChecker, compilerOptions, host, cancellationToken);
            }
            // Compute all the completion symbols again.
            var symbolCompletion = getSymbolCompletionFromEntryId(program, log, sourceFile, position, entryId);
            switch (symbolCompletion.type) {
                case "request": {
                    var request = symbolCompletion.request;
                    switch (request.kind) {
                        case 1 /* JsDocTagName */:
                            return ts.JsDoc.getJSDocTagNameCompletionDetails(name);
                        case 2 /* JsDocTag */:
                            return ts.JsDoc.getJSDocTagCompletionDetails(name);
                        case 3 /* JsDocParameterName */:
                            return ts.JsDoc.getJSDocParameterNameCompletionDetails(name);
                        default:
                            return ts.Debug.assertNever(request);
                    }
                }
                case "symbol": {
                    var symbol = symbolCompletion.symbol, location = symbolCompletion.location, symbolToOriginInfoMap = symbolCompletion.symbolToOriginInfoMap, previousToken = symbolCompletion.previousToken;
                    var _a = getCompletionEntryCodeActionsAndSourceDisplay(symbolToOriginInfoMap, symbol, program, typeChecker, host, compilerOptions, sourceFile, position, previousToken, formatContext, preferences), codeActions = _a.codeActions, sourceDisplay = _a.sourceDisplay;
                    return createCompletionDetailsForSymbol(symbol, typeChecker, sourceFile, location, cancellationToken, codeActions, sourceDisplay); // TODO: GH#18217
                }
                case "literal": {
                    var literal = symbolCompletion.literal;
                    return createSimpleDetails(completionNameForLiteral(literal), "string" /* string */, typeof literal === "string" ? ts.SymbolDisplayPartKind.stringLiteral : ts.SymbolDisplayPartKind.numericLiteral);
                }
                case "none":
                    // Didn't find a symbol with this name.  See if we can find a keyword instead.
                    return allKeywordsCompletions().some(function (c) { return c.name === name; }) ? createSimpleDetails(name, "keyword" /* keyword */, ts.SymbolDisplayPartKind.keyword) : undefined;
                default:
                    ts.Debug.assertNever(symbolCompletion);
            }
        }
        Completions.getCompletionEntryDetails = getCompletionEntryDetails;
        function createSimpleDetails(name, kind, kind2) {
            return createCompletionDetails(name, "" /* none */, kind, [ts.displayPart(name, kind2)]);
        }
        function createCompletionDetailsForSymbol(symbol, checker, sourceFile, location, cancellationToken, codeActions, sourceDisplay) {
            var _a = checker.runWithCancellationToken(cancellationToken, function (checker) {
                return ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, sourceFile, location, location, 7 /* All */);
            }), displayParts = _a.displayParts, documentation = _a.documentation, symbolKind = _a.symbolKind, tags = _a.tags;
            return createCompletionDetails(symbol.name, ts.SymbolDisplay.getSymbolModifiers(symbol), symbolKind, displayParts, documentation, tags, codeActions, sourceDisplay);
        }
        Completions.createCompletionDetailsForSymbol = createCompletionDetailsForSymbol;
        function createCompletionDetails(name, kindModifiers, kind, displayParts, documentation, tags, codeActions, source) {
            return { name: name, kindModifiers: kindModifiers, kind: kind, displayParts: displayParts, documentation: documentation, tags: tags, codeActions: codeActions, source: source };
        }
        Completions.createCompletionDetails = createCompletionDetails;
        function getCompletionEntryCodeActionsAndSourceDisplay(symbolToOriginInfoMap, symbol, program, checker, host, compilerOptions, sourceFile, position, previousToken, formatContext, preferences) {
            var symbolOriginInfo = symbolToOriginInfoMap[ts.getSymbolId(symbol)];
            if (!symbolOriginInfo || !originIsExport(symbolOriginInfo)) {
                return { codeActions: undefined, sourceDisplay: undefined };
            }
            var moduleSymbol = symbolOriginInfo.moduleSymbol;
            var exportedSymbol = checker.getMergedSymbol(ts.skipAlias(symbol.exportSymbol || symbol, checker));
            var _a = ts.codefix.getImportCompletionAction(exportedSymbol, moduleSymbol, sourceFile, getSymbolName(symbol, symbolOriginInfo, compilerOptions.target), host, program, formatContext, previousToken && ts.isIdentifier(previousToken) ? previousToken.getStart(sourceFile) : position, preferences), moduleSpecifier = _a.moduleSpecifier, codeAction = _a.codeAction;
            return { sourceDisplay: [ts.textPart(moduleSpecifier)], codeActions: [codeAction] };
        }
        function getCompletionEntrySymbol(program, log, sourceFile, position, entryId) {
            var completion = getSymbolCompletionFromEntryId(program, log, sourceFile, position, entryId);
            return completion.type === "symbol" ? completion.symbol : undefined;
        }
        Completions.getCompletionEntrySymbol = getCompletionEntrySymbol;
        var CompletionDataKind;
        (function (CompletionDataKind) {
            CompletionDataKind[CompletionDataKind["Data"] = 0] = "Data";
            CompletionDataKind[CompletionDataKind["JsDocTagName"] = 1] = "JsDocTagName";
            CompletionDataKind[CompletionDataKind["JsDocTag"] = 2] = "JsDocTag";
            CompletionDataKind[CompletionDataKind["JsDocParameterName"] = 3] = "JsDocParameterName";
        })(CompletionDataKind || (CompletionDataKind = {}));
        var CompletionKind;
        (function (CompletionKind) {
            CompletionKind[CompletionKind["ObjectPropertyDeclaration"] = 0] = "ObjectPropertyDeclaration";
            CompletionKind[CompletionKind["Global"] = 1] = "Global";
            CompletionKind[CompletionKind["PropertyAccess"] = 2] = "PropertyAccess";
            CompletionKind[CompletionKind["MemberLike"] = 3] = "MemberLike";
            CompletionKind[CompletionKind["String"] = 4] = "String";
            CompletionKind[CompletionKind["None"] = 5] = "None";
        })(CompletionKind = Completions.CompletionKind || (Completions.CompletionKind = {}));
        function getRecommendedCompletion(previousToken, contextualType, checker) {
            // For a union, return the first one with a recommended completion.
            return ts.firstDefined(contextualType && (contextualType.isUnion() ? contextualType.types : [contextualType]), function (type) {
                var symbol = type && type.symbol;
                // Don't include make a recommended completion for an abstract class
                return symbol && (symbol.flags & (8 /* EnumMember */ | 384 /* Enum */ | 32 /* Class */) && !ts.isAbstractConstructorSymbol(symbol))
                    ? getFirstSymbolInChain(symbol, previousToken, checker)
                    : undefined;
            });
        }
        function getContextualType(previousToken, position, sourceFile, checker) {
            var parent = previousToken.parent;
            switch (previousToken.kind) {
                case 73 /* Identifier */:
                    return ts.getContextualTypeFromParent(previousToken, checker);
                case 60 /* EqualsToken */:
                    switch (parent.kind) {
                        case 238 /* VariableDeclaration */:
                            return checker.getContextualType(parent.initializer); // TODO: GH#18217
                        case 205 /* BinaryExpression */:
                            return checker.getTypeAtLocation(parent.left);
                        case 268 /* JsxAttribute */:
                            return checker.getContextualTypeForJsxAttribute(parent);
                        default:
                            return undefined;
                    }
                case 96 /* NewKeyword */:
                    return checker.getContextualType(parent);
                case 75 /* CaseKeyword */:
                    return ts.getSwitchedType(ts.cast(parent, ts.isCaseClause), checker);
                case 18 /* OpenBraceToken */:
                    return ts.isJsxExpression(parent) && parent.parent.kind !== 261 /* JsxElement */ ? checker.getContextualTypeForJsxAttribute(parent.parent) : undefined;
                default:
                    var argInfo = ts.SignatureHelp.getArgumentInfoForCompletions(previousToken, position, sourceFile);
                    return argInfo
                        // At `,`, treat this as the next argument after the comma.
                        ? checker.getContextualTypeForArgumentAtIndex(argInfo.invocation, argInfo.argumentIndex + (previousToken.kind === 27 /* CommaToken */ ? 1 : 0))
                        : ts.isEqualityOperatorKind(previousToken.kind) && ts.isBinaryExpression(parent) && ts.isEqualityOperatorKind(parent.operatorToken.kind)
                            // completion at `x ===/**/` should be for the right side
                            ? checker.getTypeAtLocation(parent.left)
                            : checker.getContextualType(previousToken);
            }
        }
        function getFirstSymbolInChain(symbol, enclosingDeclaration, checker) {
            var chain = checker.getAccessibleSymbolChain(symbol, enclosingDeclaration, /*meaning*/ 67108863 /* All */, /*useOnlyExternalAliasing*/ false);
            if (chain)
                return ts.first(chain);
            return symbol.parent && (isModuleSymbol(symbol.parent) ? symbol : getFirstSymbolInChain(symbol.parent, enclosingDeclaration, checker));
        }
        function isModuleSymbol(symbol) {
            return symbol.declarations.some(function (d) { return d.kind === 285 /* SourceFile */; });
        }
        function getCompletionData(program, log, sourceFile, isUncheckedFile, position, preferences, detailsEntryId) {
            var typeChecker = program.getTypeChecker();
            var start = ts.timestamp();
            var currentToken = ts.getTokenAtPosition(sourceFile, position); // TODO: GH#15853
            // We will check for jsdoc comments with insideComment and getJsDocTagAtPosition. (TODO: that seems rather inefficient to check the same thing so many times.)
            log("getCompletionData: Get current token: " + (ts.timestamp() - start));
            start = ts.timestamp();
            var insideComment = ts.isInComment(sourceFile, position, currentToken);
            log("getCompletionData: Is inside comment: " + (ts.timestamp() - start));
            var insideJsDocTagTypeExpression = false;
            var isInSnippetScope = false;
            if (insideComment) {
                if (ts.hasDocComment(sourceFile, position)) {
                    if (sourceFile.text.charCodeAt(position - 1) === 64 /* at */) {
                        // The current position is next to the '@' sign, when no tag name being provided yet.
                        // Provide a full list of tag names
                        return { kind: 1 /* JsDocTagName */ };
                    }
                    else {
                        // When completion is requested without "@", we will have check to make sure that
                        // there are no comments prefix the request position. We will only allow "*" and space.
                        // e.g
                        //   /** |c| /*
                        //
                        //   /**
                        //     |c|
                        //    */
                        //
                        //   /**
                        //    * |c|
                        //    */
                        //
                        //   /**
                        //    *         |c|
                        //    */
                        var lineStart = ts.getLineStartPositionForPosition(position, sourceFile);
                        if (!(sourceFile.text.substring(lineStart, position).match(/[^\*|\s|(/\*\*)]/))) {
                            return { kind: 2 /* JsDocTag */ };
                        }
                    }
                }
                // Completion should work inside certain JsDoc tags. For example:
                //     /** @type {number | string} */
                // Completion should work in the brackets
                var tag = getJsDocTagAtPosition(currentToken, position);
                if (tag) {
                    if (tag.tagName.pos <= position && position <= tag.tagName.end) {
                        return { kind: 1 /* JsDocTagName */ };
                    }
                    if (isTagWithTypeExpression(tag) && tag.typeExpression && tag.typeExpression.kind === 289 /* JSDocTypeExpression */) {
                        currentToken = ts.getTokenAtPosition(sourceFile, position);
                        if (!currentToken ||
                            (!ts.isDeclarationName(currentToken) &&
                                (currentToken.parent.kind !== 311 /* JSDocPropertyTag */ ||
                                    currentToken.parent.name !== currentToken))) {
                            // Use as type location if inside tag's type expression
                            insideJsDocTagTypeExpression = isCurrentlyEditingNode(tag.typeExpression);
                        }
                    }
                    if (ts.isJSDocParameterTag(tag) && (ts.nodeIsMissing(tag.name) || tag.name.pos <= position && position <= tag.name.end)) {
                        return { kind: 3 /* JsDocParameterName */, tag: tag };
                    }
                }
                if (!insideJsDocTagTypeExpression) {
                    // Proceed if the current position is in jsDoc tag expression; otherwise it is a normal
                    // comment or the plain text part of a jsDoc comment, so no completion should be available
                    log("Returning an empty list because completion was inside a regular comment or plain text part of a JsDoc comment.");
                    return undefined;
                }
            }
            start = ts.timestamp();
            var previousToken = ts.findPrecedingToken(position, sourceFile, /*startNode*/ undefined); // TODO: GH#18217
            log("getCompletionData: Get previous token 1: " + (ts.timestamp() - start));
            // The decision to provide completion depends on the contextToken, which is determined through the previousToken.
            // Note: 'previousToken' (and thus 'contextToken') can be undefined if we are the beginning of the file
            var contextToken = previousToken;
            // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS|
            // Skip this partial identifier and adjust the contextToken to the token that precedes it.
            if (contextToken && position <= contextToken.end && (ts.isIdentifier(contextToken) || ts.isKeyword(contextToken.kind))) {
                var start_1 = ts.timestamp();
                contextToken = ts.findPrecedingToken(contextToken.getFullStart(), sourceFile, /*startNode*/ undefined); // TODO: GH#18217
                log("getCompletionData: Get previous token 2: " + (ts.timestamp() - start_1));
            }
            // Find the node where completion is requested on.
            // Also determine whether we are trying to complete with members of that node
            // or attributes of a JSX tag.
            var node = currentToken;
            var propertyAccessToConvert;
            var isRightOfDot = false;
            var isRightOfOpenTag = false;
            var isStartingCloseTag = false;
            var isJsxInitializer = false;
            var location = ts.getTouchingPropertyName(sourceFile, position);
            if (contextToken) {
                // Bail out if this is a known invalid completion location
                if (isCompletionListBlocker(contextToken)) {
                    log("Returning an empty list because completion was requested in an invalid position.");
                    return undefined;
                }
                var parent = contextToken.parent;
                if (contextToken.kind === 24 /* DotToken */) {
                    isRightOfDot = true;
                    switch (parent.kind) {
                        case 190 /* PropertyAccessExpression */:
                            propertyAccessToConvert = parent;
                            node = propertyAccessToConvert.expression;
                            if (node.end === contextToken.pos &&
                                ts.isCallExpression(node) &&
                                node.getChildCount(sourceFile) &&
                                ts.last(node.getChildren(sourceFile)).kind !== 21 /* CloseParenToken */) {
                                // This is likely dot from incorrectly parsed call expression and user is starting to write spread
                                // eg: Math.min(./**/)
                                return undefined;
                            }
                            break;
                        case 149 /* QualifiedName */:
                            node = parent.left;
                            break;
                        case 245 /* ModuleDeclaration */:
                            node = parent.name;
                            break;
                        case 184 /* ImportType */:
                        case 215 /* MetaProperty */:
                            node = parent;
                            break;
                        default:
                            // There is nothing that precedes the dot, so this likely just a stray character
                            // or leading into a '...' token. Just bail out instead.
                            return undefined;
                    }
                }
                else if (sourceFile.languageVariant === 1 /* JSX */) {
                    // <UI.Test /* completion position */ />
                    // If the tagname is a property access expression, we will then walk up to the top most of property access expression.
                    // Then, try to get a JSX container and its associated attributes type.
                    if (parent && parent.kind === 190 /* PropertyAccessExpression */) {
                        contextToken = parent;
                        parent = parent.parent;
                    }
                    // Fix location
                    if (currentToken.parent === location) {
                        switch (currentToken.kind) {
                            case 30 /* GreaterThanToken */:
                                if (currentToken.parent.kind === 261 /* JsxElement */ || currentToken.parent.kind === 263 /* JsxOpeningElement */) {
                                    location = currentToken;
                                }
                                break;
                            case 42 /* SlashToken */:
                                if (currentToken.parent.kind === 262 /* JsxSelfClosingElement */) {
                                    location = currentToken;
                                }
                                break;
                        }
                    }
                    switch (parent.kind) {
                        case 264 /* JsxClosingElement */:
                            if (contextToken.kind === 42 /* SlashToken */) {
                                isStartingCloseTag = true;
                                location = contextToken;
                            }
                            break;
                        case 205 /* BinaryExpression */:
                            if (!binaryExpressionMayBeOpenTag(parent)) {
                                break;
                            }
                        // falls through
                        case 262 /* JsxSelfClosingElement */:
                        case 261 /* JsxElement */:
                        case 263 /* JsxOpeningElement */:
                            if (contextToken.kind === 28 /* LessThanToken */) {
                                isRightOfOpenTag = true;
                                location = contextToken;
                            }
                            break;
                        case 268 /* JsxAttribute */:
                            switch (previousToken.kind) {
                                case 60 /* EqualsToken */:
                                    isJsxInitializer = true;
                                    break;
                                case 73 /* Identifier */:
                                    // For `<div x=[|f/**/|]`, `parent` will be `x` and `previousToken.parent` will be `f` (which is its own JsxAttribute)
                                    // Note for `<div someBool f>` we don't want to treat this as a jsx inializer, instead it's the attribute name.
                                    if (parent !== previousToken.parent &&
                                        !parent.initializer &&
                                        ts.findChildOfKind(parent, 60 /* EqualsToken */, sourceFile)) {
                                        isJsxInitializer = previousToken;
                                    }
                            }
                            break;
                    }
                }
            }
            var semanticStart = ts.timestamp();
            var completionKind = 5 /* None */;
            var isNewIdentifierLocation = false;
            var keywordFilters = 0 /* None */;
            var symbols = [];
            var symbolToOriginInfoMap = [];
            var symbolToSortTextMap = [];
            if (isRightOfDot) {
                getTypeScriptMemberSymbols();
            }
            else if (isRightOfOpenTag) {
                var tagSymbols = ts.Debug.assertEachDefined(typeChecker.getJsxIntrinsicTagNamesAt(location), "getJsxIntrinsicTagNames() should all be defined");
                tryGetGlobalSymbols();
                symbols = tagSymbols.concat(symbols);
                completionKind = 3 /* MemberLike */;
                keywordFilters = 0 /* None */;
            }
            else if (isStartingCloseTag) {
                var tagName = contextToken.parent.parent.openingElement.tagName;
                var tagSymbol = typeChecker.getSymbolAtLocation(tagName);
                if (tagSymbol) {
                    symbols = [tagSymbol];
                }
                completionKind = 3 /* MemberLike */;
                keywordFilters = 0 /* None */;
            }
            else {
                // For JavaScript or TypeScript, if we're not after a dot, then just try to get the
                // global symbols in scope.  These results should be valid for either language as
                // the set of symbols that can be referenced from this location.
                if (!tryGetGlobalSymbols()) {
                    return undefined;
                }
            }
            log("getCompletionData: Semantic work: " + (ts.timestamp() - semanticStart));
            var contextualType = previousToken && getContextualType(previousToken, position, sourceFile, typeChecker);
            var literals = ts.mapDefined(contextualType && (contextualType.isUnion() ? contextualType.types : [contextualType]), function (t) { return t.isLiteral() ? t.value : undefined; });
            var recommendedCompletion = previousToken && contextualType && getRecommendedCompletion(previousToken, contextualType, typeChecker);
            return {
                kind: 0 /* Data */,
                symbols: symbols,
                completionKind: completionKind,
                isInSnippetScope: isInSnippetScope,
                propertyAccessToConvert: propertyAccessToConvert,
                isNewIdentifierLocation: isNewIdentifierLocation,
                location: location,
                keywordFilters: keywordFilters,
                literals: literals,
                symbolToOriginInfoMap: symbolToOriginInfoMap,
                recommendedCompletion: recommendedCompletion,
                previousToken: previousToken,
                isJsxInitializer: isJsxInitializer,
                insideJsDocTagTypeExpression: insideJsDocTagTypeExpression,
                symbolToSortTextMap: symbolToSortTextMap
            };
            function isTagWithTypeExpression(tag) {
                switch (tag.kind) {
                    case 305 /* JSDocParameterTag */:
                    case 311 /* JSDocPropertyTag */:
                    case 306 /* JSDocReturnTag */:
                    case 308 /* JSDocTypeTag */:
                    case 310 /* JSDocTypedefTag */:
                        return true;
                    default:
                        return false;
                }
            }
            function getTypeScriptMemberSymbols() {
                // Right of dot member completion list
                completionKind = 2 /* PropertyAccess */;
                // Since this is qualified name check its a type node location
                var isImportType = ts.isLiteralImportTypeNode(node);
                var isTypeLocation = insideJsDocTagTypeExpression || (isImportType && !node.isTypeOf) || ts.isPartOfTypeNode(node.parent);
                var isRhsOfImportDeclaration = ts.isInRightSideOfInternalImportEqualsDeclaration(node);
                var allowTypeOrValue = isRhsOfImportDeclaration || (!isTypeLocation && ts.isPossiblyTypeArgumentPosition(contextToken, sourceFile, typeChecker));
                if (ts.isEntityName(node) || isImportType) {
                    var isNamespaceName = ts.isModuleDeclaration(node.parent);
                    if (isNamespaceName)
                        isNewIdentifierLocation = true;
                    var symbol = typeChecker.getSymbolAtLocation(node);
                    if (symbol) {
                        symbol = ts.skipAlias(symbol, typeChecker);
                        if (symbol.flags & (1536 /* Module */ | 384 /* Enum */)) {
                            // Extract module or enum members
                            var exportedSymbols = ts.Debug.assertEachDefined(typeChecker.getExportsOfModule(symbol), "getExportsOfModule() should all be defined");
                            var isValidValueAccess_1 = function (symbol) { return typeChecker.isValidPropertyAccess(isImportType ? node : (node.parent), symbol.name); };
                            var isValidTypeAccess_1 = function (symbol) { return symbolCanBeReferencedAtTypeLocation(symbol); };
                            var isValidAccess = isNamespaceName
                                // At `namespace N.M/**/`, if this is the only declaration of `M`, don't include `M` as a completion.
                                ? function (symbol) { return !!(symbol.flags & 1920 /* Namespace */) && !symbol.declarations.every(function (d) { return d.parent === node.parent; }); }
                                : allowTypeOrValue ?
                                    // Any kind is allowed when dotting off namespace in internal import equals declaration
                                    function (symbol) { return isValidTypeAccess_1(symbol) || isValidValueAccess_1(symbol); } :
                                    isTypeLocation ? isValidTypeAccess_1 : isValidValueAccess_1;
                            for (var _i = 0, exportedSymbols_1 = exportedSymbols; _i < exportedSymbols_1.length; _i++) {
                                var exportedSymbol = exportedSymbols_1[_i];
                                if (isValidAccess(exportedSymbol)) {
                                    symbols.push(exportedSymbol);
                                }
                            }
                            // If the module is merged with a value, we must get the type of the class and add its propertes (for inherited static methods).
                            if (!isTypeLocation &&
                                symbol.declarations &&
                                symbol.declarations.some(function (d) { return d.kind !== 285 /* SourceFile */ && d.kind !== 245 /* ModuleDeclaration */ && d.kind !== 244 /* EnumDeclaration */; })) {
                                addTypeProperties(typeChecker.getTypeOfSymbolAtLocation(symbol, node));
                            }
                            return;
                        }
                    }
                }
                if (ts.isMetaProperty(node) && (node.keywordToken === 96 /* NewKeyword */ || node.keywordToken === 93 /* ImportKeyword */)) {
                    var completion = (node.keywordToken === 96 /* NewKeyword */) ? "target" : "meta";
                    symbols.push(typeChecker.createSymbol(4 /* Property */, ts.escapeLeadingUnderscores(completion)));
                    return;
                }
                if (!isTypeLocation) {
                    addTypeProperties(typeChecker.getTypeAtLocation(node));
                }
            }
            function addTypeProperties(type) {
                isNewIdentifierLocation = !!type.getStringIndexType();
                if (isUncheckedFile) {
                    // In javascript files, for union types, we don't just get the members that
                    // the individual types have in common, we also include all the members that
                    // each individual type has. This is because we're going to add all identifiers
                    // anyways. So we might as well elevate the members that were at least part
                    // of the individual types to a higher status since we know what they are.
                    symbols.push.apply(symbols, getPropertiesForCompletion(type, typeChecker));
                }
                else {
                    for (var _i = 0, _a = type.getApparentProperties(); _i < _a.length; _i++) {
                        var symbol = _a[_i];
                        if (typeChecker.isValidPropertyAccessForCompletions(node.kind === 184 /* ImportType */ ? node : node.parent, type, symbol)) {
                            addPropertySymbol(symbol);
                        }
                    }
                }
            }
            function addPropertySymbol(symbol) {
                // For a computed property with an accessible name like `Symbol.iterator`,
                // we'll add a completion for the *name* `Symbol` instead of for the property.
                // If this is e.g. [Symbol.iterator], add a completion for `Symbol`.
                var computedPropertyName = ts.firstDefined(symbol.declarations, function (decl) { return ts.tryCast(ts.getNameOfDeclaration(decl), ts.isComputedPropertyName); });
                if (computedPropertyName) {
                    var leftMostName = getLeftMostName(computedPropertyName.expression); // The completion is for `Symbol`, not `iterator`.
                    var nameSymbol = leftMostName && typeChecker.getSymbolAtLocation(leftMostName);
                    // If this is nested like for `namespace N { export const sym = Symbol(); }`, we'll add the completion for `N`.
                    var firstAccessibleSymbol = nameSymbol && getFirstSymbolInChain(nameSymbol, contextToken, typeChecker);
                    if (firstAccessibleSymbol && !symbolToOriginInfoMap[ts.getSymbolId(firstAccessibleSymbol)]) {
                        symbols.push(firstAccessibleSymbol);
                        var moduleSymbol = firstAccessibleSymbol.parent;
                        symbolToOriginInfoMap[ts.getSymbolId(firstAccessibleSymbol)] =
                            !moduleSymbol || !ts.isExternalModuleSymbol(moduleSymbol) ? { kind: 1 /* SymbolMemberNoExport */ } : { kind: 2 /* SymbolMemberExport */, moduleSymbol: moduleSymbol, isDefaultExport: false };
                    }
                }
                else {
                    symbols.push(symbol);
                }
            }
            /** Given 'a.b.c', returns 'a'. */
            function getLeftMostName(e) {
                return ts.isIdentifier(e) ? e : ts.isPropertyAccessExpression(e) ? getLeftMostName(e.expression) : undefined;
            }
            function tryGetGlobalSymbols() {
                var result = tryGetObjectLikeCompletionSymbols()
                    || tryGetImportOrExportClauseCompletionSymbols()
                    || tryGetConstructorCompletion()
                    || tryGetClassLikeCompletionSymbols()
                    || tryGetJsxCompletionSymbols()
                    || (getGlobalCompletions(), 1 /* Success */);
                return result === 1 /* Success */;
            }
            function tryGetConstructorCompletion() {
                if (!tryGetConstructorLikeCompletionContainer(contextToken))
                    return 0 /* Continue */;
                // no members, only keywords
                completionKind = 5 /* None */;
                // Declaring new property/method/accessor
                isNewIdentifierLocation = true;
                // Has keywords for constructor parameter
                keywordFilters = 4 /* ConstructorParameterKeywords */;
                return 1 /* Success */;
            }
            function tryGetJsxCompletionSymbols() {
                var jsxContainer = tryGetContainingJsxElement(contextToken);
                // Cursor is inside a JSX self-closing element or opening element
                var attrsType = jsxContainer && typeChecker.getContextualType(jsxContainer.attributes);
                if (!attrsType)
                    return 0 /* Continue */;
                symbols = filterJsxAttributes(getPropertiesForObjectExpression(attrsType, jsxContainer.attributes, typeChecker), jsxContainer.attributes.properties);
                completionKind = 3 /* MemberLike */;
                isNewIdentifierLocation = false;
                return 1 /* Success */;
            }
            function getGlobalCompletions() {
                keywordFilters = tryGetFunctionLikeBodyCompletionContainer(contextToken) ? 5 /* FunctionLikeBodyKeywords */ : 1 /* All */;
                // Get all entities in the current scope.
                completionKind = 1 /* Global */;
                isNewIdentifierLocation = isNewIdentifierDefinitionLocation(contextToken);
                if (previousToken !== contextToken) {
                    ts.Debug.assert(!!previousToken, "Expected 'contextToken' to be defined when different from 'previousToken'.");
                }
                // We need to find the node that will give us an appropriate scope to begin
                // aggregating completion candidates. This is achieved in 'getScopeNode'
                // by finding the first node that encompasses a position, accounting for whether a node
                // is "complete" to decide whether a position belongs to the node.
                //
                // However, at the end of an identifier, we are interested in the scope of the identifier
                // itself, but fall outside of the identifier. For instance:
                //
                //      xyz => x$
                //
                // the cursor is outside of both the 'x' and the arrow function 'xyz => x',
                // so 'xyz' is not returned in our results.
                //
                // We define 'adjustedPosition' so that we may appropriately account for
                // being at the end of an identifier. The intention is that if requesting completion
                // at the end of an identifier, it should be effectively equivalent to requesting completion
                // anywhere inside/at the beginning of the identifier. So in the previous case, the
                // 'adjustedPosition' will work as if requesting completion in the following:
                //
                //      xyz => $x
                //
                // If previousToken !== contextToken, then
                //   - 'contextToken' was adjusted to the token prior to 'previousToken'
                //      because we were at the end of an identifier.
                //   - 'previousToken' is defined.
                var adjustedPosition = previousToken !== contextToken ?
                    previousToken.getStart() :
                    position;
                var scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile;
                isInSnippetScope = isSnippetScope(scopeNode);
                var isTypeOnly = isTypeOnlyCompletion();
                var symbolMeanings = (isTypeOnly ? 0 /* None */ : 67220415 /* Value */) | 67897832 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */;
                symbols = ts.Debug.assertEachDefined(typeChecker.getSymbolsInScope(scopeNode, symbolMeanings), "getSymbolsInScope() should all be defined");
                for (var _i = 0, symbols_2 = symbols; _i < symbols_2.length; _i++) {
                    var symbol = symbols_2[_i];
                    if (!typeChecker.isArgumentsSymbol(symbol) &&
                        !ts.some(symbol.declarations, function (d) { return d.getSourceFile() === sourceFile; })) {
                        symbolToSortTextMap[ts.getSymbolId(symbol)] = SortText.GlobalsOrKeywords;
                    }
                }
                // Need to insert 'this.' before properties of `this` type, so only do that if `includeInsertTextCompletions`
                if (preferences.includeCompletionsWithInsertText && scopeNode.kind !== 285 /* SourceFile */) {
                    var thisType = typeChecker.tryGetThisTypeAt(scopeNode, /*includeGlobalThis*/ false);
                    if (thisType) {
                        for (var _a = 0, _b = getPropertiesForCompletion(thisType, typeChecker); _a < _b.length; _a++) {
                            var symbol = _b[_a];
                            symbolToOriginInfoMap[ts.getSymbolId(symbol)] = { kind: 0 /* ThisType */ };
                            symbols.push(symbol);
                            symbolToSortTextMap[ts.getSymbolId(symbol)] = SortText.SuggestedClassMembers;
                        }
                    }
                }
                if (shouldOfferImportCompletions()) {
                    getSymbolsFromOtherSourceFileExports(symbols, previousToken && ts.isIdentifier(previousToken) ? previousToken.text : "", program.getCompilerOptions().target);
                }
                filterGlobalCompletion(symbols);
            }
            function shouldOfferImportCompletions() {
                // If not already a module, must have modules enabled and not currently be in a commonjs module. (TODO: import completions for commonjs)
                if (!preferences.includeCompletionsForModuleExports)
                    return false;
                // If already using ES6 modules, OK to continue using them.
                if (sourceFile.externalModuleIndicator)
                    return true;
                // If already using commonjs, don't introduce ES6.
                if (sourceFile.commonJsModuleIndicator)
                    return false;
                // If module transpilation is enabled or we're targeting es6 or above, or not emitting, OK.
                if (ts.compilerOptionsIndicateEs6Modules(program.getCompilerOptions()))
                    return true;
                // If some file is using ES6 modules, assume that it's OK to add more.
                return ts.programContainsEs6Modules(program);
            }
            function isSnippetScope(scopeNode) {
                switch (scopeNode.kind) {
                    case 285 /* SourceFile */:
                    case 207 /* TemplateExpression */:
                    case 271 /* JsxExpression */:
                    case 219 /* Block */:
                        return true;
                    default:
                        return ts.isStatement(scopeNode);
                }
            }
            function filterGlobalCompletion(symbols) {
                var isTypeOnly = isTypeOnlyCompletion();
                var allowTypes = isTypeOnly || !isContextTokenValueLocation(contextToken) && ts.isPossiblyTypeArgumentPosition(contextToken, sourceFile, typeChecker);
                if (isTypeOnly)
                    keywordFilters = 6 /* TypeKeywords */;
                ts.filterMutate(symbols, function (symbol) {
                    if (!ts.isSourceFile(location)) {
                        // export = /**/ here we want to get all meanings, so any symbol is ok
                        if (ts.isExportAssignment(location.parent)) {
                            return true;
                        }
                        symbol = ts.skipAlias(symbol, typeChecker);
                        // import m = /**/ <-- It can only access namespace (if typing import = x. this would get member symbols and not namespace)
                        if (ts.isInRightSideOfInternalImportEqualsDeclaration(location)) {
                            return !!(symbol.flags & 1920 /* Namespace */);
                        }
                        if (allowTypes) {
                            // Its a type, but you can reach it by namespace.type as well
                            var symbolAllowedAsType = symbolCanBeReferencedAtTypeLocation(symbol);
                            if (symbolAllowedAsType || isTypeOnly) {
                                return symbolAllowedAsType;
                            }
                        }
                    }
                    // expressions are value space (which includes the value namespaces)
                    return !!(ts.getCombinedLocalAndExportSymbolFlags(symbol) & 67220415 /* Value */);
                });
            }
            function isTypeOnlyCompletion() {
                return insideJsDocTagTypeExpression || !isContextTokenValueLocation(contextToken) && (ts.isPartOfTypeNode(location) || isContextTokenTypeLocation(contextToken));
            }
            function isContextTokenValueLocation(contextToken) {
                return contextToken &&
                    contextToken.kind === 105 /* TypeOfKeyword */ &&
                    (contextToken.parent.kind === 168 /* TypeQuery */ || ts.isTypeOfExpression(contextToken.parent));
            }
            function isContextTokenTypeLocation(contextToken) {
                if (contextToken) {
                    var parentKind = contextToken.parent.kind;
                    switch (contextToken.kind) {
                        case 57 /* ColonToken */:
                            return parentKind === 155 /* PropertyDeclaration */ ||
                                parentKind === 154 /* PropertySignature */ ||
                                parentKind === 152 /* Parameter */ ||
                                parentKind === 238 /* VariableDeclaration */ ||
                                ts.isFunctionLikeKind(parentKind);
                        case 60 /* EqualsToken */:
                            return parentKind === 243 /* TypeAliasDeclaration */;
                        case 120 /* AsKeyword */:
                            return parentKind === 213 /* AsExpression */;
                        case 87 /* ExtendsKeyword */:
                            return parentKind === 151 /* TypeParameter */;
                    }
                }
                return false;
            }
            /** True if symbol is a type or a module containing at least one type. */
            function symbolCanBeReferencedAtTypeLocation(symbol, seenModules) {
                if (seenModules === void 0) { seenModules = ts.createMap(); }
                var sym = ts.skipAlias(symbol.exportSymbol || symbol, typeChecker);
                return !!(sym.flags & 67897832 /* Type */) ||
                    !!(sym.flags & 1536 /* Module */) &&
                        ts.addToSeen(seenModules, ts.getSymbolId(sym)) &&
                        typeChecker.getExportsOfModule(sym).some(function (e) { return symbolCanBeReferencedAtTypeLocation(e, seenModules); });
            }
            function getSymbolsFromOtherSourceFileExports(symbols, tokenText, target) {
                var tokenTextLowerCase = tokenText.toLowerCase();
                var seenResolvedModules = ts.createMap();
                ts.codefix.forEachExternalModuleToImportFrom(typeChecker, sourceFile, program.getSourceFiles(), function (moduleSymbol) {
                    // Perf -- ignore other modules if this is a request for details
                    if (detailsEntryId && detailsEntryId.source && ts.stripQuotes(moduleSymbol.name) !== detailsEntryId.source) {
                        return;
                    }
                    var resolvedModuleSymbol = typeChecker.resolveExternalModuleSymbol(moduleSymbol);
                    // resolvedModuleSymbol may be a namespace. A namespace may be `export =` by multiple module declarations, but only keep the first one.
                    if (!ts.addToSeen(seenResolvedModules, ts.getSymbolId(resolvedModuleSymbol))) {
                        return;
                    }
                    if (resolvedModuleSymbol !== moduleSymbol &&
                        // Don't add another completion for `export =` of a symbol that's already global.
                        // So in `declare namespace foo {} declare module "foo" { export = foo; }`, there will just be the global completion for `foo`.
                        ts.some(resolvedModuleSymbol.declarations, function (d) { return !!d.getSourceFile().externalModuleIndicator; })) {
                        symbols.push(resolvedModuleSymbol);
                        symbolToSortTextMap[ts.getSymbolId(resolvedModuleSymbol)] = SortText.AutoImportSuggestions;
                        symbolToOriginInfoMap[ts.getSymbolId(resolvedModuleSymbol)] = { kind: 3 /* Export */, moduleSymbol: moduleSymbol, isDefaultExport: false };
                    }
                    for (var _i = 0, _a = typeChecker.getExportsOfModule(moduleSymbol); _i < _a.length; _i++) {
                        var symbol = _a[_i];
                        // Don't add a completion for a re-export, only for the original.
                        // The actual import fix might end up coming from a re-export -- we don't compute that until getting completion details.
                        // This is just to avoid adding duplicate completion entries.
                        //
                        // If `symbol.parent !== ...`, this is an `export * from "foo"` re-export. Those don't create new symbols.
                        if (typeChecker.getMergedSymbol(symbol.parent) !== resolvedModuleSymbol
                            || ts.some(symbol.declarations, function (d) {
                                // If `!!d.name.originalKeywordKind`, this is `export { _break as break };` -- skip this and prefer the keyword completion.
                                // If `!!d.parent.parent.moduleSpecifier`, this is `export { foo } from "foo"` re-export, which creates a new symbol (thus isn't caught by the first check).
                                return ts.isExportSpecifier(d) && (d.propertyName ? ts.isIdentifierANonContextualKeyword(d.name) : !!d.parent.parent.moduleSpecifier);
                            })) {
                            continue;
                        }
                        var isDefaultExport = symbol.escapedName === "default" /* Default */;
                        if (isDefaultExport) {
                            symbol = ts.getLocalSymbolForExportDefault(symbol) || symbol;
                        }
                        var origin = { kind: 3 /* Export */, moduleSymbol: moduleSymbol, isDefaultExport: isDefaultExport };
                        if (detailsEntryId || stringContainsCharactersInOrder(getSymbolName(symbol, origin, target).toLowerCase(), tokenTextLowerCase)) {
                            symbols.push(symbol);
                            symbolToSortTextMap[ts.getSymbolId(symbol)] = SortText.AutoImportSuggestions;
                            symbolToOriginInfoMap[ts.getSymbolId(symbol)] = origin;
                        }
                    }
                });
            }
            /**
             * True if you could remove some characters in `a` to get `b`.
             * E.g., true for "abcdef" and "bdf".
             * But not true for "abcdef" and "dbf".
             */
            function stringContainsCharactersInOrder(str, characters) {
                if (characters.length === 0) {
                    return true;
                }
                var characterIndex = 0;
                for (var strIndex = 0; strIndex < str.length; strIndex++) {
                    if (str.charCodeAt(strIndex) === characters.charCodeAt(characterIndex)) {
                        characterIndex++;
                        if (characterIndex === characters.length) {
                            return true;
                        }
                    }
                }
                // Did not find all characters
                return false;
            }
            /**
             * Finds the first node that "embraces" the position, so that one may
             * accurately aggregate locals from the closest containing scope.
             */
            function getScopeNode(initialToken, position, sourceFile) {
                var scope = initialToken;
                while (scope && !ts.positionBelongsToNode(scope, position, sourceFile)) {
                    scope = scope.parent;
                }
                return scope;
            }
            function isCompletionListBlocker(contextToken) {
                var start = ts.timestamp();
                var result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) ||
                    isSolelyIdentifierDefinitionLocation(contextToken) ||
                    isDotOfNumericLiteral(contextToken) ||
                    isInJsxText(contextToken);
                log("getCompletionsAtPosition: isCompletionListBlocker: " + (ts.timestamp() - start));
                return result;
            }
            function isInJsxText(contextToken) {
                if (contextToken.kind === 11 /* JsxText */) {
                    return true;
                }
                if (contextToken.kind === 30 /* GreaterThanToken */ && contextToken.parent) {
                    if (contextToken.parent.kind === 263 /* JsxOpeningElement */) {
                        return true;
                    }
                    if (contextToken.parent.kind === 264 /* JsxClosingElement */ || contextToken.parent.kind === 262 /* JsxSelfClosingElement */) {
                        return !!contextToken.parent.parent && contextToken.parent.parent.kind === 261 /* JsxElement */;
                    }
                }
                return false;
            }
            function isNewIdentifierDefinitionLocation(previousToken) {
                if (previousToken) {
                    var containingNodeKind = previousToken.parent.kind;
                    // Previous token may have been a keyword that was converted to an identifier.
                    switch (keywordForNode(previousToken)) {
                        case 27 /* CommaToken */:
                            return containingNodeKind === 192 /* CallExpression */ // func( a, |
                                || containingNodeKind === 158 /* Constructor */ // constructor( a, |   /* public, protected, private keywords are allowed here, so show completion */
                                || containingNodeKind === 193 /* NewExpression */ // new C(a, |
                                || containingNodeKind === 188 /* ArrayLiteralExpression */ // [a, |
                                || containingNodeKind === 205 /* BinaryExpression */ // const x = (a, |
                                || containingNodeKind === 166 /* FunctionType */; // var x: (s: string, list|
                        case 20 /* OpenParenToken */:
                            return containingNodeKind === 192 /* CallExpression */ // func( |
                                || containingNodeKind === 158 /* Constructor */ // constructor( |
                                || containingNodeKind === 193 /* NewExpression */ // new C(a|
                                || containingNodeKind === 196 /* ParenthesizedExpression */ // const x = (a|
                                || containingNodeKind === 178 /* ParenthesizedType */; // function F(pred: (a| /* this can become an arrow function, where 'a' is the argument */
                        case 22 /* OpenBracketToken */:
                            return containingNodeKind === 188 /* ArrayLiteralExpression */ // [ |
                                || containingNodeKind === 163 /* IndexSignature */ // [ | : string ]
                                || containingNodeKind === 150 /* ComputedPropertyName */; // [ |    /* this can become an index signature */
                        case 131 /* ModuleKeyword */: // module |
                        case 132 /* NamespaceKeyword */: // namespace |
                            return true;
                        case 24 /* DotToken */:
                            return containingNodeKind === 245 /* ModuleDeclaration */; // module A.|
                        case 18 /* OpenBraceToken */:
                            return containingNodeKind === 241 /* ClassDeclaration */; // class A{ |
                        case 60 /* EqualsToken */:
                            return containingNodeKind === 238 /* VariableDeclaration */ // const x = a|
                                || containingNodeKind === 205 /* BinaryExpression */; // x = a|
                        case 15 /* TemplateHead */:
                            return containingNodeKind === 207 /* TemplateExpression */; // `aa ${|
                        case 16 /* TemplateMiddle */:
                            return containingNodeKind === 217 /* TemplateSpan */; // `aa ${10} dd ${|
                        case 116 /* PublicKeyword */:
                        case 114 /* PrivateKeyword */:
                        case 115 /* ProtectedKeyword */:
                            return containingNodeKind === 155 /* PropertyDeclaration */; // class A{ public |
                    }
                }
                return false;
            }
            function isInStringOrRegularExpressionOrTemplateLiteral(contextToken) {
                // To be "in" one of these literals, the position has to be:
                //   1. entirely within the token text.
                //   2. at the end position of an unterminated token.
                //   3. at the end of a regular expression (due to trailing flags like '/foo/g').
                return (ts.isRegularExpressionLiteral(contextToken) || ts.isStringTextContainingNode(contextToken)) && (ts.rangeContainsPositionExclusive(ts.createTextRangeFromSpan(ts.createTextSpanFromNode(contextToken)), position) ||
                    position === contextToken.end && (!!contextToken.isUnterminated || ts.isRegularExpressionLiteral(contextToken)));
            }
            /**
             * Aggregates relevant symbols for completion in object literals and object binding patterns.
             * Relevant symbols are stored in the captured 'symbols' variable.
             *
             * @returns true if 'symbols' was successfully populated; false otherwise.
             */
            function tryGetObjectLikeCompletionSymbols() {
                var objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken);
                if (!objectLikeContainer)
                    return 0 /* Continue */;
                // We're looking up possible property names from contextual/inferred/declared type.
                completionKind = 0 /* ObjectPropertyDeclaration */;
                var typeMembers;
                var existingMembers;
                if (objectLikeContainer.kind === 189 /* ObjectLiteralExpression */) {
                    var typeForObject = typeChecker.getContextualType(objectLikeContainer);
                    if (!typeForObject)
                        return 2 /* Fail */;
                    isNewIdentifierLocation = ts.hasIndexSignature(typeForObject);
                    typeMembers = getPropertiesForObjectExpression(typeForObject, objectLikeContainer, typeChecker);
                    existingMembers = objectLikeContainer.properties;
                }
                else {
                    ts.Debug.assert(objectLikeContainer.kind === 185 /* ObjectBindingPattern */);
                    // We are *only* completing on properties from the type being destructured.
                    isNewIdentifierLocation = false;
                    var rootDeclaration = ts.getRootDeclaration(objectLikeContainer.parent);
                    if (!ts.isVariableLike(rootDeclaration))
                        return ts.Debug.fail("Root declaration is not variable-like.");
                    // We don't want to complete using the type acquired by the shape
                    // of the binding pattern; we are only interested in types acquired
                    // through type declaration or inference.
                    // Also proceed if rootDeclaration is a parameter and if its containing function expression/arrow function is contextually typed -
                    // type of parameter will flow in from the contextual type of the function
                    var canGetType = ts.hasInitializer(rootDeclaration) || ts.hasType(rootDeclaration) || rootDeclaration.parent.parent.kind === 228 /* ForOfStatement */;
                    if (!canGetType && rootDeclaration.kind === 152 /* Parameter */) {
                        if (ts.isExpression(rootDeclaration.parent)) {
                            canGetType = !!typeChecker.getContextualType(rootDeclaration.parent);
                        }
                        else if (rootDeclaration.parent.kind === 157 /* MethodDeclaration */ || rootDeclaration.parent.kind === 160 /* SetAccessor */) {
                            canGetType = ts.isExpression(rootDeclaration.parent.parent) && !!typeChecker.getContextualType(rootDeclaration.parent.parent);
                        }
                    }
                    if (canGetType) {
                        var typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
                        if (!typeForObject)
                            return 2 /* Fail */;
                        // In a binding pattern, get only known properties. Everywhere else we will get all possible properties.
                        typeMembers = typeChecker.getPropertiesOfType(typeForObject).filter(function (symbol) { return !(ts.getDeclarationModifierFlagsFromSymbol(symbol) & 24 /* NonPublicAccessibilityModifier */); });
                        existingMembers = objectLikeContainer.elements;
                    }
                }
                if (typeMembers && typeMembers.length > 0) {
                    // Add filtered items to the completion list
                    symbols = filterObjectMembersList(typeMembers, ts.Debug.assertDefined(existingMembers));
                }
                return 1 /* Success */;
            }
            /**
             * Aggregates relevant symbols for completion in import clauses and export clauses
             * whose declarations have a module specifier; for instance, symbols will be aggregated for
             *
             *      import { | } from "moduleName";
             *      export { a as foo, | } from "moduleName";
             *
             * but not for
             *
             *      export { | };
             *
             * Relevant symbols are stored in the captured 'symbols' variable.
             *
             * @returns true if 'symbols' was successfully populated; false otherwise.
             */
            function tryGetImportOrExportClauseCompletionSymbols() {
                // `import { |` or `import { a as 0, | }`
                var namedImportsOrExports = contextToken && (contextToken.kind === 18 /* OpenBraceToken */ || contextToken.kind === 27 /* CommaToken */)
                    ? ts.tryCast(contextToken.parent, ts.isNamedImportsOrExports) : undefined;
                if (!namedImportsOrExports)
                    return 0 /* Continue */;
                // cursor is in an import clause
                // try to show exported member for imported module
                var moduleSpecifier = (namedImportsOrExports.kind === 253 /* NamedImports */ ? namedImportsOrExports.parent.parent : namedImportsOrExports.parent).moduleSpecifier;
                var moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(moduleSpecifier); // TODO: GH#18217
                if (!moduleSpecifierSymbol)
                    return 2 /* Fail */;
                completionKind = 3 /* MemberLike */;
                isNewIdentifierLocation = false;
                var exports = typeChecker.getExportsAndPropertiesOfModule(moduleSpecifierSymbol);
                var existing = ts.arrayToSet(namedImportsOrExports.elements, function (n) { return isCurrentlyEditingNode(n) ? undefined : (n.propertyName || n.name).escapedText; });
                symbols = exports.filter(function (e) { return e.escapedName !== "default" /* Default */ && !existing.get(e.escapedName); });
                return 1 /* Success */;
            }
            /**
             * Aggregates relevant symbols for completion in class declaration
             * Relevant symbols are stored in the captured 'symbols' variable.
             */
            function tryGetClassLikeCompletionSymbols() {
                var decl = tryGetObjectTypeDeclarationCompletionContainer(sourceFile, contextToken, location);
                if (!decl)
                    return 0 /* Continue */;
                // We're looking up possible property names from parent type.
                completionKind = 3 /* MemberLike */;
                // Declaring new property/method/accessor
                isNewIdentifierLocation = true;
                keywordFilters = contextToken.kind === 40 /* AsteriskToken */ ? 0 /* None */ :
                    ts.isClassLike(decl) ? 2 /* ClassElementKeywords */ : 3 /* InterfaceElementKeywords */;
                // If you're in an interface you don't want to repeat things from super-interface. So just stop here.
                if (!ts.isClassLike(decl))
                    return 1 /* Success */;
                var classElement = contextToken.parent;
                var classElementModifierFlags = ts.isClassElement(classElement) ? ts.getModifierFlags(classElement) : 0 /* None */;
                // If this is context token is not something we are editing now, consider if this would lead to be modifier
                if (contextToken.kind === 73 /* Identifier */ && !isCurrentlyEditingNode(contextToken)) {
                    switch (contextToken.getText()) {
                        case "private":
                            classElementModifierFlags = classElementModifierFlags | 8 /* Private */;
                            break;
                        case "static":
                            classElementModifierFlags = classElementModifierFlags | 32 /* Static */;
                            break;
                    }
                }
                // No member list for private methods
                if (!(classElementModifierFlags & 8 /* Private */)) {
                    // List of property symbols of base type that are not private and already implemented
                    var baseSymbols = ts.flatMap(ts.getAllSuperTypeNodes(decl), function (baseTypeNode) {
                        var type = typeChecker.getTypeAtLocation(baseTypeNode);
                        return type && typeChecker.getPropertiesOfType(classElementModifierFlags & 32 /* Static */ ? typeChecker.getTypeOfSymbolAtLocation(type.symbol, decl) : type);
                    });
                    symbols = filterClassMembersList(baseSymbols, decl.members, classElementModifierFlags);
                }
                return 1 /* Success */;
            }
            /**
             * Returns the immediate owning object literal or binding pattern of a context token,
             * on the condition that one exists and that the context implies completion should be given.
             */
            function tryGetObjectLikeCompletionContainer(contextToken) {
                if (contextToken) {
                    var parent = contextToken.parent;
                    switch (contextToken.kind) {
                        case 18 /* OpenBraceToken */: // const x = { |
                        case 27 /* CommaToken */: // const x = { a: 0, |
                            if (ts.isObjectLiteralExpression(parent) || ts.isObjectBindingPattern(parent)) {
                                return parent;
                            }
                            break;
                        case 40 /* AsteriskToken */:
                            return ts.isMethodDeclaration(parent) ? ts.tryCast(parent.parent, ts.isObjectLiteralExpression) : undefined;
                        case 73 /* Identifier */:
                            return contextToken.text === "async" && ts.isShorthandPropertyAssignment(contextToken.parent)
                                ? contextToken.parent.parent : undefined;
                    }
                }
                return undefined;
            }
            function isConstructorParameterCompletion(node) {
                return !!node.parent && ts.isParameter(node.parent) && ts.isConstructorDeclaration(node.parent.parent)
                    && (ts.isParameterPropertyModifier(node.kind) || ts.isDeclarationName(node));
            }
            /**
             * Returns the immediate owning class declaration of a context token,
             * on the condition that one exists and that the context implies completion should be given.
             */
            function tryGetConstructorLikeCompletionContainer(contextToken) {
                if (contextToken) {
                    var parent = contextToken.parent;
                    switch (contextToken.kind) {
                        case 20 /* OpenParenToken */:
                        case 27 /* CommaToken */:
                            return ts.isConstructorDeclaration(contextToken.parent) ? contextToken.parent : undefined;
                        default:
                            if (isConstructorParameterCompletion(contextToken)) {
                                return parent.parent;
                            }
                    }
                }
                return undefined;
            }
            function tryGetFunctionLikeBodyCompletionContainer(contextToken) {
                if (contextToken) {
                    var prev_1;
                    var container = ts.findAncestor(contextToken.parent, function (node) {
                        if (ts.isClassLike(node)) {
                            return "quit";
                        }
                        if (ts.isFunctionLikeDeclaration(node) && prev_1 === node.body) {
                            return true;
                        }
                        prev_1 = node;
                        return false;
                    });
                    return container && container;
                }
            }
            function tryGetContainingJsxElement(contextToken) {
                if (contextToken) {
                    var parent = contextToken.parent;
                    switch (contextToken.kind) {
                        case 30 /* GreaterThanToken */: // End of a type argument list
                        case 29 /* LessThanSlashToken */:
                        case 42 /* SlashToken */:
                        case 73 /* Identifier */:
                        case 190 /* PropertyAccessExpression */:
                        case 269 /* JsxAttributes */:
                        case 268 /* JsxAttribute */:
                        case 270 /* JsxSpreadAttribute */:
                            if (parent && (parent.kind === 262 /* JsxSelfClosingElement */ || parent.kind === 263 /* JsxOpeningElement */)) {
                                if (contextToken.kind === 30 /* GreaterThanToken */) {
                                    var precedingToken = ts.findPrecedingToken(contextToken.pos, sourceFile, /*startNode*/ undefined);
                                    if (!parent.typeArguments || (precedingToken && precedingToken.kind === 42 /* SlashToken */))
                                        break;
                                }
                                return parent;
                            }
                            else if (parent.kind === 268 /* JsxAttribute */) {
                                // Currently we parse JsxOpeningLikeElement as:
                                //      JsxOpeningLikeElement
                                //          attributes: JsxAttributes
                                //             properties: NodeArray<JsxAttributeLike>
                                return parent.parent.parent;
                            }
                            break;
                        // The context token is the closing } or " of an attribute, which means
                        // its parent is a JsxExpression, whose parent is a JsxAttribute,
                        // whose parent is a JsxOpeningLikeElement
                        case 10 /* StringLiteral */:
                            if (parent && ((parent.kind === 268 /* JsxAttribute */) || (parent.kind === 270 /* JsxSpreadAttribute */))) {
                                // Currently we parse JsxOpeningLikeElement as:
                                //      JsxOpeningLikeElement
                                //          attributes: JsxAttributes
                                //             properties: NodeArray<JsxAttributeLike>
                                return parent.parent.parent;
                            }
                            break;
                        case 19 /* CloseBraceToken */:
                            if (parent &&
                                parent.kind === 271 /* JsxExpression */ &&
                                parent.parent && parent.parent.kind === 268 /* JsxAttribute */) {
                                // Currently we parse JsxOpeningLikeElement as:
                                //      JsxOpeningLikeElement
                                //          attributes: JsxAttributes
                                //             properties: NodeArray<JsxAttributeLike>
                                //                  each JsxAttribute can have initializer as JsxExpression
                                return parent.parent.parent.parent;
                            }
                            if (parent && parent.kind === 270 /* JsxSpreadAttribute */) {
                                // Currently we parse JsxOpeningLikeElement as:
                                //      JsxOpeningLikeElement
                                //          attributes: JsxAttributes
                                //             properties: NodeArray<JsxAttributeLike>
                                return parent.parent.parent;
                            }
                            break;
                    }
                }
                return undefined;
            }
            /**
             * @returns true if we are certain that the currently edited location must define a new location; false otherwise.
             */
            function isSolelyIdentifierDefinitionLocation(contextToken) {
                var parent = contextToken.parent;
                var containingNodeKind = parent.kind;
                switch (contextToken.kind) {
                    case 27 /* CommaToken */:
                        return containingNodeKind === 238 /* VariableDeclaration */ ||
                            containingNodeKind === 239 /* VariableDeclarationList */ ||
                            containingNodeKind === 220 /* VariableStatement */ ||
                            containingNodeKind === 244 /* EnumDeclaration */ || // enum a { foo, |
                            isFunctionLikeButNotConstructor(containingNodeKind) ||
                            containingNodeKind === 242 /* InterfaceDeclaration */ || // interface A<T, |
                            containingNodeKind === 186 /* ArrayBindingPattern */ || // var [x, y|
                            containingNodeKind === 243 /* TypeAliasDeclaration */ || // type Map, K, |
                            // class A<T, |
                            // var C = class D<T, |
                            (ts.isClassLike(parent) &&
                                !!parent.typeParameters &&
                                parent.typeParameters.end >= contextToken.pos);
                    case 24 /* DotToken */:
                        return containingNodeKind === 186 /* ArrayBindingPattern */; // var [.|
                    case 57 /* ColonToken */:
                        return containingNodeKind === 187 /* BindingElement */; // var {x :html|
                    case 22 /* OpenBracketToken */:
                        return containingNodeKind === 186 /* ArrayBindingPattern */; // var [x|
                    case 20 /* OpenParenToken */:
                        return containingNodeKind === 275 /* CatchClause */ ||
                            isFunctionLikeButNotConstructor(containingNodeKind);
                    case 18 /* OpenBraceToken */:
                        return containingNodeKind === 244 /* EnumDeclaration */; // enum a { |
                    case 28 /* LessThanToken */:
                        return containingNodeKind === 241 /* ClassDeclaration */ || // class A< |
                            containingNodeKind === 210 /* ClassExpression */ || // var C = class D< |
                            containingNodeKind === 242 /* InterfaceDeclaration */ || // interface A< |
                            containingNodeKind === 243 /* TypeAliasDeclaration */ || // type List< |
                            ts.isFunctionLikeKind(containingNodeKind);
                    case 117 /* StaticKeyword */:
                        return containingNodeKind === 155 /* PropertyDeclaration */ && !ts.isClassLike(parent.parent);
                    case 25 /* DotDotDotToken */:
                        return containingNodeKind === 152 /* Parameter */ ||
                            (!!parent.parent && parent.parent.kind === 186 /* ArrayBindingPattern */); // var [...z|
                    case 116 /* PublicKeyword */:
                    case 114 /* PrivateKeyword */:
                    case 115 /* ProtectedKeyword */:
                        return containingNodeKind === 152 /* Parameter */ && !ts.isConstructorDeclaration(parent.parent);
                    case 120 /* AsKeyword */:
                        return containingNodeKind === 254 /* ImportSpecifier */ ||
                            containingNodeKind === 258 /* ExportSpecifier */ ||
                            containingNodeKind === 252 /* NamespaceImport */;
                    case 127 /* GetKeyword */:
                    case 138 /* SetKeyword */:
                        return !isFromObjectTypeDeclaration(contextToken);
                    case 77 /* ClassKeyword */:
                    case 85 /* EnumKeyword */:
                    case 111 /* InterfaceKeyword */:
                    case 91 /* FunctionKeyword */:
                    case 106 /* VarKeyword */:
                    case 93 /* ImportKeyword */:
                    case 112 /* LetKeyword */:
                    case 78 /* ConstKeyword */:
                    case 118 /* YieldKeyword */:
                    case 141 /* TypeKeyword */: // type htm|
                        return true;
                    case 40 /* AsteriskToken */:
                        return ts.isFunctionLike(contextToken.parent) && !ts.isMethodDeclaration(contextToken.parent);
                }
                // If the previous token is keyword correspoding to class member completion keyword
                // there will be completion available here
                if (isClassMemberCompletionKeyword(keywordForNode(contextToken)) && isFromObjectTypeDeclaration(contextToken)) {
                    return false;
                }
                if (isConstructorParameterCompletion(contextToken)) {
                    // constructor parameter completion is available only if
                    // - its modifier of the constructor parameter or
                    // - its name of the parameter and not being edited
                    // eg. constructor(a |<- this shouldnt show completion
                    if (!ts.isIdentifier(contextToken) ||
                        ts.isParameterPropertyModifier(keywordForNode(contextToken)) ||
                        isCurrentlyEditingNode(contextToken)) {
                        return false;
                    }
                }
                // Previous token may have been a keyword that was converted to an identifier.
                switch (keywordForNode(contextToken)) {
                    case 119 /* AbstractKeyword */:
                    case 77 /* ClassKeyword */:
                    case 78 /* ConstKeyword */:
                    case 126 /* DeclareKeyword */:
                    case 85 /* EnumKeyword */:
                    case 91 /* FunctionKeyword */:
                    case 111 /* InterfaceKeyword */:
                    case 112 /* LetKeyword */:
                    case 114 /* PrivateKeyword */:
                    case 115 /* ProtectedKeyword */:
                    case 116 /* PublicKeyword */:
                    case 117 /* StaticKeyword */:
                    case 106 /* VarKeyword */:
                    case 118 /* YieldKeyword */:
                        return true;
                    case 122 /* AsyncKeyword */:
                        return ts.isPropertyDeclaration(contextToken.parent);
                }
                return ts.isDeclarationName(contextToken)
                    && !ts.isJsxAttribute(contextToken.parent)
                    // Don't block completions if we're in `class C /**/`, because we're *past* the end of the identifier and might want to complete `extends`.
                    // If `contextToken !== previousToken`, this is `class C ex/**/`.
                    && !(ts.isClassLike(contextToken.parent) && (contextToken !== previousToken || position > previousToken.end));
            }
            function isFunctionLikeButNotConstructor(kind) {
                return ts.isFunctionLikeKind(kind) && kind !== 158 /* Constructor */;
            }
            function isDotOfNumericLiteral(contextToken) {
                if (contextToken.kind === 8 /* NumericLiteral */) {
                    var text = contextToken.getFullText();
                    return text.charAt(text.length - 1) === ".";
                }
                return false;
            }
            /**
             * Filters out completion suggestions for named imports or exports.
             *
             * @returns Symbols to be suggested in an object binding pattern or object literal expression, barring those whose declarations
             *          do not occur at the current position and have not otherwise been typed.
             */
            function filterObjectMembersList(contextualMemberSymbols, existingMembers) {
                if (existingMembers.length === 0) {
                    return contextualMemberSymbols;
                }
                var existingMemberNames = ts.createUnderscoreEscapedMap();
                for (var _i = 0, existingMembers_1 = existingMembers; _i < existingMembers_1.length; _i++) {
                    var m = existingMembers_1[_i];
                    // Ignore omitted expressions for missing members
                    if (m.kind !== 276 /* PropertyAssignment */ &&
                        m.kind !== 277 /* ShorthandPropertyAssignment */ &&
                        m.kind !== 187 /* BindingElement */ &&
                        m.kind !== 157 /* MethodDeclaration */ &&
                        m.kind !== 159 /* GetAccessor */ &&
                        m.kind !== 160 /* SetAccessor */) {
                        continue;
                    }
                    // If this is the current item we are editing right now, do not filter it out
                    if (isCurrentlyEditingNode(m)) {
                        continue;
                    }
                    var existingName = void 0;
                    if (ts.isBindingElement(m) && m.propertyName) {
                        // include only identifiers in completion list
                        if (m.propertyName.kind === 73 /* Identifier */) {
                            existingName = m.propertyName.escapedText;
                        }
                    }
                    else {
                        // TODO: Account for computed property name
                        // NOTE: if one only performs this step when m.name is an identifier,
                        // things like '__proto__' are not filtered out.
                        var name = ts.getNameOfDeclaration(m);
                        existingName = name && ts.isPropertyNameLiteral(name) ? ts.getEscapedTextOfIdentifierOrLiteral(name) : undefined;
                    }
                    existingMemberNames.set(existingName, true); // TODO: GH#18217
                }
                return contextualMemberSymbols.filter(function (m) { return !existingMemberNames.get(m.escapedName); });
            }
            /**
             * Filters out completion suggestions for class elements.
             *
             * @returns Symbols to be suggested in an class element depending on existing memebers and symbol flags
             */
            function filterClassMembersList(baseSymbols, existingMembers, currentClassElementModifierFlags) {
                var existingMemberNames = ts.createUnderscoreEscapedMap();
                for (var _i = 0, existingMembers_2 = existingMembers; _i < existingMembers_2.length; _i++) {
                    var m = existingMembers_2[_i];
                    // Ignore omitted expressions for missing members
                    if (m.kind !== 155 /* PropertyDeclaration */ &&
                        m.kind !== 157 /* MethodDeclaration */ &&
                        m.kind !== 159 /* GetAccessor */ &&
                        m.kind !== 160 /* SetAccessor */) {
                        continue;
                    }
                    // If this is the current item we are editing right now, do not filter it out
                    if (isCurrentlyEditingNode(m)) {
                        continue;
                    }
                    // Dont filter member even if the name matches if it is declared private in the list
                    if (ts.hasModifier(m, 8 /* Private */)) {
                        continue;
                    }
                    // do not filter it out if the static presence doesnt match
                    if (ts.hasModifier(m, 32 /* Static */) !== !!(currentClassElementModifierFlags & 32 /* Static */)) {
                        continue;
                    }
                    var existingName = ts.getPropertyNameForPropertyNameNode(m.name);
                    if (existingName) {
                        existingMemberNames.set(existingName, true);
                    }
                }
                return baseSymbols.filter(function (propertySymbol) {
                    return !existingMemberNames.has(propertySymbol.escapedName) &&
                        !!propertySymbol.declarations &&
                        !(ts.getDeclarationModifierFlagsFromSymbol(propertySymbol) & 8 /* Private */);
                });
            }
            /**
             * Filters out completion suggestions from 'symbols' according to existing JSX attributes.
             *
             * @returns Symbols to be suggested in a JSX element, barring those whose attributes
             *          do not occur at the current position and have not otherwise been typed.
             */
            function filterJsxAttributes(symbols, attributes) {
                var seenNames = ts.createUnderscoreEscapedMap();
                for (var _i = 0, attributes_1 = attributes; _i < attributes_1.length; _i++) {
                    var attr = attributes_1[_i];
                    // If this is the current item we are editing right now, do not filter it out
                    if (isCurrentlyEditingNode(attr)) {
                        continue;
                    }
                    if (attr.kind === 268 /* JsxAttribute */) {
                        seenNames.set(attr.name.escapedText, true);
                    }
                }
                return symbols.filter(function (a) { return !seenNames.get(a.escapedName); });
            }
            function isCurrentlyEditingNode(node) {
                return node.getStart(sourceFile) <= position && position <= node.getEnd();
            }
        }
        function getCompletionEntryDisplayNameForSymbol(symbol, target, origin, kind) {
            var name = getSymbolName(symbol, origin, target);
            if (name === undefined
                // If the symbol is external module, don't show it in the completion list
                // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there)
                || symbol.flags & 1536 /* Module */ && ts.startsWithQuote(name)
                // If the symbol is the internal name of an ES symbol, it is not a valid entry. Internal names for ES symbols start with "__@"
                || ts.isKnownSymbol(symbol)) {
                return undefined;
            }
            var validIdentifierResult = { name: name, needsConvertPropertyAccess: false };
            if (ts.isIdentifierText(name, target))
                return validIdentifierResult;
            switch (kind) {
                case 3 /* MemberLike */:
                    return undefined;
                case 0 /* ObjectPropertyDeclaration */:
                    // TODO: GH#18169
                    return { name: JSON.stringify(name), needsConvertPropertyAccess: false };
                case 2 /* PropertyAccess */:
                case 1 /* Global */: // For a 'this.' completion it will be in a global context, but may have a non-identifier name.
                    // Don't add a completion for a name starting with a space. See https://github.com/Microsoft/TypeScript/pull/20547
                    return name.charCodeAt(0) === 32 /* space */ ? undefined : { name: name, needsConvertPropertyAccess: true };
                case 5 /* None */:
                case 4 /* String */:
                    return validIdentifierResult;
                default:
                    ts.Debug.assertNever(kind);
            }
        }
        // A cache of completion entries for keywords, these do not change between sessions
        var _keywordCompletions = [];
        var allKeywordsCompletions = ts.memoize(function () {
            var res = [];
            for (var i = 74 /* FirstKeyword */; i <= 148 /* LastKeyword */; i++) {
                res.push({
                    name: ts.tokenToString(i),
                    kind: "keyword" /* keyword */,
                    kindModifiers: "" /* none */,
                    sortText: SortText.GlobalsOrKeywords
                });
            }
            return res;
        });
        function getKeywordCompletions(keywordFilter, filterOutTsOnlyKeywords) {
            if (!filterOutTsOnlyKeywords)
                return getTypescriptKeywordCompletions(keywordFilter);
            var index = keywordFilter + 6 /* Last */ + 1;
            return _keywordCompletions[index] ||
                (_keywordCompletions[index] = getTypescriptKeywordCompletions(keywordFilter)
                    .filter(function (entry) { return !isTypeScriptOnlyKeyword(ts.stringToToken(entry.name)); }));
        }
        function getTypescriptKeywordCompletions(keywordFilter) {
            return _keywordCompletions[keywordFilter] || (_keywordCompletions[keywordFilter] = allKeywordsCompletions().filter(function (entry) {
                var kind = ts.stringToToken(entry.name);
                switch (keywordFilter) {
                    case 0 /* None */:
                        return false;
                    case 1 /* All */:
                        return kind === 122 /* AsyncKeyword */ || 123 /* AwaitKeyword */ || !ts.isContextualKeyword(kind) && !isClassMemberCompletionKeyword(kind) || kind === 126 /* DeclareKeyword */ || kind === 131 /* ModuleKeyword */
                            || ts.isTypeKeyword(kind) && kind !== 142 /* UndefinedKeyword */;
                    case 2 /* ClassElementKeywords */:
                        return isClassMemberCompletionKeyword(kind);
                    case 3 /* InterfaceElementKeywords */:
                        return isInterfaceOrTypeLiteralCompletionKeyword(kind);
                    case 4 /* ConstructorParameterKeywords */:
                        return ts.isParameterPropertyModifier(kind);
                    case 5 /* FunctionLikeBodyKeywords */:
                        return isFunctionLikeBodyKeyword(kind);
                    case 6 /* TypeKeywords */:
                        return ts.isTypeKeyword(kind);
                    default:
                        return ts.Debug.assertNever(keywordFilter);
                }
            }));
        }
        function isTypeScriptOnlyKeyword(kind) {
            switch (kind) {
                case 119 /* AbstractKeyword */:
                case 121 /* AnyKeyword */:
                case 147 /* BigIntKeyword */:
                case 124 /* BooleanKeyword */:
                case 126 /* DeclareKeyword */:
                case 85 /* EnumKeyword */:
                case 146 /* GlobalKeyword */:
                case 110 /* ImplementsKeyword */:
                case 128 /* InferKeyword */:
                case 111 /* InterfaceKeyword */:
                case 129 /* IsKeyword */:
                case 130 /* KeyOfKeyword */:
                case 131 /* ModuleKeyword */:
                case 132 /* NamespaceKeyword */:
                case 133 /* NeverKeyword */:
                case 136 /* NumberKeyword */:
                case 137 /* ObjectKeyword */:
                case 114 /* PrivateKeyword */:
                case 115 /* ProtectedKeyword */:
                case 116 /* PublicKeyword */:
                case 134 /* ReadonlyKeyword */:
                case 139 /* StringKeyword */:
                case 140 /* SymbolKeyword */:
                case 141 /* TypeKeyword */:
                case 143 /* UniqueKeyword */:
                case 144 /* UnknownKeyword */:
                    return true;
                default:
                    return false;
            }
        }
        function isInterfaceOrTypeLiteralCompletionKeyword(kind) {
            return kind === 134 /* ReadonlyKeyword */;
        }
        function isClassMemberCompletionKeyword(kind) {
            switch (kind) {
                case 119 /* AbstractKeyword */:
                case 125 /* ConstructorKeyword */:
                case 127 /* GetKeyword */:
                case 138 /* SetKeyword */:
                case 122 /* AsyncKeyword */:
                    return true;
                default:
                    return ts.isClassMemberModifier(kind);
            }
        }
        function isFunctionLikeBodyKeyword(kind) {
            return kind === 122 /* AsyncKeyword */ || kind === 123 /* AwaitKeyword */ || !ts.isContextualKeyword(kind) && !isClassMemberCompletionKeyword(kind);
        }
        function keywordForNode(node) {
            return ts.isIdentifier(node) ? node.originalKeywordKind || 0 /* Unknown */ : node.kind;
        }
        /** Get the corresponding JSDocTag node if the position is in a jsDoc comment */
        function getJsDocTagAtPosition(node, position) {
            var jsdoc = ts.findAncestor(node, ts.isJSDoc);
            return jsdoc && jsdoc.tags && (ts.rangeContainsPosition(jsdoc, position) ? ts.findLast(jsdoc.tags, function (tag) { return tag.pos < position; }) : undefined);
        }
        function getPropertiesForObjectExpression(contextualType, obj, checker) {
            return contextualType.isUnion()
                ? checker.getAllPossiblePropertiesOfTypes(contextualType.types.filter(function (memberType) {
                    // If we're providing completions for an object literal, skip primitive, array-like, or callable types since those shouldn't be implemented by object literals.
                    return !(memberType.flags & 131068 /* Primitive */ ||
                        checker.isArrayLikeType(memberType) ||
                        ts.typeHasCallOrConstructSignatures(memberType, checker) ||
                        checker.isTypeInvalidDueToUnionDiscriminant(memberType, obj));
                }))
                : contextualType.getApparentProperties();
        }
        /**
         * Gets all properties on a type, but if that type is a union of several types,
         * excludes array-like types or callable/constructable types.
         */
        function getPropertiesForCompletion(type, checker) {
            return type.isUnion()
                ? ts.Debug.assertEachDefined(checker.getAllPossiblePropertiesOfTypes(type.types), "getAllPossiblePropertiesOfTypes() should all be defined")
                : ts.Debug.assertEachDefined(type.getApparentProperties(), "getApparentProperties() should all be defined");
        }
        /**
         * Returns the immediate owning class declaration of a context token,
         * on the condition that one exists and that the context implies completion should be given.
         */
        function tryGetObjectTypeDeclarationCompletionContainer(sourceFile, contextToken, location) {
            // class c { method() { } | method2() { } }
            switch (location.kind) {
                case 312 /* SyntaxList */:
                    return ts.tryCast(location.parent, ts.isObjectTypeDeclaration);
                case 1 /* EndOfFileToken */:
                    var cls = ts.tryCast(ts.lastOrUndefined(ts.cast(location.parent, ts.isSourceFile).statements), ts.isObjectTypeDeclaration);
                    if (cls && !ts.findChildOfKind(cls, 19 /* CloseBraceToken */, sourceFile)) {
                        return cls;
                    }
            }
            if (!contextToken)
                return undefined;
            switch (contextToken.kind) {
                case 26 /* SemicolonToken */: // class c {getValue(): number; | }
                case 19 /* CloseBraceToken */: // class c { method() { } | }
                    // class c { method() { } b| }
                    return isFromObjectTypeDeclaration(location) && location.parent.name === location
                        ? location.parent.parent
                        : ts.tryCast(location, ts.isObjectTypeDeclaration);
                case 18 /* OpenBraceToken */: // class c { |
                case 27 /* CommaToken */: // class c {getValue(): number, | }
                    return ts.tryCast(contextToken.parent, ts.isObjectTypeDeclaration);
                default:
                    if (!isFromObjectTypeDeclaration(contextToken))
                        return undefined;
                    var isValidKeyword = ts.isClassLike(contextToken.parent.parent) ? isClassMemberCompletionKeyword : isInterfaceOrTypeLiteralCompletionKeyword;
                    return (isValidKeyword(contextToken.kind) || contextToken.kind === 40 /* AsteriskToken */ || ts.isIdentifier(contextToken) && isValidKeyword(ts.stringToToken(contextToken.text))) // TODO: GH#18217
                        ? contextToken.parent.parent : undefined;
            }
        }
        // TODO: GH#19856 Would like to return `node is Node & { parent: (ClassElement | TypeElement) & { parent: ObjectTypeDeclaration } }` but then compilation takes > 10 minutes
        function isFromObjectTypeDeclaration(node) {
            return node.parent && ts.isClassOrTypeElement(node.parent) && ts.isObjectTypeDeclaration(node.parent.parent);
        }
        function isValidTrigger(sourceFile, triggerCharacter, contextToken, position) {
            switch (triggerCharacter) {
                case ".":
                case "@":
                    return true;
                case '"':
                case "'":
                case "`":
                    // Only automatically bring up completions if this is an opening quote.
                    return !!contextToken && ts.isStringLiteralOrTemplate(contextToken) && position === contextToken.getStart(sourceFile) + 1;
                case "<":
                    // Opening JSX tag
                    return !!contextToken && contextToken.kind === 28 /* LessThanToken */ && (!ts.isBinaryExpression(contextToken.parent) || binaryExpressionMayBeOpenTag(contextToken.parent));
                case "/":
                    return !!contextToken && (ts.isStringLiteralLike(contextToken)
                        ? !!ts.tryGetImportFromModuleSpecifier(contextToken)
                        : contextToken.kind === 42 /* SlashToken */ && ts.isJsxClosingElement(contextToken.parent));
                default:
                    return ts.Debug.assertNever(triggerCharacter);
            }
        }
        function binaryExpressionMayBeOpenTag(_a) {
            var left = _a.left;
            return ts.nodeIsMissing(left);
        }
    })(Completions = ts.Completions || (ts.Completions = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var DocumentHighlights;
    (function (DocumentHighlights) {
        function getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch) {
            var node = ts.getTouchingPropertyName(sourceFile, position);
            if (node.parent && (ts.isJsxOpeningElement(node.parent) && node.parent.tagName === node || ts.isJsxClosingElement(node.parent))) {
                // For a JSX element, just highlight the matching tag, not all references.
                var _a = node.parent.parent, openingElement = _a.openingElement, closingElement = _a.closingElement;
                var highlightSpans = [openingElement, closingElement].map(function (_a) {
                    var tagName = _a.tagName;
                    return getHighlightSpanForNode(tagName, sourceFile);
                });
                return [{ fileName: sourceFile.fileName, highlightSpans: highlightSpans }];
            }
            return getSemanticDocumentHighlights(position, node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile);
        }
        DocumentHighlights.getDocumentHighlights = getDocumentHighlights;
        function getHighlightSpanForNode(node, sourceFile) {
            return {
                fileName: sourceFile.fileName,
                textSpan: ts.createTextSpanFromNode(node, sourceFile),
                kind: "none" /* none */
            };
        }
        function getSemanticDocumentHighlights(position, node, program, cancellationToken, sourceFilesToSearch) {
            var sourceFilesSet = ts.arrayToSet(sourceFilesToSearch, function (f) { return f.fileName; });
            var referenceEntries = ts.FindAllReferences.getReferenceEntriesForNode(position, node, program, sourceFilesToSearch, cancellationToken, /*options*/ undefined, sourceFilesSet);
            if (!referenceEntries)
                return undefined;
            var map = ts.arrayToMultiMap(referenceEntries.map(ts.FindAllReferences.toHighlightSpan), function (e) { return e.fileName; }, function (e) { return e.span; });
            return ts.arrayFrom(map.entries(), function (_a) {
                var fileName = _a[0], highlightSpans = _a[1];
                if (!sourceFilesSet.has(fileName)) {
                    ts.Debug.assert(program.redirectTargetsMap.has(fileName));
                    var redirectTarget_1 = program.getSourceFile(fileName);
                    var redirect = ts.find(sourceFilesToSearch, function (f) { return !!f.redirectInfo && f.redirectInfo.redirectTarget === redirectTarget_1; });
                    fileName = redirect.fileName;
                    ts.Debug.assert(sourceFilesSet.has(fileName));
                }
                return { fileName: fileName, highlightSpans: highlightSpans };
            });
        }
        function getSyntacticDocumentHighlights(node, sourceFile) {
            var highlightSpans = getHighlightSpans(node, sourceFile);
            return highlightSpans && [{ fileName: sourceFile.fileName, highlightSpans: highlightSpans }];
        }
        function getHighlightSpans(node, sourceFile) {
            switch (node.kind) {
                case 92 /* IfKeyword */:
                case 84 /* ElseKeyword */:
                    return ts.isIfStatement(node.parent) ? getIfElseOccurrences(node.parent, sourceFile) : undefined;
                case 98 /* ReturnKeyword */:
                    return useParent(node.parent, ts.isReturnStatement, getReturnOccurrences);
                case 102 /* ThrowKeyword */:
                    return useParent(node.parent, ts.isThrowStatement, getThrowOccurrences);
                case 104 /* TryKeyword */:
                case 76 /* CatchKeyword */:
                case 89 /* FinallyKeyword */:
                    var tryStatement = node.kind === 76 /* CatchKeyword */ ? node.parent.parent : node.parent;
                    return useParent(tryStatement, ts.isTryStatement, getTryCatchFinallyOccurrences);
                case 100 /* SwitchKeyword */:
                    return useParent(node.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences);
                case 75 /* CaseKeyword */:
                case 81 /* DefaultKeyword */:
                    return useParent(node.parent.parent.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences);
                case 74 /* BreakKeyword */:
                case 79 /* ContinueKeyword */:
                    return useParent(node.parent, ts.isBreakOrContinueStatement, getBreakOrContinueStatementOccurrences);
                case 90 /* ForKeyword */:
                case 108 /* WhileKeyword */:
                case 83 /* DoKeyword */:
                    return useParent(node.parent, function (n) { return ts.isIterationStatement(n, /*lookInLabeledStatements*/ true); }, getLoopBreakContinueOccurrences);
                case 125 /* ConstructorKeyword */:
                    return getFromAllDeclarations(ts.isConstructorDeclaration, [125 /* ConstructorKeyword */]);
                case 127 /* GetKeyword */:
                case 138 /* SetKeyword */:
                    return getFromAllDeclarations(ts.isAccessor, [127 /* GetKeyword */, 138 /* SetKeyword */]);
                case 123 /* AwaitKeyword */:
                    return useParent(node.parent, ts.isAwaitExpression, getAsyncAndAwaitOccurrences);
                case 122 /* AsyncKeyword */:
                    return highlightSpans(getAsyncAndAwaitOccurrences(node));
                case 118 /* YieldKeyword */:
                    return highlightSpans(getYieldOccurrences(node));
                default:
                    return ts.isModifierKind(node.kind) && (ts.isDeclaration(node.parent) || ts.isVariableStatement(node.parent))
                        ? highlightSpans(getModifierOccurrences(node.kind, node.parent))
                        : undefined;
            }
            function getFromAllDeclarations(nodeTest, keywords) {
                return useParent(node.parent, nodeTest, function (decl) { return ts.mapDefined(decl.symbol.declarations, function (d) {
                    return nodeTest(d) ? ts.find(d.getChildren(sourceFile), function (c) { return ts.contains(keywords, c.kind); }) : undefined;
                }); });
            }
            function useParent(node, nodeTest, getNodes) {
                return nodeTest(node) ? highlightSpans(getNodes(node, sourceFile)) : undefined;
            }
            function highlightSpans(nodes) {
                return nodes && nodes.map(function (node) { return getHighlightSpanForNode(node, sourceFile); });
            }
        }
        /**
         * Aggregates all throw-statements within this node *without* crossing
         * into function boundaries and try-blocks with catch-clauses.
         */
        function aggregateOwnedThrowStatements(node) {
            if (ts.isThrowStatement(node)) {
                return [node];
            }
            else if (ts.isTryStatement(node)) {
                // Exceptions thrown within a try block lacking a catch clause are "owned" in the current context.
                return ts.concatenate(node.catchClause ? aggregateOwnedThrowStatements(node.catchClause) : node.tryBlock && aggregateOwnedThrowStatements(node.tryBlock), node.finallyBlock && aggregateOwnedThrowStatements(node.finallyBlock));
            }
            // Do not cross function boundaries.
            return ts.isFunctionLike(node) ? undefined : flatMapChildren(node, aggregateOwnedThrowStatements);
        }
        /**
         * For lack of a better name, this function takes a throw statement and returns the
         * nearest ancestor that is a try-block (whose try statement has a catch clause),
         * function-block, or source file.
         */
        function getThrowStatementOwner(throwStatement) {
            var child = throwStatement;
            while (child.parent) {
                var parent = child.parent;
                if (ts.isFunctionBlock(parent) || parent.kind === 285 /* SourceFile */) {
                    return parent;
                }
                // A throw-statement is only owned by a try-statement if the try-statement has
                // a catch clause, and if the throw-statement occurs within the try block.
                if (ts.isTryStatement(parent) && parent.tryBlock === child && parent.catchClause) {
                    return child;
                }
                child = parent;
            }
            return undefined;
        }
        function aggregateAllBreakAndContinueStatements(node) {
            return ts.isBreakOrContinueStatement(node) ? [node] : ts.isFunctionLike(node) ? undefined : flatMapChildren(node, aggregateAllBreakAndContinueStatements);
        }
        function flatMapChildren(node, cb) {
            var result = [];
            node.forEachChild(function (child) {
                var value = cb(child);
                if (value !== undefined) {
                    result.push.apply(result, ts.toArray(value));
                }
            });
            return result;
        }
        function ownsBreakOrContinueStatement(owner, statement) {
            var actualOwner = getBreakOrContinueOwner(statement);
            return !!actualOwner && actualOwner === owner;
        }
        function getBreakOrContinueOwner(statement) {
            return ts.findAncestor(statement, function (node) {
                switch (node.kind) {
                    case 233 /* SwitchStatement */:
                        if (statement.kind === 229 /* ContinueStatement */) {
                            return false;
                        }
                    // falls through
                    case 226 /* ForStatement */:
                    case 227 /* ForInStatement */:
                    case 228 /* ForOfStatement */:
                    case 225 /* WhileStatement */:
                    case 224 /* DoStatement */:
                        return !statement.label || isLabeledBy(node, statement.label.escapedText);
                    default:
                        // Don't cross function boundaries.
                        // TODO: GH#20090
                        return ts.isFunctionLike(node) && "quit";
                }
            });
        }
        function getModifierOccurrences(modifier, declaration) {
            return ts.mapDefined(getNodesToSearchForModifier(declaration, ts.modifierToFlag(modifier)), function (node) { return ts.findModifier(node, modifier); });
        }
        function getNodesToSearchForModifier(declaration, modifierFlag) {
            // Types of node whose children might have modifiers.
            var container = declaration.parent;
            switch (container.kind) {
                case 246 /* ModuleBlock */:
                case 285 /* SourceFile */:
                case 219 /* Block */:
                case 272 /* CaseClause */:
                case 273 /* DefaultClause */:
                    // Container is either a class declaration or the declaration is a classDeclaration
                    if (modifierFlag & 128 /* Abstract */ && ts.isClassDeclaration(declaration)) {
                        return declaration.members.concat([declaration]);
                    }
                    else {
                        return container.statements;
                    }
                case 158 /* Constructor */:
                case 157 /* MethodDeclaration */:
                case 240 /* FunctionDeclaration */:
                    return container.parameters.concat((ts.isClassLike(container.parent) ? container.parent.members : []));
                case 241 /* ClassDeclaration */:
                case 210 /* ClassExpression */:
                    var nodes = container.members;
                    // If we're an accessibility modifier, we're in an instance member and should search
                    // the constructor's parameter list for instance members as well.
                    if (modifierFlag & 28 /* AccessibilityModifier */) {
                        var constructor = ts.find(container.members, ts.isConstructorDeclaration);
                        if (constructor) {
                            return nodes.concat(constructor.parameters);
                        }
                    }
                    else if (modifierFlag & 128 /* Abstract */) {
                        return nodes.concat([container]);
                    }
                    return nodes;
                default:
                    ts.Debug.assertNever(container, "Invalid container kind.");
            }
        }
        function pushKeywordIf(keywordList, token) {
            var expected = [];
            for (var _i = 2; _i < arguments.length; _i++) {
                expected[_i - 2] = arguments[_i];
            }
            if (token && ts.contains(expected, token.kind)) {
                keywordList.push(token);
                return true;
            }
            return false;
        }
        function getLoopBreakContinueOccurrences(loopNode) {
            var keywords = [];
            if (pushKeywordIf(keywords, loopNode.getFirstToken(), 90 /* ForKeyword */, 108 /* WhileKeyword */, 83 /* DoKeyword */)) {
                // If we succeeded and got a do-while loop, then start looking for a 'while' keyword.
                if (loopNode.kind === 224 /* DoStatement */) {
                    var loopTokens = loopNode.getChildren();
                    for (var i = loopTokens.length - 1; i >= 0; i--) {
                        if (pushKeywordIf(keywords, loopTokens[i], 108 /* WhileKeyword */)) {
                            break;
                        }
                    }
                }
            }
            ts.forEach(aggregateAllBreakAndContinueStatements(loopNode.statement), function (statement) {
                if (ownsBreakOrContinueStatement(loopNode, statement)) {
                    pushKeywordIf(keywords, statement.getFirstToken(), 74 /* BreakKeyword */, 79 /* ContinueKeyword */);
                }
            });
            return keywords;
        }
        function getBreakOrContinueStatementOccurrences(breakOrContinueStatement) {
            var owner = getBreakOrContinueOwner(breakOrContinueStatement);
            if (owner) {
                switch (owner.kind) {
                    case 226 /* ForStatement */:
                    case 227 /* ForInStatement */:
                    case 228 /* ForOfStatement */:
                    case 224 /* DoStatement */:
                    case 225 /* WhileStatement */:
                        return getLoopBreakContinueOccurrences(owner);
                    case 233 /* SwitchStatement */:
                        return getSwitchCaseDefaultOccurrences(owner);
                }
            }
            return undefined;
        }
        function getSwitchCaseDefaultOccurrences(switchStatement) {
            var keywords = [];
            pushKeywordIf(keywords, switchStatement.getFirstToken(), 100 /* SwitchKeyword */);
            // Go through each clause in the switch statement, collecting the 'case'/'default' keywords.
            ts.forEach(switchStatement.caseBlock.clauses, function (clause) {
                pushKeywordIf(keywords, clause.getFirstToken(), 75 /* CaseKeyword */, 81 /* DefaultKeyword */);
                ts.forEach(aggregateAllBreakAndContinueStatements(clause), function (statement) {
                    if (ownsBreakOrContinueStatement(switchStatement, statement)) {
                        pushKeywordIf(keywords, statement.getFirstToken(), 74 /* BreakKeyword */);
                    }
                });
            });
            return keywords;
        }
        function getTryCatchFinallyOccurrences(tryStatement, sourceFile) {
            var keywords = [];
            pushKeywordIf(keywords, tryStatement.getFirstToken(), 104 /* TryKeyword */);
            if (tryStatement.catchClause) {
                pushKeywordIf(keywords, tryStatement.catchClause.getFirstToken(), 76 /* CatchKeyword */);
            }
            if (tryStatement.finallyBlock) {
                var finallyKeyword = ts.findChildOfKind(tryStatement, 89 /* FinallyKeyword */, sourceFile);
                pushKeywordIf(keywords, finallyKeyword, 89 /* FinallyKeyword */);
            }
            return keywords;
        }
        function getThrowOccurrences(throwStatement, sourceFile) {
            var owner = getThrowStatementOwner(throwStatement);
            if (!owner) {
                return undefined;
            }
            var keywords = [];
            ts.forEach(aggregateOwnedThrowStatements(owner), function (throwStatement) {
                keywords.push(ts.findChildOfKind(throwStatement, 102 /* ThrowKeyword */, sourceFile));
            });
            // If the "owner" is a function, then we equate 'return' and 'throw' statements in their
            // ability to "jump out" of the function, and include occurrences for both.
            if (ts.isFunctionBlock(owner)) {
                ts.forEachReturnStatement(owner, function (returnStatement) {
                    keywords.push(ts.findChildOfKind(returnStatement, 98 /* ReturnKeyword */, sourceFile));
                });
            }
            return keywords;
        }
        function getReturnOccurrences(returnStatement, sourceFile) {
            var func = ts.getContainingFunction(returnStatement);
            if (!func) {
                return undefined;
            }
            var keywords = [];
            ts.forEachReturnStatement(ts.cast(func.body, ts.isBlock), function (returnStatement) {
                keywords.push(ts.findChildOfKind(returnStatement, 98 /* ReturnKeyword */, sourceFile));
            });
            // Include 'throw' statements that do not occur within a try block.
            ts.forEach(aggregateOwnedThrowStatements(func.body), function (throwStatement) {
                keywords.push(ts.findChildOfKind(throwStatement, 102 /* ThrowKeyword */, sourceFile));
            });
            return keywords;
        }
        function getAsyncAndAwaitOccurrences(node) {
            var func = ts.getContainingFunction(node);
            if (!func) {
                return undefined;
            }
            var keywords = [];
            if (func.modifiers) {
                func.modifiers.forEach(function (modifier) {
                    pushKeywordIf(keywords, modifier, 122 /* AsyncKeyword */);
                });
            }
            ts.forEachChild(func, function (child) {
                traverseWithoutCrossingFunction(child, function (node) {
                    if (ts.isAwaitExpression(node)) {
                        pushKeywordIf(keywords, node.getFirstToken(), 123 /* AwaitKeyword */);
                    }
                });
            });
            return keywords;
        }
        function getYieldOccurrences(node) {
            var func = ts.getContainingFunction(node);
            if (!func) {
                return undefined;
            }
            var keywords = [];
            ts.forEachChild(func, function (child) {
                traverseWithoutCrossingFunction(child, function (node) {
                    if (ts.isYieldExpression(node)) {
                        pushKeywordIf(keywords, node.getFirstToken(), 118 /* YieldKeyword */);
                    }
                });
            });
            return keywords;
        }
        // Do not cross function/class/interface/module/type boundaries.
        function traverseWithoutCrossingFunction(node, cb) {
            cb(node);
            if (!ts.isFunctionLike(node) && !ts.isClassLike(node) && !ts.isInterfaceDeclaration(node) && !ts.isModuleDeclaration(node) && !ts.isTypeAliasDeclaration(node) && !ts.isTypeNode(node)) {
                ts.forEachChild(node, function (child) { return traverseWithoutCrossingFunction(child, cb); });
            }
        }
        function getIfElseOccurrences(ifStatement, sourceFile) {
            var keywords = getIfElseKeywords(ifStatement, sourceFile);
            var result = [];
            // We'd like to highlight else/ifs together if they are only separated by whitespace
            // (i.e. the keywords are separated by no comments, no newlines).
            for (var i = 0; i < keywords.length; i++) {
                if (keywords[i].kind === 84 /* ElseKeyword */ && i < keywords.length - 1) {
                    var elseKeyword = keywords[i];
                    var ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword.
                    var shouldCombineElseAndIf = true;
                    // Avoid recalculating getStart() by iterating backwards.
                    for (var j = ifKeyword.getStart(sourceFile) - 1; j >= elseKeyword.end; j--) {
                        if (!ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(j))) {
                            shouldCombineElseAndIf = false;
                            break;
                        }
                    }
                    if (shouldCombineElseAndIf) {
                        result.push({
                            fileName: sourceFile.fileName,
                            textSpan: ts.createTextSpanFromBounds(elseKeyword.getStart(), ifKeyword.end),
                            kind: "reference" /* reference */
                        });
                        i++; // skip the next keyword
                        continue;
                    }
                }
                // Ordinary case: just highlight the keyword.
                result.push(getHighlightSpanForNode(keywords[i], sourceFile));
            }
            return result;
        }
        function getIfElseKeywords(ifStatement, sourceFile) {
            var keywords = [];
            // Traverse upwards through all parent if-statements linked by their else-branches.
            while (ts.isIfStatement(ifStatement.parent) && ifStatement.parent.elseStatement === ifStatement) {
                ifStatement = ifStatement.parent;
            }
            // Now traverse back down through the else branches, aggregating if/else keywords of if-statements.
            while (true) {
                var children = ifStatement.getChildren(sourceFile);
                pushKeywordIf(keywords, children[0], 92 /* IfKeyword */);
                // Generally the 'else' keyword is second-to-last, so we traverse backwards.
                for (var i = children.length - 1; i >= 0; i--) {
                    if (pushKeywordIf(keywords, children[i], 84 /* ElseKeyword */)) {
                        break;
                    }
                }
                if (!ifStatement.elseStatement || !ts.isIfStatement(ifStatement.elseStatement)) {
                    break;
                }
                ifStatement = ifStatement.elseStatement;
            }
            return keywords;
        }
        /**
         * Whether or not a 'node' is preceded by a label of the given string.
         * Note: 'node' cannot be a SourceFile.
         */
        function isLabeledBy(node, labelName) {
            return !!ts.findAncestor(node.parent, function (owner) { return !ts.isLabeledStatement(owner) ? "quit" : owner.label.escapedText === labelName; });
        }
    })(DocumentHighlights = ts.DocumentHighlights || (ts.DocumentHighlights = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    function createDocumentRegistry(useCaseSensitiveFileNames, currentDirectory) {
        return createDocumentRegistryInternal(useCaseSensitiveFileNames, currentDirectory);
    }
    ts.createDocumentRegistry = createDocumentRegistry;
    /*@internal*/
    function createDocumentRegistryInternal(useCaseSensitiveFileNames, currentDirectory, externalCache) {
        if (currentDirectory === void 0) { currentDirectory = ""; }
        // Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have
        // for those settings.
        var buckets = ts.createMap();
        var getCanonicalFileName = ts.createGetCanonicalFileName(!!useCaseSensitiveFileNames);
        function reportStats() {
            var bucketInfoArray = ts.arrayFrom(buckets.keys()).filter(function (name) { return name && name.charAt(0) === "_"; }).map(function (name) {
                var entries = buckets.get(name);
                var sourceFiles = [];
                entries.forEach(function (entry, name) {
                    sourceFiles.push({
                        name: name,
                        refCount: entry.languageServiceRefCount
                    });
                });
                sourceFiles.sort(function (x, y) { return y.refCount - x.refCount; });
                return {
                    bucket: name,
                    sourceFiles: sourceFiles
                };
            });
            return JSON.stringify(bucketInfoArray, undefined, 2);
        }
        function acquireDocument(fileName, compilationSettings, scriptSnapshot, version, scriptKind) {
            var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
            var key = getKeyForCompilationSettings(compilationSettings);
            return acquireDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind);
        }
        function acquireDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind) {
            return acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, /*acquiring*/ true, scriptKind);
        }
        function updateDocument(fileName, compilationSettings, scriptSnapshot, version, scriptKind) {
            var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
            var key = getKeyForCompilationSettings(compilationSettings);
            return updateDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind);
        }
        function updateDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind) {
            return acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, /*acquiring*/ false, scriptKind);
        }
        function acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, acquiring, scriptKind) {
            var bucket = ts.getOrUpdate(buckets, key, ts.createMap);
            var entry = bucket.get(path);
            var scriptTarget = scriptKind === 6 /* JSON */ ? 100 /* JSON */ : compilationSettings.target || 1 /* ES5 */;
            if (!entry && externalCache) {
                var sourceFile = externalCache.getDocument(key, path);
                if (sourceFile) {
                    ts.Debug.assert(acquiring);
                    entry = {
                        sourceFile: sourceFile,
                        languageServiceRefCount: 0
                    };
                    bucket.set(path, entry);
                }
            }
            if (!entry) {
                // Have never seen this file with these settings.  Create a new source file for it.
                var sourceFile = ts.createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, /*setNodeParents*/ false, scriptKind);
                if (externalCache) {
                    externalCache.setDocument(key, path, sourceFile);
                }
                entry = {
                    sourceFile: sourceFile,
                    languageServiceRefCount: 1,
                };
                bucket.set(path, entry);
            }
            else {
                // We have an entry for this file.  However, it may be for a different version of
                // the script snapshot.  If so, update it appropriately.  Otherwise, we can just
                // return it as is.
                if (entry.sourceFile.version !== version) {
                    entry.sourceFile = ts.updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot)); // TODO: GH#18217
                    if (externalCache) {
                        externalCache.setDocument(key, path, entry.sourceFile);
                    }
                }
                // If we're acquiring, then this is the first time this LS is asking for this document.
                // Increase our ref count so we know there's another LS using the document.  If we're
                // not acquiring, then that means the LS is 'updating' the file instead, and that means
                // it has already acquired the document previously.  As such, we do not need to increase
                // the ref count.
                if (acquiring) {
                    entry.languageServiceRefCount++;
                }
            }
            ts.Debug.assert(entry.languageServiceRefCount !== 0);
            return entry.sourceFile;
        }
        function releaseDocument(fileName, compilationSettings) {
            var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
            var key = getKeyForCompilationSettings(compilationSettings);
            return releaseDocumentWithKey(path, key);
        }
        function releaseDocumentWithKey(path, key) {
            var bucket = ts.Debug.assertDefined(buckets.get(key));
            var entry = bucket.get(path);
            entry.languageServiceRefCount--;
            ts.Debug.assert(entry.languageServiceRefCount >= 0);
            if (entry.languageServiceRefCount === 0) {
                bucket.delete(path);
            }
        }
        function getLanguageServiceRefCounts(path) {
            return ts.arrayFrom(buckets.entries(), function (_a) {
                var key = _a[0], bucket = _a[1];
                var entry = bucket.get(path);
                return [key, entry && entry.languageServiceRefCount];
            });
        }
        return {
            acquireDocument: acquireDocument,
            acquireDocumentWithKey: acquireDocumentWithKey,
            updateDocument: updateDocument,
            updateDocumentWithKey: updateDocumentWithKey,
            releaseDocument: releaseDocument,
            releaseDocumentWithKey: releaseDocumentWithKey,
            getLanguageServiceRefCounts: getLanguageServiceRefCounts,
            reportStats: reportStats,
            getKeyForCompilationSettings: getKeyForCompilationSettings
        };
    }
    ts.createDocumentRegistryInternal = createDocumentRegistryInternal;
    function getKeyForCompilationSettings(settings) {
        return ts.sourceFileAffectingCompilerOptions.map(function (option) { return ts.getCompilerOptionValue(settings, option); }).join("|");
    }
})(ts || (ts = {}));
/* Code for finding imports of an exported symbol. Used only by FindAllReferences. */
/* @internal */
var ts;
(function (ts) {
    var FindAllReferences;
    (function (FindAllReferences) {
        /** Creates the imports map and returns an ImportTracker that uses it. Call this lazily to avoid calling `getDirectImportsMap` unnecessarily.  */
        function createImportTracker(sourceFiles, sourceFilesSet, checker, cancellationToken) {
            var allDirectImports = getDirectImportsMap(sourceFiles, checker, cancellationToken);
            return function (exportSymbol, exportInfo, isForRename) {
                var _a = getImportersForExport(sourceFiles, sourceFilesSet, allDirectImports, exportInfo, checker, cancellationToken), directImports = _a.directImports, indirectUsers = _a.indirectUsers;
                return __assign({ indirectUsers: indirectUsers }, getSearchesFromDirectImports(directImports, exportSymbol, exportInfo.exportKind, checker, isForRename));
            };
        }
        FindAllReferences.createImportTracker = createImportTracker;
        var ExportKind;
        (function (ExportKind) {
            ExportKind[ExportKind["Named"] = 0] = "Named";
            ExportKind[ExportKind["Default"] = 1] = "Default";
            ExportKind[ExportKind["ExportEquals"] = 2] = "ExportEquals";
        })(ExportKind = FindAllReferences.ExportKind || (FindAllReferences.ExportKind = {}));
        var ImportExport;
        (function (ImportExport) {
            ImportExport[ImportExport["Import"] = 0] = "Import";
            ImportExport[ImportExport["Export"] = 1] = "Export";
        })(ImportExport = FindAllReferences.ImportExport || (FindAllReferences.ImportExport = {}));
        /** Returns import statements that directly reference the exporting module, and a list of files that may access the module through a namespace. */
        function getImportersForExport(sourceFiles, sourceFilesSet, allDirectImports, _a, checker, cancellationToken) {
            var exportingModuleSymbol = _a.exportingModuleSymbol, exportKind = _a.exportKind;
            var markSeenDirectImport = ts.nodeSeenTracker();
            var markSeenIndirectUser = ts.nodeSeenTracker();
            var directImports = [];
            var isAvailableThroughGlobal = !!exportingModuleSymbol.globalExports;
            var indirectUserDeclarations = isAvailableThroughGlobal ? undefined : [];
            handleDirectImports(exportingModuleSymbol);
            return { directImports: directImports, indirectUsers: getIndirectUsers() };
            function getIndirectUsers() {
                if (isAvailableThroughGlobal) {
                    // It has `export as namespace`, so anything could potentially use it.
                    return sourceFiles;
                }
                // Module augmentations may use this module's exports without importing it.
                for (var _i = 0, _a = exportingModuleSymbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    if (ts.isExternalModuleAugmentation(decl) && sourceFilesSet.has(decl.getSourceFile().fileName)) {
                        addIndirectUser(decl);
                    }
                }
                // This may return duplicates (if there are multiple module declarations in a single source file, all importing the same thing as a namespace), but `State.markSearchedSymbol` will handle that.
                return indirectUserDeclarations.map(ts.getSourceFileOfNode);
            }
            function handleDirectImports(exportingModuleSymbol) {
                var theseDirectImports = getDirectImports(exportingModuleSymbol);
                if (theseDirectImports) {
                    for (var _i = 0, theseDirectImports_1 = theseDirectImports; _i < theseDirectImports_1.length; _i++) {
                        var direct = theseDirectImports_1[_i];
                        if (!markSeenDirectImport(direct)) {
                            continue;
                        }
                        if (cancellationToken)
                            cancellationToken.throwIfCancellationRequested();
                        switch (direct.kind) {
                            case 192 /* CallExpression */:
                                if (!isAvailableThroughGlobal) {
                                    var parent = direct.parent;
                                    if (exportKind === 2 /* ExportEquals */ && parent.kind === 238 /* VariableDeclaration */) {
                                        var name = parent.name;
                                        if (name.kind === 73 /* Identifier */) {
                                            directImports.push(name);
                                            break;
                                        }
                                    }
                                    // Don't support re-exporting 'require()' calls, so just add a single indirect user.
                                    addIndirectUser(direct.getSourceFile());
                                }
                                break;
                            case 73 /* Identifier */: // for 'const x = require("y");
                                break; // TODO: GH#23879
                            case 249 /* ImportEqualsDeclaration */:
                                handleNamespaceImport(direct, direct.name, ts.hasModifier(direct, 1 /* Export */), /*alreadyAddedDirect*/ false);
                                break;
                            case 250 /* ImportDeclaration */:
                                directImports.push(direct);
                                var namedBindings = direct.importClause && direct.importClause.namedBindings;
                                if (namedBindings && namedBindings.kind === 252 /* NamespaceImport */) {
                                    handleNamespaceImport(direct, namedBindings.name, /*isReExport*/ false, /*alreadyAddedDirect*/ true);
                                }
                                else if (!isAvailableThroughGlobal && ts.isDefaultImport(direct)) {
                                    addIndirectUser(getSourceFileLikeForImportDeclaration(direct)); // Add a check for indirect uses to handle synthetic default imports
                                }
                                break;
                            case 256 /* ExportDeclaration */:
                                if (!direct.exportClause) {
                                    // This is `export * from "foo"`, so imports of this module may import the export too.
                                    handleDirectImports(getContainingModuleSymbol(direct, checker));
                                }
                                else {
                                    // This is `export { foo } from "foo"` and creates an alias symbol, so recursive search will get handle re-exports.
                                    directImports.push(direct);
                                }
                                break;
                            case 184 /* ImportType */:
                                directImports.push(direct);
                                break;
                            default:
                                ts.Debug.failBadSyntaxKind(direct, "Unexpected import kind.");
                        }
                    }
                }
            }
            function handleNamespaceImport(importDeclaration, name, isReExport, alreadyAddedDirect) {
                if (exportKind === 2 /* ExportEquals */) {
                    // This is a direct import, not import-as-namespace.
                    if (!alreadyAddedDirect)
                        directImports.push(importDeclaration);
                }
                else if (!isAvailableThroughGlobal) {
                    var sourceFileLike = getSourceFileLikeForImportDeclaration(importDeclaration);
                    ts.Debug.assert(sourceFileLike.kind === 285 /* SourceFile */ || sourceFileLike.kind === 245 /* ModuleDeclaration */);
                    if (isReExport || findNamespaceReExports(sourceFileLike, name, checker)) {
                        addIndirectUsers(sourceFileLike);
                    }
                    else {
                        addIndirectUser(sourceFileLike);
                    }
                }
            }
            function addIndirectUser(sourceFileLike) {
                ts.Debug.assert(!isAvailableThroughGlobal);
                var isNew = markSeenIndirectUser(sourceFileLike);
                if (isNew) {
                    indirectUserDeclarations.push(sourceFileLike); // TODO: GH#18217
                }
                return isNew;
            }
            /** Adds a module and all of its transitive dependencies as possible indirect users. */
            function addIndirectUsers(sourceFileLike) {
                if (!addIndirectUser(sourceFileLike)) {
                    return;
                }
                var moduleSymbol = checker.getMergedSymbol(sourceFileLike.symbol);
                ts.Debug.assert(!!(moduleSymbol.flags & 1536 /* Module */));
                var directImports = getDirectImports(moduleSymbol);
                if (directImports) {
                    for (var _i = 0, directImports_1 = directImports; _i < directImports_1.length; _i++) {
                        var directImport = directImports_1[_i];
                        addIndirectUsers(getSourceFileLikeForImportDeclaration(directImport));
                    }
                }
            }
            function getDirectImports(moduleSymbol) {
                return allDirectImports.get(ts.getSymbolId(moduleSymbol).toString());
            }
        }
        /**
         * Given the set of direct imports of a module, we need to find which ones import the particular exported symbol.
         * The returned `importSearches` will result in the entire source file being searched.
         * But re-exports will be placed in 'singleReferences' since they cannot be locally referenced.
         */
        function getSearchesFromDirectImports(directImports, exportSymbol, exportKind, checker, isForRename) {
            var importSearches = [];
            var singleReferences = [];
            function addSearch(location, symbol) {
                importSearches.push([location, symbol]);
            }
            if (directImports) {
                for (var _i = 0, directImports_2 = directImports; _i < directImports_2.length; _i++) {
                    var decl = directImports_2[_i];
                    handleImport(decl);
                }
            }
            return { importSearches: importSearches, singleReferences: singleReferences };
            function handleImport(decl) {
                if (decl.kind === 249 /* ImportEqualsDeclaration */) {
                    if (isExternalModuleImportEquals(decl)) {
                        handleNamespaceImportLike(decl.name);
                    }
                    return;
                }
                if (decl.kind === 73 /* Identifier */) {
                    handleNamespaceImportLike(decl);
                    return;
                }
                if (decl.kind === 184 /* ImportType */) {
                    if (decl.qualifier) {
                        if (ts.isIdentifier(decl.qualifier) && decl.qualifier.escapedText === ts.symbolName(exportSymbol)) {
                            singleReferences.push(decl.qualifier);
                        }
                    }
                    else if (exportKind === 2 /* ExportEquals */) {
                        singleReferences.push(decl.argument.literal);
                    }
                    return;
                }
                // Ignore if there's a grammar error
                if (decl.moduleSpecifier.kind !== 10 /* StringLiteral */) {
                    return;
                }
                if (decl.kind === 256 /* ExportDeclaration */) {
                    searchForNamedImport(decl.exportClause);
                    return;
                }
                var _a = decl.importClause || { name: undefined, namedBindings: undefined }, name = _a.name, namedBindings = _a.namedBindings;
                if (namedBindings) {
                    switch (namedBindings.kind) {
                        case 252 /* NamespaceImport */:
                            handleNamespaceImportLike(namedBindings.name);
                            break;
                        case 253 /* NamedImports */:
                            // 'default' might be accessed as a named import `{ default as foo }`.
                            if (exportKind === 0 /* Named */ || exportKind === 1 /* Default */) {
                                searchForNamedImport(namedBindings);
                            }
                            break;
                        default:
                            ts.Debug.assertNever(namedBindings);
                    }
                }
                // `export =` might be imported by a default import if `--allowSyntheticDefaultImports` is on, so this handles both ExportKind.Default and ExportKind.ExportEquals.
                // If a default import has the same name as the default export, allow to rename it.
                // Given `import f` and `export default function f`, we will rename both, but for `import g` we will rename just that.
                if (name && (exportKind === 1 /* Default */ || exportKind === 2 /* ExportEquals */) && (!isForRename || name.escapedText === ts.symbolEscapedNameNoDefault(exportSymbol))) {
                    var defaultImportAlias = checker.getSymbolAtLocation(name);
                    addSearch(name, defaultImportAlias);
                }
            }
            /**
             * `import x = require("./x")` or `import * as x from "./x"`.
             * An `export =` may be imported by this syntax, so it may be a direct import.
             * If it's not a direct import, it will be in `indirectUsers`, so we don't have to do anything here.
             */
            function handleNamespaceImportLike(importName) {
                // Don't rename an import that already has a different name than the export.
                if (exportKind === 2 /* ExportEquals */ && (!isForRename || isNameMatch(importName.escapedText))) {
                    addSearch(importName, checker.getSymbolAtLocation(importName));
                }
            }
            function searchForNamedImport(namedBindings) {
                if (!namedBindings) {
                    return;
                }
                for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    var name = element.name, propertyName = element.propertyName;
                    if (!isNameMatch((propertyName || name).escapedText)) {
                        continue;
                    }
                    if (propertyName) {
                        // This is `import { foo as bar } from "./a"` or `export { foo as bar } from "./a"`. `foo` isn't a local in the file, so just add it as a single reference.
                        singleReferences.push(propertyName);
                        // If renaming `{ foo as bar }`, don't touch `bar`, just `foo`.
                        // But do rename `foo` in ` { default as foo }` if that's the original export name.
                        if (!isForRename || name.escapedText === exportSymbol.escapedName) {
                            // Search locally for `bar`.
                            addSearch(name, checker.getSymbolAtLocation(name));
                        }
                    }
                    else {
                        var localSymbol = element.kind === 258 /* ExportSpecifier */ && element.propertyName
                            ? checker.getExportSpecifierLocalTargetSymbol(element) // For re-exporting under a different name, we want to get the re-exported symbol.
                            : checker.getSymbolAtLocation(name);
                        addSearch(name, localSymbol);
                    }
                }
            }
            function isNameMatch(name) {
                // Use name of "default" even in `export =` case because we may have allowSyntheticDefaultImports
                return name === exportSymbol.escapedName || exportKind !== 0 /* Named */ && name === "default" /* Default */;
            }
        }
        /** Returns 'true' is the namespace 'name' is re-exported from this module, and 'false' if it is only used locally. */
        function findNamespaceReExports(sourceFileLike, name, checker) {
            var namespaceImportSymbol = checker.getSymbolAtLocation(name);
            return !!forEachPossibleImportOrExportStatement(sourceFileLike, function (statement) {
                if (!ts.isExportDeclaration(statement))
                    return;
                var exportClause = statement.exportClause, moduleSpecifier = statement.moduleSpecifier;
                return !moduleSpecifier && exportClause &&
                    exportClause.elements.some(function (element) { return checker.getExportSpecifierLocalTargetSymbol(element) === namespaceImportSymbol; });
            });
        }
        function findModuleReferences(program, sourceFiles, searchModuleSymbol) {
            var refs = [];
            var checker = program.getTypeChecker();
            for (var _i = 0, sourceFiles_1 = sourceFiles; _i < sourceFiles_1.length; _i++) {
                var referencingFile = sourceFiles_1[_i];
                var searchSourceFile = searchModuleSymbol.valueDeclaration;
                if (searchSourceFile.kind === 285 /* SourceFile */) {
                    for (var _a = 0, _b = referencingFile.referencedFiles; _a < _b.length; _a++) {
                        var ref = _b[_a];
                        if (program.getSourceFileFromReference(referencingFile, ref) === searchSourceFile) {
                            refs.push({ kind: "reference", referencingFile: referencingFile, ref: ref });
                        }
                    }
                    for (var _c = 0, _d = referencingFile.typeReferenceDirectives; _c < _d.length; _c++) {
                        var ref = _d[_c];
                        var referenced = program.getResolvedTypeReferenceDirectives().get(ref.fileName);
                        if (referenced !== undefined && referenced.resolvedFileName === searchSourceFile.fileName) {
                            refs.push({ kind: "reference", referencingFile: referencingFile, ref: ref });
                        }
                    }
                }
                forEachImport(referencingFile, function (_importDecl, moduleSpecifier) {
                    var moduleSymbol = checker.getSymbolAtLocation(moduleSpecifier);
                    if (moduleSymbol === searchModuleSymbol) {
                        refs.push({ kind: "import", literal: moduleSpecifier });
                    }
                });
            }
            return refs;
        }
        FindAllReferences.findModuleReferences = findModuleReferences;
        /** Returns a map from a module symbol Id to all import statements that directly reference the module. */
        function getDirectImportsMap(sourceFiles, checker, cancellationToken) {
            var map = ts.createMap();
            for (var _i = 0, sourceFiles_2 = sourceFiles; _i < sourceFiles_2.length; _i++) {
                var sourceFile = sourceFiles_2[_i];
                if (cancellationToken)
                    cancellationToken.throwIfCancellationRequested();
                forEachImport(sourceFile, function (importDecl, moduleSpecifier) {
                    var moduleSymbol = checker.getSymbolAtLocation(moduleSpecifier);
                    if (moduleSymbol) {
                        var id = ts.getSymbolId(moduleSymbol).toString();
                        var imports = map.get(id);
                        if (!imports) {
                            map.set(id, imports = []);
                        }
                        imports.push(importDecl);
                    }
                });
            }
            return map;
        }
        /** Iterates over all statements at the top level or in module declarations. Returns the first truthy result. */
        function forEachPossibleImportOrExportStatement(sourceFileLike, action) {
            return ts.forEach(sourceFileLike.kind === 285 /* SourceFile */ ? sourceFileLike.statements : sourceFileLike.body.statements, function (statement) {
                return action(statement) || (isAmbientModuleDeclaration(statement) && ts.forEach(statement.body && statement.body.statements, action));
            });
        }
        /** Calls `action` for each import, re-export, or require() in a file. */
        function forEachImport(sourceFile, action) {
            if (sourceFile.externalModuleIndicator || sourceFile.imports !== undefined) {
                for (var _i = 0, _a = sourceFile.imports; _i < _a.length; _i++) {
                    var i = _a[_i];
                    action(ts.importFromModuleSpecifier(i), i);
                }
            }
            else {
                forEachPossibleImportOrExportStatement(sourceFile, function (statement) {
                    switch (statement.kind) {
                        case 256 /* ExportDeclaration */:
                        case 250 /* ImportDeclaration */: {
                            var decl = statement;
                            if (decl.moduleSpecifier && ts.isStringLiteral(decl.moduleSpecifier)) {
                                action(decl, decl.moduleSpecifier);
                            }
                            break;
                        }
                        case 249 /* ImportEqualsDeclaration */: {
                            var decl = statement;
                            if (isExternalModuleImportEquals(decl)) {
                                action(decl, decl.moduleReference.expression);
                            }
                            break;
                        }
                    }
                });
            }
        }
        /**
         * Given a local reference, we might notice that it's an import/export and recursively search for references of that.
         * If at an import, look locally for the symbol it imports.
         * If an an export, look for all imports of it.
         * This doesn't handle export specifiers; that is done in `getReferencesAtExportSpecifier`.
         * @param comingFromExport If we are doing a search for all exports, don't bother looking backwards for the imported symbol, since that's the reason we're here.
         */
        function getImportOrExportSymbol(node, symbol, checker, comingFromExport) {
            return comingFromExport ? getExport() : getExport() || getImport();
            function getExport() {
                var parent = node.parent;
                var grandParent = parent.parent;
                if (symbol.exportSymbol) {
                    if (parent.kind === 190 /* PropertyAccessExpression */) {
                        // When accessing an export of a JS module, there's no alias. The symbol will still be flagged as an export even though we're at the use.
                        // So check that we are at the declaration.
                        return symbol.declarations.some(function (d) { return d === parent; }) && ts.isBinaryExpression(grandParent)
                            ? getSpecialPropertyExport(grandParent, /*useLhsSymbol*/ false)
                            : undefined;
                    }
                    else {
                        return exportInfo(symbol.exportSymbol, getExportKindForDeclaration(parent));
                    }
                }
                else {
                    var exportNode = getExportNode(parent, node);
                    if (exportNode && ts.hasModifier(exportNode, 1 /* Export */)) {
                        if (ts.isImportEqualsDeclaration(exportNode) && exportNode.moduleReference === node) {
                            // We're at `Y` in `export import X = Y`. This is not the exported symbol, the left-hand-side is. So treat this as an import statement.
                            if (comingFromExport) {
                                return undefined;
                            }
                            var lhsSymbol = checker.getSymbolAtLocation(exportNode.name);
                            return { kind: 0 /* Import */, symbol: lhsSymbol };
                        }
                        else {
                            return exportInfo(symbol, getExportKindForDeclaration(exportNode));
                        }
                    }
                    // If we are in `export = a;` or `export default a;`, `parent` is the export assignment.
                    else if (ts.isExportAssignment(parent)) {
                        return getExportAssignmentExport(parent);
                    }
                    // If we are in `export = class A {};` (or `export = class A {};`) at `A`, `parent.parent` is the export assignment.
                    else if (ts.isExportAssignment(grandParent)) {
                        return getExportAssignmentExport(grandParent);
                    }
                    // Similar for `module.exports =` and `exports.A =`.
                    else if (ts.isBinaryExpression(parent)) {
                        return getSpecialPropertyExport(parent, /*useLhsSymbol*/ true);
                    }
                    else if (ts.isBinaryExpression(grandParent)) {
                        return getSpecialPropertyExport(grandParent, /*useLhsSymbol*/ true);
                    }
                    else if (ts.isJSDocTypedefTag(parent)) {
                        return exportInfo(symbol, 0 /* Named */);
                    }
                }
                function getExportAssignmentExport(ex) {
                    // Get the symbol for the `export =` node; its parent is the module it's the export of.
                    var exportingModuleSymbol = ts.Debug.assertDefined(ex.symbol.parent, "Expected export symbol to have a parent");
                    var exportKind = ex.isExportEquals ? 2 /* ExportEquals */ : 1 /* Default */;
                    return { kind: 1 /* Export */, symbol: symbol, exportInfo: { exportingModuleSymbol: exportingModuleSymbol, exportKind: exportKind } };
                }
                function getSpecialPropertyExport(node, useLhsSymbol) {
                    var kind;
                    switch (ts.getAssignmentDeclarationKind(node)) {
                        case 1 /* ExportsProperty */:
                            kind = 0 /* Named */;
                            break;
                        case 2 /* ModuleExports */:
                            kind = 2 /* ExportEquals */;
                            break;
                        default:
                            return undefined;
                    }
                    var sym = useLhsSymbol ? checker.getSymbolAtLocation(ts.cast(node.left, ts.isPropertyAccessExpression).name) : symbol;
                    // Better detection for GH#20803
                    if (sym && !(checker.getMergedSymbol(sym.parent).flags & 1536 /* Module */)) {
                        ts.Debug.fail("Special property assignment kind does not have a module as its parent. Assignment is " + ts.Debug.formatSymbol(sym) + ", parent is " + ts.Debug.formatSymbol(sym.parent));
                    }
                    return sym && exportInfo(sym, kind);
                }
            }
            function getImport() {
                var isImport = isNodeImport(node);
                if (!isImport)
                    return undefined;
                // A symbol being imported is always an alias. So get what that aliases to find the local symbol.
                var importedSymbol = checker.getImmediateAliasedSymbol(symbol);
                if (!importedSymbol)
                    return undefined;
                // Search on the local symbol in the exporting module, not the exported symbol.
                importedSymbol = skipExportSpecifierSymbol(importedSymbol, checker);
                // Similarly, skip past the symbol for 'export ='
                if (importedSymbol.escapedName === "export=") {
                    importedSymbol = getExportEqualsLocalSymbol(importedSymbol, checker);
                }
                // If the import has a different name than the export, do not continue searching.
                // If `importedName` is undefined, do continue searching as the export is anonymous.
                // (All imports returned from this function will be ignored anyway if we are in rename and this is a not a named export.)
                var importedName = ts.symbolEscapedNameNoDefault(importedSymbol);
                if (importedName === undefined || importedName === "default" /* Default */ || importedName === symbol.escapedName) {
                    return { kind: 0 /* Import */, symbol: importedSymbol };
                }
            }
            function exportInfo(symbol, kind) {
                var exportInfo = getExportInfo(symbol, kind, checker);
                return exportInfo && { kind: 1 /* Export */, symbol: symbol, exportInfo: exportInfo };
            }
            // Not meant for use with export specifiers or export assignment.
            function getExportKindForDeclaration(node) {
                return ts.hasModifier(node, 512 /* Default */) ? 1 /* Default */ : 0 /* Named */;
            }
        }
        FindAllReferences.getImportOrExportSymbol = getImportOrExportSymbol;
        function getExportEqualsLocalSymbol(importedSymbol, checker) {
            if (importedSymbol.flags & 2097152 /* Alias */) {
                return ts.Debug.assertDefined(checker.getImmediateAliasedSymbol(importedSymbol));
            }
            var decl = importedSymbol.valueDeclaration;
            if (ts.isExportAssignment(decl)) { // `export = class {}`
                return ts.Debug.assertDefined(decl.expression.symbol);
            }
            else if (ts.isBinaryExpression(decl)) { // `module.exports = class {}`
                return ts.Debug.assertDefined(decl.right.symbol);
            }
            else if (ts.isSourceFile(decl)) { // json module
                return ts.Debug.assertDefined(decl.symbol);
            }
            return ts.Debug.fail();
        }
        // If a reference is a class expression, the exported node would be its parent.
        // If a reference is a variable declaration, the exported node would be the variable statement.
        function getExportNode(parent, node) {
            if (parent.kind === 238 /* VariableDeclaration */) {
                var p = parent;
                return p.name !== node ? undefined :
                    p.parent.kind === 275 /* CatchClause */ ? undefined : p.parent.parent.kind === 220 /* VariableStatement */ ? p.parent.parent : undefined;
            }
            else {
                return parent;
            }
        }
        function isNodeImport(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 249 /* ImportEqualsDeclaration */:
                    return parent.name === node && isExternalModuleImportEquals(parent);
                case 254 /* ImportSpecifier */:
                    // For a rename import `{ foo as bar }`, don't search for the imported symbol. Just find local uses of `bar`.
                    return !parent.propertyName;
                case 251 /* ImportClause */:
                case 252 /* NamespaceImport */:
                    ts.Debug.assert(parent.name === node);
                    return true;
                default:
                    return false;
            }
        }
        function getExportInfo(exportSymbol, exportKind, checker) {
            var moduleSymbol = exportSymbol.parent;
            if (!moduleSymbol)
                return undefined; // This can happen if an `export` is not at the top-level (which is a compile error).
            var exportingModuleSymbol = checker.getMergedSymbol(moduleSymbol); // Need to get merged symbol in case there's an augmentation.
            // `export` may appear in a namespace. In that case, just rely on global search.
            return ts.isExternalModuleSymbol(exportingModuleSymbol) ? { exportingModuleSymbol: exportingModuleSymbol, exportKind: exportKind } : undefined;
        }
        FindAllReferences.getExportInfo = getExportInfo;
        /** If at an export specifier, go to the symbol it refers to. */
        function skipExportSpecifierSymbol(symbol, checker) {
            // For `export { foo } from './bar", there's nothing to skip, because it does not create a new alias. But `export { foo } does.
            if (symbol.declarations) {
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    if (ts.isExportSpecifier(declaration) && !declaration.propertyName && !declaration.parent.parent.moduleSpecifier) {
                        return checker.getExportSpecifierLocalTargetSymbol(declaration);
                    }
                }
            }
            return symbol;
        }
        function getContainingModuleSymbol(importer, checker) {
            return checker.getMergedSymbol(getSourceFileLikeForImportDeclaration(importer).symbol);
        }
        function getSourceFileLikeForImportDeclaration(node) {
            if (node.kind === 192 /* CallExpression */) {
                return node.getSourceFile();
            }
            var parent = node.parent;
            if (parent.kind === 285 /* SourceFile */) {
                return parent;
            }
            ts.Debug.assert(parent.kind === 246 /* ModuleBlock */);
            return ts.cast(parent.parent, isAmbientModuleDeclaration);
        }
        function isAmbientModuleDeclaration(node) {
            return node.kind === 245 /* ModuleDeclaration */ && node.name.kind === 10 /* StringLiteral */;
        }
        function isExternalModuleImportEquals(eq) {
            return eq.moduleReference.kind === 260 /* ExternalModuleReference */ && eq.moduleReference.expression.kind === 10 /* StringLiteral */;
        }
    })(FindAllReferences = ts.FindAllReferences || (ts.FindAllReferences = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var FindAllReferences;
    (function (FindAllReferences) {
        var DefinitionKind;
        (function (DefinitionKind) {
            DefinitionKind[DefinitionKind["Symbol"] = 0] = "Symbol";
            DefinitionKind[DefinitionKind["Label"] = 1] = "Label";
            DefinitionKind[DefinitionKind["Keyword"] = 2] = "Keyword";
            DefinitionKind[DefinitionKind["This"] = 3] = "This";
            DefinitionKind[DefinitionKind["String"] = 4] = "String";
        })(DefinitionKind = FindAllReferences.DefinitionKind || (FindAllReferences.DefinitionKind = {}));
        var EntryKind;
        (function (EntryKind) {
            EntryKind[EntryKind["Span"] = 0] = "Span";
            EntryKind[EntryKind["Node"] = 1] = "Node";
            EntryKind[EntryKind["StringLiteral"] = 2] = "StringLiteral";
            EntryKind[EntryKind["SearchedLocalFoundProperty"] = 3] = "SearchedLocalFoundProperty";
            EntryKind[EntryKind["SearchedPropertyFoundLocal"] = 4] = "SearchedPropertyFoundLocal";
        })(EntryKind = FindAllReferences.EntryKind || (FindAllReferences.EntryKind = {}));
        function nodeEntry(node, kind) {
            if (kind === void 0) { kind = 1 /* Node */; }
            return { kind: kind, node: node.name || node };
        }
        FindAllReferences.nodeEntry = nodeEntry;
        function findReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position) {
            var node = ts.getTouchingPropertyName(sourceFile, position);
            var referencedSymbols = FindAllReferences.Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken);
            var checker = program.getTypeChecker();
            return !referencedSymbols || !referencedSymbols.length ? undefined : ts.mapDefined(referencedSymbols, function (_a) {
                var definition = _a.definition, references = _a.references;
                // Only include referenced symbols that have a valid definition.
                return definition && {
                    definition: checker.runWithCancellationToken(cancellationToken, function (checker) { return definitionToReferencedSymbolDefinitionInfo(definition, checker, node); }),
                    references: references.map(toReferenceEntry)
                };
            });
        }
        FindAllReferences.findReferencedSymbols = findReferencedSymbols;
        function getImplementationsAtPosition(program, cancellationToken, sourceFiles, sourceFile, position) {
            var node = ts.getTouchingPropertyName(sourceFile, position);
            var referenceEntries = getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node, position);
            var checker = program.getTypeChecker();
            return ts.map(referenceEntries, function (entry) { return toImplementationLocation(entry, checker); });
        }
        FindAllReferences.getImplementationsAtPosition = getImplementationsAtPosition;
        function getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node, position) {
            if (node.kind === 285 /* SourceFile */) {
                return undefined;
            }
            var checker = program.getTypeChecker();
            // If invoked directly on a shorthand property assignment, then return
            // the declaration of the symbol being assigned (not the symbol being assigned to).
            if (node.parent.kind === 277 /* ShorthandPropertyAssignment */) {
                var result_1 = [];
                FindAllReferences.Core.getReferenceEntriesForShorthandPropertyAssignment(node, checker, function (node) { return result_1.push(nodeEntry(node)); });
                return result_1;
            }
            else if (node.kind === 99 /* SuperKeyword */ || ts.isSuperProperty(node.parent)) {
                // References to and accesses on the super keyword only have one possible implementation, so no
                // need to "Find all References"
                var symbol = checker.getSymbolAtLocation(node);
                return symbol.valueDeclaration && [nodeEntry(symbol.valueDeclaration)];
            }
            else {
                // Perform "Find all References" and retrieve only those that are implementations
                return getReferenceEntriesForNode(position, node, program, sourceFiles, cancellationToken, { implementations: true });
            }
        }
        function findReferenceOrRenameEntries(program, cancellationToken, sourceFiles, node, position, options, convertEntry) {
            return ts.map(flattenEntries(FindAllReferences.Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options)), function (entry) { return convertEntry(entry, node, program.getTypeChecker()); });
        }
        FindAllReferences.findReferenceOrRenameEntries = findReferenceOrRenameEntries;
        function getReferenceEntriesForNode(position, node, program, sourceFiles, cancellationToken, options, sourceFilesSet) {
            if (options === void 0) { options = {}; }
            if (sourceFilesSet === void 0) { sourceFilesSet = ts.arrayToSet(sourceFiles, function (f) { return f.fileName; }); }
            return flattenEntries(FindAllReferences.Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options, sourceFilesSet));
        }
        FindAllReferences.getReferenceEntriesForNode = getReferenceEntriesForNode;
        function flattenEntries(referenceSymbols) {
            return referenceSymbols && ts.flatMap(referenceSymbols, function (r) { return r.references; });
        }
        function definitionToReferencedSymbolDefinitionInfo(def, checker, originalNode) {
            var info = (function () {
                switch (def.type) {
                    case 0 /* Symbol */: {
                        var symbol = def.symbol;
                        var _a = getDefinitionKindAndDisplayParts(symbol, checker, originalNode), displayParts_1 = _a.displayParts, kind_1 = _a.kind;
                        var name_1 = displayParts_1.map(function (p) { return p.text; }).join("");
                        return { node: symbol.declarations ? ts.getNameOfDeclaration(ts.first(symbol.declarations)) || ts.first(symbol.declarations) : originalNode, name: name_1, kind: kind_1, displayParts: displayParts_1 };
                    }
                    case 1 /* Label */: {
                        var node_1 = def.node;
                        return { node: node_1, name: node_1.text, kind: "label" /* label */, displayParts: [ts.displayPart(node_1.text, ts.SymbolDisplayPartKind.text)] };
                    }
                    case 2 /* Keyword */: {
                        var node_2 = def.node;
                        var name_2 = ts.tokenToString(node_2.kind);
                        return { node: node_2, name: name_2, kind: "keyword" /* keyword */, displayParts: [{ text: name_2, kind: "keyword" /* keyword */ }] };
                    }
                    case 3 /* This */: {
                        var node_3 = def.node;
                        var symbol = checker.getSymbolAtLocation(node_3);
                        var displayParts_2 = symbol && ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, node_3.getSourceFile(), ts.getContainerNode(node_3), node_3).displayParts || [ts.textPart("this")];
                        return { node: node_3, name: "this", kind: "var" /* variableElement */, displayParts: displayParts_2 };
                    }
                    case 4 /* String */: {
                        var node_4 = def.node;
                        return { node: node_4, name: node_4.text, kind: "var" /* variableElement */, displayParts: [ts.displayPart(ts.getTextOfNode(node_4), ts.SymbolDisplayPartKind.stringLiteral)] };
                    }
                    default:
                        return ts.Debug.assertNever(def);
                }
            })();
            var node = info.node, name = info.name, kind = info.kind, displayParts = info.displayParts;
            var sourceFile = node.getSourceFile();
            return { containerKind: "" /* unknown */, containerName: "", fileName: sourceFile.fileName, kind: kind, name: name, textSpan: getTextSpan(ts.isComputedPropertyName(node) ? node.expression : node, sourceFile), displayParts: displayParts };
        }
        function getDefinitionKindAndDisplayParts(symbol, checker, node) {
            var meaning = FindAllReferences.Core.getIntersectingMeaningFromDeclarations(node, symbol);
            var enclosingDeclaration = symbol.declarations && ts.firstOrUndefined(symbol.declarations) || node;
            var _a = ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, enclosingDeclaration.getSourceFile(), enclosingDeclaration, enclosingDeclaration, meaning), displayParts = _a.displayParts, symbolKind = _a.symbolKind;
            return { displayParts: displayParts, kind: symbolKind };
        }
        function toRenameLocation(entry, originalNode, checker, providePrefixAndSuffixText) {
            return __assign({}, entryToDocumentSpan(entry), (providePrefixAndSuffixText && getPrefixAndSuffixText(entry, originalNode, checker)));
        }
        FindAllReferences.toRenameLocation = toRenameLocation;
        function toReferenceEntry(entry) {
            var _a = entryToDocumentSpan(entry), textSpan = _a.textSpan, fileName = _a.fileName;
            if (entry.kind === 0 /* Span */) {
                return { textSpan: textSpan, fileName: fileName, isWriteAccess: false, isDefinition: false };
            }
            var kind = entry.kind, node = entry.node;
            return {
                textSpan: textSpan,
                fileName: fileName,
                isWriteAccess: isWriteAccessForReference(node),
                isDefinition: node.kind === 81 /* DefaultKeyword */
                    || !!ts.getDeclarationFromName(node)
                    || ts.isLiteralComputedPropertyDeclarationName(node),
                isInString: kind === 2 /* StringLiteral */ ? true : undefined,
            };
        }
        FindAllReferences.toReferenceEntry = toReferenceEntry;
        function entryToDocumentSpan(entry) {
            if (entry.kind === 0 /* Span */) {
                return { textSpan: entry.textSpan, fileName: entry.fileName };
            }
            else {
                var sourceFile = entry.node.getSourceFile();
                return { textSpan: getTextSpan(entry.node, sourceFile), fileName: sourceFile.fileName };
            }
        }
        function getPrefixAndSuffixText(entry, originalNode, checker) {
            if (entry.kind !== 0 /* Span */ && ts.isIdentifier(originalNode)) {
                var node = entry.node, kind = entry.kind;
                var name = originalNode.text;
                var isShorthandAssignment = ts.isShorthandPropertyAssignment(node.parent);
                if (isShorthandAssignment || ts.isObjectBindingElementWithoutPropertyName(node.parent)) {
                    var prefixColon = { prefixText: name + ": " };
                    var suffixColon = { suffixText: ": " + name };
                    return kind === 3 /* SearchedLocalFoundProperty */ ? prefixColon
                        : kind === 4 /* SearchedPropertyFoundLocal */ ? suffixColon
                            // In `const o = { x }; o.x`, symbolAtLocation at `x` in `{ x }` is the property symbol.
                            // For a binding element `const { x } = o;`, symbolAtLocation at `x` is the property symbol.
                            : isShorthandAssignment ? suffixColon : prefixColon;
                }
                else if (ts.isImportSpecifier(entry.node.parent) && !entry.node.parent.propertyName) {
                    // If the original symbol was using this alias, just rename the alias.
                    var originalSymbol = ts.isExportSpecifier(originalNode.parent) ? checker.getExportSpecifierLocalTargetSymbol(originalNode.parent) : checker.getSymbolAtLocation(originalNode);
                    return ts.contains(originalSymbol.declarations, entry.node.parent) ? { prefixText: name + " as " } : ts.emptyOptions;
                }
                else if (ts.isExportSpecifier(entry.node.parent) && !entry.node.parent.propertyName) {
                    return originalNode === entry.node ? { prefixText: name + " as " } : { suffixText: " as " + name };
                }
            }
            return ts.emptyOptions;
        }
        function toImplementationLocation(entry, checker) {
            if (entry.kind !== 0 /* Span */) {
                var node = entry.node;
                var sourceFile = node.getSourceFile();
                return __assign({ textSpan: getTextSpan(node, sourceFile), fileName: sourceFile.fileName }, implementationKindDisplayParts(node, checker));
            }
            else {
                var textSpan = entry.textSpan, fileName = entry.fileName;
                return { textSpan: textSpan, fileName: fileName, kind: "" /* unknown */, displayParts: [] };
            }
        }
        function implementationKindDisplayParts(node, checker) {
            var symbol = checker.getSymbolAtLocation(ts.isDeclaration(node) && node.name ? node.name : node);
            if (symbol) {
                return getDefinitionKindAndDisplayParts(symbol, checker, node);
            }
            else if (node.kind === 189 /* ObjectLiteralExpression */) {
                return {
                    kind: "interface" /* interfaceElement */,
                    displayParts: [ts.punctuationPart(20 /* OpenParenToken */), ts.textPart("object literal"), ts.punctuationPart(21 /* CloseParenToken */)]
                };
            }
            else if (node.kind === 210 /* ClassExpression */) {
                return {
                    kind: "local class" /* localClassElement */,
                    displayParts: [ts.punctuationPart(20 /* OpenParenToken */), ts.textPart("anonymous local class"), ts.punctuationPart(21 /* CloseParenToken */)]
                };
            }
            else {
                return { kind: ts.getNodeKind(node), displayParts: [] };
            }
        }
        function toHighlightSpan(entry) {
            if (entry.kind === 0 /* Span */) {
                var fileName = entry.fileName, textSpan = entry.textSpan;
                return { fileName: fileName, span: { textSpan: textSpan, kind: "reference" /* reference */ } };
            }
            var node = entry.node, kind = entry.kind;
            var sourceFile = node.getSourceFile();
            var writeAccess = isWriteAccessForReference(node);
            var span = {
                textSpan: getTextSpan(node, sourceFile),
                kind: writeAccess ? "writtenReference" /* writtenReference */ : "reference" /* reference */,
                isInString: kind === 2 /* StringLiteral */ ? true : undefined,
            };
            return { fileName: sourceFile.fileName, span: span };
        }
        FindAllReferences.toHighlightSpan = toHighlightSpan;
        function getTextSpan(node, sourceFile) {
            var start = node.getStart(sourceFile);
            var end = node.getEnd();
            if (node.kind === 10 /* StringLiteral */) {
                start += 1;
                end -= 1;
            }
            return ts.createTextSpanFromBounds(start, end);
        }
        function getTextSpanOfEntry(entry) {
            return entry.kind === 0 /* Span */ ? entry.textSpan :
                getTextSpan(entry.node, entry.node.getSourceFile());
        }
        FindAllReferences.getTextSpanOfEntry = getTextSpanOfEntry;
        /** A node is considered a writeAccess iff it is a name of a declaration or a target of an assignment */
        function isWriteAccessForReference(node) {
            var decl = ts.getDeclarationFromName(node);
            return !!decl && declarationIsWriteAccess(decl) || node.kind === 81 /* DefaultKeyword */ || ts.isWriteAccess(node);
        }
        /**
         * True if 'decl' provides a value, as in `function f() {}`;
         * false if 'decl' is just a location for a future write, as in 'let x;'
         */
        function declarationIsWriteAccess(decl) {
            // Consider anything in an ambient declaration to be a write access since it may be coming from JS.
            if (!!(decl.flags & 4194304 /* Ambient */))
                return true;
            switch (decl.kind) {
                case 205 /* BinaryExpression */:
                case 187 /* BindingElement */:
                case 241 /* ClassDeclaration */:
                case 210 /* ClassExpression */:
                case 81 /* DefaultKeyword */:
                case 244 /* EnumDeclaration */:
                case 279 /* EnumMember */:
                case 258 /* ExportSpecifier */:
                case 251 /* ImportClause */: // default import
                case 249 /* ImportEqualsDeclaration */:
                case 254 /* ImportSpecifier */:
                case 242 /* InterfaceDeclaration */:
                case 303 /* JSDocCallbackTag */:
                case 310 /* JSDocTypedefTag */:
                case 268 /* JsxAttribute */:
                case 245 /* ModuleDeclaration */:
                case 248 /* NamespaceExportDeclaration */:
                case 252 /* NamespaceImport */:
                case 152 /* Parameter */:
                case 277 /* ShorthandPropertyAssignment */:
                case 243 /* TypeAliasDeclaration */:
                case 151 /* TypeParameter */:
                    return true;
                case 276 /* PropertyAssignment */:
                    // In `({ x: y } = 0);`, `x` is not a write access. (Won't call this function for `y`.)
                    return !ts.isArrayLiteralOrObjectLiteralDestructuringPattern(decl.parent);
                case 240 /* FunctionDeclaration */:
                case 197 /* FunctionExpression */:
                case 158 /* Constructor */:
                case 157 /* MethodDeclaration */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    return !!decl.body;
                case 238 /* VariableDeclaration */:
                case 155 /* PropertyDeclaration */:
                    return !!decl.initializer || ts.isCatchClause(decl.parent);
                case 156 /* MethodSignature */:
                case 154 /* PropertySignature */:
                case 311 /* JSDocPropertyTag */:
                case 305 /* JSDocParameterTag */:
                    return false;
                default:
                    return ts.Debug.failBadSyntaxKind(decl);
            }
        }
    })(FindAllReferences = ts.FindAllReferences || (ts.FindAllReferences = {}));
})(ts || (ts = {}));
/** Encapsulates the core find-all-references algorithm. */
/* @internal */
(function (ts) {
    var FindAllReferences;
    (function (FindAllReferences) {
        var Core;
        (function (Core) {
            /** Core find-all-references algorithm. Handles special cases before delegating to `getReferencedSymbolsForSymbol`. */
            function getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options, sourceFilesSet) {
                if (options === void 0) { options = {}; }
                if (sourceFilesSet === void 0) { sourceFilesSet = ts.arrayToSet(sourceFiles, function (f) { return f.fileName; }); }
                if (ts.isSourceFile(node)) {
                    var reference = ts.GoToDefinition.getReferenceAtPosition(node, position, program);
                    var moduleSymbol = reference && program.getTypeChecker().getMergedSymbol(reference.file.symbol);
                    return moduleSymbol && getReferencedSymbolsForModule(program, moduleSymbol, /*excludeImportTypeOfExportEquals*/ false, sourceFiles, sourceFilesSet);
                }
                if (!options.implementations) {
                    var special = getReferencedSymbolsSpecial(node, sourceFiles, cancellationToken);
                    if (special) {
                        return special;
                    }
                }
                var checker = program.getTypeChecker();
                var symbol = checker.getSymbolAtLocation(node);
                // Could not find a symbol e.g. unknown identifier
                if (!symbol) {
                    // String literal might be a property (and thus have a symbol), so do this here rather than in getReferencedSymbolsSpecial.
                    return !options.implementations && ts.isStringLiteral(node) ? getReferencesForStringLiteral(node, sourceFiles, cancellationToken) : undefined;
                }
                if (symbol.escapedName === "export=" /* ExportEquals */) {
                    return getReferencedSymbolsForModule(program, symbol.parent, /*excludeImportTypeOfExportEquals*/ false, sourceFiles, sourceFilesSet);
                }
                var moduleReferences = getReferencedSymbolsForModuleIfDeclaredBySourceFile(symbol, program, sourceFiles, cancellationToken, options, sourceFilesSet);
                if (moduleReferences && !(symbol.flags & 33554432 /* Transient */)) {
                    return moduleReferences;
                }
                var aliasedSymbol = getMergedAliasedSymbolOfNamespaceExportDeclaration(node, symbol, checker);
                var moduleReferencesOfExportTarget = aliasedSymbol &&
                    getReferencedSymbolsForModuleIfDeclaredBySourceFile(aliasedSymbol, program, sourceFiles, cancellationToken, options, sourceFilesSet);
                var references = getReferencedSymbolsForSymbol(symbol, node, sourceFiles, sourceFilesSet, checker, cancellationToken, options);
                return mergeReferences(program, moduleReferences, references, moduleReferencesOfExportTarget);
            }
            Core.getReferencedSymbolsForNode = getReferencedSymbolsForNode;
            function getMergedAliasedSymbolOfNamespaceExportDeclaration(node, symbol, checker) {
                if (node.parent && ts.isNamespaceExportDeclaration(node.parent)) {
                    var aliasedSymbol = checker.getAliasedSymbol(symbol);
                    var targetSymbol = checker.getMergedSymbol(aliasedSymbol);
                    if (aliasedSymbol !== targetSymbol) {
                        return targetSymbol;
                    }
                }
                return undefined;
            }
            function getReferencedSymbolsForModuleIfDeclaredBySourceFile(symbol, program, sourceFiles, cancellationToken, options, sourceFilesSet) {
                var moduleSourceFile = symbol.flags & 1536 /* Module */ ? ts.find(symbol.declarations, ts.isSourceFile) : undefined;
                if (!moduleSourceFile)
                    return undefined;
                var exportEquals = symbol.exports.get("export=" /* ExportEquals */);
                // If !!exportEquals, we're about to add references to `import("mod")` anyway, so don't double-count them.
                var moduleReferences = getReferencedSymbolsForModule(program, symbol, !!exportEquals, sourceFiles, sourceFilesSet);
                if (!exportEquals || !sourceFilesSet.has(moduleSourceFile.fileName))
                    return moduleReferences;
                // Continue to get references to 'export ='.
                var checker = program.getTypeChecker();
                symbol = ts.skipAlias(exportEquals, checker);
                return mergeReferences(program, moduleReferences, getReferencedSymbolsForSymbol(symbol, /*node*/ undefined, sourceFiles, sourceFilesSet, checker, cancellationToken, options));
            }
            /**
             * Merges the references by sorting them (by file index in sourceFiles and their location in it) that point to same definition symbol
             */
            function mergeReferences(program) {
                var referencesToMerge = [];
                for (var _i = 1; _i < arguments.length; _i++) {
                    referencesToMerge[_i - 1] = arguments[_i];
                }
                var result;
                for (var _a = 0, referencesToMerge_1 = referencesToMerge; _a < referencesToMerge_1.length; _a++) {
                    var references = referencesToMerge_1[_a];
                    if (!references || !references.length)
                        continue;
                    if (!result) {
                        result = references;
                        continue;
                    }
                    var _loop_3 = function (entry) {
                        if (!entry.definition || entry.definition.type !== 0 /* Symbol */) {
                            result.push(entry);
                            return "continue";
                        }
                        var symbol = entry.definition.symbol;
                        var refIndex = ts.findIndex(result, function (ref) { return !!ref.definition &&
                            ref.definition.type === 0 /* Symbol */ &&
                            ref.definition.symbol === symbol; });
                        if (refIndex === -1) {
                            result.push(entry);
                            return "continue";
                        }
                        var reference = result[refIndex];
                        result[refIndex] = {
                            definition: reference.definition,
                            references: reference.references.concat(entry.references).sort(function (entry1, entry2) {
                                var entry1File = getSourceFileIndexOfEntry(program, entry1);
                                var entry2File = getSourceFileIndexOfEntry(program, entry2);
                                if (entry1File !== entry2File) {
                                    return ts.compareValues(entry1File, entry2File);
                                }
                                var entry1Span = FindAllReferences.getTextSpanOfEntry(entry1);
                                var entry2Span = FindAllReferences.getTextSpanOfEntry(entry2);
                                return entry1Span.start !== entry2Span.start ?
                                    ts.compareValues(entry1Span.start, entry2Span.start) :
                                    ts.compareValues(entry1Span.length, entry2Span.length);
                            })
                        };
                    };
                    for (var _b = 0, references_1 = references; _b < references_1.length; _b++) {
                        var entry = references_1[_b];
                        _loop_3(entry);
                    }
                }
                return result;
            }
            function getSourceFileIndexOfEntry(program, entry) {
                var sourceFile = entry.kind === 0 /* Span */ ?
                    program.getSourceFile(entry.fileName) :
                    entry.node.getSourceFile();
                return program.getSourceFiles().indexOf(sourceFile);
            }
            function getReferencedSymbolsForModule(program, symbol, excludeImportTypeOfExportEquals, sourceFiles, sourceFilesSet) {
                ts.Debug.assert(!!symbol.valueDeclaration);
                var references = ts.mapDefined(FindAllReferences.findModuleReferences(program, sourceFiles, symbol), function (reference) {
                    if (reference.kind === "import") {
                        var parent = reference.literal.parent;
                        if (ts.isLiteralTypeNode(parent)) {
                            var importType = ts.cast(parent.parent, ts.isImportTypeNode);
                            if (excludeImportTypeOfExportEquals && !importType.qualifier) {
                                return undefined;
                            }
                        }
                        // import("foo") with no qualifier will reference the `export =` of the module, which may be referenced anyway.
                        return FindAllReferences.nodeEntry(reference.literal);
                    }
                    else {
                        return {
                            kind: 0 /* Span */,
                            fileName: reference.referencingFile.fileName,
                            textSpan: ts.createTextSpanFromRange(reference.ref),
                        };
                    }
                });
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    switch (decl.kind) {
                        case 285 /* SourceFile */:
                            // Don't include the source file itself. (This may not be ideal behavior, but awkward to include an entire file as a reference.)
                            break;
                        case 245 /* ModuleDeclaration */:
                            if (sourceFilesSet.has(decl.getSourceFile().fileName)) {
                                references.push(FindAllReferences.nodeEntry(decl.name));
                            }
                            break;
                        default:
                            // This may be merged with something.
                            ts.Debug.assert(!!(symbol.flags & 33554432 /* Transient */), "Expected a module symbol to be declared by a SourceFile or ModuleDeclaration.");
                    }
                }
                var exported = symbol.exports.get("export=" /* ExportEquals */);
                if (exported) {
                    for (var _b = 0, _c = exported.declarations; _b < _c.length; _b++) {
                        var decl = _c[_b];
                        var sourceFile = decl.getSourceFile();
                        if (sourceFilesSet.has(sourceFile.fileName)) {
                            // At `module.exports = ...`, reference node is `module`
                            var node = ts.isBinaryExpression(decl) && ts.isPropertyAccessExpression(decl.left)
                                ? decl.left.expression
                                : ts.isExportAssignment(decl)
                                    ? ts.Debug.assertDefined(ts.findChildOfKind(decl, 86 /* ExportKeyword */, sourceFile))
                                    : ts.getNameOfDeclaration(decl) || decl;
                            references.push(FindAllReferences.nodeEntry(node));
                        }
                    }
                }
                return references.length ? [{ definition: { type: 0 /* Symbol */, symbol: symbol }, references: references }] : ts.emptyArray;
            }
            /** getReferencedSymbols for special node kinds. */
            function getReferencedSymbolsSpecial(node, sourceFiles, cancellationToken) {
                if (ts.isTypeKeyword(node.kind)) {
                    return getAllReferencesForKeyword(sourceFiles, node.kind, cancellationToken);
                }
                // Labels
                if (ts.isJumpStatementTarget(node)) {
                    var labelDefinition = ts.getTargetLabel(node.parent, node.text);
                    // if we have a label definition, look within its statement for references, if not, then
                    // the label is undefined and we have no results..
                    return labelDefinition && getLabelReferencesInNode(labelDefinition.parent, labelDefinition);
                }
                else if (ts.isLabelOfLabeledStatement(node)) {
                    // it is a label definition and not a target, search within the parent labeledStatement
                    return getLabelReferencesInNode(node.parent, node);
                }
                if (ts.isThis(node)) {
                    return getReferencesForThisKeyword(node, sourceFiles, cancellationToken);
                }
                if (node.kind === 99 /* SuperKeyword */) {
                    return getReferencesForSuperKeyword(node);
                }
                return undefined;
            }
            /** Core find-all-references algorithm for a normal symbol. */
            function getReferencedSymbolsForSymbol(originalSymbol, node, sourceFiles, sourceFilesSet, checker, cancellationToken, options) {
                var symbol = node && skipPastExportOrImportSpecifierOrUnion(originalSymbol, node, checker, /*useLocalSymbolForExportSpecifier*/ !isForRenameWithPrefixAndSuffixText(options)) || originalSymbol;
                // Compute the meaning from the location and the symbol it references
                var searchMeaning = node ? getIntersectingMeaningFromDeclarations(node, symbol) : 7 /* All */;
                var result = [];
                var state = new State(sourceFiles, sourceFilesSet, node ? getSpecialSearchKind(node) : 0 /* None */, checker, cancellationToken, searchMeaning, options, result);
                var exportSpecifier = !isForRenameWithPrefixAndSuffixText(options) ? undefined : ts.find(symbol.declarations, ts.isExportSpecifier);
                if (exportSpecifier) {
                    // When renaming at an export specifier, rename the export and not the thing being exported.
                    getReferencesAtExportSpecifier(exportSpecifier.name, symbol, exportSpecifier, state.createSearch(node, originalSymbol, /*comingFrom*/ undefined), state, /*addReferencesHere*/ true, /*alwaysGetReferences*/ true);
                }
                else if (node && node.kind === 81 /* DefaultKeyword */) {
                    addReference(node, symbol, state);
                    searchForImportsOfExport(node, symbol, { exportingModuleSymbol: ts.Debug.assertDefined(symbol.parent, "Expected export symbol to have a parent"), exportKind: 1 /* Default */ }, state);
                }
                else {
                    var search = state.createSearch(node, symbol, /*comingFrom*/ undefined, { allSearchSymbols: node ? populateSearchSymbolSet(symbol, node, checker, !!options.isForRename, !!options.providePrefixAndSuffixTextForRename, !!options.implementations) : [symbol] });
                    getReferencesInContainerOrFiles(symbol, state, search);
                }
                return result;
            }
            function getReferencesInContainerOrFiles(symbol, state, search) {
                // Try to get the smallest valid scope that we can limit our search to;
                // otherwise we'll need to search globally (i.e. include each file).
                var scope = getSymbolScope(symbol);
                if (scope) {
                    getReferencesInContainer(scope, scope.getSourceFile(), search, state, /*addReferencesHere*/ !(ts.isSourceFile(scope) && !ts.contains(state.sourceFiles, scope)));
                }
                else {
                    // Global search
                    for (var _i = 0, _a = state.sourceFiles; _i < _a.length; _i++) {
                        var sourceFile = _a[_i];
                        state.cancellationToken.throwIfCancellationRequested();
                        searchForName(sourceFile, search, state);
                    }
                }
            }
            function getSpecialSearchKind(node) {
                switch (node.kind) {
                    case 125 /* ConstructorKeyword */:
                        return 1 /* Constructor */;
                    case 73 /* Identifier */:
                        if (ts.isClassLike(node.parent)) {
                            ts.Debug.assert(node.parent.name === node);
                            return 2 /* Class */;
                        }
                    // falls through
                    default:
                        return 0 /* None */;
                }
            }
            /** Handle a few special cases relating to export/import specifiers. */
            function skipPastExportOrImportSpecifierOrUnion(symbol, node, checker, useLocalSymbolForExportSpecifier) {
                var parent = node.parent;
                if (ts.isExportSpecifier(parent) && useLocalSymbolForExportSpecifier) {
                    return getLocalSymbolForExportSpecifier(node, symbol, parent, checker);
                }
                // If the symbol is declared as part of a declaration like `{ type: "a" } | { type: "b" }`, use the property on the union type to get more references.
                return ts.firstDefined(symbol.declarations, function (decl) {
                    if (!decl.parent) {
                        // Ignore UMD module and global merge
                        if (symbol.flags & 33554432 /* Transient */)
                            return undefined;
                        // Assertions for GH#21814. We should be handling SourceFile symbols in `getReferencedSymbolsForModule` instead of getting here.
                        ts.Debug.fail("Unexpected symbol at " + ts.Debug.formatSyntaxKind(node.kind) + ": " + ts.Debug.formatSymbol(symbol));
                    }
                    return ts.isTypeLiteralNode(decl.parent) && ts.isUnionTypeNode(decl.parent.parent)
                        ? checker.getPropertyOfType(checker.getTypeFromTypeNode(decl.parent.parent), symbol.name)
                        : undefined;
                });
            }
            var SpecialSearchKind;
            (function (SpecialSearchKind) {
                SpecialSearchKind[SpecialSearchKind["None"] = 0] = "None";
                SpecialSearchKind[SpecialSearchKind["Constructor"] = 1] = "Constructor";
                SpecialSearchKind[SpecialSearchKind["Class"] = 2] = "Class";
            })(SpecialSearchKind || (SpecialSearchKind = {}));
            function getNonModuleSymbolOfMergedModuleSymbol(symbol) {
                if (!(symbol.flags & (1536 /* Module */ | 33554432 /* Transient */)))
                    return undefined;
                var decl = symbol.declarations && ts.find(symbol.declarations, function (d) { return !ts.isSourceFile(d) && !ts.isModuleDeclaration(d); });
                return decl && decl.symbol;
            }
            /**
             * Holds all state needed for the finding references.
             * Unlike `Search`, there is only one `State`.
             */
            var State = /** @class */ (function () {
                function State(sourceFiles, sourceFilesSet, specialSearchKind, checker, cancellationToken, searchMeaning, options, result) {
                    this.sourceFiles = sourceFiles;
                    this.sourceFilesSet = sourceFilesSet;
                    this.specialSearchKind = specialSearchKind;
                    this.checker = checker;
                    this.cancellationToken = cancellationToken;
                    this.searchMeaning = searchMeaning;
                    this.options = options;
                    this.result = result;
                    /** Cache for `explicitlyinheritsFrom`. */
                    this.inheritsFromCache = ts.createMap();
                    /**
                     * Type nodes can contain multiple references to the same type. For example:
                     *      let x: Foo & (Foo & Bar) = ...
                     * Because we are returning the implementation locations and not the identifier locations,
                     * duplicate entries would be returned here as each of the type references is part of
                     * the same implementation. For that reason, check before we add a new entry.
                     */
                    this.markSeenContainingTypeReference = ts.nodeSeenTracker();
                    /**
                     * It's possible that we will encounter the right side of `export { foo as bar } from "x";` more than once.
                     * For example:
                     *     // b.ts
                     *     export { foo as bar } from "./a";
                     *     import { bar } from "./b";
                     *
                     * Normally at `foo as bar` we directly add `foo` and do not locally search for it (since it doesn't declare a local).
                     * But another reference to it may appear in the same source file.
                     * See `tests/cases/fourslash/transitiveExportImports3.ts`.
                     */
                    this.markSeenReExportRHS = ts.nodeSeenTracker();
                    this.symbolIdToReferences = [];
                    // Source file ID → symbol ID → Whether the symbol has been searched for in the source file.
                    this.sourceFileToSeenSymbols = [];
                }
                State.prototype.includesSourceFile = function (sourceFile) {
                    return this.sourceFilesSet.has(sourceFile.fileName);
                };
                /** Gets every place to look for references of an exported symbols. See `ImportsResult` in `importTracker.ts` for more documentation. */
                State.prototype.getImportSearches = function (exportSymbol, exportInfo) {
                    if (!this.importTracker)
                        this.importTracker = FindAllReferences.createImportTracker(this.sourceFiles, this.sourceFilesSet, this.checker, this.cancellationToken);
                    return this.importTracker(exportSymbol, exportInfo, !!this.options.isForRename);
                };
                /** @param allSearchSymbols set of additional symbols for use by `includes`. */
                State.prototype.createSearch = function (location, symbol, comingFrom, searchOptions) {
                    if (searchOptions === void 0) { searchOptions = {}; }
                    // Note: if this is an external module symbol, the name doesn't include quotes.
                    // Note: getLocalSymbolForExportDefault handles `export default class C {}`, but not `export default C` or `export { C as default }`.
                    // The other two forms seem to be handled downstream (e.g. in `skipPastExportOrImportSpecifier`), so special-casing the first form
                    // here appears to be intentional).
                    var _a = searchOptions.text, text = _a === void 0 ? ts.stripQuotes(ts.unescapeLeadingUnderscores((ts.getLocalSymbolForExportDefault(symbol) || getNonModuleSymbolOfMergedModuleSymbol(symbol) || symbol).escapedName)) : _a, _b = searchOptions.allSearchSymbols, allSearchSymbols = _b === void 0 ? [symbol] : _b;
                    var escapedText = ts.escapeLeadingUnderscores(text);
                    var parents = this.options.implementations && location ? getParentSymbolsOfPropertyAccess(location, symbol, this.checker) : undefined;
                    return { symbol: symbol, comingFrom: comingFrom, text: text, escapedText: escapedText, parents: parents, allSearchSymbols: allSearchSymbols, includes: function (sym) { return ts.contains(allSearchSymbols, sym); } };
                };
                /**
                 * Callback to add references for a particular searched symbol.
                 * This initializes a reference group, so only call this if you will add at least one reference.
                 */
                State.prototype.referenceAdder = function (searchSymbol) {
                    var symbolId = ts.getSymbolId(searchSymbol);
                    var references = this.symbolIdToReferences[symbolId];
                    if (!references) {
                        references = this.symbolIdToReferences[symbolId] = [];
                        this.result.push({ definition: { type: 0 /* Symbol */, symbol: searchSymbol }, references: references });
                    }
                    return function (node, kind) { return references.push(FindAllReferences.nodeEntry(node, kind)); };
                };
                /** Add a reference with no associated definition. */
                State.prototype.addStringOrCommentReference = function (fileName, textSpan) {
                    this.result.push({
                        definition: undefined,
                        references: [{ kind: 0 /* Span */, fileName: fileName, textSpan: textSpan }]
                    });
                };
                /** Returns `true` the first time we search for a symbol in a file and `false` afterwards. */
                State.prototype.markSearchedSymbols = function (sourceFile, symbols) {
                    var sourceId = ts.getNodeId(sourceFile);
                    var seenSymbols = this.sourceFileToSeenSymbols[sourceId] || (this.sourceFileToSeenSymbols[sourceId] = ts.createMap());
                    var anyNewSymbols = false;
                    for (var _i = 0, symbols_3 = symbols; _i < symbols_3.length; _i++) {
                        var sym = symbols_3[_i];
                        anyNewSymbols = ts.addToSeen(seenSymbols, ts.getSymbolId(sym)) || anyNewSymbols;
                    }
                    return anyNewSymbols;
                };
                return State;
            }());
            /** Search for all imports of a given exported symbol using `State.getImportSearches`. */
            function searchForImportsOfExport(exportLocation, exportSymbol, exportInfo, state) {
                var _a = state.getImportSearches(exportSymbol, exportInfo), importSearches = _a.importSearches, singleReferences = _a.singleReferences, indirectUsers = _a.indirectUsers;
                // For `import { foo as bar }` just add the reference to `foo`, and don't otherwise search in the file.
                if (singleReferences.length) {
                    var addRef = state.referenceAdder(exportSymbol);
                    for (var _i = 0, singleReferences_1 = singleReferences; _i < singleReferences_1.length; _i++) {
                        var singleRef = singleReferences_1[_i];
                        if (shouldAddSingleReference(singleRef, state))
                            addRef(singleRef);
                    }
                }
                // For each import, find all references to that import in its source file.
                for (var _b = 0, importSearches_1 = importSearches; _b < importSearches_1.length; _b++) {
                    var _c = importSearches_1[_b], importLocation = _c[0], importSymbol = _c[1];
                    getReferencesInSourceFile(importLocation.getSourceFile(), state.createSearch(importLocation, importSymbol, 1 /* Export */), state);
                }
                if (indirectUsers.length) {
                    var indirectSearch = void 0;
                    switch (exportInfo.exportKind) {
                        case 0 /* Named */:
                            indirectSearch = state.createSearch(exportLocation, exportSymbol, 1 /* Export */);
                            break;
                        case 1 /* Default */:
                            // Search for a property access to '.default'. This can't be renamed.
                            indirectSearch = state.options.isForRename ? undefined : state.createSearch(exportLocation, exportSymbol, 1 /* Export */, { text: "default" });
                            break;
                        case 2 /* ExportEquals */:
                            break;
                    }
                    if (indirectSearch) {
                        for (var _d = 0, indirectUsers_1 = indirectUsers; _d < indirectUsers_1.length; _d++) {
                            var indirectUser = indirectUsers_1[_d];
                            searchForName(indirectUser, indirectSearch, state);
                        }
                    }
                }
            }
            function eachExportReference(sourceFiles, checker, cancellationToken, exportSymbol, exportingModuleSymbol, exportName, isDefaultExport, cb) {
                var importTracker = FindAllReferences.createImportTracker(sourceFiles, ts.arrayToSet(sourceFiles, function (f) { return f.fileName; }), checker, cancellationToken);
                var _a = importTracker(exportSymbol, { exportKind: isDefaultExport ? 1 /* Default */ : 0 /* Named */, exportingModuleSymbol: exportingModuleSymbol }, /*isForRename*/ false), importSearches = _a.importSearches, indirectUsers = _a.indirectUsers;
                for (var _i = 0, importSearches_2 = importSearches; _i < importSearches_2.length; _i++) {
                    var importLocation = importSearches_2[_i][0];
                    cb(importLocation);
                }
                for (var _b = 0, indirectUsers_2 = indirectUsers; _b < indirectUsers_2.length; _b++) {
                    var indirectUser = indirectUsers_2[_b];
                    for (var _c = 0, _d = getPossibleSymbolReferenceNodes(indirectUser, isDefaultExport ? "default" : exportName); _c < _d.length; _c++) {
                        var node = _d[_c];
                        // Import specifiers should be handled by importSearches
                        if (ts.isIdentifier(node) && !ts.isImportOrExportSpecifier(node.parent) && checker.getSymbolAtLocation(node) === exportSymbol) {
                            cb(node);
                        }
                    }
                }
            }
            Core.eachExportReference = eachExportReference;
            function shouldAddSingleReference(singleRef, state) {
                if (!hasMatchingMeaning(singleRef, state))
                    return false;
                if (!state.options.isForRename)
                    return true;
                // Don't rename an import type `import("./module-name")` when renaming `name` in `export = name;`
                if (!ts.isIdentifier(singleRef))
                    return false;
                // At `default` in `import { default as x }` or `export { default as x }`, do add a reference, but do not rename.
                return !(ts.isImportOrExportSpecifier(singleRef.parent) && singleRef.escapedText === "default" /* Default */);
            }
            // Go to the symbol we imported from and find references for it.
            function searchForImportedSymbol(symbol, state) {
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    var exportingFile = declaration.getSourceFile();
                    // Need to search in the file even if it's not in the search-file set, because it might export the symbol.
                    getReferencesInSourceFile(exportingFile, state.createSearch(declaration, symbol, 0 /* Import */), state, state.includesSourceFile(exportingFile));
                }
            }
            /** Search for all occurences of an identifier in a source file (and filter out the ones that match). */
            function searchForName(sourceFile, search, state) {
                if (ts.getNameTable(sourceFile).get(search.escapedText) !== undefined) {
                    getReferencesInSourceFile(sourceFile, search, state);
                }
            }
            function getPropertySymbolOfDestructuringAssignment(location, checker) {
                return ts.isArrayLiteralOrObjectLiteralDestructuringPattern(location.parent.parent)
                    ? checker.getPropertySymbolOfDestructuringAssignment(location)
                    : undefined;
            }
            /**
             * Determines the smallest scope in which a symbol may have named references.
             * Note that not every construct has been accounted for. This function can
             * probably be improved.
             *
             * @returns undefined if the scope cannot be determined, implying that
             * a reference to a symbol can occur anywhere.
             */
            function getSymbolScope(symbol) {
                // If this is the symbol of a named function expression or named class expression,
                // then named references are limited to its own scope.
                var declarations = symbol.declarations, flags = symbol.flags, parent = symbol.parent, valueDeclaration = symbol.valueDeclaration;
                if (valueDeclaration && (valueDeclaration.kind === 197 /* FunctionExpression */ || valueDeclaration.kind === 210 /* ClassExpression */)) {
                    return valueDeclaration;
                }
                if (!declarations) {
                    return undefined;
                }
                // If this is private property or method, the scope is the containing class
                if (flags & (4 /* Property */ | 8192 /* Method */)) {
                    var privateDeclaration = ts.find(declarations, function (d) { return ts.hasModifier(d, 8 /* Private */); });
                    if (privateDeclaration) {
                        return ts.getAncestor(privateDeclaration, 241 /* ClassDeclaration */);
                    }
                    // Else this is a public property and could be accessed from anywhere.
                    return undefined;
                }
                // If symbol is of object binding pattern element without property name we would want to
                // look for property too and that could be anywhere
                if (declarations.some(ts.isObjectBindingElementWithoutPropertyName)) {
                    return undefined;
                }
                /*
                If the symbol has a parent, it's globally visible unless:
                - It's a private property (handled above).
                - It's a type parameter.
                - The parent is an external module: then we should only search in the module (and recurse on the export later).
                  - But if the parent has `export as namespace`, the symbol is globally visible through that namespace.
                */
                var exposedByParent = parent && !(symbol.flags & 262144 /* TypeParameter */);
                if (exposedByParent && !(ts.isExternalModuleSymbol(parent) && !parent.globalExports)) {
                    return undefined;
                }
                var scope;
                for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) {
                    var declaration = declarations_1[_i];
                    var container = ts.getContainerNode(declaration);
                    if (scope && scope !== container) {
                        // Different declarations have different containers, bail out
                        return undefined;
                    }
                    if (!container || container.kind === 285 /* SourceFile */ && !ts.isExternalOrCommonJsModule(container)) {
                        // This is a global variable and not an external module, any declaration defined
                        // within this scope is visible outside the file
                        return undefined;
                    }
                    // The search scope is the container node
                    scope = container;
                }
                // If symbol.parent, this means we are in an export of an external module. (Otherwise we would have returned `undefined` above.)
                // For an export of a module, we may be in a declaration file, and it may be accessed elsewhere. E.g.:
                //     declare module "a" { export type T = number; }
                //     declare module "b" { import { T } from "a"; export const x: T; }
                // So we must search the whole source file. (Because we will mark the source file as seen, we we won't return to it when searching for imports.)
                return exposedByParent ? scope.getSourceFile() : scope; // TODO: GH#18217
            }
            /** Used as a quick check for whether a symbol is used at all in a file (besides its definition). */
            function isSymbolReferencedInFile(definition, checker, sourceFile) {
                return eachSymbolReferenceInFile(definition, checker, sourceFile, function () { return true; }) || false;
            }
            Core.isSymbolReferencedInFile = isSymbolReferencedInFile;
            function eachSymbolReferenceInFile(definition, checker, sourceFile, cb) {
                var symbol = ts.isParameterPropertyDeclaration(definition.parent)
                    ? ts.first(checker.getSymbolsOfParameterPropertyDeclaration(definition.parent, definition.text))
                    : checker.getSymbolAtLocation(definition);
                if (!symbol)
                    return undefined;
                for (var _i = 0, _a = getPossibleSymbolReferenceNodes(sourceFile, symbol.name); _i < _a.length; _i++) {
                    var token = _a[_i];
                    if (!ts.isIdentifier(token) || token === definition || token.escapedText !== definition.escapedText)
                        continue;
                    var referenceSymbol = checker.getSymbolAtLocation(token); // See GH#19955 for why the type annotation is necessary
                    if (referenceSymbol === symbol
                        || checker.getShorthandAssignmentValueSymbol(token.parent) === symbol
                        || ts.isExportSpecifier(token.parent) && getLocalSymbolForExportSpecifier(token, referenceSymbol, token.parent, checker) === symbol) {
                        var res = cb(token);
                        if (res)
                            return res;
                    }
                }
            }
            Core.eachSymbolReferenceInFile = eachSymbolReferenceInFile;
            function eachSignatureCall(signature, sourceFiles, checker, cb) {
                if (!signature.name || !ts.isIdentifier(signature.name))
                    return;
                var symbol = ts.Debug.assertDefined(checker.getSymbolAtLocation(signature.name));
                for (var _i = 0, sourceFiles_3 = sourceFiles; _i < sourceFiles_3.length; _i++) {
                    var sourceFile = sourceFiles_3[_i];
                    for (var _a = 0, _b = getPossibleSymbolReferenceNodes(sourceFile, symbol.name); _a < _b.length; _a++) {
                        var name = _b[_a];
                        if (!ts.isIdentifier(name) || name === signature.name || name.escapedText !== signature.name.escapedText)
                            continue;
                        var called = ts.climbPastPropertyAccess(name);
                        var call = called.parent;
                        if (!ts.isCallExpression(call) || call.expression !== called)
                            continue;
                        var referenceSymbol = checker.getSymbolAtLocation(name);
                        if (referenceSymbol && checker.getRootSymbols(referenceSymbol).some(function (s) { return s === symbol; })) {
                            cb(call);
                        }
                    }
                }
            }
            Core.eachSignatureCall = eachSignatureCall;
            function getPossibleSymbolReferenceNodes(sourceFile, symbolName, container) {
                if (container === void 0) { container = sourceFile; }
                return getPossibleSymbolReferencePositions(sourceFile, symbolName, container).map(function (pos) { return ts.getTouchingPropertyName(sourceFile, pos); });
            }
            function getPossibleSymbolReferencePositions(sourceFile, symbolName, container) {
                if (container === void 0) { container = sourceFile; }
                var positions = [];
                /// TODO: Cache symbol existence for files to save text search
                // Also, need to make this work for unicode escapes.
                // Be resilient in the face of a symbol with no name or zero length name
                if (!symbolName || !symbolName.length) {
                    return positions;
                }
                var text = sourceFile.text;
                var sourceLength = text.length;
                var symbolNameLength = symbolName.length;
                var position = text.indexOf(symbolName, container.pos);
                while (position >= 0) {
                    // If we are past the end, stop looking
                    if (position > container.end)
                        break;
                    // We found a match.  Make sure it's not part of a larger word (i.e. the char
                    // before and after it have to be a non-identifier char).
                    var endPosition = position + symbolNameLength;
                    if ((position === 0 || !ts.isIdentifierPart(text.charCodeAt(position - 1), 8 /* Latest */)) &&
                        (endPosition === sourceLength || !ts.isIdentifierPart(text.charCodeAt(endPosition), 8 /* Latest */))) {
                        // Found a real match.  Keep searching.
                        positions.push(position);
                    }
                    position = text.indexOf(symbolName, position + symbolNameLength + 1);
                }
                return positions;
            }
            function getLabelReferencesInNode(container, targetLabel) {
                var sourceFile = container.getSourceFile();
                var labelName = targetLabel.text;
                var references = ts.mapDefined(getPossibleSymbolReferenceNodes(sourceFile, labelName, container), function (node) {
                    // Only pick labels that are either the target label, or have a target that is the target label
                    return node === targetLabel || (ts.isJumpStatementTarget(node) && ts.getTargetLabel(node, labelName) === targetLabel) ? FindAllReferences.nodeEntry(node) : undefined;
                });
                return [{ definition: { type: 1 /* Label */, node: targetLabel }, references: references }];
            }
            function isValidReferencePosition(node, searchSymbolName) {
                // Compare the length so we filter out strict superstrings of the symbol we are looking for
                switch (node.kind) {
                    case 73 /* Identifier */:
                        return node.text.length === searchSymbolName.length;
                    case 10 /* StringLiteral */: {
                        var str = node;
                        return (ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(str) || ts.isNameOfModuleDeclaration(node) || ts.isExpressionOfExternalModuleImportEqualsDeclaration(node) || (ts.isCallExpression(node.parent) && ts.isBindableObjectDefinePropertyCall(node.parent) && node.parent.arguments[1] === node)) &&
                            str.text.length === searchSymbolName.length;
                    }
                    case 8 /* NumericLiteral */:
                        return ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(node) && node.text.length === searchSymbolName.length;
                    case 81 /* DefaultKeyword */:
                        return "default".length === searchSymbolName.length;
                    default:
                        return false;
                }
            }
            function getAllReferencesForKeyword(sourceFiles, keywordKind, cancellationToken) {
                var references = ts.flatMap(sourceFiles, function (sourceFile) {
                    cancellationToken.throwIfCancellationRequested();
                    return ts.mapDefined(getPossibleSymbolReferenceNodes(sourceFile, ts.tokenToString(keywordKind), sourceFile), function (referenceLocation) {
                        return referenceLocation.kind === keywordKind ? FindAllReferences.nodeEntry(referenceLocation) : undefined;
                    });
                });
                return references.length ? [{ definition: { type: 2 /* Keyword */, node: references[0].node }, references: references }] : undefined;
            }
            function getReferencesInSourceFile(sourceFile, search, state, addReferencesHere) {
                if (addReferencesHere === void 0) { addReferencesHere = true; }
                state.cancellationToken.throwIfCancellationRequested();
                return getReferencesInContainer(sourceFile, sourceFile, search, state, addReferencesHere);
            }
            /**
             * Search within node "container" for references for a search value, where the search value is defined as a
             * tuple of(searchSymbol, searchText, searchLocation, and searchMeaning).
             * searchLocation: a node where the search value
             */
            function getReferencesInContainer(container, sourceFile, search, state, addReferencesHere) {
                if (!state.markSearchedSymbols(sourceFile, search.allSearchSymbols)) {
                    return;
                }
                for (var _i = 0, _a = getPossibleSymbolReferencePositions(sourceFile, search.text, container); _i < _a.length; _i++) {
                    var position = _a[_i];
                    getReferencesAtLocation(sourceFile, position, search, state, addReferencesHere);
                }
            }
            function hasMatchingMeaning(referenceLocation, state) {
                return !!(ts.getMeaningFromLocation(referenceLocation) & state.searchMeaning);
            }
            function getReferencesAtLocation(sourceFile, position, search, state, addReferencesHere) {
                var referenceLocation = ts.getTouchingPropertyName(sourceFile, position);
                if (!isValidReferencePosition(referenceLocation, search.text)) {
                    // This wasn't the start of a token.  Check to see if it might be a
                    // match in a comment or string if that's what the caller is asking
                    // for.
                    if (!state.options.implementations && (state.options.findInStrings && ts.isInString(sourceFile, position) || state.options.findInComments && ts.isInNonReferenceComment(sourceFile, position))) {
                        // In the case where we're looking inside comments/strings, we don't have
                        // an actual definition.  So just use 'undefined' here.  Features like
                        // 'Rename' won't care (as they ignore the definitions), and features like
                        // 'FindReferences' will just filter out these results.
                        state.addStringOrCommentReference(sourceFile.fileName, ts.createTextSpan(position, search.text.length));
                    }
                    return;
                }
                if (!hasMatchingMeaning(referenceLocation, state))
                    return;
                var referenceSymbol = state.checker.getSymbolAtLocation(referenceLocation);
                if (!referenceSymbol) {
                    return;
                }
                var parent = referenceLocation.parent;
                if (ts.isImportSpecifier(parent) && parent.propertyName === referenceLocation) {
                    // This is added through `singleReferences` in ImportsResult. If we happen to see it again, don't add it again.
                    return;
                }
                if (ts.isExportSpecifier(parent)) {
                    ts.Debug.assert(referenceLocation.kind === 73 /* Identifier */);
                    getReferencesAtExportSpecifier(referenceLocation, referenceSymbol, parent, search, state, addReferencesHere);
                    return;
                }
                var relatedSymbol = getRelatedSymbol(search, referenceSymbol, referenceLocation, state);
                if (!relatedSymbol) {
                    getReferenceForShorthandProperty(referenceSymbol, search, state);
                    return;
                }
                switch (state.specialSearchKind) {
                    case 0 /* None */:
                        if (addReferencesHere)
                            addReference(referenceLocation, relatedSymbol, state);
                        break;
                    case 1 /* Constructor */:
                        addConstructorReferences(referenceLocation, sourceFile, search, state);
                        break;
                    case 2 /* Class */:
                        addClassStaticThisReferences(referenceLocation, search, state);
                        break;
                    default:
                        ts.Debug.assertNever(state.specialSearchKind);
                }
                getImportOrExportReferences(referenceLocation, referenceSymbol, search, state);
            }
            function getReferencesAtExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, search, state, addReferencesHere, alwaysGetReferences) {
                ts.Debug.assert(!alwaysGetReferences || !!state.options.providePrefixAndSuffixTextForRename, "If alwaysGetReferences is true, then prefix/suffix text must be enabled");
                var parent = exportSpecifier.parent, propertyName = exportSpecifier.propertyName, name = exportSpecifier.name;
                var exportDeclaration = parent.parent;
                var localSymbol = getLocalSymbolForExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, state.checker);
                if (!alwaysGetReferences && !search.includes(localSymbol)) {
                    return;
                }
                if (!propertyName) {
                    // Don't rename at `export { default } from "m";`. (but do continue to search for imports of the re-export)
                    if (!(state.options.isForRename && (name.escapedText === "default" /* Default */))) {
                        addRef();
                    }
                }
                else if (referenceLocation === propertyName) {
                    // For `export { foo as bar } from "baz"`, "`foo`" will be added from the singleReferences for import searches of the original export.
                    // For `export { foo as bar };`, where `foo` is a local, so add it now.
                    if (!exportDeclaration.moduleSpecifier) {
                        addRef();
                    }
                    if (addReferencesHere && !state.options.isForRename && state.markSeenReExportRHS(name)) {
                        addReference(name, ts.Debug.assertDefined(exportSpecifier.symbol), state);
                    }
                }
                else {
                    if (state.markSeenReExportRHS(referenceLocation)) {
                        addRef();
                    }
                }
                // For `export { foo as bar }`, rename `foo`, but not `bar`.
                if (!isForRenameWithPrefixAndSuffixText(state.options) || alwaysGetReferences) {
                    var isDefaultExport = referenceLocation.originalKeywordKind === 81 /* DefaultKeyword */
                        || exportSpecifier.name.originalKeywordKind === 81 /* DefaultKeyword */;
                    var exportKind = isDefaultExport ? 1 /* Default */ : 0 /* Named */;
                    var exportSymbol = ts.Debug.assertDefined(exportSpecifier.symbol);
                    var exportInfo = ts.Debug.assertDefined(FindAllReferences.getExportInfo(exportSymbol, exportKind, state.checker));
                    searchForImportsOfExport(referenceLocation, exportSymbol, exportInfo, state);
                }
                // At `export { x } from "foo"`, also search for the imported symbol `"foo".x`.
                if (search.comingFrom !== 1 /* Export */ && exportDeclaration.moduleSpecifier && !propertyName && !isForRenameWithPrefixAndSuffixText(state.options)) {
                    var imported = state.checker.getExportSpecifierLocalTargetSymbol(exportSpecifier);
                    if (imported)
                        searchForImportedSymbol(imported, state);
                }
                function addRef() {
                    if (addReferencesHere)
                        addReference(referenceLocation, localSymbol, state);
                }
            }
            function getLocalSymbolForExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, checker) {
                return isExportSpecifierAlias(referenceLocation, exportSpecifier) && checker.getExportSpecifierLocalTargetSymbol(exportSpecifier) || referenceSymbol;
            }
            function isExportSpecifierAlias(referenceLocation, exportSpecifier) {
                var parent = exportSpecifier.parent, propertyName = exportSpecifier.propertyName, name = exportSpecifier.name;
                ts.Debug.assert(propertyName === referenceLocation || name === referenceLocation);
                if (propertyName) {
                    // Given `export { foo as bar } [from "someModule"]`: It's an alias at `foo`, but at `bar` it's a new symbol.
                    return propertyName === referenceLocation;
                }
                else {
                    // `export { foo } from "foo"` is a re-export.
                    // `export { foo };` is not a re-export, it creates an alias for the local variable `foo`.
                    return !parent.parent.moduleSpecifier;
                }
            }
            function getImportOrExportReferences(referenceLocation, referenceSymbol, search, state) {
                var importOrExport = FindAllReferences.getImportOrExportSymbol(referenceLocation, referenceSymbol, state.checker, search.comingFrom === 1 /* Export */);
                if (!importOrExport)
                    return;
                var symbol = importOrExport.symbol;
                if (importOrExport.kind === 0 /* Import */) {
                    if (!(isForRenameWithPrefixAndSuffixText(state.options))) {
                        searchForImportedSymbol(symbol, state);
                    }
                }
                else {
                    searchForImportsOfExport(referenceLocation, symbol, importOrExport.exportInfo, state);
                }
            }
            function getReferenceForShorthandProperty(_a, search, state) {
                var flags = _a.flags, valueDeclaration = _a.valueDeclaration;
                var shorthandValueSymbol = state.checker.getShorthandAssignmentValueSymbol(valueDeclaration);
                var name = valueDeclaration && ts.getNameOfDeclaration(valueDeclaration);
                /*
                 * Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment
                 * has two meanings: property name and property value. Therefore when we do findAllReference at the position where
                 * an identifier is declared, the language service should return the position of the variable declaration as well as
                 * the position in short-hand property assignment excluding property accessing. However, if we do findAllReference at the
                 * position of property accessing, the referenceEntry of such position will be handled in the first case.
                 */
                if (!(flags & 33554432 /* Transient */) && name && search.includes(shorthandValueSymbol)) {
                    addReference(name, shorthandValueSymbol, state);
                }
            }
            function addReference(referenceLocation, relatedSymbol, state) {
                var _a = "kind" in relatedSymbol ? relatedSymbol : { kind: undefined, symbol: relatedSymbol }, kind = _a.kind, symbol = _a.symbol;
                var addRef = state.referenceAdder(symbol);
                if (state.options.implementations) {
                    addImplementationReferences(referenceLocation, addRef, state);
                }
                else {
                    addRef(referenceLocation, kind);
                }
            }
            /** Adds references when a constructor is used with `new this()` in its own class and `super()` calls in subclasses.  */
            function addConstructorReferences(referenceLocation, sourceFile, search, state) {
                if (ts.isNewExpressionTarget(referenceLocation)) {
                    addReference(referenceLocation, search.symbol, state);
                }
                var pusher = function () { return state.referenceAdder(search.symbol); };
                if (ts.isClassLike(referenceLocation.parent)) {
                    ts.Debug.assert(referenceLocation.kind === 81 /* DefaultKeyword */ || referenceLocation.parent.name === referenceLocation);
                    // This is the class declaration containing the constructor.
                    findOwnConstructorReferences(search.symbol, sourceFile, pusher());
                }
                else {
                    // If this class appears in `extends C`, then the extending class' "super" calls are references.
                    var classExtending = tryGetClassByExtendingIdentifier(referenceLocation);
                    if (classExtending) {
                        findSuperConstructorAccesses(classExtending, pusher());
                        findInheritedConstructorReferences(classExtending, state);
                    }
                }
            }
            function addClassStaticThisReferences(referenceLocation, search, state) {
                addReference(referenceLocation, search.symbol, state);
                var classLike = referenceLocation.parent;
                if (state.options.isForRename || !ts.isClassLike(classLike))
                    return;
                ts.Debug.assert(classLike.name === referenceLocation);
                var addRef = state.referenceAdder(search.symbol);
                for (var _i = 0, _a = classLike.members; _i < _a.length; _i++) {
                    var member = _a[_i];
                    if (!(ts.isMethodOrAccessor(member) && ts.hasModifier(member, 32 /* Static */))) {
                        continue;
                    }
                    if (member.body) {
                        member.body.forEachChild(function cb(node) {
                            if (node.kind === 101 /* ThisKeyword */) {
                                addRef(node);
                            }
                            else if (!ts.isFunctionLike(node) && !ts.isClassLike(node)) {
                                node.forEachChild(cb);
                            }
                        });
                    }
                }
            }
            /**
             * `classSymbol` is the class where the constructor was defined.
             * Reference the constructor and all calls to `new this()`.
             */
            function findOwnConstructorReferences(classSymbol, sourceFile, addNode) {
                var constructorSymbol = getClassConstructorSymbol(classSymbol);
                if (constructorSymbol) {
                    for (var _i = 0, _a = constructorSymbol.declarations; _i < _a.length; _i++) {
                        var decl = _a[_i];
                        var ctrKeyword = ts.findChildOfKind(decl, 125 /* ConstructorKeyword */, sourceFile);
                        ts.Debug.assert(decl.kind === 158 /* Constructor */ && !!ctrKeyword);
                        addNode(ctrKeyword);
                    }
                }
                if (classSymbol.exports) {
                    classSymbol.exports.forEach(function (member) {
                        var decl = member.valueDeclaration;
                        if (decl && decl.kind === 157 /* MethodDeclaration */) {
                            var body = decl.body;
                            if (body) {
                                forEachDescendantOfKind(body, 101 /* ThisKeyword */, function (thisKeyword) {
                                    if (ts.isNewExpressionTarget(thisKeyword)) {
                                        addNode(thisKeyword);
                                    }
                                });
                            }
                        }
                    });
                }
            }
            function getClassConstructorSymbol(classSymbol) {
                return classSymbol.members && classSymbol.members.get("__constructor" /* Constructor */);
            }
            /** Find references to `super` in the constructor of an extending class.  */
            function findSuperConstructorAccesses(classDeclaration, addNode) {
                var constructor = getClassConstructorSymbol(classDeclaration.symbol);
                if (!constructor) {
                    return;
                }
                for (var _i = 0, _a = constructor.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    ts.Debug.assert(decl.kind === 158 /* Constructor */);
                    var body = decl.body;
                    if (body) {
                        forEachDescendantOfKind(body, 99 /* SuperKeyword */, function (node) {
                            if (ts.isCallExpressionTarget(node)) {
                                addNode(node);
                            }
                        });
                    }
                }
            }
            function hasOwnConstructor(classDeclaration) {
                return !!getClassConstructorSymbol(classDeclaration.symbol);
            }
            function findInheritedConstructorReferences(classDeclaration, state) {
                if (hasOwnConstructor(classDeclaration))
                    return;
                var classSymbol = classDeclaration.symbol;
                var search = state.createSearch(/*location*/ undefined, classSymbol, /*comingFrom*/ undefined);
                getReferencesInContainerOrFiles(classSymbol, state, search);
            }
            function addImplementationReferences(refNode, addReference, state) {
                // Check if we found a function/propertyAssignment/method with an implementation or initializer
                if (ts.isDeclarationName(refNode) && isImplementation(refNode.parent)) {
                    addReference(refNode);
                    return;
                }
                if (refNode.kind !== 73 /* Identifier */) {
                    return;
                }
                if (refNode.parent.kind === 277 /* ShorthandPropertyAssignment */) {
                    // Go ahead and dereference the shorthand assignment by going to its definition
                    getReferenceEntriesForShorthandPropertyAssignment(refNode, state.checker, addReference);
                }
                // Check if the node is within an extends or implements clause
                var containingClass = getContainingClassIfInHeritageClause(refNode);
                if (containingClass) {
                    addReference(containingClass);
                    return;
                }
                // If we got a type reference, try and see if the reference applies to any expressions that can implement an interface
                // Find the first node whose parent isn't a type node -- i.e., the highest type node.
                var typeNode = ts.findAncestor(refNode, function (a) { return !ts.isQualifiedName(a.parent) && !ts.isTypeNode(a.parent) && !ts.isTypeElement(a.parent); });
                var typeHavingNode = typeNode.parent;
                if (ts.hasType(typeHavingNode) && typeHavingNode.type === typeNode && state.markSeenContainingTypeReference(typeHavingNode)) {
                    if (ts.hasInitializer(typeHavingNode)) {
                        addIfImplementation(typeHavingNode.initializer);
                    }
                    else if (ts.isFunctionLike(typeHavingNode) && typeHavingNode.body) {
                        var body = typeHavingNode.body;
                        if (body.kind === 219 /* Block */) {
                            ts.forEachReturnStatement(body, function (returnStatement) {
                                if (returnStatement.expression)
                                    addIfImplementation(returnStatement.expression);
                            });
                        }
                        else {
                            addIfImplementation(body);
                        }
                    }
                    else if (ts.isAssertionExpression(typeHavingNode)) {
                        addIfImplementation(typeHavingNode.expression);
                    }
                }
                function addIfImplementation(e) {
                    if (isImplementationExpression(e))
                        addReference(e);
                }
            }
            function getContainingClassIfInHeritageClause(node) {
                return ts.isIdentifier(node) || ts.isPropertyAccessExpression(node) ? getContainingClassIfInHeritageClause(node.parent)
                    : ts.isExpressionWithTypeArguments(node) ? ts.tryCast(node.parent.parent, ts.isClassLike) : undefined;
            }
            /**
             * Returns true if this is an expression that can be considered an implementation
             */
            function isImplementationExpression(node) {
                switch (node.kind) {
                    case 196 /* ParenthesizedExpression */:
                        return isImplementationExpression(node.expression);
                    case 198 /* ArrowFunction */:
                    case 197 /* FunctionExpression */:
                    case 189 /* ObjectLiteralExpression */:
                    case 210 /* ClassExpression */:
                    case 188 /* ArrayLiteralExpression */:
                        return true;
                    default:
                        return false;
                }
            }
            /**
             * Determines if the parent symbol occurs somewhere in the child's ancestry. If the parent symbol
             * is an interface, determines if some ancestor of the child symbol extends or inherits from it.
             * Also takes in a cache of previous results which makes this slightly more efficient and is
             * necessary to avoid potential loops like so:
             *     class A extends B { }
             *     class B extends A { }
             *
             * We traverse the AST rather than using the type checker because users are typically only interested
             * in explicit implementations of an interface/class when calling "Go to Implementation". Sibling
             * implementations of types that share a common ancestor with the type whose implementation we are
             * searching for need to be filtered out of the results. The type checker doesn't let us make the
             * distinction between structurally compatible implementations and explicit implementations, so we
             * must use the AST.
             *
             * @param symbol         A class or interface Symbol
             * @param parent        Another class or interface Symbol
             * @param cachedResults A map of symbol id pairs (i.e. "child,parent") to booleans indicating previous results
             */
            function explicitlyInheritsFrom(symbol, parent, cachedResults, checker) {
                if (symbol === parent) {
                    return true;
                }
                var key = ts.getSymbolId(symbol) + "," + ts.getSymbolId(parent);
                var cached = cachedResults.get(key);
                if (cached !== undefined) {
                    return cached;
                }
                // Set the key so that we don't infinitely recurse
                cachedResults.set(key, false);
                var inherits = symbol.declarations.some(function (declaration) {
                    return ts.getAllSuperTypeNodes(declaration).some(function (typeReference) {
                        var type = checker.getTypeAtLocation(typeReference);
                        return !!type && !!type.symbol && explicitlyInheritsFrom(type.symbol, parent, cachedResults, checker);
                    });
                });
                cachedResults.set(key, inherits);
                return inherits;
            }
            function getReferencesForSuperKeyword(superKeyword) {
                var searchSpaceNode = ts.getSuperContainer(superKeyword, /*stopOnFunctions*/ false);
                if (!searchSpaceNode) {
                    return undefined;
                }
                // Whether 'super' occurs in a static context within a class.
                var staticFlag = 32 /* Static */;
                switch (searchSpaceNode.kind) {
                    case 155 /* PropertyDeclaration */:
                    case 154 /* PropertySignature */:
                    case 157 /* MethodDeclaration */:
                    case 156 /* MethodSignature */:
                    case 158 /* Constructor */:
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                        staticFlag &= ts.getModifierFlags(searchSpaceNode);
                        searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class
                        break;
                    default:
                        return undefined;
                }
                var sourceFile = searchSpaceNode.getSourceFile();
                var references = ts.mapDefined(getPossibleSymbolReferenceNodes(sourceFile, "super", searchSpaceNode), function (node) {
                    if (node.kind !== 99 /* SuperKeyword */) {
                        return;
                    }
                    var container = ts.getSuperContainer(node, /*stopOnFunctions*/ false);
                    // If we have a 'super' container, we must have an enclosing class.
                    // Now make sure the owning class is the same as the search-space
                    // and has the same static qualifier as the original 'super's owner.
                    return container && (32 /* Static */ & ts.getModifierFlags(container)) === staticFlag && container.parent.symbol === searchSpaceNode.symbol ? FindAllReferences.nodeEntry(node) : undefined;
                });
                return [{ definition: { type: 0 /* Symbol */, symbol: searchSpaceNode.symbol }, references: references }];
            }
            function isParameterName(node) {
                return node.kind === 73 /* Identifier */ && node.parent.kind === 152 /* Parameter */ && node.parent.name === node;
            }
            function getReferencesForThisKeyword(thisOrSuperKeyword, sourceFiles, cancellationToken) {
                var searchSpaceNode = ts.getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false);
                // Whether 'this' occurs in a static context within a class.
                var staticFlag = 32 /* Static */;
                switch (searchSpaceNode.kind) {
                    case 157 /* MethodDeclaration */:
                    case 156 /* MethodSignature */:
                        if (ts.isObjectLiteralMethod(searchSpaceNode)) {
                            break;
                        }
                    // falls through
                    case 155 /* PropertyDeclaration */:
                    case 154 /* PropertySignature */:
                    case 158 /* Constructor */:
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                        staticFlag &= ts.getModifierFlags(searchSpaceNode);
                        searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class
                        break;
                    case 285 /* SourceFile */:
                        if (ts.isExternalModule(searchSpaceNode) || isParameterName(thisOrSuperKeyword)) {
                            return undefined;
                        }
                    // falls through
                    case 240 /* FunctionDeclaration */:
                    case 197 /* FunctionExpression */:
                        break;
                    // Computed properties in classes are not handled here because references to this are illegal,
                    // so there is no point finding references to them.
                    default:
                        return undefined;
                }
                var references = ts.flatMap(searchSpaceNode.kind === 285 /* SourceFile */ ? sourceFiles : [searchSpaceNode.getSourceFile()], function (sourceFile) {
                    cancellationToken.throwIfCancellationRequested();
                    return getPossibleSymbolReferenceNodes(sourceFile, "this", ts.isSourceFile(searchSpaceNode) ? sourceFile : searchSpaceNode).filter(function (node) {
                        if (!ts.isThis(node)) {
                            return false;
                        }
                        var container = ts.getThisContainer(node, /* includeArrowFunctions */ false);
                        switch (searchSpaceNode.kind) {
                            case 197 /* FunctionExpression */:
                            case 240 /* FunctionDeclaration */:
                                return searchSpaceNode.symbol === container.symbol;
                            case 157 /* MethodDeclaration */:
                            case 156 /* MethodSignature */:
                                return ts.isObjectLiteralMethod(searchSpaceNode) && searchSpaceNode.symbol === container.symbol;
                            case 210 /* ClassExpression */:
                            case 241 /* ClassDeclaration */:
                                // Make sure the container belongs to the same class
                                // and has the appropriate static modifier from the original container.
                                return container.parent && searchSpaceNode.symbol === container.parent.symbol && (ts.getModifierFlags(container) & 32 /* Static */) === staticFlag;
                            case 285 /* SourceFile */:
                                return container.kind === 285 /* SourceFile */ && !ts.isExternalModule(container) && !isParameterName(node);
                        }
                    });
                }).map(function (n) { return FindAllReferences.nodeEntry(n); });
                var thisParameter = ts.firstDefined(references, function (r) { return ts.isParameter(r.node.parent) ? r.node : undefined; });
                return [{
                        definition: { type: 3 /* This */, node: thisParameter || thisOrSuperKeyword },
                        references: references
                    }];
            }
            function getReferencesForStringLiteral(node, sourceFiles, cancellationToken) {
                var references = ts.flatMap(sourceFiles, function (sourceFile) {
                    cancellationToken.throwIfCancellationRequested();
                    return ts.mapDefined(getPossibleSymbolReferenceNodes(sourceFile, node.text), function (ref) {
                        return ts.isStringLiteral(ref) && ref.text === node.text ? FindAllReferences.nodeEntry(ref, 2 /* StringLiteral */) : undefined;
                    });
                });
                return [{
                        definition: { type: 4 /* String */, node: node },
                        references: references
                    }];
            }
            // For certain symbol kinds, we need to include other symbols in the search set.
            // This is not needed when searching for re-exports.
            function populateSearchSymbolSet(symbol, location, checker, isForRename, providePrefixAndSuffixText, implementations) {
                var result = [];
                forEachRelatedSymbol(symbol, location, checker, isForRename, !(isForRename && providePrefixAndSuffixText), function (sym, root, base) { result.push(base || root || sym); }, 
                /*allowBaseTypes*/ function () { return !implementations; });
                return result;
            }
            function forEachRelatedSymbol(symbol, location, checker, isForRenamePopulateSearchSymbolSet, onlyIncludeBindingElementAtReferenceLocation, cbSymbol, allowBaseTypes) {
                var containingObjectLiteralElement = ts.getContainingObjectLiteralElement(location);
                if (containingObjectLiteralElement) {
                    /* Because in short-hand property assignment, location has two meaning : property name and as value of the property
                     * When we do findAllReference at the position of the short-hand property assignment, we would want to have references to position of
                     * property name and variable declaration of the identifier.
                     * Like in below example, when querying for all references for an identifier 'name', of the property assignment, the language service
                     * should show both 'name' in 'obj' and 'name' in variable declaration
                     *      const name = "Foo";
                     *      const obj = { name };
                     * In order to do that, we will populate the search set with the value symbol of the identifier as a value of the property assignment
                     * so that when matching with potential reference symbol, both symbols from property declaration and variable declaration
                     * will be included correctly.
                     */
                    var shorthandValueSymbol = checker.getShorthandAssignmentValueSymbol(location.parent); // gets the local symbol
                    if (shorthandValueSymbol && isForRenamePopulateSearchSymbolSet) {
                        // When renaming 'x' in `const o = { x }`, just rename the local variable, not the property.
                        return cbSymbol(shorthandValueSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, 3 /* SearchedLocalFoundProperty */);
                    }
                    // If the location is in a context sensitive location (i.e. in an object literal) try
                    // to get a contextual type for it, and add the property symbol from the contextual
                    // type to the search set
                    var contextualType = checker.getContextualType(containingObjectLiteralElement.parent);
                    var res_1 = contextualType && ts.firstDefined(ts.getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker, contextualType, /*unionSymbolOk*/ true), function (sym) { return fromRoot(sym, 4 /* SearchedPropertyFoundLocal */); });
                    if (res_1)
                        return res_1;
                    // If the location is name of property symbol from object literal destructuring pattern
                    // Search the property symbol
                    //      for ( { property: p2 } of elems) { }
                    var propertySymbol = getPropertySymbolOfDestructuringAssignment(location, checker);
                    var res1 = propertySymbol && cbSymbol(propertySymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, 4 /* SearchedPropertyFoundLocal */);
                    if (res1)
                        return res1;
                    var res2 = shorthandValueSymbol && cbSymbol(shorthandValueSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, 3 /* SearchedLocalFoundProperty */);
                    if (res2)
                        return res2;
                }
                var aliasedSymbol = getMergedAliasedSymbolOfNamespaceExportDeclaration(location, symbol, checker);
                if (aliasedSymbol) {
                    // In case of UMD module and global merging, search for global as well
                    var res_2 = cbSymbol(aliasedSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, 1 /* Node */);
                    if (res_2)
                        return res_2;
                }
                var res = fromRoot(symbol);
                if (res)
                    return res;
                if (symbol.valueDeclaration && ts.isParameterPropertyDeclaration(symbol.valueDeclaration)) {
                    // For a parameter property, now try on the other symbol (property if this was a parameter, parameter if this was a property).
                    var paramProps = checker.getSymbolsOfParameterPropertyDeclaration(ts.cast(symbol.valueDeclaration, ts.isParameter), symbol.name);
                    ts.Debug.assert(paramProps.length === 2 && !!(paramProps[0].flags & 1 /* FunctionScopedVariable */) && !!(paramProps[1].flags & 4 /* Property */)); // is [parameter, property]
                    return fromRoot(symbol.flags & 1 /* FunctionScopedVariable */ ? paramProps[1] : paramProps[0]);
                }
                // symbolAtLocation for a binding element is the local symbol. See if the search symbol is the property.
                // Don't do this when populating search set for a rename when prefix and suffix text will be provided -- just rename the local.
                if (!isForRenamePopulateSearchSymbolSet) {
                    var bindingElementPropertySymbol = void 0;
                    if (onlyIncludeBindingElementAtReferenceLocation) {
                        bindingElementPropertySymbol = ts.isObjectBindingElementWithoutPropertyName(location.parent) ? ts.getPropertySymbolFromBindingElement(checker, location.parent) : undefined;
                    }
                    else {
                        bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker);
                    }
                    return bindingElementPropertySymbol && fromRoot(bindingElementPropertySymbol, 4 /* SearchedPropertyFoundLocal */);
                }
                ts.Debug.assert(isForRenamePopulateSearchSymbolSet);
                // due to the above assert and the arguments at the uses of this function,
                // (onlyIncludeBindingElementAtReferenceLocation <=> !providePrefixAndSuffixTextForRename) holds
                var includeOriginalSymbolOfBindingElement = onlyIncludeBindingElementAtReferenceLocation;
                if (includeOriginalSymbolOfBindingElement) {
                    var bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker);
                    return bindingElementPropertySymbol && fromRoot(bindingElementPropertySymbol, 4 /* SearchedPropertyFoundLocal */);
                }
                function fromRoot(sym, kind) {
                    // If this is a union property:
                    //   - In populateSearchSymbolsSet we will add all the symbols from all its source symbols in all unioned types.
                    //   - In findRelatedSymbol, we will just use the union symbol if any source symbol is included in the search.
                    // If the symbol is an instantiation from a another symbol (e.g. widened symbol):
                    //   - In populateSearchSymbolsSet, add the root the list
                    //   - In findRelatedSymbol, return the source symbol if that is in the search. (Do not return the instantiation symbol.)
                    return ts.firstDefined(checker.getRootSymbols(sym), function (rootSymbol) {
                        return cbSymbol(sym, rootSymbol, /*baseSymbol*/ undefined, kind)
                            // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
                            || (rootSymbol.parent && rootSymbol.parent.flags & (32 /* Class */ | 64 /* Interface */) && allowBaseTypes(rootSymbol)
                                ? ts.getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, checker, function (base) { return cbSymbol(sym, rootSymbol, base, kind); })
                                : undefined);
                    });
                }
                function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker) {
                    var bindingElement = ts.getDeclarationOfKind(symbol, 187 /* BindingElement */);
                    if (bindingElement && ts.isObjectBindingElementWithoutPropertyName(bindingElement)) {
                        return ts.getPropertySymbolFromBindingElement(checker, bindingElement);
                    }
                }
            }
            function getRelatedSymbol(search, referenceSymbol, referenceLocation, state) {
                var checker = state.checker;
                return forEachRelatedSymbol(referenceSymbol, referenceLocation, checker, /*isForRenamePopulateSearchSymbolSet*/ false, 
                /*onlyIncludeBindingElementAtReferenceLocation*/ !state.options.isForRename || !!state.options.providePrefixAndSuffixTextForRename, function (sym, rootSymbol, baseSymbol, kind) { return search.includes(baseSymbol || rootSymbol || sym)
                    // For a base type, use the symbol for the derived type. For a synthetic (e.g. union) property, use the union symbol.
                    ? { symbol: rootSymbol && !(ts.getCheckFlags(sym) & 6 /* Synthetic */) ? rootSymbol : sym, kind: kind }
                    : undefined; }, 
                /*allowBaseTypes*/ function (rootSymbol) {
                    return !(search.parents && !search.parents.some(function (parent) { return explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, checker); }));
                });
            }
            /**
             * Given an initial searchMeaning, extracted from a location, widen the search scope based on the declarations
             * of the corresponding symbol. e.g. if we are searching for "Foo" in value position, but "Foo" references a class
             * then we need to widen the search to include type positions as well.
             * On the contrary, if we are searching for "Bar" in type position and we trace bar to an interface, and an uninstantiated
             * module, we want to keep the search limited to only types, as the two declarations (interface and uninstantiated module)
             * do not intersect in any of the three spaces.
             */
            function getIntersectingMeaningFromDeclarations(node, symbol) {
                var meaning = ts.getMeaningFromLocation(node);
                var declarations = symbol.declarations;
                if (declarations) {
                    var lastIterationMeaning = void 0;
                    do {
                        // The result is order-sensitive, for instance if initialMeaning === Namespace, and declarations = [class, instantiated module]
                        // we need to consider both as they initialMeaning intersects with the module in the namespace space, and the module
                        // intersects with the class in the value space.
                        // To achieve that we will keep iterating until the result stabilizes.
                        // Remember the last meaning
                        lastIterationMeaning = meaning;
                        for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) {
                            var declaration = declarations_2[_i];
                            var declarationMeaning = ts.getMeaningFromDeclaration(declaration);
                            if (declarationMeaning & meaning) {
                                meaning |= declarationMeaning;
                            }
                        }
                    } while (meaning !== lastIterationMeaning);
                }
                return meaning;
            }
            Core.getIntersectingMeaningFromDeclarations = getIntersectingMeaningFromDeclarations;
            function isImplementation(node) {
                return !!(node.flags & 4194304 /* Ambient */)
                    ? !(ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node))
                    : (ts.isVariableLike(node) ? ts.hasInitializer(node)
                        : ts.isFunctionLikeDeclaration(node) ? !!node.body
                            : ts.isClassLike(node) || ts.isModuleOrEnumDeclaration(node));
            }
            function getReferenceEntriesForShorthandPropertyAssignment(node, checker, addReference) {
                var refSymbol = checker.getSymbolAtLocation(node);
                var shorthandSymbol = checker.getShorthandAssignmentValueSymbol(refSymbol.valueDeclaration);
                if (shorthandSymbol) {
                    for (var _i = 0, _a = shorthandSymbol.getDeclarations(); _i < _a.length; _i++) {
                        var declaration = _a[_i];
                        if (ts.getMeaningFromDeclaration(declaration) & 1 /* Value */) {
                            addReference(declaration);
                        }
                    }
                }
            }
            Core.getReferenceEntriesForShorthandPropertyAssignment = getReferenceEntriesForShorthandPropertyAssignment;
            function forEachDescendantOfKind(node, kind, action) {
                ts.forEachChild(node, function (child) {
                    if (child.kind === kind) {
                        action(child);
                    }
                    forEachDescendantOfKind(child, kind, action);
                });
            }
            /** Get `C` given `N` if `N` is in the position `class C extends N` or `class C extends foo.N` where `N` is an identifier. */
            function tryGetClassByExtendingIdentifier(node) {
                return ts.tryGetClassExtendingExpressionWithTypeArguments(ts.climbPastPropertyAccess(node).parent);
            }
            /**
             * If we are just looking for implementations and this is a property access expression, we need to get the
             * symbol of the local type of the symbol the property is being accessed on. This is because our search
             * symbol may have a different parent symbol if the local type's symbol does not declare the property
             * being accessed (i.e. it is declared in some parent class or interface)
             */
            function getParentSymbolsOfPropertyAccess(location, symbol, checker) {
                var propertyAccessExpression = ts.isRightSideOfPropertyAccess(location) ? location.parent : undefined;
                var lhsType = propertyAccessExpression && checker.getTypeAtLocation(propertyAccessExpression.expression);
                var res = ts.mapDefined(lhsType && (lhsType.isUnionOrIntersection() ? lhsType.types : lhsType.symbol === symbol.parent ? undefined : [lhsType]), function (t) {
                    return t.symbol && t.symbol.flags & (32 /* Class */ | 64 /* Interface */) ? t.symbol : undefined;
                });
                return res.length === 0 ? undefined : res;
            }
            function isForRenameWithPrefixAndSuffixText(options) {
                return options.isForRename && options.providePrefixAndSuffixTextForRename;
            }
        })(Core = FindAllReferences.Core || (FindAllReferences.Core = {}));
    })(FindAllReferences = ts.FindAllReferences || (ts.FindAllReferences = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function getEditsForFileRename(program, oldFileOrDirPath, newFileOrDirPath, host, formatContext, _preferences, sourceMapper) {
        var useCaseSensitiveFileNames = ts.hostUsesCaseSensitiveFileNames(host);
        var getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        var oldToNew = getPathUpdater(oldFileOrDirPath, newFileOrDirPath, getCanonicalFileName, sourceMapper);
        var newToOld = getPathUpdater(newFileOrDirPath, oldFileOrDirPath, getCanonicalFileName, sourceMapper);
        return ts.textChanges.ChangeTracker.with({ host: host, formatContext: formatContext }, function (changeTracker) {
            updateTsconfigFiles(program, changeTracker, oldToNew, oldFileOrDirPath, newFileOrDirPath, host.getCurrentDirectory(), useCaseSensitiveFileNames);
            updateImports(program, changeTracker, oldToNew, newToOld, host, getCanonicalFileName);
        });
    }
    ts.getEditsForFileRename = getEditsForFileRename;
    // exported for tests
    function getPathUpdater(oldFileOrDirPath, newFileOrDirPath, getCanonicalFileName, sourceMapper) {
        var canonicalOldPath = getCanonicalFileName(oldFileOrDirPath);
        return function (path) {
            var originalPath = sourceMapper && sourceMapper.tryGetSourcePosition({ fileName: path, pos: 0 });
            var updatedPath = getUpdatedPath(originalPath ? originalPath.fileName : path);
            return originalPath
                ? updatedPath === undefined ? undefined : makeCorrespondingRelativeChange(originalPath.fileName, updatedPath, path, getCanonicalFileName)
                : updatedPath;
        };
        function getUpdatedPath(pathToUpdate) {
            if (getCanonicalFileName(pathToUpdate) === canonicalOldPath)
                return newFileOrDirPath;
            var suffix = ts.tryRemoveDirectoryPrefix(pathToUpdate, canonicalOldPath, getCanonicalFileName);
            return suffix === undefined ? undefined : newFileOrDirPath + "/" + suffix;
        }
    }
    ts.getPathUpdater = getPathUpdater;
    // Relative path from a0 to b0 should be same as relative path from a1 to b1. Returns b1.
    function makeCorrespondingRelativeChange(a0, b0, a1, getCanonicalFileName) {
        var rel = ts.getRelativePathFromFile(a0, b0, getCanonicalFileName);
        return combinePathsSafe(ts.getDirectoryPath(a1), rel);
    }
    function updateTsconfigFiles(program, changeTracker, oldToNew, oldFileOrDirPath, newFileOrDirPath, currentDirectory, useCaseSensitiveFileNames) {
        var configFile = program.getCompilerOptions().configFile;
        if (!configFile)
            return;
        var configDir = ts.getDirectoryPath(configFile.fileName);
        var jsonObjectLiteral = ts.getTsConfigObjectLiteralExpression(configFile);
        if (!jsonObjectLiteral)
            return;
        forEachProperty(jsonObjectLiteral, function (property, propertyName) {
            switch (propertyName) {
                case "files":
                case "include":
                case "exclude": {
                    var foundExactMatch = updatePaths(property);
                    if (!foundExactMatch && propertyName === "include" && ts.isArrayLiteralExpression(property.initializer)) {
                        var includes = ts.mapDefined(property.initializer.elements, function (e) { return ts.isStringLiteral(e) ? e.text : undefined; });
                        var matchers = ts.getFileMatcherPatterns(configDir, /*excludes*/ [], includes, useCaseSensitiveFileNames, currentDirectory);
                        // If there isn't some include for this, add a new one.
                        if (ts.getRegexFromPattern(ts.Debug.assertDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(oldFileOrDirPath) &&
                            !ts.getRegexFromPattern(ts.Debug.assertDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(newFileOrDirPath)) {
                            changeTracker.insertNodeAfter(configFile, ts.last(property.initializer.elements), ts.createStringLiteral(relativePath(newFileOrDirPath)));
                        }
                    }
                    break;
                }
                case "compilerOptions":
                    forEachProperty(property.initializer, function (property, propertyName) {
                        var option = ts.getOptionFromName(propertyName);
                        if (option && (option.isFilePath || option.type === "list" && option.element.isFilePath)) {
                            updatePaths(property);
                        }
                        else if (propertyName === "paths") {
                            forEachProperty(property.initializer, function (pathsProperty) {
                                if (!ts.isArrayLiteralExpression(pathsProperty.initializer))
                                    return;
                                for (var _i = 0, _a = pathsProperty.initializer.elements; _i < _a.length; _i++) {
                                    var e = _a[_i];
                                    tryUpdateString(e);
                                }
                            });
                        }
                    });
                    break;
            }
        });
        function updatePaths(property) {
            // Type annotation needed due to #7294
            var elements = ts.isArrayLiteralExpression(property.initializer) ? property.initializer.elements : [property.initializer];
            var foundExactMatch = false;
            for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
                var element = elements_1[_i];
                foundExactMatch = tryUpdateString(element) || foundExactMatch;
            }
            return foundExactMatch;
        }
        function tryUpdateString(element) {
            if (!ts.isStringLiteral(element))
                return false;
            var elementFileName = combinePathsSafe(configDir, element.text);
            var updated = oldToNew(elementFileName);
            if (updated !== undefined) {
                changeTracker.replaceRangeWithText(configFile, createStringRange(element, configFile), relativePath(updated));
                return true;
            }
            return false;
        }
        function relativePath(path) {
            return ts.getRelativePathFromDirectory(configDir, path, /*ignoreCase*/ !useCaseSensitiveFileNames);
        }
    }
    function updateImports(program, changeTracker, oldToNew, newToOld, host, getCanonicalFileName) {
        var allFiles = program.getSourceFiles();
        var _loop_4 = function (sourceFile) {
            var newFromOld = oldToNew(sourceFile.path);
            var newImportFromPath = newFromOld !== undefined ? newFromOld : sourceFile.path;
            var newImportFromDirectory = ts.getDirectoryPath(newImportFromPath);
            var oldFromNew = newToOld(sourceFile.fileName);
            var oldImportFromPath = oldFromNew || sourceFile.fileName;
            var oldImportFromDirectory = ts.getDirectoryPath(oldImportFromPath);
            var importingSourceFileMoved = newFromOld !== undefined || oldFromNew !== undefined;
            updateImportsWorker(sourceFile, changeTracker, function (referenceText) {
                if (!ts.pathIsRelative(referenceText))
                    return undefined;
                var oldAbsolute = combinePathsSafe(oldImportFromDirectory, referenceText);
                var newAbsolute = oldToNew(oldAbsolute);
                return newAbsolute === undefined ? undefined : ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(newImportFromDirectory, newAbsolute, getCanonicalFileName));
            }, function (importLiteral) {
                var importedModuleSymbol = program.getTypeChecker().getSymbolAtLocation(importLiteral);
                // No need to update if it's an ambient module^M
                if (importedModuleSymbol && importedModuleSymbol.declarations.some(function (d) { return ts.isAmbientModule(d); }))
                    return undefined;
                var toImport = oldFromNew !== undefined
                    // If we're at the new location (file was already renamed), need to redo module resolution starting from the old location.
                    // TODO:GH#18217
                    ? getSourceFileToImportFromResolved(ts.resolveModuleName(importLiteral.text, oldImportFromPath, program.getCompilerOptions(), host), oldToNew)
                    : getSourceFileToImport(importedModuleSymbol, importLiteral, sourceFile, program, host, oldToNew);
                // Need an update if the imported file moved, or the importing file moved and was using a relative path.
                return toImport !== undefined && (toImport.updated || (importingSourceFileMoved && ts.pathIsRelative(importLiteral.text)))
                    ? ts.moduleSpecifiers.updateModuleSpecifier(program.getCompilerOptions(), newImportFromPath, toImport.newFileName, host, allFiles, program.redirectTargetsMap, importLiteral.text)
                    : undefined;
            });
        };
        for (var _i = 0, allFiles_1 = allFiles; _i < allFiles_1.length; _i++) {
            var sourceFile = allFiles_1[_i];
            _loop_4(sourceFile);
        }
    }
    function combineNormal(pathA, pathB) {
        return ts.normalizePath(ts.combinePaths(pathA, pathB));
    }
    function combinePathsSafe(pathA, pathB) {
        return ts.ensurePathIsNonModuleName(combineNormal(pathA, pathB));
    }
    function getSourceFileToImport(importedModuleSymbol, importLiteral, importingSourceFile, program, host, oldToNew) {
        if (importedModuleSymbol) {
            // `find` should succeed because we checked for ambient modules before calling this function.
            var oldFileName = ts.find(importedModuleSymbol.declarations, ts.isSourceFile).fileName;
            var newFileName = oldToNew(oldFileName);
            return newFileName === undefined ? { newFileName: oldFileName, updated: false } : { newFileName: newFileName, updated: true };
        }
        else {
            var resolved = host.resolveModuleNames
                ? host.getResolvedModuleWithFailedLookupLocationsFromCache && host.getResolvedModuleWithFailedLookupLocationsFromCache(importLiteral.text, importingSourceFile.fileName)
                : program.getResolvedModuleWithFailedLookupLocationsFromCache(importLiteral.text, importingSourceFile.fileName);
            return getSourceFileToImportFromResolved(resolved, oldToNew);
        }
    }
    function getSourceFileToImportFromResolved(resolved, oldToNew) {
        // Search through all locations looking for a moved file, and only then test already existing files.
        // This is because if `a.ts` is compiled to `a.js` and `a.ts` is moved, we don't want to resolve anything to `a.js`, but to `a.ts`'s new location.
        if (!resolved)
            return undefined;
        // First try resolved module
        if (resolved.resolvedModule) {
            var result_2 = tryChange(resolved.resolvedModule.resolvedFileName);
            if (result_2)
                return result_2;
        }
        // Then failed lookups except package.json since we dont want to touch them (only included ts/js files)
        var result = ts.forEach(resolved.failedLookupLocations, tryChangeWithIgnoringPackageJson);
        if (result)
            return result;
        // If nothing changed, then result is resolved module file thats not updated
        return resolved.resolvedModule && { newFileName: resolved.resolvedModule.resolvedFileName, updated: false };
        function tryChangeWithIgnoringPackageJson(oldFileName) {
            return !ts.endsWith(oldFileName, "/package.json") ? tryChange(oldFileName) : undefined;
        }
        function tryChange(oldFileName) {
            var newFileName = oldToNew(oldFileName);
            return newFileName && { newFileName: newFileName, updated: true };
        }
    }
    function updateImportsWorker(sourceFile, changeTracker, updateRef, updateImport) {
        for (var _i = 0, _a = sourceFile.referencedFiles || ts.emptyArray; _i < _a.length; _i++) { // TODO: GH#26162
            var ref = _a[_i];
            var updated = updateRef(ref.fileName);
            if (updated !== undefined && updated !== sourceFile.text.slice(ref.pos, ref.end))
                changeTracker.replaceRangeWithText(sourceFile, ref, updated);
        }
        for (var _b = 0, _c = sourceFile.imports; _b < _c.length; _b++) {
            var importStringLiteral = _c[_b];
            var updated = updateImport(importStringLiteral);
            if (updated !== undefined && updated !== importStringLiteral.text)
                changeTracker.replaceRangeWithText(sourceFile, createStringRange(importStringLiteral, sourceFile), updated);
        }
    }
    function createStringRange(node, sourceFile) {
        return ts.createRange(node.getStart(sourceFile) + 1, node.end - 1);
    }
    function forEachProperty(objectLiteral, cb) {
        if (!ts.isObjectLiteralExpression(objectLiteral))
            return;
        for (var _i = 0, _a = objectLiteral.properties; _i < _a.length; _i++) {
            var property = _a[_i];
            if (ts.isPropertyAssignment(property) && ts.isStringLiteral(property.name)) {
                cb(property, property.name.text);
            }
        }
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var GoToDefinition;
    (function (GoToDefinition) {
        function getDefinitionAtPosition(program, sourceFile, position) {
            var reference = getReferenceAtPosition(sourceFile, position, program);
            if (reference) {
                return [getDefinitionInfoForFileReference(reference.fileName, reference.file.fileName)];
            }
            var node = ts.getTouchingPropertyName(sourceFile, position);
            if (node === sourceFile) {
                return undefined;
            }
            var parent = node.parent;
            // Labels
            if (ts.isJumpStatementTarget(node)) {
                var label = ts.getTargetLabel(node.parent, node.text);
                return label ? [createDefinitionInfoFromName(label, "label" /* label */, node.text, /*containerName*/ undefined)] : undefined; // TODO: GH#18217
            }
            var typeChecker = program.getTypeChecker();
            var symbol = getSymbol(node, typeChecker);
            // Could not find a symbol e.g. node is string or number keyword,
            // or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol
            if (!symbol) {
                return getDefinitionInfoForIndexSignatures(node, typeChecker);
            }
            var calledDeclaration = tryGetSignatureDeclaration(typeChecker, node);
            // Don't go to the component constructor definition for a JSX element, just go to the component definition.
            if (calledDeclaration && !(ts.isJsxOpeningLikeElement(node.parent) && isConstructorLike(calledDeclaration))) {
                var sigInfo = createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration);
                // For a function, if this is the original function definition, return just sigInfo.
                // If this is the original constructor definition, parent is the class.
                if (typeChecker.getRootSymbols(symbol).some(function (s) { return symbolMatchesSignature(s, calledDeclaration); }) ||
                    // TODO: GH#25533 Following check shouldn't be necessary if 'require' is an alias
                    symbol.declarations && symbol.declarations.some(function (d) { return ts.isVariableDeclaration(d) && !!d.initializer && ts.isRequireCall(d.initializer, /*checkArgumentIsStringLiteralLike*/ false); })) {
                    return [sigInfo];
                }
                else {
                    var defs = getDefinitionFromSymbol(typeChecker, symbol, node) || ts.emptyArray;
                    // For a 'super()' call, put the signature first, else put the variable first.
                    return node.kind === 99 /* SuperKeyword */ ? [sigInfo].concat(defs) : defs.concat([sigInfo]);
                }
            }
            // Because name in short-hand property assignment has two different meanings: property name and property value,
            // using go-to-definition at such position should go to the variable declaration of the property value rather than
            // go to the declaration of the property name (in this case stay at the same position). However, if go-to-definition
            // is performed at the location of property access, we would like to go to definition of the property in the short-hand
            // assignment. This case and others are handled by the following code.
            if (node.parent.kind === 277 /* ShorthandPropertyAssignment */) {
                var shorthandSymbol_1 = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration);
                return shorthandSymbol_1 ? shorthandSymbol_1.declarations.map(function (decl) { return createDefinitionInfo(decl, typeChecker, shorthandSymbol_1, node); }) : [];
            }
            // If the node is the name of a BindingElement within an ObjectBindingPattern instead of just returning the
            // declaration the symbol (which is itself), we should try to get to the original type of the ObjectBindingPattern
            // and return the property declaration for the referenced property.
            // For example:
            //      import('./foo').then(({ b/*goto*/ar }) => undefined); => should get use to the declaration in file "./foo"
            //
            //      function bar<T>(onfulfilled: (value: T) => void) { //....}
            //      interface Test {
            //          pr/*destination*/op1: number
            //      }
            //      bar<Test>(({pr/*goto*/op1})=>{});
            if (ts.isPropertyName(node) && ts.isBindingElement(parent) && ts.isObjectBindingPattern(parent.parent) &&
                (node === (parent.propertyName || parent.name))) {
                var name_3 = ts.getNameFromPropertyName(node);
                var type = typeChecker.getTypeAtLocation(parent.parent);
                return name_3 === undefined ? ts.emptyArray : ts.flatMap(type.isUnion() ? type.types : [type], function (t) {
                    var prop = t.getProperty(name_3);
                    return prop && getDefinitionFromSymbol(typeChecker, prop, node);
                });
            }
            // If the current location we want to find its definition is in an object literal, try to get the contextual type for the
            // object literal, lookup the property symbol in the contextual type, and use this for goto-definition.
            // For example
            //      interface Props{
            //          /*first*/prop1: number
            //          prop2: boolean
            //      }
            //      function Foo(arg: Props) {}
            //      Foo( { pr/*1*/op1: 10, prop2: true })
            var element = ts.getContainingObjectLiteralElement(node);
            if (element) {
                var contextualType = element && typeChecker.getContextualType(element.parent);
                if (contextualType) {
                    return ts.flatMap(ts.getPropertySymbolsFromContextualType(element, typeChecker, contextualType, /*unionSymbolOk*/ false), function (propertySymbol) {
                        return getDefinitionFromSymbol(typeChecker, propertySymbol, node);
                    });
                }
            }
            return getDefinitionFromSymbol(typeChecker, symbol, node);
        }
        GoToDefinition.getDefinitionAtPosition = getDefinitionAtPosition;
        /**
         * True if we should not add definitions for both the signature symbol and the definition symbol.
         * True for `const |f = |() => 0`, false for `function |f() {} const |g = f;`.
         */
        function symbolMatchesSignature(s, calledDeclaration) {
            return s === calledDeclaration.symbol || s === calledDeclaration.symbol.parent ||
                !ts.isCallLikeExpression(calledDeclaration.parent) && s === calledDeclaration.parent.symbol;
        }
        function getReferenceAtPosition(sourceFile, position, program) {
            var referencePath = findReferenceInPosition(sourceFile.referencedFiles, position);
            if (referencePath) {
                var file = ts.tryResolveScriptReference(program, sourceFile, referencePath);
                return file && { fileName: referencePath.fileName, file: file };
            }
            var typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position);
            if (typeReferenceDirective) {
                var reference = program.getResolvedTypeReferenceDirectives().get(typeReferenceDirective.fileName);
                var file = reference && program.getSourceFile(reference.resolvedFileName); // TODO:GH#18217
                return file && { fileName: typeReferenceDirective.fileName, file: file };
            }
            var libReferenceDirective = findReferenceInPosition(sourceFile.libReferenceDirectives, position);
            if (libReferenceDirective) {
                var file = program.getLibFileFromReference(libReferenceDirective);
                return file && { fileName: libReferenceDirective.fileName, file: file };
            }
            return undefined;
        }
        GoToDefinition.getReferenceAtPosition = getReferenceAtPosition;
        /// Goto type
        function getTypeDefinitionAtPosition(typeChecker, sourceFile, position) {
            var node = ts.getTouchingPropertyName(sourceFile, position);
            if (node === sourceFile) {
                return undefined;
            }
            var symbol = typeChecker.getSymbolAtLocation(node);
            if (!symbol)
                return undefined;
            var typeAtLocation = typeChecker.getTypeOfSymbolAtLocation(symbol, node);
            var returnType = tryGetReturnTypeOfFunction(symbol, typeAtLocation, typeChecker);
            var fromReturnType = returnType && definitionFromType(returnType, typeChecker, node);
            // If a function returns 'void' or some other type with no definition, just return the function definition.
            return fromReturnType && fromReturnType.length !== 0 ? fromReturnType : definitionFromType(typeAtLocation, typeChecker, node);
        }
        GoToDefinition.getTypeDefinitionAtPosition = getTypeDefinitionAtPosition;
        function definitionFromType(type, checker, node) {
            return ts.flatMap(type.isUnion() && !(type.flags & 32 /* Enum */) ? type.types : [type], function (t) {
                return t.symbol && getDefinitionFromSymbol(checker, t.symbol, node);
            });
        }
        function tryGetReturnTypeOfFunction(symbol, type, checker) {
            // If the type is just a function's inferred type,
            // go-to-type should go to the return type instead, since go-to-definition takes you to the function anyway.
            if (type.symbol === symbol ||
                // At `const f = () => {}`, the symbol is `f` and the type symbol is at `() => {}`
                symbol.valueDeclaration && type.symbol && ts.isVariableDeclaration(symbol.valueDeclaration) && symbol.valueDeclaration.initializer === type.symbol.valueDeclaration) {
                var sigs = type.getCallSignatures();
                if (sigs.length === 1)
                    return checker.getReturnTypeOfSignature(ts.first(sigs));
            }
            return undefined;
        }
        function getDefinitionAndBoundSpan(program, sourceFile, position) {
            var definitions = getDefinitionAtPosition(program, sourceFile, position);
            if (!definitions || definitions.length === 0) {
                return undefined;
            }
            // Check if position is on triple slash reference.
            var comment = findReferenceInPosition(sourceFile.referencedFiles, position) ||
                findReferenceInPosition(sourceFile.typeReferenceDirectives, position) ||
                findReferenceInPosition(sourceFile.libReferenceDirectives, position);
            if (comment) {
                return { definitions: definitions, textSpan: ts.createTextSpanFromRange(comment) };
            }
            var node = ts.getTouchingPropertyName(sourceFile, position);
            var textSpan = ts.createTextSpan(node.getStart(), node.getWidth());
            return { definitions: definitions, textSpan: textSpan };
        }
        GoToDefinition.getDefinitionAndBoundSpan = getDefinitionAndBoundSpan;
        // At 'x.foo', see if the type of 'x' has an index signature, and if so find its declarations.
        function getDefinitionInfoForIndexSignatures(node, checker) {
            if (!ts.isPropertyAccessExpression(node.parent) || node.parent.name !== node)
                return;
            var type = checker.getTypeAtLocation(node.parent.expression);
            return ts.mapDefined(type.isUnionOrIntersection() ? type.types : [type], function (nonUnionType) {
                var info = checker.getIndexInfoOfType(nonUnionType, 0 /* String */);
                return info && info.declaration && createDefinitionFromSignatureDeclaration(checker, info.declaration);
            });
        }
        function getSymbol(node, checker) {
            var symbol = checker.getSymbolAtLocation(node);
            // If this is an alias, and the request came at the declaration location
            // get the aliased symbol instead. This allows for goto def on an import e.g.
            //   import {A, B} from "mod";
            // to jump to the implementation directly.
            if (symbol && symbol.flags & 2097152 /* Alias */ && shouldSkipAlias(node, symbol.declarations[0])) {
                var aliased = checker.getAliasedSymbol(symbol);
                if (aliased.declarations) {
                    return aliased;
                }
            }
            return symbol;
        }
        // Go to the original declaration for cases:
        //
        //   (1) when the aliased symbol was declared in the location(parent).
        //   (2) when the aliased symbol is originating from an import.
        //
        function shouldSkipAlias(node, declaration) {
            if (node.kind !== 73 /* Identifier */) {
                return false;
            }
            if (node.parent === declaration) {
                return true;
            }
            switch (declaration.kind) {
                case 251 /* ImportClause */:
                case 249 /* ImportEqualsDeclaration */:
                    return true;
                case 254 /* ImportSpecifier */:
                    return declaration.parent.kind === 253 /* NamedImports */;
                default:
                    return false;
            }
        }
        function getDefinitionFromSymbol(typeChecker, symbol, node) {
            return getConstructSignatureDefinition() || getCallSignatureDefinition() || ts.map(symbol.declarations, function (declaration) { return createDefinitionInfo(declaration, typeChecker, symbol, node); });
            function getConstructSignatureDefinition() {
                // Applicable only if we are in a new expression, or we are on a constructor declaration
                // and in either case the symbol has a construct signature definition, i.e. class
                if (symbol.flags & 32 /* Class */ && (ts.isNewExpressionTarget(node) || node.kind === 125 /* ConstructorKeyword */)) {
                    var cls = ts.find(symbol.declarations, ts.isClassLike) || ts.Debug.fail("Expected declaration to have at least one class-like declaration");
                    return getSignatureDefinition(cls.members, /*selectConstructors*/ true);
                }
            }
            function getCallSignatureDefinition() {
                return ts.isCallOrNewExpressionTarget(node) || ts.isNameOfFunctionDeclaration(node)
                    ? getSignatureDefinition(symbol.declarations, /*selectConstructors*/ false)
                    : undefined;
            }
            function getSignatureDefinition(signatureDeclarations, selectConstructors) {
                if (!signatureDeclarations) {
                    return undefined;
                }
                var declarations = signatureDeclarations.filter(selectConstructors ? ts.isConstructorDeclaration : ts.isFunctionLike);
                return declarations.length
                    ? [createDefinitionInfo(ts.find(declarations, function (d) { return !!d.body; }) || ts.last(declarations), typeChecker, symbol, node)]
                    : undefined;
            }
        }
        /** Creates a DefinitionInfo from a Declaration, using the declaration's name if possible. */
        function createDefinitionInfo(declaration, checker, symbol, node) {
            var symbolName = checker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol
            var symbolKind = ts.SymbolDisplay.getSymbolKind(checker, symbol, node);
            var containerName = symbol.parent ? checker.symbolToString(symbol.parent, node) : "";
            return createDefinitionInfoFromName(declaration, symbolKind, symbolName, containerName);
        }
        /** Creates a DefinitionInfo directly from the name of a declaration. */
        function createDefinitionInfoFromName(declaration, symbolKind, symbolName, containerName) {
            var name = ts.getNameOfDeclaration(declaration) || declaration;
            var sourceFile = name.getSourceFile();
            return {
                fileName: sourceFile.fileName,
                textSpan: ts.createTextSpanFromNode(name, sourceFile),
                kind: symbolKind,
                name: symbolName,
                containerKind: undefined,
                containerName: containerName
            };
        }
        function createDefinitionFromSignatureDeclaration(typeChecker, decl) {
            return createDefinitionInfo(decl, typeChecker, decl.symbol, decl);
        }
        function findReferenceInPosition(refs, pos) {
            return ts.find(refs, function (ref) { return ts.textRangeContainsPositionInclusive(ref, pos); });
        }
        GoToDefinition.findReferenceInPosition = findReferenceInPosition;
        function getDefinitionInfoForFileReference(name, targetFileName) {
            return {
                fileName: targetFileName,
                textSpan: ts.createTextSpanFromBounds(0, 0),
                kind: "script" /* scriptElement */,
                name: name,
                containerName: undefined,
                containerKind: undefined,
            };
        }
        /** Returns a CallLikeExpression where `node` is the target being invoked. */
        function getAncestorCallLikeExpression(node) {
            var target = climbPastManyPropertyAccesses(node);
            var callLike = target.parent;
            return callLike && ts.isCallLikeExpression(callLike) && ts.getInvokedExpression(callLike) === target ? callLike : undefined;
        }
        function climbPastManyPropertyAccesses(node) {
            return ts.isRightSideOfPropertyAccess(node) ? climbPastManyPropertyAccesses(node.parent) : node;
        }
        function tryGetSignatureDeclaration(typeChecker, node) {
            var callLike = getAncestorCallLikeExpression(node);
            var signature = callLike && typeChecker.getResolvedSignature(callLike);
            // Don't go to a function type, go to the value having that type.
            return ts.tryCast(signature && signature.declaration, function (d) { return ts.isFunctionLike(d) && !ts.isFunctionTypeNode(d); });
        }
        function isConstructorLike(node) {
            switch (node.kind) {
                case 158 /* Constructor */:
                case 167 /* ConstructorType */:
                case 162 /* ConstructSignature */:
                    return true;
                default:
                    return false;
            }
        }
    })(GoToDefinition = ts.GoToDefinition || (ts.GoToDefinition = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var JsDoc;
    (function (JsDoc) {
        var jsDocTagNames = [
            "abstract",
            "access",
            "alias",
            "argument",
            "async",
            "augments",
            "author",
            "borrows",
            "callback",
            "class",
            "classdesc",
            "constant",
            "constructor",
            "constructs",
            "copyright",
            "default",
            "deprecated",
            "description",
            "emits",
            "enum",
            "event",
            "example",
            "exports",
            "extends",
            "external",
            "field",
            "file",
            "fileoverview",
            "fires",
            "function",
            "generator",
            "global",
            "hideconstructor",
            "host",
            "ignore",
            "implements",
            "inheritdoc",
            "inner",
            "instance",
            "interface",
            "kind",
            "lends",
            "license",
            "listens",
            "member",
            "memberof",
            "method",
            "mixes",
            "module",
            "name",
            "namespace",
            "override",
            "package",
            "param",
            "private",
            "property",
            "protected",
            "public",
            "readonly",
            "requires",
            "returns",
            "see",
            "since",
            "static",
            "summary",
            "template",
            "this",
            "throws",
            "todo",
            "tutorial",
            "type",
            "typedef",
            "var",
            "variation",
            "version",
            "virtual",
            "yields"
        ];
        var jsDocTagNameCompletionEntries;
        var jsDocTagCompletionEntries;
        function getJsDocCommentsFromDeclarations(declarations) {
            // Only collect doc comments from duplicate declarations once:
            // In case of a union property there might be same declaration multiple times
            // which only varies in type parameter
            // Eg. const a: Array<string> | Array<number>; a.length
            // The property length will have two declarations of property length coming
            // from Array<T> - Array<string> and Array<number>
            var documentationComment = [];
            forEachUnique(declarations, function (declaration) {
                for (var _i = 0, _a = getCommentHavingNodes(declaration); _i < _a.length; _i++) {
                    var comment = _a[_i].comment;
                    if (comment === undefined)
                        continue;
                    if (documentationComment.length) {
                        documentationComment.push(ts.lineBreakPart());
                    }
                    documentationComment.push(ts.textPart(comment));
                }
            });
            return documentationComment;
        }
        JsDoc.getJsDocCommentsFromDeclarations = getJsDocCommentsFromDeclarations;
        function getCommentHavingNodes(declaration) {
            switch (declaration.kind) {
                case 305 /* JSDocParameterTag */:
                case 311 /* JSDocPropertyTag */:
                    return [declaration];
                case 303 /* JSDocCallbackTag */:
                case 310 /* JSDocTypedefTag */:
                    return [declaration, declaration.parent];
                default:
                    return ts.getJSDocCommentsAndTags(declaration);
            }
        }
        function getJsDocTagsFromDeclarations(declarations) {
            // Only collect doc comments from duplicate declarations once.
            var tags = [];
            forEachUnique(declarations, function (declaration) {
                for (var _i = 0, _a = ts.getJSDocTags(declaration); _i < _a.length; _i++) {
                    var tag = _a[_i];
                    tags.push({ name: tag.tagName.text, text: getCommentText(tag) });
                }
            });
            return tags;
        }
        JsDoc.getJsDocTagsFromDeclarations = getJsDocTagsFromDeclarations;
        function getCommentText(tag) {
            var comment = tag.comment;
            switch (tag.kind) {
                case 301 /* JSDocAugmentsTag */:
                    return withNode(tag.class);
                case 309 /* JSDocTemplateTag */:
                    return withList(tag.typeParameters);
                case 308 /* JSDocTypeTag */:
                    return withNode(tag.typeExpression);
                case 310 /* JSDocTypedefTag */:
                case 303 /* JSDocCallbackTag */:
                case 311 /* JSDocPropertyTag */:
                case 305 /* JSDocParameterTag */:
                    var name = tag.name;
                    return name ? withNode(name) : comment;
                default:
                    return comment;
            }
            function withNode(node) {
                return addComment(node.getText());
            }
            function withList(list) {
                return addComment(list.map(function (x) { return x.getText(); }).join(", "));
            }
            function addComment(s) {
                return comment === undefined ? s : s + " " + comment;
            }
        }
        /**
         * Iterates through 'array' by index and performs the callback on each element of array until the callback
         * returns a truthy value, then returns that value.
         * If no such value is found, the callback is applied to each element of array and undefined is returned.
         */
        function forEachUnique(array, callback) {
            if (array) {
                for (var i = 0; i < array.length; i++) {
                    if (array.indexOf(array[i]) === i) {
                        var result = callback(array[i], i);
                        if (result) {
                            return result;
                        }
                    }
                }
            }
            return undefined;
        }
        function getJSDocTagNameCompletions() {
            return jsDocTagNameCompletionEntries || (jsDocTagNameCompletionEntries = ts.map(jsDocTagNames, function (tagName) {
                return {
                    name: tagName,
                    kind: "keyword" /* keyword */,
                    kindModifiers: "",
                    sortText: "0",
                };
            }));
        }
        JsDoc.getJSDocTagNameCompletions = getJSDocTagNameCompletions;
        JsDoc.getJSDocTagNameCompletionDetails = getJSDocTagCompletionDetails;
        function getJSDocTagCompletions() {
            return jsDocTagCompletionEntries || (jsDocTagCompletionEntries = ts.map(jsDocTagNames, function (tagName) {
                return {
                    name: "@" + tagName,
                    kind: "keyword" /* keyword */,
                    kindModifiers: "",
                    sortText: "0"
                };
            }));
        }
        JsDoc.getJSDocTagCompletions = getJSDocTagCompletions;
        function getJSDocTagCompletionDetails(name) {
            return {
                name: name,
                kind: "" /* unknown */,
                kindModifiers: "",
                displayParts: [ts.textPart(name)],
                documentation: ts.emptyArray,
                tags: undefined,
                codeActions: undefined,
            };
        }
        JsDoc.getJSDocTagCompletionDetails = getJSDocTagCompletionDetails;
        function getJSDocParameterNameCompletions(tag) {
            if (!ts.isIdentifier(tag.name)) {
                return ts.emptyArray;
            }
            var nameThusFar = tag.name.text;
            var jsdoc = tag.parent;
            var fn = jsdoc.parent;
            if (!ts.isFunctionLike(fn))
                return [];
            return ts.mapDefined(fn.parameters, function (param) {
                if (!ts.isIdentifier(param.name))
                    return undefined;
                var name = param.name.text;
                if (jsdoc.tags.some(function (t) { return t !== tag && ts.isJSDocParameterTag(t) && ts.isIdentifier(t.name) && t.name.escapedText === name; }) // TODO: GH#18217
                    || nameThusFar !== undefined && !ts.startsWith(name, nameThusFar)) {
                    return undefined;
                }
                return { name: name, kind: "parameter" /* parameterElement */, kindModifiers: "", sortText: "0" };
            });
        }
        JsDoc.getJSDocParameterNameCompletions = getJSDocParameterNameCompletions;
        function getJSDocParameterNameCompletionDetails(name) {
            return {
                name: name,
                kind: "parameter" /* parameterElement */,
                kindModifiers: "",
                displayParts: [ts.textPart(name)],
                documentation: ts.emptyArray,
                tags: undefined,
                codeActions: undefined,
            };
        }
        JsDoc.getJSDocParameterNameCompletionDetails = getJSDocParameterNameCompletionDetails;
        /**
         * Checks if position points to a valid position to add JSDoc comments, and if so,
         * returns the appropriate template. Otherwise returns an empty string.
         * Valid positions are
         *      - outside of comments, statements, and expressions, and
         *      - preceding a:
         *          - function/constructor/method declaration
         *          - class declarations
         *          - variable statements
         *          - namespace declarations
         *          - interface declarations
         *          - method signatures
         *          - type alias declarations
         *
         * Hosts should ideally check that:
         * - The line is all whitespace up to 'position' before performing the insertion.
         * - If the keystroke sequence "/\*\*" induced the call, we also check that the next
         * non-whitespace character is '*', which (approximately) indicates whether we added
         * the second '*' to complete an existing (JSDoc) comment.
         * @param fileName The file in which to perform the check.
         * @param position The (character-indexed) position in the file where the check should
         * be performed.
         */
        function getDocCommentTemplateAtPosition(newLine, sourceFile, position) {
            var tokenAtPos = ts.getTokenAtPosition(sourceFile, position);
            var existingDocComment = ts.findAncestor(tokenAtPos, ts.isJSDoc);
            if (existingDocComment && (existingDocComment.comment !== undefined || ts.length(existingDocComment.tags))) {
                // Non-empty comment already exists.
                return undefined;
            }
            var tokenStart = tokenAtPos.getStart(sourceFile);
            // Don't provide a doc comment template based on a *previous* node. (But an existing empty jsdoc comment will likely start before `position`.)
            if (!existingDocComment && tokenStart < position) {
                return undefined;
            }
            var commentOwnerInfo = getCommentOwnerInfo(tokenAtPos);
            if (!commentOwnerInfo) {
                return undefined;
            }
            var commentOwner = commentOwnerInfo.commentOwner, parameters = commentOwnerInfo.parameters;
            if (commentOwner.getStart(sourceFile) < position) {
                return undefined;
            }
            if (!parameters || parameters.length === 0) {
                // if there are no parameters, just complete to a single line JSDoc comment
                var singleLineResult = "/** */";
                return { newText: singleLineResult, caretOffset: 3 };
            }
            var indentationStr = getIndentationStringAtPosition(sourceFile, position);
            // A doc comment consists of the following
            // * The opening comment line
            // * the first line (without a param) for the object's untagged info (this is also where the caret ends up)
            // * the '@param'-tagged lines
            // * TODO: other tags.
            // * the closing comment line
            // * if the caret was directly in front of the object, then we add an extra line and indentation.
            var preamble = "/**" + newLine + indentationStr + " * ";
            var result = preamble + newLine +
                parameterDocComments(parameters, ts.hasJSFileExtension(sourceFile.fileName), indentationStr, newLine) +
                indentationStr + " */" +
                (tokenStart === position ? newLine + indentationStr : "");
            return { newText: result, caretOffset: preamble.length };
        }
        JsDoc.getDocCommentTemplateAtPosition = getDocCommentTemplateAtPosition;
        function getIndentationStringAtPosition(sourceFile, position) {
            var text = sourceFile.text;
            var lineStart = ts.getLineStartPositionForPosition(position, sourceFile);
            var pos = lineStart;
            for (; pos <= position && ts.isWhiteSpaceSingleLine(text.charCodeAt(pos)); pos++)
                ;
            return text.slice(lineStart, pos);
        }
        function parameterDocComments(parameters, isJavaScriptFile, indentationStr, newLine) {
            return parameters.map(function (_a, i) {
                var name = _a.name, dotDotDotToken = _a.dotDotDotToken;
                var paramName = name.kind === 73 /* Identifier */ ? name.text : "param" + i;
                var type = isJavaScriptFile ? (dotDotDotToken ? "{...any} " : "{any} ") : "";
                return indentationStr + " * @param " + type + paramName + newLine;
            }).join("");
        }
        function getCommentOwnerInfo(tokenAtPos) {
            return ts.forEachAncestor(tokenAtPos, getCommentOwnerInfoWorker);
        }
        function getCommentOwnerInfoWorker(commentOwner) {
            switch (commentOwner.kind) {
                case 240 /* FunctionDeclaration */:
                case 197 /* FunctionExpression */:
                case 157 /* MethodDeclaration */:
                case 158 /* Constructor */:
                case 156 /* MethodSignature */:
                    var parameters = commentOwner.parameters;
                    return { commentOwner: commentOwner, parameters: parameters };
                case 276 /* PropertyAssignment */:
                    return getCommentOwnerInfoWorker(commentOwner.initializer);
                case 241 /* ClassDeclaration */:
                case 242 /* InterfaceDeclaration */:
                case 154 /* PropertySignature */:
                case 244 /* EnumDeclaration */:
                case 279 /* EnumMember */:
                case 243 /* TypeAliasDeclaration */:
                    return { commentOwner: commentOwner };
                case 220 /* VariableStatement */: {
                    var varStatement = commentOwner;
                    var varDeclarations = varStatement.declarationList.declarations;
                    var parameters_1 = varDeclarations.length === 1 && varDeclarations[0].initializer
                        ? getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer)
                        : undefined;
                    return { commentOwner: commentOwner, parameters: parameters_1 };
                }
                case 285 /* SourceFile */:
                    return "quit";
                case 245 /* ModuleDeclaration */:
                    // If in walking up the tree, we hit a a nested namespace declaration,
                    // then we must be somewhere within a dotted namespace name; however we don't
                    // want to give back a JSDoc template for the 'b' or 'c' in 'namespace a.b.c { }'.
                    return commentOwner.parent.kind === 245 /* ModuleDeclaration */ ? undefined : { commentOwner: commentOwner };
                case 205 /* BinaryExpression */: {
                    var be = commentOwner;
                    if (ts.getAssignmentDeclarationKind(be) === 0 /* None */) {
                        return "quit";
                    }
                    var parameters_2 = ts.isFunctionLike(be.right) ? be.right.parameters : ts.emptyArray;
                    return { commentOwner: commentOwner, parameters: parameters_2 };
                }
            }
        }
        /**
         * Digs into an an initializer or RHS operand of an assignment operation
         * to get the parameters of an apt signature corresponding to a
         * function expression or a class expression.
         *
         * @param rightHandSide the expression which may contain an appropriate set of parameters
         * @returns the parameters of a signature found on the RHS if one exists; otherwise 'emptyArray'.
         */
        function getParametersFromRightHandSideOfAssignment(rightHandSide) {
            while (rightHandSide.kind === 196 /* ParenthesizedExpression */) {
                rightHandSide = rightHandSide.expression;
            }
            switch (rightHandSide.kind) {
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */:
                    return rightHandSide.parameters;
                case 210 /* ClassExpression */: {
                    var ctr = ts.find(rightHandSide.members, ts.isConstructorDeclaration);
                    return ctr ? ctr.parameters : ts.emptyArray;
                }
            }
            return ts.emptyArray;
        }
    })(JsDoc = ts.JsDoc || (ts.JsDoc = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var NavigateTo;
    (function (NavigateTo) {
        function getNavigateToItems(sourceFiles, checker, cancellationToken, searchValue, maxResultCount, excludeDtsFiles) {
            var patternMatcher = ts.createPatternMatcher(searchValue);
            if (!patternMatcher)
                return ts.emptyArray;
            var rawItems = [];
            var _loop_5 = function (sourceFile) {
                cancellationToken.throwIfCancellationRequested();
                if (excludeDtsFiles && sourceFile.isDeclarationFile) {
                    return "continue";
                }
                sourceFile.getNamedDeclarations().forEach(function (declarations, name) {
                    getItemsFromNamedDeclaration(patternMatcher, name, declarations, checker, sourceFile.fileName, rawItems);
                });
            };
            // Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[]
            for (var _i = 0, sourceFiles_4 = sourceFiles; _i < sourceFiles_4.length; _i++) {
                var sourceFile = sourceFiles_4[_i];
                _loop_5(sourceFile);
            }
            rawItems.sort(compareNavigateToItems);
            return (maxResultCount === undefined ? rawItems : rawItems.slice(0, maxResultCount)).map(createNavigateToItem);
        }
        NavigateTo.getNavigateToItems = getNavigateToItems;
        function getItemsFromNamedDeclaration(patternMatcher, name, declarations, checker, fileName, rawItems) {
            // First do a quick check to see if the name of the declaration matches the
            // last portion of the (possibly) dotted name they're searching for.
            var match = patternMatcher.getMatchForLastSegmentOfPattern(name);
            if (!match) {
                return; // continue to next named declarations
            }
            for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) {
                var declaration = declarations_3[_i];
                if (!shouldKeepItem(declaration, checker))
                    continue;
                if (patternMatcher.patternContainsDots) {
                    // If the pattern has dots in it, then also see if the declaration container matches as well.
                    var fullMatch = patternMatcher.getFullMatch(getContainers(declaration), name);
                    if (fullMatch) {
                        rawItems.push({ name: name, fileName: fileName, matchKind: fullMatch.kind, isCaseSensitive: fullMatch.isCaseSensitive, declaration: declaration });
                    }
                }
                else {
                    rawItems.push({ name: name, fileName: fileName, matchKind: match.kind, isCaseSensitive: match.isCaseSensitive, declaration: declaration });
                }
            }
        }
        function shouldKeepItem(declaration, checker) {
            switch (declaration.kind) {
                case 251 /* ImportClause */:
                case 254 /* ImportSpecifier */:
                case 249 /* ImportEqualsDeclaration */:
                    var importer = checker.getSymbolAtLocation(declaration.name); // TODO: GH#18217
                    var imported = checker.getAliasedSymbol(importer);
                    return importer.escapedName !== imported.escapedName;
                default:
                    return true;
            }
        }
        function tryAddSingleDeclarationName(declaration, containers) {
            var name = ts.getNameOfDeclaration(declaration);
            return !!name && (pushLiteral(name, containers) || name.kind === 150 /* ComputedPropertyName */ && tryAddComputedPropertyName(name.expression, containers));
        }
        // Only added the names of computed properties if they're simple dotted expressions, like:
        //
        //      [X.Y.Z]() { }
        function tryAddComputedPropertyName(expression, containers) {
            return pushLiteral(expression, containers)
                || ts.isPropertyAccessExpression(expression) && (containers.push(expression.name.text), true) && tryAddComputedPropertyName(expression.expression, containers);
        }
        function pushLiteral(node, containers) {
            return ts.isPropertyNameLiteral(node) && (containers.push(ts.getTextOfIdentifierOrLiteral(node)), true);
        }
        function getContainers(declaration) {
            var containers = [];
            // First, if we started with a computed property name, then add all but the last
            // portion into the container array.
            var name = ts.getNameOfDeclaration(declaration);
            if (name && name.kind === 150 /* ComputedPropertyName */ && !tryAddComputedPropertyName(name.expression, containers)) {
                return ts.emptyArray;
            }
            // Don't include the last portion.
            containers.shift();
            // Now, walk up our containers, adding all their names to the container array.
            var container = ts.getContainerNode(declaration);
            while (container) {
                if (!tryAddSingleDeclarationName(container, containers)) {
                    return ts.emptyArray;
                }
                container = ts.getContainerNode(container);
            }
            return containers.reverse();
        }
        function compareNavigateToItems(i1, i2) {
            // TODO(cyrusn): get the gamut of comparisons that VS already uses here.
            return ts.compareValues(i1.matchKind, i2.matchKind)
                || ts.compareStringsCaseSensitiveUI(i1.name, i2.name);
        }
        function createNavigateToItem(rawItem) {
            var declaration = rawItem.declaration;
            var container = ts.getContainerNode(declaration);
            var containerName = container && ts.getNameOfDeclaration(container);
            return {
                name: rawItem.name,
                kind: ts.getNodeKind(declaration),
                kindModifiers: ts.getNodeModifiers(declaration),
                matchKind: ts.PatternMatchKind[rawItem.matchKind],
                isCaseSensitive: rawItem.isCaseSensitive,
                fileName: rawItem.fileName,
                textSpan: ts.createTextSpanFromNode(declaration),
                // TODO(jfreeman): What should be the containerName when the container has a computed name?
                containerName: containerName ? containerName.text : "",
                containerKind: containerName ? ts.getNodeKind(container) : "" /* unknown */,
            };
        }
    })(NavigateTo = ts.NavigateTo || (ts.NavigateTo = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var NavigationBar;
    (function (NavigationBar) {
        /**
         * Matches all whitespace characters in a string. Eg:
         *
         * "app.
         *
         * onactivated"
         *
         * matches because of the newline, whereas
         *
         * "app.onactivated"
         *
         * does not match.
         */
        var whiteSpaceRegex = /\s+/g;
        // Keep sourceFile handy so we don't have to search for it every time we need to call `getText`.
        var curCancellationToken;
        var curSourceFile;
        /**
         * For performance, we keep navigation bar parents on a stack rather than passing them through each recursion.
         * `parent` is the current parent and is *not* stored in parentsStack.
         * `startNode` sets a new parent and `endNode` returns to the previous parent.
         */
        var parentsStack = [];
        var parent;
        // NavigationBarItem requires an array, but will not mutate it, so just give it this for performance.
        var emptyChildItemArray = [];
        function getNavigationBarItems(sourceFile, cancellationToken) {
            curCancellationToken = cancellationToken;
            curSourceFile = sourceFile;
            try {
                return ts.map(topLevelItems(rootNavigationBarNode(sourceFile)), convertToTopLevelItem);
            }
            finally {
                reset();
            }
        }
        NavigationBar.getNavigationBarItems = getNavigationBarItems;
        function getNavigationTree(sourceFile, cancellationToken) {
            curCancellationToken = cancellationToken;
            curSourceFile = sourceFile;
            try {
                return convertToTree(rootNavigationBarNode(sourceFile));
            }
            finally {
                reset();
            }
        }
        NavigationBar.getNavigationTree = getNavigationTree;
        function reset() {
            curSourceFile = undefined;
            curCancellationToken = undefined;
            parentsStack = [];
            parent = undefined;
            emptyChildItemArray = [];
        }
        function nodeText(node) {
            return node.getText(curSourceFile);
        }
        function navigationBarNodeKind(n) {
            return n.node.kind;
        }
        function pushChild(parent, child) {
            if (parent.children) {
                parent.children.push(child);
            }
            else {
                parent.children = [child];
            }
        }
        function rootNavigationBarNode(sourceFile) {
            ts.Debug.assert(!parentsStack.length);
            var root = { node: sourceFile, name: undefined, additionalNodes: undefined, parent: undefined, children: undefined, indent: 0 };
            parent = root;
            for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
                var statement = _a[_i];
                addChildrenRecursively(statement);
            }
            endNode();
            ts.Debug.assert(!parent && !parentsStack.length);
            return root;
        }
        function addLeafNode(node) {
            pushChild(parent, emptyNavigationBarNode(node));
        }
        function emptyNavigationBarNode(node) {
            return {
                node: node,
                name: ts.isDeclaration(node) || ts.isExpression(node) ? ts.getNameOfDeclaration(node) : undefined,
                additionalNodes: undefined,
                parent: parent,
                children: undefined,
                indent: parent.indent + 1
            };
        }
        /**
         * Add a new level of NavigationBarNodes.
         * This pushes to the stack, so you must call `endNode` when you are done adding to this node.
         */
        function startNode(node) {
            var navNode = emptyNavigationBarNode(node);
            pushChild(parent, navNode);
            // Save the old parent
            parentsStack.push(parent);
            parent = navNode;
        }
        /** Call after calling `startNode` and adding children to it. */
        function endNode() {
            if (parent.children) {
                mergeChildren(parent.children, parent);
                sortChildren(parent.children);
            }
            parent = parentsStack.pop();
        }
        function addNodeWithRecursiveChild(node, child) {
            startNode(node);
            addChildrenRecursively(child);
            endNode();
        }
        /** Look for navigation bar items in node's subtree, adding them to the current `parent`. */
        function addChildrenRecursively(node) {
            curCancellationToken.throwIfCancellationRequested();
            if (!node || ts.isToken(node)) {
                return;
            }
            switch (node.kind) {
                case 158 /* Constructor */:
                    // Get parameter properties, and treat them as being on the *same* level as the constructor, not under it.
                    var ctr = node;
                    addNodeWithRecursiveChild(ctr, ctr.body);
                    // Parameter properties are children of the class, not the constructor.
                    for (var _i = 0, _a = ctr.parameters; _i < _a.length; _i++) {
                        var param = _a[_i];
                        if (ts.isParameterPropertyDeclaration(param)) {
                            addLeafNode(param);
                        }
                    }
                    break;
                case 157 /* MethodDeclaration */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                case 156 /* MethodSignature */:
                    if (!ts.hasDynamicName(node)) {
                        addNodeWithRecursiveChild(node, node.body);
                    }
                    break;
                case 155 /* PropertyDeclaration */:
                case 154 /* PropertySignature */:
                    if (!ts.hasDynamicName(node)) {
                        addLeafNode(node);
                    }
                    break;
                case 251 /* ImportClause */:
                    var importClause = node;
                    // Handle default import case e.g.:
                    //    import d from "mod";
                    if (importClause.name) {
                        addLeafNode(importClause.name);
                    }
                    // Handle named bindings in imports e.g.:
                    //    import * as NS from "mod";
                    //    import {a, b as B} from "mod";
                    var namedBindings = importClause.namedBindings;
                    if (namedBindings) {
                        if (namedBindings.kind === 252 /* NamespaceImport */) {
                            addLeafNode(namedBindings);
                        }
                        else {
                            for (var _b = 0, _c = namedBindings.elements; _b < _c.length; _b++) {
                                var element = _c[_b];
                                addLeafNode(element);
                            }
                        }
                    }
                    break;
                case 187 /* BindingElement */:
                case 238 /* VariableDeclaration */:
                    var _d = node, name = _d.name, initializer = _d.initializer;
                    if (ts.isBindingPattern(name)) {
                        addChildrenRecursively(name);
                    }
                    else if (initializer && isFunctionOrClassExpression(initializer)) {
                        if (initializer.name) {
                            // Don't add a node for the VariableDeclaration, just for the initializer.
                            addChildrenRecursively(initializer);
                        }
                        else {
                            // Add a node for the VariableDeclaration, but not for the initializer.
                            startNode(node);
                            ts.forEachChild(initializer, addChildrenRecursively);
                            endNode();
                        }
                    }
                    else {
                        addNodeWithRecursiveChild(node, initializer);
                    }
                    break;
                case 198 /* ArrowFunction */:
                case 240 /* FunctionDeclaration */:
                case 197 /* FunctionExpression */:
                    addNodeWithRecursiveChild(node, node.body);
                    break;
                case 244 /* EnumDeclaration */:
                    startNode(node);
                    for (var _e = 0, _f = node.members; _e < _f.length; _e++) {
                        var member = _f[_e];
                        if (!isComputedProperty(member)) {
                            addLeafNode(member);
                        }
                    }
                    endNode();
                    break;
                case 241 /* ClassDeclaration */:
                case 210 /* ClassExpression */:
                case 242 /* InterfaceDeclaration */:
                    startNode(node);
                    for (var _g = 0, _h = node.members; _g < _h.length; _g++) {
                        var member = _h[_g];
                        addChildrenRecursively(member);
                    }
                    endNode();
                    break;
                case 245 /* ModuleDeclaration */:
                    addNodeWithRecursiveChild(node, getInteriorModule(node).body);
                    break;
                case 258 /* ExportSpecifier */:
                case 249 /* ImportEqualsDeclaration */:
                case 163 /* IndexSignature */:
                case 161 /* CallSignature */:
                case 162 /* ConstructSignature */:
                case 243 /* TypeAliasDeclaration */:
                    addLeafNode(node);
                    break;
                case 205 /* BinaryExpression */: {
                    var special = ts.getAssignmentDeclarationKind(node);
                    switch (special) {
                        case 1 /* ExportsProperty */:
                        case 2 /* ModuleExports */:
                        case 3 /* PrototypeProperty */:
                        case 6 /* Prototype */:
                            addNodeWithRecursiveChild(node, node.right);
                            return;
                        case 4 /* ThisProperty */:
                        case 5 /* Property */:
                        case 0 /* None */:
                        case 7 /* ObjectDefinePropertyValue */:
                        case 8 /* ObjectDefinePropertyExports */:
                        case 9 /* ObjectDefinePrototypeProperty */:
                            break;
                        default:
                            ts.Debug.assertNever(special);
                    }
                }
                // falls through
                default:
                    if (ts.hasJSDocNodes(node)) {
                        ts.forEach(node.jsDoc, function (jsDoc) {
                            ts.forEach(jsDoc.tags, function (tag) {
                                if (ts.isJSDocTypeAlias(tag)) {
                                    addLeafNode(tag);
                                }
                            });
                        });
                    }
                    ts.forEachChild(node, addChildrenRecursively);
            }
        }
        /** Merge declarations of the same kind. */
        function mergeChildren(children, node) {
            var nameToItems = ts.createMap();
            ts.filterMutate(children, function (child) {
                var declName = ts.getNameOfDeclaration(child.node);
                var name = declName && nodeText(declName);
                if (!name) {
                    // Anonymous items are never merged.
                    return true;
                }
                var itemsWithSameName = nameToItems.get(name);
                if (!itemsWithSameName) {
                    nameToItems.set(name, child);
                    return true;
                }
                if (itemsWithSameName instanceof Array) {
                    for (var _i = 0, itemsWithSameName_1 = itemsWithSameName; _i < itemsWithSameName_1.length; _i++) {
                        var itemWithSameName = itemsWithSameName_1[_i];
                        if (tryMerge(itemWithSameName, child, node)) {
                            return false;
                        }
                    }
                    itemsWithSameName.push(child);
                    return true;
                }
                else {
                    var itemWithSameName = itemsWithSameName;
                    if (tryMerge(itemWithSameName, child, node)) {
                        return false;
                    }
                    nameToItems.set(name, [itemWithSameName, child]);
                    return true;
                }
            });
        }
        function tryMerge(a, b, parent) {
            if (shouldReallyMerge(a.node, b.node, parent)) {
                merge(a, b);
                return true;
            }
            return false;
        }
        /** a and b have the same name, but they may not be mergeable. */
        function shouldReallyMerge(a, b, parent) {
            if (a.kind !== b.kind || a.parent !== b.parent && !(isOwnChild(a, parent) && isOwnChild(b, parent))) {
                return false;
            }
            switch (a.kind) {
                case 155 /* PropertyDeclaration */:
                case 157 /* MethodDeclaration */:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                    return ts.hasModifier(a, 32 /* Static */) === ts.hasModifier(b, 32 /* Static */);
                case 245 /* ModuleDeclaration */:
                    return areSameModule(a, b);
                default:
                    return true;
            }
        }
        // We want to merge own children like `I` in in `module A { interface I {} } module A { interface I {} }`
        // We don't want to merge unrelated children like `m` in `const o = { a: { m() {} }, b: { m() {} } };`
        function isOwnChild(n, parent) {
            var par = ts.isModuleBlock(n.parent) ? n.parent.parent : n.parent;
            return par === parent.node || ts.contains(parent.additionalNodes, par);
        }
        // We use 1 NavNode to represent 'A.B.C', but there are multiple source nodes.
        // Only merge module nodes that have the same chain. Don't merge 'A.B.C' with 'A'!
        function areSameModule(a, b) {
            // TODO: GH#18217
            return a.body.kind === b.body.kind && (a.body.kind !== 245 /* ModuleDeclaration */ || areSameModule(a.body, b.body));
        }
        /** Merge source into target. Source should be thrown away after this is called. */
        function merge(target, source) {
            var _a;
            target.additionalNodes = target.additionalNodes || [];
            target.additionalNodes.push(source.node);
            if (source.additionalNodes) {
                (_a = target.additionalNodes).push.apply(_a, source.additionalNodes);
            }
            target.children = ts.concatenate(target.children, source.children);
            if (target.children) {
                mergeChildren(target.children, target);
                sortChildren(target.children);
            }
        }
        /** Recursively ensure that each NavNode's children are in sorted order. */
        function sortChildren(children) {
            children.sort(compareChildren);
        }
        function compareChildren(child1, child2) {
            return ts.compareStringsCaseSensitiveUI(tryGetName(child1.node), tryGetName(child2.node)) // TODO: GH#18217
                || ts.compareValues(navigationBarNodeKind(child1), navigationBarNodeKind(child2));
        }
        /**
         * This differs from getItemName because this is just used for sorting.
         * We only sort nodes by name that have a more-or-less "direct" name, as opposed to `new()` and the like.
         * So `new()` can still come before an `aardvark` method.
         */
        function tryGetName(node) {
            if (node.kind === 245 /* ModuleDeclaration */) {
                return getModuleName(node);
            }
            var declName = ts.getNameOfDeclaration(node);
            if (declName && ts.isPropertyName(declName)) {
                return ts.unescapeLeadingUnderscores(ts.getPropertyNameForPropertyNameNode(declName)); // TODO: GH#18217
            }
            switch (node.kind) {
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */:
                case 210 /* ClassExpression */:
                    return getFunctionOrClassName(node);
                default:
                    return undefined;
            }
        }
        function getItemName(node, name) {
            if (node.kind === 245 /* ModuleDeclaration */) {
                return getModuleName(node);
            }
            if (name) {
                var text = nodeText(name);
                if (text.length > 0) {
                    return text;
                }
            }
            switch (node.kind) {
                case 285 /* SourceFile */:
                    var sourceFile = node;
                    return ts.isExternalModule(sourceFile)
                        ? "\"" + ts.escapeString(ts.getBaseFileName(ts.removeFileExtension(ts.normalizePath(sourceFile.fileName)))) + "\""
                        : "<global>";
                case 198 /* ArrowFunction */:
                case 240 /* FunctionDeclaration */:
                case 197 /* FunctionExpression */:
                case 241 /* ClassDeclaration */:
                case 210 /* ClassExpression */:
                    if (ts.getModifierFlags(node) & 512 /* Default */) {
                        return "default";
                    }
                    // We may get a string with newlines or other whitespace in the case of an object dereference
                    // (eg: "app\n.onactivated"), so we should remove the whitespace for readabiltiy in the
                    // navigation bar.
                    return getFunctionOrClassName(node);
                case 158 /* Constructor */:
                    return "constructor";
                case 162 /* ConstructSignature */:
                    return "new()";
                case 161 /* CallSignature */:
                    return "()";
                case 163 /* IndexSignature */:
                    return "[]";
                default:
                    return "<unknown>";
            }
        }
        /** Flattens the NavNode tree to a list, keeping only the top-level items. */
        function topLevelItems(root) {
            var topLevel = [];
            function recur(item) {
                if (isTopLevel(item)) {
                    topLevel.push(item);
                    if (item.children) {
                        for (var _i = 0, _a = item.children; _i < _a.length; _i++) {
                            var child = _a[_i];
                            recur(child);
                        }
                    }
                }
            }
            recur(root);
            return topLevel;
            function isTopLevel(item) {
                switch (navigationBarNodeKind(item)) {
                    case 241 /* ClassDeclaration */:
                    case 210 /* ClassExpression */:
                    case 244 /* EnumDeclaration */:
                    case 242 /* InterfaceDeclaration */:
                    case 245 /* ModuleDeclaration */:
                    case 285 /* SourceFile */:
                    case 243 /* TypeAliasDeclaration */:
                    case 310 /* JSDocTypedefTag */:
                    case 303 /* JSDocCallbackTag */:
                        return true;
                    case 158 /* Constructor */:
                    case 157 /* MethodDeclaration */:
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                    case 238 /* VariableDeclaration */:
                        return hasSomeImportantChild(item);
                    case 198 /* ArrowFunction */:
                    case 240 /* FunctionDeclaration */:
                    case 197 /* FunctionExpression */:
                        return isTopLevelFunctionDeclaration(item);
                    default:
                        return false;
                }
                function isTopLevelFunctionDeclaration(item) {
                    if (!item.node.body) {
                        return false;
                    }
                    switch (navigationBarNodeKind(item.parent)) {
                        case 246 /* ModuleBlock */:
                        case 285 /* SourceFile */:
                        case 157 /* MethodDeclaration */:
                        case 158 /* Constructor */:
                            return true;
                        default:
                            return hasSomeImportantChild(item);
                    }
                }
                function hasSomeImportantChild(item) {
                    return ts.some(item.children, function (child) {
                        var childKind = navigationBarNodeKind(child);
                        return childKind !== 238 /* VariableDeclaration */ && childKind !== 187 /* BindingElement */;
                    });
                }
            }
        }
        function convertToTree(n) {
            return {
                text: getItemName(n.node, n.name),
                kind: ts.getNodeKind(n.node),
                kindModifiers: getModifiers(n.node),
                spans: getSpans(n),
                nameSpan: n.name && getNodeSpan(n.name),
                childItems: ts.map(n.children, convertToTree)
            };
        }
        function convertToTopLevelItem(n) {
            return {
                text: getItemName(n.node, n.name),
                kind: ts.getNodeKind(n.node),
                kindModifiers: getModifiers(n.node),
                spans: getSpans(n),
                childItems: ts.map(n.children, convertToChildItem) || emptyChildItemArray,
                indent: n.indent,
                bolded: false,
                grayed: false
            };
            function convertToChildItem(n) {
                return {
                    text: getItemName(n.node, n.name),
                    kind: ts.getNodeKind(n.node),
                    kindModifiers: ts.getNodeModifiers(n.node),
                    spans: getSpans(n),
                    childItems: emptyChildItemArray,
                    indent: 0,
                    bolded: false,
                    grayed: false
                };
            }
        }
        function getSpans(n) {
            var spans = [getNodeSpan(n.node)];
            if (n.additionalNodes) {
                for (var _i = 0, _a = n.additionalNodes; _i < _a.length; _i++) {
                    var node = _a[_i];
                    spans.push(getNodeSpan(node));
                }
            }
            return spans;
        }
        function getModuleName(moduleDeclaration) {
            // We want to maintain quotation marks.
            if (ts.isAmbientModule(moduleDeclaration)) {
                return ts.getTextOfNode(moduleDeclaration.name);
            }
            // Otherwise, we need to aggregate each identifier to build up the qualified name.
            var result = [];
            result.push(ts.getTextOfIdentifierOrLiteral(moduleDeclaration.name));
            while (moduleDeclaration.body && moduleDeclaration.body.kind === 245 /* ModuleDeclaration */) {
                moduleDeclaration = moduleDeclaration.body;
                result.push(ts.getTextOfIdentifierOrLiteral(moduleDeclaration.name));
            }
            return result.join(".");
        }
        /**
         * For 'module A.B.C', we want to get the node for 'C'.
         * We store 'A' as associated with a NavNode, and use getModuleName to traverse down again.
         */
        function getInteriorModule(decl) {
            return decl.body && ts.isModuleDeclaration(decl.body) ? getInteriorModule(decl.body) : decl;
        }
        function isComputedProperty(member) {
            return !member.name || member.name.kind === 150 /* ComputedPropertyName */;
        }
        function getNodeSpan(node) {
            return node.kind === 285 /* SourceFile */ ? ts.createTextSpanFromRange(node) : ts.createTextSpanFromNode(node, curSourceFile);
        }
        function getModifiers(node) {
            if (node.parent && node.parent.kind === 238 /* VariableDeclaration */) {
                node = node.parent;
            }
            return ts.getNodeModifiers(node);
        }
        function getFunctionOrClassName(node) {
            var parent = node.parent;
            if (node.name && ts.getFullWidth(node.name) > 0) {
                return ts.declarationNameToString(node.name);
            }
            // See if it is a var initializer. If so, use the var name.
            else if (ts.isVariableDeclaration(parent)) {
                return ts.declarationNameToString(parent.name);
            }
            // See if it is of the form "<expr> = function(){...}". If so, use the text from the left-hand side.
            else if (ts.isBinaryExpression(parent) && parent.operatorToken.kind === 60 /* EqualsToken */) {
                return nodeText(parent.left).replace(whiteSpaceRegex, "");
            }
            // See if it is a property assignment, and if so use the property name
            else if (ts.isPropertyAssignment(parent)) {
                return nodeText(parent.name);
            }
            // Default exports are named "default"
            else if (ts.getModifierFlags(node) & 512 /* Default */) {
                return "default";
            }
            else if (ts.isClassLike(node)) {
                return "<class>";
            }
            else if (ts.isCallExpression(parent)) {
                var name = getCalledExpressionName(parent.expression);
                if (name !== undefined) {
                    var args = ts.mapDefined(parent.arguments, function (a) { return ts.isStringLiteralLike(a) ? a.getText(curSourceFile) : undefined; }).join(", ");
                    return name + "(" + args + ") callback";
                }
            }
            return "<function>";
        }
        function getCalledExpressionName(expr) {
            if (ts.isIdentifier(expr)) {
                return expr.text;
            }
            else if (ts.isPropertyAccessExpression(expr)) {
                var left = getCalledExpressionName(expr.expression);
                var right = expr.name.text;
                return left === undefined ? right : left + "." + right;
            }
            else {
                return undefined;
            }
        }
        function isFunctionOrClassExpression(node) {
            switch (node.kind) {
                case 198 /* ArrowFunction */:
                case 197 /* FunctionExpression */:
                case 210 /* ClassExpression */:
                    return true;
                default:
                    return false;
            }
        }
    })(NavigationBar = ts.NavigationBar || (ts.NavigationBar = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var OrganizeImports;
    (function (OrganizeImports) {
        /**
         * Organize imports by:
         *   1) Removing unused imports
         *   2) Coalescing imports from the same module
         *   3) Sorting imports
         */
        function organizeImports(sourceFile, formatContext, host, program, _preferences) {
            var changeTracker = ts.textChanges.ChangeTracker.fromContext({ host: host, formatContext: formatContext });
            var coalesceAndOrganizeImports = function (importGroup) { return coalesceImports(removeUnusedImports(importGroup, sourceFile, program)); };
            // All of the old ImportDeclarations in the file, in syntactic order.
            var topLevelImportDecls = sourceFile.statements.filter(ts.isImportDeclaration);
            organizeImportsWorker(topLevelImportDecls, coalesceAndOrganizeImports);
            // All of the old ExportDeclarations in the file, in syntactic order.
            var topLevelExportDecls = sourceFile.statements.filter(ts.isExportDeclaration);
            organizeImportsWorker(topLevelExportDecls, coalesceExports);
            for (var _i = 0, _a = sourceFile.statements.filter(ts.isAmbientModule); _i < _a.length; _i++) {
                var ambientModule = _a[_i];
                if (!ambientModule.body) {
                    continue;
                }
                var ambientModuleImportDecls = ambientModule.body.statements.filter(ts.isImportDeclaration);
                organizeImportsWorker(ambientModuleImportDecls, coalesceAndOrganizeImports);
                var ambientModuleExportDecls = ambientModule.body.statements.filter(ts.isExportDeclaration);
                organizeImportsWorker(ambientModuleExportDecls, coalesceExports);
            }
            return changeTracker.getChanges();
            function organizeImportsWorker(oldImportDecls, coalesce) {
                if (ts.length(oldImportDecls) === 0) {
                    return;
                }
                // Special case: normally, we'd expect leading and trailing trivia to follow each import
                // around as it's sorted.  However, we do not want this to happen for leading trivia
                // on the first import because it is probably the header comment for the file.
                // Consider: we could do a more careful check that this trivia is actually a header,
                // but the consequences of being wrong are very minor.
                ts.suppressLeadingTrivia(oldImportDecls[0]);
                var oldImportGroups = ts.group(oldImportDecls, function (importDecl) { return getExternalModuleName(importDecl.moduleSpecifier); });
                var sortedImportGroups = ts.stableSort(oldImportGroups, function (group1, group2) { return compareModuleSpecifiers(group1[0].moduleSpecifier, group2[0].moduleSpecifier); });
                var newImportDecls = ts.flatMap(sortedImportGroups, function (importGroup) {
                    return getExternalModuleName(importGroup[0].moduleSpecifier)
                        ? coalesce(importGroup)
                        : importGroup;
                });
                // Delete or replace the first import.
                if (newImportDecls.length === 0) {
                    changeTracker.delete(sourceFile, oldImportDecls[0]);
                }
                else {
                    // Note: Delete the surrounding trivia because it will have been retained in newImportDecls.
                    changeTracker.replaceNodeWithNodes(sourceFile, oldImportDecls[0], newImportDecls, {
                        leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude,
                        trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Include,
                        suffix: ts.getNewLineOrDefaultFromHost(host, formatContext.options),
                    });
                }
                // Delete any subsequent imports.
                for (var i = 1; i < oldImportDecls.length; i++) {
                    changeTracker.delete(sourceFile, oldImportDecls[i]);
                }
            }
        }
        OrganizeImports.organizeImports = organizeImports;
        function removeUnusedImports(oldImports, sourceFile, program) {
            var typeChecker = program.getTypeChecker();
            var jsxNamespace = typeChecker.getJsxNamespace(sourceFile);
            var jsxElementsPresent = !!(sourceFile.transformFlags & 2 /* ContainsJsx */);
            var usedImports = [];
            for (var _i = 0, oldImports_1 = oldImports; _i < oldImports_1.length; _i++) {
                var importDecl = oldImports_1[_i];
                var importClause = importDecl.importClause;
                if (!importClause) {
                    // Imports without import clauses are assumed to be included for their side effects and are not removed.
                    usedImports.push(importDecl);
                    continue;
                }
                var name = importClause.name, namedBindings = importClause.namedBindings;
                // Default import
                if (name && !isDeclarationUsed(name)) {
                    name = undefined;
                }
                if (namedBindings) {
                    if (ts.isNamespaceImport(namedBindings)) {
                        // Namespace import
                        if (!isDeclarationUsed(namedBindings.name)) {
                            namedBindings = undefined;
                        }
                    }
                    else {
                        // List of named imports
                        var newElements = namedBindings.elements.filter(function (e) { return isDeclarationUsed(e.name); });
                        if (newElements.length < namedBindings.elements.length) {
                            namedBindings = newElements.length
                                ? ts.updateNamedImports(namedBindings, newElements)
                                : undefined;
                        }
                    }
                }
                if (name || namedBindings) {
                    usedImports.push(updateImportDeclarationAndClause(importDecl, name, namedBindings));
                }
            }
            return usedImports;
            function isDeclarationUsed(identifier) {
                // The JSX factory symbol is always used if JSX elements are present - even if they are not allowed.
                return jsxElementsPresent && (identifier.text === jsxNamespace) || ts.FindAllReferences.Core.isSymbolReferencedInFile(identifier, typeChecker, sourceFile);
            }
        }
        function getExternalModuleName(specifier) {
            return specifier !== undefined && ts.isStringLiteralLike(specifier)
                ? specifier.text
                : undefined;
        }
        // Internal for testing
        /**
         * @param importGroup a list of ImportDeclarations, all with the same module name.
         */
        function coalesceImports(importGroup) {
            if (importGroup.length === 0) {
                return importGroup;
            }
            var _a = getCategorizedImports(importGroup), importWithoutClause = _a.importWithoutClause, defaultImports = _a.defaultImports, namespaceImports = _a.namespaceImports, namedImports = _a.namedImports;
            var coalescedImports = [];
            if (importWithoutClause) {
                coalescedImports.push(importWithoutClause);
            }
            // Normally, we don't combine default and namespace imports, but it would be silly to
            // produce two import declarations in this special case.
            if (defaultImports.length === 1 && namespaceImports.length === 1 && namedImports.length === 0) {
                // Add the namespace import to the existing default ImportDeclaration.
                var defaultImport = defaultImports[0];
                coalescedImports.push(updateImportDeclarationAndClause(defaultImport, defaultImport.importClause.name, namespaceImports[0].importClause.namedBindings)); // TODO: GH#18217
                return coalescedImports;
            }
            var sortedNamespaceImports = ts.stableSort(namespaceImports, function (i1, i2) {
                return compareIdentifiers(i1.importClause.namedBindings.name, i2.importClause.namedBindings.name);
            }); // TODO: GH#18217
            for (var _i = 0, sortedNamespaceImports_1 = sortedNamespaceImports; _i < sortedNamespaceImports_1.length; _i++) {
                var namespaceImport = sortedNamespaceImports_1[_i];
                // Drop the name, if any
                coalescedImports.push(updateImportDeclarationAndClause(namespaceImport, /*name*/ undefined, namespaceImport.importClause.namedBindings)); // TODO: GH#18217
            }
            if (defaultImports.length === 0 && namedImports.length === 0) {
                return coalescedImports;
            }
            var newDefaultImport;
            var newImportSpecifiers = [];
            if (defaultImports.length === 1) {
                newDefaultImport = defaultImports[0].importClause.name;
            }
            else {
                for (var _b = 0, defaultImports_1 = defaultImports; _b < defaultImports_1.length; _b++) {
                    var defaultImport = defaultImports_1[_b];
                    newImportSpecifiers.push(ts.createImportSpecifier(ts.createIdentifier("default"), defaultImport.importClause.name)); // TODO: GH#18217
                }
            }
            newImportSpecifiers.push.apply(newImportSpecifiers, ts.flatMap(namedImports, function (i) { return i.importClause.namedBindings.elements; })); // TODO: GH#18217
            var sortedImportSpecifiers = sortSpecifiers(newImportSpecifiers);
            var importDecl = defaultImports.length > 0
                ? defaultImports[0]
                : namedImports[0];
            var newNamedImports = sortedImportSpecifiers.length === 0
                ? newDefaultImport
                    ? undefined
                    : ts.createNamedImports(ts.emptyArray)
                : namedImports.length === 0
                    ? ts.createNamedImports(sortedImportSpecifiers)
                    : ts.updateNamedImports(namedImports[0].importClause.namedBindings, sortedImportSpecifiers); // TODO: GH#18217
            coalescedImports.push(updateImportDeclarationAndClause(importDecl, newDefaultImport, newNamedImports));
            return coalescedImports;
            /*
             * Returns entire import declarations because they may already have been rewritten and
             * may lack parent pointers.  The desired parts can easily be recovered based on the
             * categorization.
             *
             * NB: There may be overlap between `defaultImports` and `namespaceImports`/`namedImports`.
             */
            function getCategorizedImports(importGroup) {
                var importWithoutClause;
                var defaultImports = [];
                var namespaceImports = [];
                var namedImports = [];
                for (var _i = 0, importGroup_1 = importGroup; _i < importGroup_1.length; _i++) {
                    var importDeclaration = importGroup_1[_i];
                    if (importDeclaration.importClause === undefined) {
                        // Only the first such import is interesting - the others are redundant.
                        // Note: Unfortunately, we will lose trivia that was on this node.
                        importWithoutClause = importWithoutClause || importDeclaration;
                        continue;
                    }
                    var _a = importDeclaration.importClause, name = _a.name, namedBindings = _a.namedBindings;
                    if (name) {
                        defaultImports.push(importDeclaration);
                    }
                    if (namedBindings) {
                        if (ts.isNamespaceImport(namedBindings)) {
                            namespaceImports.push(importDeclaration);
                        }
                        else {
                            namedImports.push(importDeclaration);
                        }
                    }
                }
                return {
                    importWithoutClause: importWithoutClause,
                    defaultImports: defaultImports,
                    namespaceImports: namespaceImports,
                    namedImports: namedImports,
                };
            }
        }
        OrganizeImports.coalesceImports = coalesceImports;
        // Internal for testing
        /**
         * @param exportGroup a list of ExportDeclarations, all with the same module name.
         */
        function coalesceExports(exportGroup) {
            if (exportGroup.length === 0) {
                return exportGroup;
            }
            var _a = getCategorizedExports(exportGroup), exportWithoutClause = _a.exportWithoutClause, namedExports = _a.namedExports;
            var coalescedExports = [];
            if (exportWithoutClause) {
                coalescedExports.push(exportWithoutClause);
            }
            if (namedExports.length === 0) {
                return coalescedExports;
            }
            var newExportSpecifiers = [];
            newExportSpecifiers.push.apply(newExportSpecifiers, ts.flatMap(namedExports, function (i) { return (i.exportClause).elements; }));
            var sortedExportSpecifiers = sortSpecifiers(newExportSpecifiers);
            var exportDecl = namedExports[0];
            coalescedExports.push(ts.updateExportDeclaration(exportDecl, exportDecl.decorators, exportDecl.modifiers, ts.updateNamedExports(exportDecl.exportClause, sortedExportSpecifiers), exportDecl.moduleSpecifier));
            return coalescedExports;
            /*
             * Returns entire export declarations because they may already have been rewritten and
             * may lack parent pointers.  The desired parts can easily be recovered based on the
             * categorization.
             */
            function getCategorizedExports(exportGroup) {
                var exportWithoutClause;
                var namedExports = [];
                for (var _i = 0, exportGroup_1 = exportGroup; _i < exportGroup_1.length; _i++) {
                    var exportDeclaration = exportGroup_1[_i];
                    if (exportDeclaration.exportClause === undefined) {
                        // Only the first such export is interesting - the others are redundant.
                        // Note: Unfortunately, we will lose trivia that was on this node.
                        exportWithoutClause = exportWithoutClause || exportDeclaration;
                    }
                    else {
                        namedExports.push(exportDeclaration);
                    }
                }
                return {
                    exportWithoutClause: exportWithoutClause,
                    namedExports: namedExports,
                };
            }
        }
        OrganizeImports.coalesceExports = coalesceExports;
        function updateImportDeclarationAndClause(importDeclaration, name, namedBindings) {
            return ts.updateImportDeclaration(importDeclaration, importDeclaration.decorators, importDeclaration.modifiers, ts.updateImportClause(importDeclaration.importClause, name, namedBindings), // TODO: GH#18217
            importDeclaration.moduleSpecifier);
        }
        function sortSpecifiers(specifiers) {
            return ts.stableSort(specifiers, function (s1, s2) {
                return compareIdentifiers(s1.propertyName || s1.name, s2.propertyName || s2.name) ||
                    compareIdentifiers(s1.name, s2.name);
            });
        }
        /* internal */ // Exported for testing
        function compareModuleSpecifiers(m1, m2) {
            var name1 = getExternalModuleName(m1);
            var name2 = getExternalModuleName(m2);
            return ts.compareBooleans(name1 === undefined, name2 === undefined) ||
                ts.compareBooleans(ts.isExternalModuleNameRelative(name1), ts.isExternalModuleNameRelative(name2)) ||
                ts.compareStringsCaseInsensitive(name1, name2);
        }
        OrganizeImports.compareModuleSpecifiers = compareModuleSpecifiers;
        function compareIdentifiers(s1, s2) {
            return ts.compareStringsCaseInsensitive(s1.text, s2.text);
        }
    })(OrganizeImports = ts.OrganizeImports || (ts.OrganizeImports = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var OutliningElementsCollector;
    (function (OutliningElementsCollector) {
        function collectElements(sourceFile, cancellationToken) {
            var res = [];
            addNodeOutliningSpans(sourceFile, cancellationToken, res);
            addRegionOutliningSpans(sourceFile, res);
            return res.sort(function (span1, span2) { return span1.textSpan.start - span2.textSpan.start; });
        }
        OutliningElementsCollector.collectElements = collectElements;
        function addNodeOutliningSpans(sourceFile, cancellationToken, out) {
            var depthRemaining = 40;
            var current = 0;
            var statements = sourceFile.statements;
            var n = statements.length;
            while (current < n) {
                while (current < n && !ts.isAnyImportSyntax(statements[current])) {
                    visitNonImportNode(statements[current]);
                    current++;
                }
                if (current === n)
                    break;
                var firstImport = current;
                while (current < n && ts.isAnyImportSyntax(statements[current])) {
                    addOutliningForLeadingCommentsForNode(statements[current], sourceFile, cancellationToken, out);
                    current++;
                }
                var lastImport = current - 1;
                if (lastImport !== firstImport) {
                    out.push(createOutliningSpanFromBounds(ts.findChildOfKind(statements[firstImport], 93 /* ImportKeyword */, sourceFile).getStart(sourceFile), statements[lastImport].getEnd(), "imports" /* Imports */));
                }
            }
            function visitNonImportNode(n) {
                if (depthRemaining === 0)
                    return;
                cancellationToken.throwIfCancellationRequested();
                if (ts.isDeclaration(n)) {
                    addOutliningForLeadingCommentsForNode(n, sourceFile, cancellationToken, out);
                }
                if (isFunctionExpressionAssignedToVariable(n)) {
                    addOutliningForLeadingCommentsForNode(n.parent.parent.parent, sourceFile, cancellationToken, out);
                }
                var span = getOutliningSpanForNode(n, sourceFile);
                if (span)
                    out.push(span);
                depthRemaining--;
                if (ts.isIfStatement(n) && n.elseStatement && ts.isIfStatement(n.elseStatement)) {
                    // Consider an 'else if' to be on the same depth as the 'if'.
                    visitNonImportNode(n.expression);
                    visitNonImportNode(n.thenStatement);
                    depthRemaining++;
                    visitNonImportNode(n.elseStatement);
                    depthRemaining--;
                }
                else {
                    n.forEachChild(visitNonImportNode);
                }
                depthRemaining++;
            }
            function isFunctionExpressionAssignedToVariable(n) {
                if (!ts.isFunctionExpression(n) && !ts.isArrowFunction(n)) {
                    return false;
                }
                var ancestor = ts.findAncestor(n, ts.isVariableStatement);
                return !!ancestor && ts.getSingleInitializerOfVariableStatementOrPropertyDeclaration(ancestor) === n;
            }
        }
        function addRegionOutliningSpans(sourceFile, out) {
            var regions = [];
            var lineStarts = sourceFile.getLineStarts();
            for (var i = 0; i < lineStarts.length; i++) {
                var currentLineStart = lineStarts[i];
                var lineEnd = i + 1 === lineStarts.length ? sourceFile.getEnd() : lineStarts[i + 1] - 1;
                var lineText = sourceFile.text.substring(currentLineStart, lineEnd);
                var result = isRegionDelimiter(lineText);
                if (!result || ts.isInComment(sourceFile, currentLineStart)) {
                    continue;
                }
                if (!result[1]) {
                    var span = ts.createTextSpanFromBounds(sourceFile.text.indexOf("//", currentLineStart), lineEnd);
                    regions.push(createOutliningSpan(span, "region" /* Region */, span, /*autoCollapse*/ false, result[2] || "#region"));
                }
                else {
                    var region = regions.pop();
                    if (region) {
                        region.textSpan.length = lineEnd - region.textSpan.start;
                        region.hintSpan.length = lineEnd - region.textSpan.start;
                        out.push(region);
                    }
                }
            }
        }
        var regionDelimiterRegExp = /^\s*\/\/\s*#(end)?region(?:\s+(.*))?(?:\r)?$/;
        function isRegionDelimiter(lineText) {
            return regionDelimiterRegExp.exec(lineText);
        }
        function addOutliningForLeadingCommentsForNode(n, sourceFile, cancellationToken, out) {
            var comments = ts.getLeadingCommentRangesOfNode(n, sourceFile);
            if (!comments)
                return;
            var firstSingleLineCommentStart = -1;
            var lastSingleLineCommentEnd = -1;
            var singleLineCommentCount = 0;
            var sourceText = sourceFile.getFullText();
            for (var _i = 0, comments_1 = comments; _i < comments_1.length; _i++) {
                var _a = comments_1[_i], kind = _a.kind, pos = _a.pos, end = _a.end;
                cancellationToken.throwIfCancellationRequested();
                switch (kind) {
                    case 2 /* SingleLineCommentTrivia */:
                        // never fold region delimiters into single-line comment regions
                        var commentText = sourceText.slice(pos, end);
                        if (isRegionDelimiter(commentText)) {
                            combineAndAddMultipleSingleLineComments();
                            singleLineCommentCount = 0;
                            break;
                        }
                        // For single line comments, combine consecutive ones (2 or more) into
                        // a single span from the start of the first till the end of the last
                        if (singleLineCommentCount === 0) {
                            firstSingleLineCommentStart = pos;
                        }
                        lastSingleLineCommentEnd = end;
                        singleLineCommentCount++;
                        break;
                    case 3 /* MultiLineCommentTrivia */:
                        combineAndAddMultipleSingleLineComments();
                        out.push(createOutliningSpanFromBounds(pos, end, "comment" /* Comment */));
                        singleLineCommentCount = 0;
                        break;
                    default:
                        ts.Debug.assertNever(kind);
                }
            }
            combineAndAddMultipleSingleLineComments();
            function combineAndAddMultipleSingleLineComments() {
                // Only outline spans of two or more consecutive single line comments
                if (singleLineCommentCount > 1) {
                    out.push(createOutliningSpanFromBounds(firstSingleLineCommentStart, lastSingleLineCommentEnd, "comment" /* Comment */));
                }
            }
        }
        function createOutliningSpanFromBounds(pos, end, kind) {
            return createOutliningSpan(ts.createTextSpanFromBounds(pos, end), kind);
        }
        function getOutliningSpanForNode(n, sourceFile) {
            switch (n.kind) {
                case 219 /* Block */:
                    if (ts.isFunctionLike(n.parent)) {
                        return functionSpan(n.parent, n, sourceFile);
                    }
                    // Check if the block is standalone, or 'attached' to some parent statement.
                    // If the latter, we want to collapse the block, but consider its hint span
                    // to be the entire span of the parent.
                    switch (n.parent.kind) {
                        case 224 /* DoStatement */:
                        case 227 /* ForInStatement */:
                        case 228 /* ForOfStatement */:
                        case 226 /* ForStatement */:
                        case 223 /* IfStatement */:
                        case 225 /* WhileStatement */:
                        case 232 /* WithStatement */:
                        case 275 /* CatchClause */:
                            return spanForNode(n.parent);
                        case 236 /* TryStatement */:
                            // Could be the try-block, or the finally-block.
                            var tryStatement = n.parent;
                            if (tryStatement.tryBlock === n) {
                                return spanForNode(n.parent);
                            }
                            else if (tryStatement.finallyBlock === n) {
                                return spanForNode(ts.findChildOfKind(tryStatement, 89 /* FinallyKeyword */, sourceFile));
                            }
                        // falls through
                        default:
                            // Block was a standalone block.  In this case we want to only collapse
                            // the span of the block, independent of any parent span.
                            return createOutliningSpan(ts.createTextSpanFromNode(n, sourceFile), "code" /* Code */);
                    }
                case 246 /* ModuleBlock */:
                    return spanForNode(n.parent);
                case 241 /* ClassDeclaration */:
                case 210 /* ClassExpression */:
                case 242 /* InterfaceDeclaration */:
                case 244 /* EnumDeclaration */:
                case 247 /* CaseBlock */:
                    return spanForNode(n);
                case 189 /* ObjectLiteralExpression */:
                    return spanForObjectOrArrayLiteral(n);
                case 188 /* ArrayLiteralExpression */:
                    return spanForObjectOrArrayLiteral(n, 22 /* OpenBracketToken */);
                case 261 /* JsxElement */:
                    return spanForJSXElement(n);
                case 262 /* JsxSelfClosingElement */:
                case 263 /* JsxOpeningElement */:
                    return spanForJSXAttributes(n.attributes);
            }
            function spanForJSXElement(node) {
                var textSpan = ts.createTextSpanFromBounds(node.openingElement.getStart(sourceFile), node.closingElement.getEnd());
                var tagName = node.openingElement.tagName.getText(sourceFile);
                var bannerText = "<" + tagName + ">...</" + tagName + ">";
                return createOutliningSpan(textSpan, "code" /* Code */, textSpan, /*autoCollapse*/ false, bannerText);
            }
            function spanForJSXAttributes(node) {
                if (node.properties.length === 0) {
                    return undefined;
                }
                return createOutliningSpanFromBounds(node.getStart(sourceFile), node.getEnd(), "code" /* Code */);
            }
            function spanForObjectOrArrayLiteral(node, open) {
                if (open === void 0) { open = 18 /* OpenBraceToken */; }
                // If the block has no leading keywords and is inside an array literal or call expression,
                // we only want to collapse the span of the block.
                // Otherwise, the collapsed section will include the end of the previous line.
                return spanForNode(node, /*autoCollapse*/ false, /*useFullStart*/ !ts.isArrayLiteralExpression(node.parent) && !ts.isCallExpression(node.parent), open);
            }
            function spanForNode(hintSpanNode, autoCollapse, useFullStart, open, close) {
                if (autoCollapse === void 0) { autoCollapse = false; }
                if (useFullStart === void 0) { useFullStart = true; }
                if (open === void 0) { open = 18 /* OpenBraceToken */; }
                if (close === void 0) { close = open === 18 /* OpenBraceToken */ ? 19 /* CloseBraceToken */ : 23 /* CloseBracketToken */; }
                var openToken = ts.findChildOfKind(n, open, sourceFile);
                var closeToken = ts.findChildOfKind(n, close, sourceFile);
                return openToken && closeToken && spanBetweenTokens(openToken, closeToken, hintSpanNode, sourceFile, autoCollapse, useFullStart);
            }
        }
        function functionSpan(node, body, sourceFile) {
            var openToken = ts.isNodeArrayMultiLine(node.parameters, sourceFile)
                ? ts.findChildOfKind(node, 20 /* OpenParenToken */, sourceFile)
                : ts.findChildOfKind(body, 18 /* OpenBraceToken */, sourceFile);
            var closeToken = ts.findChildOfKind(body, 19 /* CloseBraceToken */, sourceFile);
            return openToken && closeToken && spanBetweenTokens(openToken, closeToken, node, sourceFile, /*autoCollapse*/ node.kind !== 198 /* ArrowFunction */);
        }
        function spanBetweenTokens(openToken, closeToken, hintSpanNode, sourceFile, autoCollapse, useFullStart) {
            if (autoCollapse === void 0) { autoCollapse = false; }
            if (useFullStart === void 0) { useFullStart = true; }
            var textSpan = ts.createTextSpanFromBounds(useFullStart ? openToken.getFullStart() : openToken.getStart(sourceFile), closeToken.getEnd());
            return createOutliningSpan(textSpan, "code" /* Code */, ts.createTextSpanFromNode(hintSpanNode, sourceFile), autoCollapse);
        }
        function createOutliningSpan(textSpan, kind, hintSpan, autoCollapse, bannerText) {
            if (hintSpan === void 0) { hintSpan = textSpan; }
            if (autoCollapse === void 0) { autoCollapse = false; }
            if (bannerText === void 0) { bannerText = "..."; }
            return { textSpan: textSpan, kind: kind, hintSpan: hintSpan, bannerText: bannerText, autoCollapse: autoCollapse };
        }
    })(OutliningElementsCollector = ts.OutliningElementsCollector || (ts.OutliningElementsCollector = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    // Note(cyrusn): this enum is ordered from strongest match type to weakest match type.
    var PatternMatchKind;
    (function (PatternMatchKind) {
        PatternMatchKind[PatternMatchKind["exact"] = 0] = "exact";
        PatternMatchKind[PatternMatchKind["prefix"] = 1] = "prefix";
        PatternMatchKind[PatternMatchKind["substring"] = 2] = "substring";
        PatternMatchKind[PatternMatchKind["camelCase"] = 3] = "camelCase";
    })(PatternMatchKind = ts.PatternMatchKind || (ts.PatternMatchKind = {}));
    function createPatternMatch(kind, isCaseSensitive) {
        return {
            kind: kind,
            isCaseSensitive: isCaseSensitive
        };
    }
    function createPatternMatcher(pattern) {
        // We'll often see the same candidate string many times when searching (For example, when
        // we see the name of a module that is used everywhere, or the name of an overload).  As
        // such, we cache the information we compute about the candidate for the life of this
        // pattern matcher so we don't have to compute it multiple times.
        var stringToWordSpans = ts.createMap();
        var dotSeparatedSegments = pattern.trim().split(".").map(function (p) { return createSegment(p.trim()); });
        // A segment is considered invalid if we couldn't find any words in it.
        if (dotSeparatedSegments.some(function (segment) { return !segment.subWordTextChunks.length; }))
            return undefined;
        return {
            getFullMatch: function (containers, candidate) { return getFullMatch(containers, candidate, dotSeparatedSegments, stringToWordSpans); },
            getMatchForLastSegmentOfPattern: function (candidate) { return matchSegment(candidate, ts.last(dotSeparatedSegments), stringToWordSpans); },
            patternContainsDots: dotSeparatedSegments.length > 1
        };
    }
    ts.createPatternMatcher = createPatternMatcher;
    function getFullMatch(candidateContainers, candidate, dotSeparatedSegments, stringToWordSpans) {
        // First, check that the last part of the dot separated pattern matches the name of the
        // candidate.  If not, then there's no point in proceeding and doing the more
        // expensive work.
        var candidateMatch = matchSegment(candidate, ts.last(dotSeparatedSegments), stringToWordSpans);
        if (!candidateMatch) {
            return undefined;
        }
        // -1 because the last part was checked against the name, and only the rest
        // of the parts are checked against the container.
        if (dotSeparatedSegments.length - 1 > candidateContainers.length) {
            // There weren't enough container parts to match against the pattern parts.
            // So this definitely doesn't match.
            return undefined;
        }
        var bestMatch;
        for (var i = dotSeparatedSegments.length - 2, j = candidateContainers.length - 1; i >= 0; i -= 1, j -= 1) {
            bestMatch = betterMatch(bestMatch, matchSegment(candidateContainers[j], dotSeparatedSegments[i], stringToWordSpans));
        }
        return bestMatch;
    }
    function getWordSpans(word, stringToWordSpans) {
        var spans = stringToWordSpans.get(word);
        if (!spans) {
            stringToWordSpans.set(word, spans = breakIntoWordSpans(word));
        }
        return spans;
    }
    function matchTextChunk(candidate, chunk, stringToWordSpans) {
        var index = indexOfIgnoringCase(candidate, chunk.textLowerCase);
        if (index === 0) {
            // a) Check if the word is a prefix of the candidate, in a case insensitive or
            //    sensitive manner. If it does, return that there was an exact match if the word and candidate are the same length, else a prefix match.
            return createPatternMatch(chunk.text.length === candidate.length ? PatternMatchKind.exact : PatternMatchKind.prefix, /*isCaseSensitive:*/ ts.startsWith(candidate, chunk.text));
        }
        if (chunk.isLowerCase) {
            if (index === -1)
                return undefined;
            // b) If the part is entirely lowercase, then check if it is contained anywhere in the
            //    candidate in a case insensitive manner.  If so, return that there was a substring
            //    match.
            //
            //    Note: We only have a substring match if the lowercase part is prefix match of some
            //    word part. That way we don't match something like 'Class' when the user types 'a'.
            //    But we would match 'FooAttribute' (since 'Attribute' starts with 'a').
            var wordSpans = getWordSpans(candidate, stringToWordSpans);
            for (var _i = 0, wordSpans_1 = wordSpans; _i < wordSpans_1.length; _i++) {
                var span = wordSpans_1[_i];
                if (partStartsWith(candidate, span, chunk.text, /*ignoreCase:*/ true)) {
                    return createPatternMatch(PatternMatchKind.substring, /*isCaseSensitive:*/ partStartsWith(candidate, span, chunk.text, /*ignoreCase:*/ false));
                }
            }
            // c) Is the pattern a substring of the candidate starting on one of the candidate's word boundaries?
            // We could check every character boundary start of the candidate for the pattern. However, that's
            // an m * n operation in the wost case. Instead, find the first instance of the pattern
            // substring, and see if it starts on a capital letter. It seems unlikely that the user will try to
            // filter the list based on a substring that starts on a capital letter and also with a lowercase one.
            // (Pattern: fogbar, Candidate: quuxfogbarFogBar).
            if (chunk.text.length < candidate.length && isUpperCaseLetter(candidate.charCodeAt(index))) {
                return createPatternMatch(PatternMatchKind.substring, /*isCaseSensitive:*/ false);
            }
        }
        else {
            // d) If the part was not entirely lowercase, then check if it is contained in the
            //    candidate in a case *sensitive* manner. If so, return that there was a substring
            //    match.
            if (candidate.indexOf(chunk.text) > 0) {
                return createPatternMatch(PatternMatchKind.substring, /*isCaseSensitive:*/ true);
            }
            // e) If the part was not entirely lowercase, then attempt a camel cased match as well.
            if (chunk.characterSpans.length > 0) {
                var candidateParts = getWordSpans(candidate, stringToWordSpans);
                var isCaseSensitive = tryCamelCaseMatch(candidate, candidateParts, chunk, /*ignoreCase:*/ false) ? true
                    : tryCamelCaseMatch(candidate, candidateParts, chunk, /*ignoreCase:*/ true) ? false : undefined;
                if (isCaseSensitive !== undefined) {
                    return createPatternMatch(PatternMatchKind.camelCase, isCaseSensitive);
                }
            }
        }
    }
    function matchSegment(candidate, segment, stringToWordSpans) {
        // First check if the segment matches as is.  This is also useful if the segment contains
        // characters we would normally strip when splitting into parts that we also may want to
        // match in the candidate.  For example if the segment is "@int" and the candidate is
        // "@int", then that will show up as an exact match here.
        //
        // Note: if the segment contains a space or an asterisk then we must assume that it's a
        // multi-word segment.
        if (every(segment.totalTextChunk.text, function (ch) { return ch !== 32 /* space */ && ch !== 42 /* asterisk */; })) {
            var match = matchTextChunk(candidate, segment.totalTextChunk, stringToWordSpans);
            if (match)
                return match;
        }
        // The logic for pattern matching is now as follows:
        //
        // 1) Break the segment passed in into words.  Breaking is rather simple and a
        //    good way to think about it that if gives you all the individual alphanumeric words
        //    of the pattern.
        //
        // 2) For each word try to match the word against the candidate value.
        //
        // 3) Matching is as follows:
        //
        //   a) Check if the word is a prefix of the candidate, in a case insensitive or
        //      sensitive manner. If it does, return that there was an exact match if the word and candidate are the same length, else a prefix match.
        //
        //   If the word is entirely lowercase:
        //      b) Then check if it is contained anywhere in the
        //          candidate in a case insensitive manner.  If so, return that there was a substring
        //          match.
        //
        //          Note: We only have a substring match if the lowercase part is prefix match of
        //          some word part. That way we don't match something like 'Class' when the user
        //          types 'a'. But we would match 'FooAttribute' (since 'Attribute' starts with
        //          'a').
        //
        //       c) The word is all lower case. Is it a case insensitive substring of the candidate starting
        //          on a part boundary of the candidate?
        //
        //   Else:
        //       d) If the word was not entirely lowercase, then check if it is contained in the
        //          candidate in a case *sensitive* manner. If so, return that there was a substring
        //          match.
        //
        //       e) If the word was not entirely lowercase, then attempt a camel cased match as
        //          well.
        //
        // Only if all words have some sort of match is the pattern considered matched.
        var subWordTextChunks = segment.subWordTextChunks;
        var bestMatch;
        for (var _i = 0, subWordTextChunks_1 = subWordTextChunks; _i < subWordTextChunks_1.length; _i++) {
            var subWordTextChunk = subWordTextChunks_1[_i];
            bestMatch = betterMatch(bestMatch, matchTextChunk(candidate, subWordTextChunk, stringToWordSpans));
        }
        return bestMatch;
    }
    function betterMatch(a, b) {
        return ts.min(a, b, compareMatches);
    }
    function compareMatches(a, b) {
        return a === undefined ? 1 /* GreaterThan */ : b === undefined ? -1 /* LessThan */
            : ts.compareValues(a.kind, b.kind) || ts.compareBooleans(!a.isCaseSensitive, !b.isCaseSensitive);
    }
    function partStartsWith(candidate, candidateSpan, pattern, ignoreCase, patternSpan) {
        if (patternSpan === void 0) { patternSpan = { start: 0, length: pattern.length }; }
        return patternSpan.length <= candidateSpan.length // If pattern part is longer than the candidate part there can never be a match.
            && everyInRange(0, patternSpan.length, function (i) { return equalChars(pattern.charCodeAt(patternSpan.start + i), candidate.charCodeAt(candidateSpan.start + i), ignoreCase); });
    }
    function equalChars(ch1, ch2, ignoreCase) {
        return ignoreCase ? toLowerCase(ch1) === toLowerCase(ch2) : ch1 === ch2;
    }
    function tryCamelCaseMatch(candidate, candidateParts, chunk, ignoreCase) {
        var chunkCharacterSpans = chunk.characterSpans;
        // Note: we may have more pattern parts than candidate parts.  This is because multiple
        // pattern parts may match a candidate part.  For example "SiUI" against "SimpleUI".
        // We'll have 3 pattern parts Si/U/I against two candidate parts Simple/UI.  However, U
        // and I will both match in UI.
        var currentCandidate = 0;
        var currentChunkSpan = 0;
        var firstMatch;
        var contiguous;
        while (true) {
            // Let's consider our termination cases
            if (currentChunkSpan === chunkCharacterSpans.length) {
                return true;
            }
            else if (currentCandidate === candidateParts.length) {
                // No match, since we still have more of the pattern to hit
                return false;
            }
            var candidatePart = candidateParts[currentCandidate];
            var gotOneMatchThisCandidate = false;
            // Consider the case of matching SiUI against SimpleUIElement. The candidate parts
            // will be Simple/UI/Element, and the pattern parts will be Si/U/I.  We'll match 'Si'
            // against 'Simple' first.  Then we'll match 'U' against 'UI'. However, we want to
            // still keep matching pattern parts against that candidate part.
            for (; currentChunkSpan < chunkCharacterSpans.length; currentChunkSpan++) {
                var chunkCharacterSpan = chunkCharacterSpans[currentChunkSpan];
                if (gotOneMatchThisCandidate) {
                    // We've already gotten one pattern part match in this candidate.  We will
                    // only continue trying to consumer pattern parts if the last part and this
                    // part are both upper case.
                    if (!isUpperCaseLetter(chunk.text.charCodeAt(chunkCharacterSpans[currentChunkSpan - 1].start)) ||
                        !isUpperCaseLetter(chunk.text.charCodeAt(chunkCharacterSpans[currentChunkSpan].start))) {
                        break;
                    }
                }
                if (!partStartsWith(candidate, candidatePart, chunk.text, ignoreCase, chunkCharacterSpan)) {
                    break;
                }
                gotOneMatchThisCandidate = true;
                firstMatch = firstMatch === undefined ? currentCandidate : firstMatch;
                // If we were contiguous, then keep that value.  If we weren't, then keep that
                // value.  If we don't know, then set the value to 'true' as an initial match is
                // obviously contiguous.
                contiguous = contiguous === undefined ? true : contiguous;
                candidatePart = ts.createTextSpan(candidatePart.start + chunkCharacterSpan.length, candidatePart.length - chunkCharacterSpan.length);
            }
            // Check if we matched anything at all.  If we didn't, then we need to unset the
            // contiguous bit if we currently had it set.
            // If we haven't set the bit yet, then that means we haven't matched anything so
            // far, and we don't want to change that.
            if (!gotOneMatchThisCandidate && contiguous !== undefined) {
                contiguous = false;
            }
            // Move onto the next candidate.
            currentCandidate++;
        }
    }
    function createSegment(text) {
        return {
            totalTextChunk: createTextChunk(text),
            subWordTextChunks: breakPatternIntoTextChunks(text)
        };
    }
    function isUpperCaseLetter(ch) {
        // Fast check for the ascii range.
        if (ch >= 65 /* A */ && ch <= 90 /* Z */) {
            return true;
        }
        if (ch < 127 /* maxAsciiCharacter */ || !ts.isUnicodeIdentifierStart(ch, 8 /* Latest */)) {
            return false;
        }
        // TODO: find a way to determine this for any unicode characters in a
        // non-allocating manner.
        var str = String.fromCharCode(ch);
        return str === str.toUpperCase();
    }
    function isLowerCaseLetter(ch) {
        // Fast check for the ascii range.
        if (ch >= 97 /* a */ && ch <= 122 /* z */) {
            return true;
        }
        if (ch < 127 /* maxAsciiCharacter */ || !ts.isUnicodeIdentifierStart(ch, 8 /* Latest */)) {
            return false;
        }
        // TODO: find a way to determine this for any unicode characters in a
        // non-allocating manner.
        var str = String.fromCharCode(ch);
        return str === str.toLowerCase();
    }
    // Assumes 'value' is already lowercase.
    function indexOfIgnoringCase(str, value) {
        var n = str.length - value.length;
        var _loop_6 = function (start) {
            if (every(value, function (valueChar, i) { return toLowerCase(str.charCodeAt(i + start)) === valueChar; })) {
                return { value: start };
            }
        };
        for (var start = 0; start <= n; start++) {
            var state_1 = _loop_6(start);
            if (typeof state_1 === "object")
                return state_1.value;
        }
        return -1;
    }
    function toLowerCase(ch) {
        // Fast convert for the ascii range.
        if (ch >= 65 /* A */ && ch <= 90 /* Z */) {
            return 97 /* a */ + (ch - 65 /* A */);
        }
        if (ch < 127 /* maxAsciiCharacter */) {
            return ch;
        }
        // TODO: find a way to compute this for any unicode characters in a
        // non-allocating manner.
        return String.fromCharCode(ch).toLowerCase().charCodeAt(0);
    }
    function isDigit(ch) {
        // TODO(cyrusn): Find a way to support this for unicode digits.
        return ch >= 48 /* _0 */ && ch <= 57 /* _9 */;
    }
    function isWordChar(ch) {
        return isUpperCaseLetter(ch) || isLowerCaseLetter(ch) || isDigit(ch) || ch === 95 /* _ */ || ch === 36 /* $ */;
    }
    function breakPatternIntoTextChunks(pattern) {
        var result = [];
        var wordStart = 0;
        var wordLength = 0;
        for (var i = 0; i < pattern.length; i++) {
            var ch = pattern.charCodeAt(i);
            if (isWordChar(ch)) {
                if (wordLength === 0) {
                    wordStart = i;
                }
                wordLength++;
            }
            else {
                if (wordLength > 0) {
                    result.push(createTextChunk(pattern.substr(wordStart, wordLength)));
                    wordLength = 0;
                }
            }
        }
        if (wordLength > 0) {
            result.push(createTextChunk(pattern.substr(wordStart, wordLength)));
        }
        return result;
    }
    function createTextChunk(text) {
        var textLowerCase = text.toLowerCase();
        return {
            text: text,
            textLowerCase: textLowerCase,
            isLowerCase: text === textLowerCase,
            characterSpans: breakIntoCharacterSpans(text)
        };
    }
    function breakIntoCharacterSpans(identifier) {
        return breakIntoSpans(identifier, /*word:*/ false);
    }
    ts.breakIntoCharacterSpans = breakIntoCharacterSpans;
    function breakIntoWordSpans(identifier) {
        return breakIntoSpans(identifier, /*word:*/ true);
    }
    ts.breakIntoWordSpans = breakIntoWordSpans;
    function breakIntoSpans(identifier, word) {
        var result = [];
        var wordStart = 0;
        for (var i = 1; i < identifier.length; i++) {
            var lastIsDigit = isDigit(identifier.charCodeAt(i - 1));
            var currentIsDigit = isDigit(identifier.charCodeAt(i));
            var hasTransitionFromLowerToUpper = transitionFromLowerToUpper(identifier, word, i);
            var hasTransitionFromUpperToLower = word && transitionFromUpperToLower(identifier, i, wordStart);
            if (charIsPunctuation(identifier.charCodeAt(i - 1)) ||
                charIsPunctuation(identifier.charCodeAt(i)) ||
                lastIsDigit !== currentIsDigit ||
                hasTransitionFromLowerToUpper ||
                hasTransitionFromUpperToLower) {
                if (!isAllPunctuation(identifier, wordStart, i)) {
                    result.push(ts.createTextSpan(wordStart, i - wordStart));
                }
                wordStart = i;
            }
        }
        if (!isAllPunctuation(identifier, wordStart, identifier.length)) {
            result.push(ts.createTextSpan(wordStart, identifier.length - wordStart));
        }
        return result;
    }
    function charIsPunctuation(ch) {
        switch (ch) {
            case 33 /* exclamation */:
            case 34 /* doubleQuote */:
            case 35 /* hash */:
            case 37 /* percent */:
            case 38 /* ampersand */:
            case 39 /* singleQuote */:
            case 40 /* openParen */:
            case 41 /* closeParen */:
            case 42 /* asterisk */:
            case 44 /* comma */:
            case 45 /* minus */:
            case 46 /* dot */:
            case 47 /* slash */:
            case 58 /* colon */:
            case 59 /* semicolon */:
            case 63 /* question */:
            case 64 /* at */:
            case 91 /* openBracket */:
            case 92 /* backslash */:
            case 93 /* closeBracket */:
            case 95 /* _ */:
            case 123 /* openBrace */:
            case 125 /* closeBrace */:
                return true;
        }
        return false;
    }
    function isAllPunctuation(identifier, start, end) {
        return every(identifier, function (ch) { return charIsPunctuation(ch) && ch !== 95 /* _ */; }, start, end);
    }
    function transitionFromUpperToLower(identifier, index, wordStart) {
        // Cases this supports:
        // 1) IDisposable -> I, Disposable
        // 2) UIElement -> UI, Element
        // 3) HTMLDocument -> HTML, Document
        //
        // etc.
        // We have a transition from an upper to a lower letter here.  But we only
        // want to break if all the letters that preceded are uppercase.  i.e. if we
        // have "Foo" we don't want to break that into "F, oo".  But if we have
        // "IFoo" or "UIFoo", then we want to break that into "I, Foo" and "UI,
        // Foo".  i.e. the last uppercase letter belongs to the lowercase letters
        // that follows.  Note: this will make the following not split properly:
        // "HELLOthere".  However, these sorts of names do not show up in .Net
        // programs.
        return index !== wordStart
            && index + 1 < identifier.length
            && isUpperCaseLetter(identifier.charCodeAt(index))
            && isLowerCaseLetter(identifier.charCodeAt(index + 1))
            && every(identifier, isUpperCaseLetter, wordStart, index);
    }
    function transitionFromLowerToUpper(identifier, word, index) {
        var lastIsUpper = isUpperCaseLetter(identifier.charCodeAt(index - 1));
        var currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index));
        // See if the casing indicates we're starting a new word. Note: if we're breaking on
        // words, then just seeing an upper case character isn't enough.  Instead, it has to
        // be uppercase and the previous character can't be uppercase.
        //
        // For example, breaking "AddMetadata" on words would make: Add Metadata
        //
        // on characters would be: A dd M etadata
        //
        // Break "AM" on words would be: AM
        //
        // on characters would be: A M
        //
        // We break the search string on characters.  But we break the symbol name on words.
        return currentIsUpper && (!word || !lastIsUpper);
    }
    function everyInRange(start, end, pred) {
        for (var i = start; i < end; i++) {
            if (!pred(i)) {
                return false;
            }
        }
        return true;
    }
    function every(s, pred, start, end) {
        if (start === void 0) { start = 0; }
        if (end === void 0) { end = s.length; }
        return everyInRange(start, end, function (i) { return pred(s.charCodeAt(i), i); });
    }
})(ts || (ts = {}));
var ts;
(function (ts) {
    function preProcessFile(sourceText, readImportFiles, detectJavaScriptImports) {
        if (readImportFiles === void 0) { readImportFiles = true; }
        if (detectJavaScriptImports === void 0) { detectJavaScriptImports = false; }
        var pragmaContext = {
            languageVersion: 1 /* ES5 */,
            pragmas: undefined,
            checkJsDirective: undefined,
            referencedFiles: [],
            typeReferenceDirectives: [],
            libReferenceDirectives: [],
            amdDependencies: [],
            hasNoDefaultLib: undefined,
            moduleName: undefined
        };
        var importedFiles = [];
        var ambientExternalModules;
        var lastToken;
        var currentToken;
        var braceNesting = 0;
        // assume that text represent an external module if it contains at least one top level import/export
        // ambient modules that are found inside external modules are interpreted as module augmentations
        var externalModule = false;
        function nextToken() {
            lastToken = currentToken;
            currentToken = ts.scanner.scan();
            if (currentToken === 18 /* OpenBraceToken */) {
                braceNesting++;
            }
            else if (currentToken === 19 /* CloseBraceToken */) {
                braceNesting--;
            }
            return currentToken;
        }
        function getFileReference() {
            var fileName = ts.scanner.getTokenValue();
            var pos = ts.scanner.getTokenPos();
            return { fileName: fileName, pos: pos, end: pos + fileName.length };
        }
        function recordAmbientExternalModule() {
            if (!ambientExternalModules) {
                ambientExternalModules = [];
            }
            ambientExternalModules.push({ ref: getFileReference(), depth: braceNesting });
        }
        function recordModuleName() {
            importedFiles.push(getFileReference());
            markAsExternalModuleIfTopLevel();
        }
        function markAsExternalModuleIfTopLevel() {
            if (braceNesting === 0) {
                externalModule = true;
            }
        }
        /**
         * Returns true if at least one token was consumed from the stream
         */
        function tryConsumeDeclare() {
            var token = ts.scanner.getToken();
            if (token === 126 /* DeclareKeyword */) {
                // declare module "mod"
                token = nextToken();
                if (token === 131 /* ModuleKeyword */) {
                    token = nextToken();
                    if (token === 10 /* StringLiteral */) {
                        recordAmbientExternalModule();
                    }
                }
                return true;
            }
            return false;
        }
        /**
         * Returns true if at least one token was consumed from the stream
         */
        function tryConsumeImport() {
            if (lastToken === 24 /* DotToken */) {
                return false;
            }
            var token = ts.scanner.getToken();
            if (token === 93 /* ImportKeyword */) {
                token = nextToken();
                if (token === 20 /* OpenParenToken */) {
                    token = nextToken();
                    if (token === 10 /* StringLiteral */) {
                        // import("mod");
                        recordModuleName();
                        return true;
                    }
                }
                else if (token === 10 /* StringLiteral */) {
                    // import "mod";
                    recordModuleName();
                    return true;
                }
                else {
                    if (token === 73 /* Identifier */ || ts.isKeyword(token)) {
                        token = nextToken();
                        if (token === 145 /* FromKeyword */) {
                            token = nextToken();
                            if (token === 10 /* StringLiteral */) {
                                // import d from "mod";
                                recordModuleName();
                                return true;
                            }
                        }
                        else if (token === 60 /* EqualsToken */) {
                            if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) {
                                return true;
                            }
                        }
                        else if (token === 27 /* CommaToken */) {
                            // consume comma and keep going
                            token = nextToken();
                        }
                        else {
                            // unknown syntax
                            return true;
                        }
                    }
                    if (token === 18 /* OpenBraceToken */) {
                        token = nextToken();
                        // consume "{ a as B, c, d as D}" clauses
                        // make sure that it stops on EOF
                        while (token !== 19 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) {
                            token = nextToken();
                        }
                        if (token === 19 /* CloseBraceToken */) {
                            token = nextToken();
                            if (token === 145 /* FromKeyword */) {
                                token = nextToken();
                                if (token === 10 /* StringLiteral */) {
                                    // import {a as A} from "mod";
                                    // import d, {a, b as B} from "mod"
                                    recordModuleName();
                                }
                            }
                        }
                    }
                    else if (token === 40 /* AsteriskToken */) {
                        token = nextToken();
                        if (token === 120 /* AsKeyword */) {
                            token = nextToken();
                            if (token === 73 /* Identifier */ || ts.isKeyword(token)) {
                                token = nextToken();
                                if (token === 145 /* FromKeyword */) {
                                    token = nextToken();
                                    if (token === 10 /* StringLiteral */) {
                                        // import * as NS from "mod"
                                        // import d, * as NS from "mod"
                                        recordModuleName();
                                    }
                                }
                            }
                        }
                    }
                }
                return true;
            }
            return false;
        }
        function tryConsumeExport() {
            var token = ts.scanner.getToken();
            if (token === 86 /* ExportKeyword */) {
                markAsExternalModuleIfTopLevel();
                token = nextToken();
                if (token === 18 /* OpenBraceToken */) {
                    token = nextToken();
                    // consume "{ a as B, c, d as D}" clauses
                    // make sure it stops on EOF
                    while (token !== 19 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) {
                        token = nextToken();
                    }
                    if (token === 19 /* CloseBraceToken */) {
                        token = nextToken();
                        if (token === 145 /* FromKeyword */) {
                            token = nextToken();
                            if (token === 10 /* StringLiteral */) {
                                // export {a as A} from "mod";
                                // export {a, b as B} from "mod"
                                recordModuleName();
                            }
                        }
                    }
                }
                else if (token === 40 /* AsteriskToken */) {
                    token = nextToken();
                    if (token === 145 /* FromKeyword */) {
                        token = nextToken();
                        if (token === 10 /* StringLiteral */) {
                            // export * from "mod"
                            recordModuleName();
                        }
                    }
                }
                else if (token === 93 /* ImportKeyword */) {
                    token = nextToken();
                    if (token === 73 /* Identifier */ || ts.isKeyword(token)) {
                        token = nextToken();
                        if (token === 60 /* EqualsToken */) {
                            if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) {
                                return true;
                            }
                        }
                    }
                }
                return true;
            }
            return false;
        }
        function tryConsumeRequireCall(skipCurrentToken) {
            var token = skipCurrentToken ? nextToken() : ts.scanner.getToken();
            if (token === 135 /* RequireKeyword */) {
                token = nextToken();
                if (token === 20 /* OpenParenToken */) {
                    token = nextToken();
                    if (token === 10 /* StringLiteral */) {
                        //  require("mod");
                        recordModuleName();
                    }
                }
                return true;
            }
            return false;
        }
        function tryConsumeDefine() {
            var token = ts.scanner.getToken();
            if (token === 73 /* Identifier */ && ts.scanner.getTokenValue() === "define") {
                token = nextToken();
                if (token !== 20 /* OpenParenToken */) {
                    return true;
                }
                token = nextToken();
                if (token === 10 /* StringLiteral */) {
                    // looks like define ("modname", ... - skip string literal and comma
                    token = nextToken();
                    if (token === 27 /* CommaToken */) {
                        token = nextToken();
                    }
                    else {
                        // unexpected token
                        return true;
                    }
                }
                // should be start of dependency list
                if (token !== 22 /* OpenBracketToken */) {
                    return true;
                }
                // skip open bracket
                token = nextToken();
                // scan until ']' or EOF
                while (token !== 23 /* CloseBracketToken */ && token !== 1 /* EndOfFileToken */) {
                    // record string literals as module names
                    if (token === 10 /* StringLiteral */) {
                        recordModuleName();
                    }
                    token = nextToken();
                }
                return true;
            }
            return false;
        }
        function processImports() {
            ts.scanner.setText(sourceText);
            nextToken();
            // Look for:
            //    import "mod";
            //    import d from "mod"
            //    import {a as A } from "mod";
            //    import * as NS from "mod"
            //    import d, {a, b as B} from "mod"
            //    import i = require("mod");
            //    import("mod");
            //    export * from "mod"
            //    export {a as b} from "mod"
            //    export import i = require("mod")
            //    (for JavaScript files) require("mod")
            // Do not look for:
            //    AnySymbol.import("mod")
            //    AnySymbol.nested.import("mod")
            while (true) {
                if (ts.scanner.getToken() === 1 /* EndOfFileToken */) {
                    break;
                }
                // check if at least one of alternative have moved scanner forward
                if (tryConsumeDeclare() ||
                    tryConsumeImport() ||
                    tryConsumeExport() ||
                    (detectJavaScriptImports && (tryConsumeRequireCall(/*skipCurrentToken*/ false) || tryConsumeDefine()))) {
                    continue;
                }
                else {
                    nextToken();
                }
            }
            ts.scanner.setText(undefined);
        }
        if (readImportFiles) {
            processImports();
        }
        ts.processCommentPragmas(pragmaContext, sourceText);
        ts.processPragmasIntoFields(pragmaContext, ts.noop);
        if (externalModule) {
            // for external modules module all nested ambient modules are augmentations
            if (ambientExternalModules) {
                // move all detected ambient modules to imported files since they need to be resolved
                for (var _i = 0, ambientExternalModules_1 = ambientExternalModules; _i < ambientExternalModules_1.length; _i++) {
                    var decl = ambientExternalModules_1[_i];
                    importedFiles.push(decl.ref);
                }
            }
            return { referencedFiles: pragmaContext.referencedFiles, typeReferenceDirectives: pragmaContext.typeReferenceDirectives, libReferenceDirectives: pragmaContext.libReferenceDirectives, importedFiles: importedFiles, isLibFile: !!pragmaContext.hasNoDefaultLib, ambientExternalModules: undefined };
        }
        else {
            // for global scripts ambient modules still can have augmentations - look for ambient modules with depth > 0
            var ambientModuleNames = void 0;
            if (ambientExternalModules) {
                for (var _a = 0, ambientExternalModules_2 = ambientExternalModules; _a < ambientExternalModules_2.length; _a++) {
                    var decl = ambientExternalModules_2[_a];
                    if (decl.depth === 0) {
                        if (!ambientModuleNames) {
                            ambientModuleNames = [];
                        }
                        ambientModuleNames.push(decl.ref.fileName);
                    }
                    else {
                        importedFiles.push(decl.ref);
                    }
                }
            }
            return { referencedFiles: pragmaContext.referencedFiles, typeReferenceDirectives: pragmaContext.typeReferenceDirectives, libReferenceDirectives: pragmaContext.libReferenceDirectives, importedFiles: importedFiles, isLibFile: !!pragmaContext.hasNoDefaultLib, ambientExternalModules: ambientModuleNames };
        }
    }
    ts.preProcessFile = preProcessFile;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var Rename;
    (function (Rename) {
        function getRenameInfo(program, sourceFile, position, options) {
            var node = ts.getTouchingPropertyName(sourceFile, position);
            var renameInfo = node && nodeIsEligibleForRename(node)
                ? getRenameInfoForNode(node, program.getTypeChecker(), sourceFile, function (declaration) { return program.isSourceFileDefaultLibrary(declaration.getSourceFile()); }, options)
                : undefined;
            return renameInfo || getRenameInfoError(ts.Diagnostics.You_cannot_rename_this_element);
        }
        Rename.getRenameInfo = getRenameInfo;
        function getRenameInfoForNode(node, typeChecker, sourceFile, isDefinedInLibraryFile, options) {
            var symbol = typeChecker.getSymbolAtLocation(node);
            if (!symbol)
                return;
            // Only allow a symbol to be renamed if it actually has at least one declaration.
            var declarations = symbol.declarations;
            if (!declarations || declarations.length === 0)
                return;
            // Disallow rename for elements that are defined in the standard TypeScript library.
            if (declarations.some(isDefinedInLibraryFile)) {
                return getRenameInfoError(ts.Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library);
            }
            // Cannot rename `default` as in `import { default as foo } from "./someModule";
            if (ts.isIdentifier(node) && node.originalKeywordKind === 81 /* DefaultKeyword */ && symbol.parent.flags & 1536 /* Module */) {
                return undefined;
            }
            if (ts.isStringLiteralLike(node) && ts.tryGetImportFromModuleSpecifier(node)) {
                return options && options.allowRenameOfImportPath ? getRenameInfoForModule(node, sourceFile, symbol) : undefined;
            }
            var kind = ts.SymbolDisplay.getSymbolKind(typeChecker, symbol, node);
            var specifierName = (ts.isImportOrExportSpecifierName(node) || ts.isStringOrNumericLiteralLike(node) && node.parent.kind === 150 /* ComputedPropertyName */)
                ? ts.stripQuotes(ts.getTextOfIdentifierOrLiteral(node))
                : undefined;
            var displayName = specifierName || typeChecker.symbolToString(symbol);
            var fullDisplayName = specifierName || typeChecker.getFullyQualifiedName(symbol);
            return getRenameInfoSuccess(displayName, fullDisplayName, kind, ts.SymbolDisplay.getSymbolModifiers(symbol), node, sourceFile);
        }
        function getRenameInfoForModule(node, sourceFile, moduleSymbol) {
            if (!ts.isExternalModuleNameRelative(node.text)) {
                return getRenameInfoError(ts.Diagnostics.You_cannot_rename_a_module_via_a_global_import);
            }
            var moduleSourceFile = ts.find(moduleSymbol.declarations, ts.isSourceFile);
            if (!moduleSourceFile)
                return undefined;
            var withoutIndex = ts.endsWith(node.text, "/index") || ts.endsWith(node.text, "/index.js") ? undefined : ts.tryRemoveSuffix(ts.removeFileExtension(moduleSourceFile.fileName), "/index");
            var name = withoutIndex === undefined ? moduleSourceFile.fileName : withoutIndex;
            var kind = withoutIndex === undefined ? "module" /* moduleElement */ : "directory" /* directory */;
            var indexAfterLastSlash = node.text.lastIndexOf("/") + 1;
            // Span should only be the last component of the path. + 1 to account for the quote character.
            var triggerSpan = ts.createTextSpan(node.getStart(sourceFile) + 1 + indexAfterLastSlash, node.text.length - indexAfterLastSlash);
            return {
                canRename: true,
                fileToRename: name,
                kind: kind,
                displayName: name,
                fullDisplayName: name,
                kindModifiers: "" /* none */,
                triggerSpan: triggerSpan,
            };
        }
        function getRenameInfoSuccess(displayName, fullDisplayName, kind, kindModifiers, node, sourceFile) {
            return {
                canRename: true,
                fileToRename: undefined,
                kind: kind,
                displayName: displayName,
                fullDisplayName: fullDisplayName,
                kindModifiers: kindModifiers,
                triggerSpan: createTriggerSpanForNode(node, sourceFile)
            };
        }
        function getRenameInfoError(diagnostic) {
            return { canRename: false, localizedErrorMessage: ts.getLocaleSpecificMessage(diagnostic) };
        }
        function createTriggerSpanForNode(node, sourceFile) {
            var start = node.getStart(sourceFile);
            var width = node.getWidth(sourceFile);
            if (node.kind === 10 /* StringLiteral */) {
                // Exclude the quotes
                start += 1;
                width -= 2;
            }
            return ts.createTextSpan(start, width);
        }
        function nodeIsEligibleForRename(node) {
            switch (node.kind) {
                case 73 /* Identifier */:
                case 10 /* StringLiteral */:
                case 101 /* ThisKeyword */:
                    return true;
                case 8 /* NumericLiteral */:
                    return ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(node);
                default:
                    return false;
            }
        }
    })(Rename = ts.Rename || (ts.Rename = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var SmartSelectionRange;
    (function (SmartSelectionRange) {
        function getSmartSelectionRange(pos, sourceFile) {
            var selectionRange = {
                textSpan: ts.createTextSpanFromBounds(sourceFile.getFullStart(), sourceFile.getEnd())
            };
            var parentNode = sourceFile;
            outer: while (true) {
                var children = getSelectionChildren(parentNode);
                if (!children.length)
                    break;
                for (var i = 0; i < children.length; i++) {
                    var prevNode = children[i - 1];
                    var node = children[i];
                    var nextNode = children[i + 1];
                    if (node.getStart(sourceFile) > pos) {
                        break outer;
                    }
                    if (positionShouldSnapToNode(pos, node, nextNode)) {
                        // 1. Blocks are effectively redundant with SyntaxLists.
                        // 2. TemplateSpans, along with the SyntaxLists containing them, are a somewhat unintuitive grouping
                        //    of things that should be considered independently.
                        // 3. A VariableStatement’s children are just a VaraiableDeclarationList and a semicolon.
                        // 4. A lone VariableDeclaration in a VaraibleDeclaration feels redundant with the VariableStatement.
                        //
                        // Dive in without pushing a selection range.
                        if (ts.isBlock(node)
                            || ts.isTemplateSpan(node) || ts.isTemplateHead(node)
                            || prevNode && ts.isTemplateHead(prevNode)
                            || ts.isVariableDeclarationList(node) && ts.isVariableStatement(parentNode)
                            || ts.isSyntaxList(node) && ts.isVariableDeclarationList(parentNode)
                            || ts.isVariableDeclaration(node) && ts.isSyntaxList(parentNode) && children.length === 1) {
                            parentNode = node;
                            break;
                        }
                        // Synthesize a stop for '${ ... }' since '${' and '}' actually belong to siblings.
                        if (ts.isTemplateSpan(parentNode) && nextNode && ts.isTemplateMiddleOrTemplateTail(nextNode)) {
                            var start_2 = node.getFullStart() - "${".length;
                            var end_2 = nextNode.getStart() + "}".length;
                            pushSelectionRange(start_2, end_2);
                        }
                        // Blocks with braces, brackets, parens, or JSX tags on separate lines should be
                        // selected from open to close, including whitespace but not including the braces/etc. themselves.
                        var isBetweenMultiLineBookends = ts.isSyntaxList(node)
                            && isListOpener(prevNode)
                            && isListCloser(nextNode)
                            && !ts.positionsAreOnSameLine(prevNode.getStart(), nextNode.getStart(), sourceFile);
                        var jsDocCommentStart = ts.hasJSDocNodes(node) && node.jsDoc[0].getStart();
                        var start = isBetweenMultiLineBookends ? prevNode.getEnd() : node.getStart();
                        var end = isBetweenMultiLineBookends ? nextNode.getStart() : node.getEnd();
                        if (ts.isNumber(jsDocCommentStart)) {
                            pushSelectionRange(jsDocCommentStart, end);
                        }
                        pushSelectionRange(start, end);
                        // String literals should have a stop both inside and outside their quotes.
                        if (ts.isStringLiteral(node) || ts.isTemplateLiteral(node)) {
                            pushSelectionRange(start + 1, end - 1);
                        }
                        parentNode = node;
                        break;
                    }
                }
            }
            return selectionRange;
            function pushSelectionRange(start, end) {
                // Skip empty ranges
                if (start !== end) {
                    // Skip ranges that are identical to the parent
                    var textSpan = ts.createTextSpanFromBounds(start, end);
                    if (!selectionRange || !ts.textSpansEqual(textSpan, selectionRange.textSpan)) {
                        selectionRange = __assign({ textSpan: textSpan }, selectionRange && { parent: selectionRange });
                    }
                }
            }
        }
        SmartSelectionRange.getSmartSelectionRange = getSmartSelectionRange;
        /**
         * Like `ts.positionBelongsToNode`, except positions immediately after nodes
         * count too, unless that position belongs to the next node. In effect, makes
         * selections able to snap to preceding tokens when the cursor is on the tail
         * end of them with only whitespace ahead.
         * @param pos The position to check.
         * @param node The candidate node to snap to.
         * @param nextNode The next sibling node in the tree.
         * @param sourceFile The source file containing the nodes.
         */
        function positionShouldSnapToNode(pos, node, nextNode) {
            // Can’t use 'ts.positionBelongsToNode()' here because it cleverly accounts
            // for missing nodes, which can’t really be considered when deciding what
            // to select.
            ts.Debug.assert(node.pos <= pos);
            if (pos < node.end) {
                return true;
            }
            var nodeEnd = node.getEnd();
            var nextNodeStart = nextNode && nextNode.getStart();
            if (nodeEnd === pos) {
                return pos !== nextNodeStart;
            }
            return false;
        }
        var isImport = ts.or(ts.isImportDeclaration, ts.isImportEqualsDeclaration);
        /**
         * Gets the children of a node to be considered for selection ranging,
         * transforming them into an artificial tree according to their intuitive
         * grouping where no grouping actually exists in the parse tree. For example,
         * top-level imports are grouped into their own SyntaxList so they can be
         * selected all together, even though in the AST they’re just siblings of each
         * other as well as of other top-level statements and declarations.
         */
        function getSelectionChildren(node) {
            // Group top-level imports
            if (ts.isSourceFile(node)) {
                return groupChildren(node.getChildAt(0).getChildren(), isImport);
            }
            // Mapped types _look_ like ObjectTypes with a single member,
            // but in fact don’t contain a SyntaxList or a node containing
            // the “key/value” pair like ObjectTypes do, but it seems intuitive
            // that the selection would snap to those points. The philosophy
            // of choosing a selection range is not so much about what the
            // syntax currently _is_ as what the syntax might easily become
            // if the user is making a selection; e.g., we synthesize a selection
            // around the “key/value” pair not because there’s a node there, but
            // because it allows the mapped type to become an object type with a
            // few keystrokes.
            if (ts.isMappedTypeNode(node)) {
                var _a = node.getChildren(), openBraceToken = _a[0], children = _a.slice(1);
                var closeBraceToken = ts.Debug.assertDefined(children.pop());
                ts.Debug.assertEqual(openBraceToken.kind, 18 /* OpenBraceToken */);
                ts.Debug.assertEqual(closeBraceToken.kind, 19 /* CloseBraceToken */);
                // Group `-/+readonly` and `-/+?`
                var groupedWithPlusMinusTokens = groupChildren(children, function (child) {
                    return child === node.readonlyToken || child.kind === 134 /* ReadonlyKeyword */ ||
                        child === node.questionToken || child.kind === 56 /* QuestionToken */;
                });
                // Group type parameter with surrounding brackets
                var groupedWithBrackets = groupChildren(groupedWithPlusMinusTokens, function (_a) {
                    var kind = _a.kind;
                    return kind === 22 /* OpenBracketToken */ ||
                        kind === 151 /* TypeParameter */ ||
                        kind === 23 /* CloseBracketToken */;
                });
                return [
                    openBraceToken,
                    // Pivot on `:`
                    createSyntaxList(splitChildren(groupedWithBrackets, function (_a) {
                        var kind = _a.kind;
                        return kind === 57 /* ColonToken */;
                    })),
                    closeBraceToken,
                ];
            }
            // Group modifiers and property name, then pivot on `:`.
            if (ts.isPropertySignature(node)) {
                var children = groupChildren(node.getChildren(), function (child) {
                    return child === node.name || ts.contains(node.modifiers, child);
                });
                return splitChildren(children, function (_a) {
                    var kind = _a.kind;
                    return kind === 57 /* ColonToken */;
                });
            }
            // Group the parameter name with its `...`, then that group with its `?`, then pivot on `=`.
            if (ts.isParameter(node)) {
                var groupedDotDotDotAndName_1 = groupChildren(node.getChildren(), function (child) {
                    return child === node.dotDotDotToken || child === node.name;
                });
                var groupedWithQuestionToken = groupChildren(groupedDotDotDotAndName_1, function (child) {
                    return child === groupedDotDotDotAndName_1[0] || child === node.questionToken;
                });
                return splitChildren(groupedWithQuestionToken, function (_a) {
                    var kind = _a.kind;
                    return kind === 60 /* EqualsToken */;
                });
            }
            // Pivot on '='
            if (ts.isBindingElement(node)) {
                return splitChildren(node.getChildren(), function (_a) {
                    var kind = _a.kind;
                    return kind === 60 /* EqualsToken */;
                });
            }
            return node.getChildren();
        }
        /**
         * Groups sibling nodes together into their own SyntaxList if they
         * a) are adjacent, AND b) match a predicate function.
         */
        function groupChildren(children, groupOn) {
            var result = [];
            var group;
            for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
                var child = children_1[_i];
                if (groupOn(child)) {
                    group = group || [];
                    group.push(child);
                }
                else {
                    if (group) {
                        result.push(createSyntaxList(group));
                        group = undefined;
                    }
                    result.push(child);
                }
            }
            if (group) {
                result.push(createSyntaxList(group));
            }
            return result;
        }
        /**
         * Splits sibling nodes into up to four partitions:
         * 1) everything left of the first node matched by `pivotOn`,
         * 2) the first node matched by `pivotOn`,
         * 3) everything right of the first node matched by `pivotOn`,
         * 4) a trailing semicolon, if `separateTrailingSemicolon` is enabled.
         * The left and right groups, if not empty, will each be grouped into their own containing SyntaxList.
         * @param children The sibling nodes to split.
         * @param pivotOn The predicate function to match the node to be the pivot. The first node that matches
         * the predicate will be used; any others that may match will be included into the right-hand group.
         * @param separateTrailingSemicolon If the last token is a semicolon, it will be returned as a separate
         * child rather than be included in the right-hand group.
         */
        function splitChildren(children, pivotOn, separateTrailingSemicolon) {
            if (separateTrailingSemicolon === void 0) { separateTrailingSemicolon = true; }
            if (children.length < 2) {
                return children;
            }
            var splitTokenIndex = ts.findIndex(children, pivotOn);
            if (splitTokenIndex === -1) {
                return children;
            }
            var leftChildren = children.slice(0, splitTokenIndex);
            var splitToken = children[splitTokenIndex];
            var lastToken = ts.last(children);
            var separateLastToken = separateTrailingSemicolon && lastToken.kind === 26 /* SemicolonToken */;
            var rightChildren = children.slice(splitTokenIndex + 1, separateLastToken ? children.length - 1 : undefined);
            var result = ts.compact([
                leftChildren.length ? createSyntaxList(leftChildren) : undefined,
                splitToken,
                rightChildren.length ? createSyntaxList(rightChildren) : undefined,
            ]);
            return separateLastToken ? result.concat(lastToken) : result;
        }
        function createSyntaxList(children) {
            ts.Debug.assertGreaterThanOrEqual(children.length, 1);
            var syntaxList = ts.createNode(312 /* SyntaxList */, children[0].pos, ts.last(children).end);
            syntaxList._children = children;
            return syntaxList;
        }
        function isListOpener(token) {
            var kind = token && token.kind;
            return kind === 18 /* OpenBraceToken */
                || kind === 22 /* OpenBracketToken */
                || kind === 20 /* OpenParenToken */
                || kind === 263 /* JsxOpeningElement */;
        }
        function isListCloser(token) {
            var kind = token && token.kind;
            return kind === 19 /* CloseBraceToken */
                || kind === 23 /* CloseBracketToken */
                || kind === 21 /* CloseParenToken */
                || kind === 264 /* JsxClosingElement */;
        }
    })(SmartSelectionRange = ts.SmartSelectionRange || (ts.SmartSelectionRange = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var SignatureHelp;
    (function (SignatureHelp) {
        var InvocationKind;
        (function (InvocationKind) {
            InvocationKind[InvocationKind["Call"] = 0] = "Call";
            InvocationKind[InvocationKind["TypeArgs"] = 1] = "TypeArgs";
            InvocationKind[InvocationKind["Contextual"] = 2] = "Contextual";
        })(InvocationKind || (InvocationKind = {}));
        function getSignatureHelpItems(program, sourceFile, position, triggerReason, cancellationToken) {
            var typeChecker = program.getTypeChecker();
            // Decide whether to show signature help
            var startingToken = ts.findTokenOnLeftOfPosition(sourceFile, position);
            if (!startingToken) {
                // We are at the beginning of the file
                return undefined;
            }
            // Only need to be careful if the user typed a character and signature help wasn't showing.
            var onlyUseSyntacticOwners = !!triggerReason && triggerReason.kind === "characterTyped";
            // Bail out quickly in the middle of a string or comment, don't provide signature help unless the user explicitly requested it.
            if (onlyUseSyntacticOwners && (ts.isInString(sourceFile, position, startingToken) || ts.isInComment(sourceFile, position))) {
                return undefined;
            }
            var isManuallyInvoked = !!triggerReason && triggerReason.kind === "invoked";
            var argumentInfo = getContainingArgumentInfo(startingToken, position, sourceFile, typeChecker, isManuallyInvoked);
            if (!argumentInfo)
                return undefined;
            cancellationToken.throwIfCancellationRequested();
            // Extra syntactic and semantic filtering of signature help
            var candidateInfo = getCandidateOrTypeInfo(argumentInfo, typeChecker, sourceFile, startingToken, onlyUseSyntacticOwners);
            cancellationToken.throwIfCancellationRequested();
            if (!candidateInfo) {
                // We didn't have any sig help items produced by the TS compiler.  If this is a JS
                // file, then see if we can figure out anything better.
                return ts.isSourceFileJS(sourceFile) ? createJSSignatureHelpItems(argumentInfo, program, cancellationToken) : undefined;
            }
            return typeChecker.runWithCancellationToken(cancellationToken, function (typeChecker) {
                return candidateInfo.kind === 0 /* Candidate */
                    ? createSignatureHelpItems(candidateInfo.candidates, candidateInfo.resolvedSignature, argumentInfo, sourceFile, typeChecker)
                    : createTypeHelpItems(candidateInfo.symbol, argumentInfo, sourceFile, typeChecker);
            });
        }
        SignatureHelp.getSignatureHelpItems = getSignatureHelpItems;
        var CandidateOrTypeKind;
        (function (CandidateOrTypeKind) {
            CandidateOrTypeKind[CandidateOrTypeKind["Candidate"] = 0] = "Candidate";
            CandidateOrTypeKind[CandidateOrTypeKind["Type"] = 1] = "Type";
        })(CandidateOrTypeKind || (CandidateOrTypeKind = {}));
        function getCandidateOrTypeInfo(_a, checker, sourceFile, startingToken, onlyUseSyntacticOwners) {
            var invocation = _a.invocation, argumentCount = _a.argumentCount;
            switch (invocation.kind) {
                case 0 /* Call */: {
                    if (onlyUseSyntacticOwners && !isSyntacticOwner(startingToken, invocation.node, sourceFile)) {
                        return undefined;
                    }
                    var candidates = [];
                    var resolvedSignature = checker.getResolvedSignatureForSignatureHelp(invocation.node, candidates, argumentCount); // TODO: GH#18217
                    return candidates.length === 0 ? undefined : { kind: 0 /* Candidate */, candidates: candidates, resolvedSignature: resolvedSignature };
                }
                case 1 /* TypeArgs */: {
                    var called = invocation.called;
                    if (onlyUseSyntacticOwners && !containsPrecedingToken(startingToken, sourceFile, ts.isIdentifier(called) ? called.parent : called)) {
                        return undefined;
                    }
                    var candidates = ts.getPossibleGenericSignatures(called, argumentCount, checker);
                    if (candidates.length !== 0)
                        return { kind: 0 /* Candidate */, candidates: candidates, resolvedSignature: ts.first(candidates) };
                    var symbol = checker.getSymbolAtLocation(called);
                    return symbol && { kind: 1 /* Type */, symbol: symbol };
                }
                case 2 /* Contextual */:
                    return { kind: 0 /* Candidate */, candidates: [invocation.signature], resolvedSignature: invocation.signature };
                default:
                    return ts.Debug.assertNever(invocation);
            }
        }
        function isSyntacticOwner(startingToken, node, sourceFile) {
            if (!ts.isCallOrNewExpression(node))
                return false;
            var invocationChildren = node.getChildren(sourceFile);
            switch (startingToken.kind) {
                case 20 /* OpenParenToken */:
                    return ts.contains(invocationChildren, startingToken);
                case 27 /* CommaToken */: {
                    var containingList = ts.findContainingList(startingToken);
                    return !!containingList && ts.contains(invocationChildren, containingList);
                }
                case 28 /* LessThanToken */:
                    return containsPrecedingToken(startingToken, sourceFile, node.expression);
                default:
                    return false;
            }
        }
        function createJSSignatureHelpItems(argumentInfo, program, cancellationToken) {
            if (argumentInfo.invocation.kind === 2 /* Contextual */)
                return undefined;
            // See if we can find some symbol with the call expression name that has call signatures.
            var expression = getExpressionFromInvocation(argumentInfo.invocation);
            var name = ts.isIdentifier(expression) ? expression.text : ts.isPropertyAccessExpression(expression) ? expression.name.text : undefined;
            var typeChecker = program.getTypeChecker();
            return name === undefined ? undefined : ts.firstDefined(program.getSourceFiles(), function (sourceFile) {
                return ts.firstDefined(sourceFile.getNamedDeclarations().get(name), function (declaration) {
                    var type = declaration.symbol && typeChecker.getTypeOfSymbolAtLocation(declaration.symbol, declaration);
                    var callSignatures = type && type.getCallSignatures();
                    if (callSignatures && callSignatures.length) {
                        return typeChecker.runWithCancellationToken(cancellationToken, function (typeChecker) { return createSignatureHelpItems(callSignatures, callSignatures[0], argumentInfo, sourceFile, typeChecker); });
                    }
                });
            });
        }
        function containsPrecedingToken(startingToken, sourceFile, container) {
            var pos = startingToken.getFullStart();
            // There’s a possibility that `startingToken.parent` contains only `startingToken` and
            // missing nodes, none of which are valid to be returned by `findPrecedingToken`. In that
            // case, the preceding token we want is actually higher up the tree—almost definitely the
            // next parent, but theoretically the situation with missing nodes might be happening on
            // multiple nested levels.
            var currentParent = startingToken.parent;
            while (currentParent) {
                var precedingToken = ts.findPrecedingToken(pos, sourceFile, currentParent, /*excludeJsdoc*/ true);
                if (precedingToken) {
                    return ts.rangeContainsRange(container, precedingToken);
                }
                currentParent = currentParent.parent;
            }
            return ts.Debug.fail("Could not find preceding token");
        }
        function getArgumentInfoForCompletions(node, position, sourceFile) {
            var info = getImmediatelyContainingArgumentInfo(node, position, sourceFile);
            return !info || info.isTypeParameterList || info.invocation.kind !== 0 /* Call */ ? undefined
                : { invocation: info.invocation.node, argumentCount: info.argumentCount, argumentIndex: info.argumentIndex };
        }
        SignatureHelp.getArgumentInfoForCompletions = getArgumentInfoForCompletions;
        function getArgumentOrParameterListInfo(node, sourceFile) {
            var info = getArgumentOrParameterListAndIndex(node, sourceFile);
            if (!info)
                return undefined;
            var list = info.list, argumentIndex = info.argumentIndex;
            var argumentCount = getArgumentCount(list);
            if (argumentIndex !== 0) {
                ts.Debug.assertLessThan(argumentIndex, argumentCount);
            }
            var argumentsSpan = getApplicableSpanForArguments(list, sourceFile);
            return { list: list, argumentIndex: argumentIndex, argumentCount: argumentCount, argumentsSpan: argumentsSpan };
        }
        function getArgumentOrParameterListAndIndex(node, sourceFile) {
            if (node.kind === 28 /* LessThanToken */ || node.kind === 20 /* OpenParenToken */) {
                // Find the list that starts right *after* the < or ( token.
                // If the user has just opened a list, consider this item 0.
                return { list: getChildListThatStartsWithOpenerToken(node.parent, node, sourceFile), argumentIndex: 0 };
            }
            else {
                // findListItemInfo can return undefined if we are not in parent's argument list
                // or type argument list. This includes cases where the cursor is:
                //   - To the right of the closing parenthesis, non-substitution template, or template tail.
                //   - Between the type arguments and the arguments (greater than token)
                //   - On the target of the call (parent.func)
                //   - On the 'new' keyword in a 'new' expression
                var list = ts.findContainingList(node);
                return list && { list: list, argumentIndex: getArgumentIndex(list, node) };
            }
        }
        /**
         * Returns relevant information for the argument list and the current argument if we are
         * in the argument of an invocation; returns undefined otherwise.
         */
        function getImmediatelyContainingArgumentInfo(node, position, sourceFile) {
            var parent = node.parent;
            if (ts.isCallOrNewExpression(parent)) {
                var invocation = parent;
                // There are 3 cases to handle:
                //   1. The token introduces a list, and should begin a signature help session
                //   2. The token is either not associated with a list, or ends a list, so the session should end
                //   3. The token is buried inside a list, and should give signature help
                //
                // The following are examples of each:
                //
                //    Case 1:
                //          foo<#T, U>(#a, b)    -> The token introduces a list, and should begin a signature help session
                //    Case 2:
                //          fo#o<T, U>#(a, b)#   -> The token is either not associated with a list, or ends a list, so the session should end
                //    Case 3:
                //          foo<T#, U#>(a#, #b#) -> The token is buried inside a list, and should give signature help
                // Find out if 'node' is an argument, a type argument, or neither
                var info = getArgumentOrParameterListInfo(node, sourceFile);
                if (!info)
                    return undefined;
                var list = info.list, argumentIndex = info.argumentIndex, argumentCount = info.argumentCount, argumentsSpan = info.argumentsSpan;
                var isTypeParameterList = !!parent.typeArguments && parent.typeArguments.pos === list.pos;
                return { isTypeParameterList: isTypeParameterList, invocation: { kind: 0 /* Call */, node: invocation }, argumentsSpan: argumentsSpan, argumentIndex: argumentIndex, argumentCount: argumentCount };
            }
            else if (ts.isNoSubstitutionTemplateLiteral(node) && ts.isTaggedTemplateExpression(parent)) {
                // Check if we're actually inside the template;
                // otherwise we'll fall out and return undefined.
                if (ts.isInsideTemplateLiteral(node, position, sourceFile)) {
                    return getArgumentListInfoForTemplate(parent, /*argumentIndex*/ 0, sourceFile);
                }
                return undefined;
            }
            else if (ts.isTemplateHead(node) && parent.parent.kind === 194 /* TaggedTemplateExpression */) {
                var templateExpression = parent;
                var tagExpression = templateExpression.parent;
                ts.Debug.assert(templateExpression.kind === 207 /* TemplateExpression */);
                var argumentIndex = ts.isInsideTemplateLiteral(node, position, sourceFile) ? 0 : 1;
                return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile);
            }
            else if (ts.isTemplateSpan(parent) && ts.isTaggedTemplateExpression(parent.parent.parent)) {
                var templateSpan = parent;
                var tagExpression = parent.parent.parent;
                // If we're just after a template tail, don't show signature help.
                if (ts.isTemplateTail(node) && !ts.isInsideTemplateLiteral(node, position, sourceFile)) {
                    return undefined;
                }
                var spanIndex = templateSpan.parent.templateSpans.indexOf(templateSpan);
                var argumentIndex = getArgumentIndexForTemplatePiece(spanIndex, node, position, sourceFile);
                return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile);
            }
            else if (ts.isJsxOpeningLikeElement(parent)) {
                // Provide a signature help for JSX opening element or JSX self-closing element.
                // This is not guarantee that JSX tag-name is resolved into stateless function component. (that is done in "getSignatureHelpItems")
                // i.e
                //      export function MainButton(props: ButtonProps, context: any): JSX.Element { ... }
                //      <MainButton /*signatureHelp*/
                var attributeSpanStart = parent.attributes.pos;
                var attributeSpanEnd = ts.skipTrivia(sourceFile.text, parent.attributes.end, /*stopAfterLineBreak*/ false);
                return {
                    isTypeParameterList: false,
                    invocation: { kind: 0 /* Call */, node: parent },
                    argumentsSpan: ts.createTextSpan(attributeSpanStart, attributeSpanEnd - attributeSpanStart),
                    argumentIndex: 0,
                    argumentCount: 1
                };
            }
            else {
                var typeArgInfo = ts.getPossibleTypeArgumentsInfo(node, sourceFile);
                if (typeArgInfo) {
                    var called = typeArgInfo.called, nTypeArguments = typeArgInfo.nTypeArguments;
                    var invocation = { kind: 1 /* TypeArgs */, called: called };
                    var argumentsSpan = ts.createTextSpanFromBounds(called.getStart(sourceFile), node.end);
                    return { isTypeParameterList: true, invocation: invocation, argumentsSpan: argumentsSpan, argumentIndex: nTypeArguments, argumentCount: nTypeArguments + 1 };
                }
                return undefined;
            }
        }
        function getImmediatelyContainingArgumentOrContextualParameterInfo(node, position, sourceFile, checker) {
            return tryGetParameterInfo(node, position, sourceFile, checker) || getImmediatelyContainingArgumentInfo(node, position, sourceFile);
        }
        function getHighestBinary(b) {
            return ts.isBinaryExpression(b.parent) ? getHighestBinary(b.parent) : b;
        }
        function countBinaryExpressionParameters(b) {
            return ts.isBinaryExpression(b.left) ? countBinaryExpressionParameters(b.left) + 1 : 2;
        }
        function tryGetParameterInfo(startingToken, _position, sourceFile, checker) {
            var info = getContextualSignatureLocationInfo(startingToken, sourceFile, checker);
            if (!info)
                return undefined;
            var contextualType = info.contextualType, argumentIndex = info.argumentIndex, argumentCount = info.argumentCount, argumentsSpan = info.argumentsSpan;
            var signatures = contextualType.getCallSignatures();
            if (signatures.length !== 1)
                return undefined;
            var invocation = { kind: 2 /* Contextual */, signature: ts.first(signatures), node: startingToken, symbol: chooseBetterSymbol(contextualType.symbol) };
            return { isTypeParameterList: false, invocation: invocation, argumentsSpan: argumentsSpan, argumentIndex: argumentIndex, argumentCount: argumentCount };
        }
        function getContextualSignatureLocationInfo(startingToken, sourceFile, checker) {
            if (startingToken.kind !== 20 /* OpenParenToken */ && startingToken.kind !== 27 /* CommaToken */)
                return undefined;
            var parent = startingToken.parent;
            switch (parent.kind) {
                case 196 /* ParenthesizedExpression */:
                case 157 /* MethodDeclaration */:
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */:
                    var info = getArgumentOrParameterListInfo(startingToken, sourceFile);
                    if (!info)
                        return undefined;
                    var argumentIndex = info.argumentIndex, argumentCount = info.argumentCount, argumentsSpan = info.argumentsSpan;
                    var contextualType = ts.isMethodDeclaration(parent) ? checker.getContextualTypeForObjectLiteralElement(parent) : checker.getContextualType(parent);
                    return contextualType && { contextualType: contextualType, argumentIndex: argumentIndex, argumentCount: argumentCount, argumentsSpan: argumentsSpan };
                case 205 /* BinaryExpression */: {
                    var highestBinary = getHighestBinary(parent);
                    var contextualType_1 = checker.getContextualType(highestBinary);
                    var argumentIndex_1 = startingToken.kind === 20 /* OpenParenToken */ ? 0 : countBinaryExpressionParameters(parent) - 1;
                    var argumentCount_1 = countBinaryExpressionParameters(highestBinary);
                    return contextualType_1 && { contextualType: contextualType_1, argumentIndex: argumentIndex_1, argumentCount: argumentCount_1, argumentsSpan: ts.createTextSpanFromNode(parent) };
                }
                default:
                    return undefined;
            }
        }
        // The type of a function type node has a symbol at that node, but it's better to use the symbol for a parameter or type alias.
        function chooseBetterSymbol(s) {
            return s.name === "__type" /* Type */
                ? ts.firstDefined(s.declarations, function (d) { return ts.isFunctionTypeNode(d) ? d.parent.symbol : undefined; }) || s
                : s;
        }
        function getArgumentIndex(argumentsList, node) {
            // The list we got back can include commas.  In the presence of errors it may
            // also just have nodes without commas.  For example "Foo(a b c)" will have 3
            // args without commas. We want to find what index we're at.  So we count
            // forward until we hit ourselves, only incrementing the index if it isn't a
            // comma.
            //
            // Note: the subtlety around trailing commas (in getArgumentCount) does not apply
            // here.  That's because we're only walking forward until we hit the node we're
            // on.  In that case, even if we're after the trailing comma, we'll still see
            // that trailing comma in the list, and we'll have generated the appropriate
            // arg index.
            var argumentIndex = 0;
            for (var _i = 0, _a = argumentsList.getChildren(); _i < _a.length; _i++) {
                var child = _a[_i];
                if (child === node) {
                    break;
                }
                if (child.kind !== 27 /* CommaToken */) {
                    argumentIndex++;
                }
            }
            return argumentIndex;
        }
        function getArgumentCount(argumentsList) {
            // The argument count for a list is normally the number of non-comma children it has.
            // For example, if you have "Foo(a,b)" then there will be three children of the arg
            // list 'a' '<comma>' 'b'.  So, in this case the arg count will be 2.  However, there
            // is a small subtlety.  If you have "Foo(a,)", then the child list will just have
            // 'a' '<comma>'.  So, in the case where the last child is a comma, we increase the
            // arg count by one to compensate.
            //
            // Note: this subtlety only applies to the last comma.  If you had "Foo(a,," then
            // we'll have: 'a' '<comma>' '<missing>'
            // That will give us 2 non-commas.  We then add one for the last comma, giving us an
            // arg count of 3.
            var listChildren = argumentsList.getChildren();
            var argumentCount = ts.countWhere(listChildren, function (arg) { return arg.kind !== 27 /* CommaToken */; });
            if (listChildren.length > 0 && ts.last(listChildren).kind === 27 /* CommaToken */) {
                argumentCount++;
            }
            return argumentCount;
        }
        // spanIndex is either the index for a given template span.
        // This does not give appropriate results for a NoSubstitutionTemplateLiteral
        function getArgumentIndexForTemplatePiece(spanIndex, node, position, sourceFile) {
            // Because the TemplateStringsArray is the first argument, we have to offset each substitution expression by 1.
            // There are three cases we can encounter:
            //      1. We are precisely in the template literal (argIndex = 0).
            //      2. We are in or to the right of the substitution expression (argIndex = spanIndex + 1).
            //      3. We are directly to the right of the template literal, but because we look for the token on the left,
            //          not enough to put us in the substitution expression; we should consider ourselves part of
            //          the *next* span's expression by offsetting the index (argIndex = (spanIndex + 1) + 1).
            //
            // tslint:disable no-double-space
            // Example: f  `# abcd $#{#  1 + 1#  }# efghi ${ #"#hello"#  }  #  `
            //              ^       ^ ^       ^   ^          ^ ^      ^     ^
            // Case:        1       1 3       2   1          3 2      2     1
            // tslint:enable no-double-space
            ts.Debug.assert(position >= node.getStart(), "Assumed 'position' could not occur before node.");
            if (ts.isTemplateLiteralToken(node)) {
                if (ts.isInsideTemplateLiteral(node, position, sourceFile)) {
                    return 0;
                }
                return spanIndex + 2;
            }
            return spanIndex + 1;
        }
        function getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile) {
            // argumentCount is either 1 or (numSpans + 1) to account for the template strings array argument.
            var argumentCount = ts.isNoSubstitutionTemplateLiteral(tagExpression.template) ? 1 : tagExpression.template.templateSpans.length + 1;
            if (argumentIndex !== 0) {
                ts.Debug.assertLessThan(argumentIndex, argumentCount);
            }
            return {
                isTypeParameterList: false,
                invocation: { kind: 0 /* Call */, node: tagExpression },
                argumentsSpan: getApplicableSpanForTaggedTemplate(tagExpression, sourceFile),
                argumentIndex: argumentIndex,
                argumentCount: argumentCount
            };
        }
        function getApplicableSpanForArguments(argumentsList, sourceFile) {
            // We use full start and skip trivia on the end because we want to include trivia on
            // both sides. For example,
            //
            //    foo(   /*comment */     a, b, c      /*comment*/     )
            //        |                                               |
            //
            // The applicable span is from the first bar to the second bar (inclusive,
            // but not including parentheses)
            var applicableSpanStart = argumentsList.getFullStart();
            var applicableSpanEnd = ts.skipTrivia(sourceFile.text, argumentsList.getEnd(), /*stopAfterLineBreak*/ false);
            return ts.createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
        }
        function getApplicableSpanForTaggedTemplate(taggedTemplate, sourceFile) {
            var template = taggedTemplate.template;
            var applicableSpanStart = template.getStart();
            var applicableSpanEnd = template.getEnd();
            // We need to adjust the end position for the case where the template does not have a tail.
            // Otherwise, we will not show signature help past the expression.
            // For example,
            //
            //      ` ${ 1 + 1 foo(10)
            //       |       |
            // This is because a Missing node has no width. However, what we actually want is to include trivia
            // leading up to the next token in case the user is about to type in a TemplateMiddle or TemplateTail.
            if (template.kind === 207 /* TemplateExpression */) {
                var lastSpan = ts.last(template.templateSpans);
                if (lastSpan.literal.getFullWidth() === 0) {
                    applicableSpanEnd = ts.skipTrivia(sourceFile.text, applicableSpanEnd, /*stopAfterLineBreak*/ false);
                }
            }
            return ts.createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
        }
        function getContainingArgumentInfo(node, position, sourceFile, checker, isManuallyInvoked) {
            var _loop_7 = function (n) {
                // If the node is not a subspan of its parent, this is a big problem.
                // There have been crashes that might be caused by this violation.
                ts.Debug.assert(ts.rangeContainsRange(n.parent, n), "Not a subspan", function () { return "Child: " + ts.Debug.formatSyntaxKind(n.kind) + ", parent: " + ts.Debug.formatSyntaxKind(n.parent.kind); });
                var argumentInfo = getImmediatelyContainingArgumentOrContextualParameterInfo(n, position, sourceFile, checker);
                if (argumentInfo) {
                    return { value: argumentInfo };
                }
            };
            for (var n = node; !ts.isSourceFile(n) && (isManuallyInvoked || !ts.isBlock(n)); n = n.parent) {
                var state_2 = _loop_7(n);
                if (typeof state_2 === "object")
                    return state_2.value;
            }
            return undefined;
        }
        function getChildListThatStartsWithOpenerToken(parent, openerToken, sourceFile) {
            var children = parent.getChildren(sourceFile);
            var indexOfOpenerToken = children.indexOf(openerToken);
            ts.Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1);
            return children[indexOfOpenerToken + 1];
        }
        function getExpressionFromInvocation(invocation) {
            return invocation.kind === 0 /* Call */ ? ts.getInvokedExpression(invocation.node) : invocation.called;
        }
        function getEnclosingDeclarationFromInvocation(invocation) {
            return invocation.kind === 0 /* Call */ ? invocation.node : invocation.kind === 1 /* TypeArgs */ ? invocation.called : invocation.node;
        }
        var signatureHelpNodeBuilderFlags = 8192 /* OmitParameterModifiers */ | 70221824 /* IgnoreErrors */ | 16384 /* UseAliasDefinedOutsideCurrentScope */;
        function createSignatureHelpItems(candidates, resolvedSignature, _a, sourceFile, typeChecker) {
            var isTypeParameterList = _a.isTypeParameterList, argumentCount = _a.argumentCount, applicableSpan = _a.argumentsSpan, invocation = _a.invocation, argumentIndex = _a.argumentIndex;
            var enclosingDeclaration = getEnclosingDeclarationFromInvocation(invocation);
            var callTargetSymbol = invocation.kind === 2 /* Contextual */ ? invocation.symbol : typeChecker.getSymbolAtLocation(getExpressionFromInvocation(invocation));
            var callTargetDisplayParts = callTargetSymbol ? ts.symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined) : ts.emptyArray;
            var items = candidates.map(function (candidateSignature) { return getSignatureHelpItem(candidateSignature, callTargetDisplayParts, isTypeParameterList, typeChecker, enclosingDeclaration, sourceFile); });
            if (argumentIndex !== 0) {
                ts.Debug.assertLessThan(argumentIndex, argumentCount);
            }
            var selectedItemIndex = candidates.indexOf(resolvedSignature);
            ts.Debug.assert(selectedItemIndex !== -1); // If candidates is non-empty it should always include bestSignature. We check for an empty candidates before calling this function.
            return { items: items, applicableSpan: applicableSpan, selectedItemIndex: selectedItemIndex, argumentIndex: argumentIndex, argumentCount: argumentCount };
        }
        function createTypeHelpItems(symbol, _a, sourceFile, checker) {
            var argumentCount = _a.argumentCount, applicableSpan = _a.argumentsSpan, invocation = _a.invocation, argumentIndex = _a.argumentIndex;
            var typeParameters = checker.getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
            if (!typeParameters)
                return undefined;
            var items = [getTypeHelpItem(symbol, typeParameters, checker, getEnclosingDeclarationFromInvocation(invocation), sourceFile)];
            return { items: items, applicableSpan: applicableSpan, selectedItemIndex: 0, argumentIndex: argumentIndex, argumentCount: argumentCount };
        }
        function getTypeHelpItem(symbol, typeParameters, checker, enclosingDeclaration, sourceFile) {
            var typeSymbolDisplay = ts.symbolToDisplayParts(checker, symbol);
            var printer = ts.createPrinter({ removeComments: true });
            var parameters = typeParameters.map(function (t) { return createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer); });
            var documentation = symbol.getDocumentationComment(checker);
            var tags = symbol.getJsDocTags();
            var prefixDisplayParts = typeSymbolDisplay.concat([ts.punctuationPart(28 /* LessThanToken */)]);
            return { isVariadic: false, prefixDisplayParts: prefixDisplayParts, suffixDisplayParts: [ts.punctuationPart(30 /* GreaterThanToken */)], separatorDisplayParts: separatorDisplayParts, parameters: parameters, documentation: documentation, tags: tags };
        }
        var separatorDisplayParts = [ts.punctuationPart(27 /* CommaToken */), ts.spacePart()];
        function getSignatureHelpItem(candidateSignature, callTargetDisplayParts, isTypeParameterList, checker, enclosingDeclaration, sourceFile) {
            var _a = (isTypeParameterList ? itemInfoForTypeParameters : itemInfoForParameters)(candidateSignature, checker, enclosingDeclaration, sourceFile), isVariadic = _a.isVariadic, parameters = _a.parameters, prefix = _a.prefix, suffix = _a.suffix;
            var prefixDisplayParts = callTargetDisplayParts.concat(prefix);
            var suffixDisplayParts = suffix.concat(returnTypeToDisplayParts(candidateSignature, enclosingDeclaration, checker));
            var documentation = candidateSignature.getDocumentationComment(checker);
            var tags = candidateSignature.getJsDocTags();
            return { isVariadic: isVariadic, prefixDisplayParts: prefixDisplayParts, suffixDisplayParts: suffixDisplayParts, separatorDisplayParts: separatorDisplayParts, parameters: parameters, documentation: documentation, tags: tags };
        }
        function returnTypeToDisplayParts(candidateSignature, enclosingDeclaration, checker) {
            return ts.mapToDisplayParts(function (writer) {
                writer.writePunctuation(":");
                writer.writeSpace(" ");
                var predicate = checker.getTypePredicateOfSignature(candidateSignature);
                if (predicate) {
                    checker.writeTypePredicate(predicate, enclosingDeclaration, /*flags*/ undefined, writer);
                }
                else {
                    checker.writeType(checker.getReturnTypeOfSignature(candidateSignature), enclosingDeclaration, /*flags*/ undefined, writer);
                }
            });
        }
        function itemInfoForTypeParameters(candidateSignature, checker, enclosingDeclaration, sourceFile) {
            var typeParameters = (candidateSignature.target || candidateSignature).typeParameters;
            var printer = ts.createPrinter({ removeComments: true });
            var parameters = (typeParameters || ts.emptyArray).map(function (t) { return createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer); });
            var parameterParts = ts.mapToDisplayParts(function (writer) {
                var thisParameter = candidateSignature.thisParameter ? [checker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)] : [];
                var params = ts.createNodeArray(thisParameter.concat(checker.getExpandedParameters(candidateSignature).map(function (param) { return checker.symbolToParameterDeclaration(param, enclosingDeclaration, signatureHelpNodeBuilderFlags); })));
                printer.writeList(2576 /* CallExpressionArguments */, params, sourceFile, writer);
            });
            return { isVariadic: false, parameters: parameters, prefix: [ts.punctuationPart(28 /* LessThanToken */)], suffix: [ts.punctuationPart(30 /* GreaterThanToken */)].concat(parameterParts) };
        }
        function itemInfoForParameters(candidateSignature, checker, enclosingDeclaration, sourceFile) {
            var isVariadic = checker.hasEffectiveRestParameter(candidateSignature);
            var printer = ts.createPrinter({ removeComments: true });
            var typeParameterParts = ts.mapToDisplayParts(function (writer) {
                if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) {
                    var args = ts.createNodeArray(candidateSignature.typeParameters.map(function (p) { return checker.typeParameterToDeclaration(p, enclosingDeclaration); }));
                    printer.writeList(53776 /* TypeParameters */, args, sourceFile, writer);
                }
            });
            var parameters = checker.getExpandedParameters(candidateSignature).map(function (p) { return createSignatureHelpParameterForParameter(p, checker, enclosingDeclaration, sourceFile, printer); });
            return { isVariadic: isVariadic, parameters: parameters, prefix: typeParameterParts.concat([ts.punctuationPart(20 /* OpenParenToken */)]), suffix: [ts.punctuationPart(21 /* CloseParenToken */)] };
        }
        function createSignatureHelpParameterForParameter(parameter, checker, enclosingDeclaration, sourceFile, printer) {
            var displayParts = ts.mapToDisplayParts(function (writer) {
                var param = checker.symbolToParameterDeclaration(parameter, enclosingDeclaration, signatureHelpNodeBuilderFlags);
                printer.writeNode(4 /* Unspecified */, param, sourceFile, writer);
            });
            var isOptional = checker.isOptionalParameter(parameter.valueDeclaration);
            return { name: parameter.name, documentation: parameter.getDocumentationComment(checker), displayParts: displayParts, isOptional: isOptional };
        }
        function createSignatureHelpParameterForTypeParameter(typeParameter, checker, enclosingDeclaration, sourceFile, printer) {
            var displayParts = ts.mapToDisplayParts(function (writer) {
                var param = checker.typeParameterToDeclaration(typeParameter, enclosingDeclaration);
                printer.writeNode(4 /* Unspecified */, param, sourceFile, writer);
            });
            return { name: typeParameter.symbol.name, documentation: typeParameter.symbol.getDocumentationComment(checker), displayParts: displayParts, isOptional: false };
        }
    })(SignatureHelp = ts.SignatureHelp || (ts.SignatureHelp = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var base64UrlRegExp = /^data:(?:application\/json(?:;charset=[uU][tT][fF]-8);base64,([A-Za-z0-9+\/=]+)$)?/;
    function getSourceMapper(host) {
        var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames());
        var currentDirectory = host.getCurrentDirectory();
        var sourceFileLike = ts.createMap();
        var documentPositionMappers = ts.createMap();
        return { tryGetSourcePosition: tryGetSourcePosition, tryGetGeneratedPosition: tryGetGeneratedPosition, toLineColumnOffset: toLineColumnOffset, clearCache: clearCache };
        function toPath(fileName) {
            return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
        }
        function getDocumentPositionMapper(generatedFileName, sourceFileName) {
            var path = toPath(generatedFileName);
            var value = documentPositionMappers.get(path);
            if (value)
                return value;
            var mapper;
            if (host.getDocumentPositionMapper) {
                mapper = host.getDocumentPositionMapper(generatedFileName, sourceFileName);
            }
            else if (host.readFile) {
                var file = getSourceFileLike(generatedFileName);
                mapper = file && ts.getDocumentPositionMapper({ getSourceFileLike: getSourceFileLike, getCanonicalFileName: getCanonicalFileName, log: function (s) { return host.log(s); } }, generatedFileName, ts.getLineInfo(file.text, ts.getLineStarts(file)), function (f) { return !host.fileExists || host.fileExists(f) ? host.readFile(f) : undefined; });
            }
            documentPositionMappers.set(path, mapper || ts.identitySourceMapConsumer);
            return mapper || ts.identitySourceMapConsumer;
        }
        function tryGetSourcePosition(info) {
            if (!ts.isDeclarationFileName(info.fileName))
                return undefined;
            var file = getSourceFile(info.fileName);
            if (!file)
                return undefined;
            var newLoc = getDocumentPositionMapper(info.fileName).getSourcePosition(info);
            return !newLoc || newLoc === info ? undefined : tryGetSourcePosition(newLoc) || newLoc;
        }
        function tryGetGeneratedPosition(info) {
            if (ts.isDeclarationFileName(info.fileName))
                return undefined;
            var sourceFile = getSourceFile(info.fileName);
            if (!sourceFile)
                return undefined;
            var program = host.getProgram();
            var options = program.getCompilerOptions();
            var outPath = options.outFile || options.out;
            var declarationPath = outPath ?
                ts.removeFileExtension(outPath) + ".d.ts" /* Dts */ :
                ts.getDeclarationEmitOutputFilePathWorker(info.fileName, program.getCompilerOptions(), currentDirectory, program.getCommonSourceDirectory(), getCanonicalFileName);
            if (declarationPath === undefined)
                return undefined;
            var newLoc = getDocumentPositionMapper(declarationPath, info.fileName).getGeneratedPosition(info);
            return newLoc === info ? undefined : newLoc;
        }
        function getSourceFile(fileName) {
            var program = host.getProgram();
            if (!program)
                return undefined;
            var path = toPath(fileName);
            // file returned here could be .d.ts when asked for .ts file if projectReferences and module resolution created this source file
            var file = program.getSourceFileByPath(path);
            return file && file.resolvedPath === path ? file : undefined;
        }
        function getOrCreateSourceFileLike(fileName) {
            var path = toPath(fileName);
            var fileFromCache = sourceFileLike.get(path);
            if (fileFromCache !== undefined)
                return fileFromCache ? fileFromCache : undefined;
            if (!host.readFile || host.fileExists && !host.fileExists(path)) {
                sourceFileLike.set(path, false);
                return undefined;
            }
            // And failing that, check the disk
            var text = host.readFile(path);
            var file = text ? createSourceFileLike(text) : false;
            sourceFileLike.set(path, file);
            return file ? file : undefined;
        }
        // This can be called from source mapper in either source program or program that includes generated file
        function getSourceFileLike(fileName) {
            return !host.getSourceFileLike ?
                getSourceFile(fileName) || getOrCreateSourceFileLike(fileName) :
                host.getSourceFileLike(fileName);
        }
        function toLineColumnOffset(fileName, position) {
            var file = getSourceFileLike(fileName); // TODO: GH#18217
            return file.getLineAndCharacterOfPosition(position);
        }
        function clearCache() {
            sourceFileLike.clear();
            documentPositionMappers.clear();
        }
    }
    ts.getSourceMapper = getSourceMapper;
    function getDocumentPositionMapper(host, generatedFileName, generatedFileLineInfo, readMapFile) {
        var mapFileName = ts.tryGetSourceMappingURL(generatedFileLineInfo);
        if (mapFileName) {
            var match = base64UrlRegExp.exec(mapFileName);
            if (match) {
                if (match[1]) {
                    var base64Object = match[1];
                    return convertDocumentToSourceMapper(host, ts.base64decode(ts.sys, base64Object), generatedFileName);
                }
                // Not a data URL we can parse, skip it
                mapFileName = undefined;
            }
        }
        var possibleMapLocations = [];
        if (mapFileName) {
            possibleMapLocations.push(mapFileName);
        }
        possibleMapLocations.push(generatedFileName + ".map");
        var originalMapFileName = mapFileName && ts.getNormalizedAbsolutePath(mapFileName, ts.getDirectoryPath(generatedFileName));
        for (var _i = 0, possibleMapLocations_1 = possibleMapLocations; _i < possibleMapLocations_1.length; _i++) {
            var location = possibleMapLocations_1[_i];
            var mapFileName_1 = ts.getNormalizedAbsolutePath(location, ts.getDirectoryPath(generatedFileName));
            var mapFileContents = readMapFile(mapFileName_1, originalMapFileName);
            if (ts.isString(mapFileContents)) {
                return convertDocumentToSourceMapper(host, mapFileContents, mapFileName_1);
            }
            if (mapFileContents !== undefined) {
                return mapFileContents || undefined;
            }
        }
        return undefined;
    }
    ts.getDocumentPositionMapper = getDocumentPositionMapper;
    function convertDocumentToSourceMapper(host, contents, mapFileName) {
        var map = ts.tryParseRawSourceMap(contents);
        if (!map || !map.sources || !map.file || !map.mappings) {
            // obviously invalid map
            return undefined;
        }
        return ts.createDocumentPositionMapper(host, map, mapFileName);
    }
    function createSourceFileLike(text, lineMap) {
        return {
            text: text,
            lineMap: lineMap,
            getLineAndCharacterOfPosition: function (pos) {
                return ts.computeLineAndCharacterOfPosition(ts.getLineStarts(this), pos);
            }
        };
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var visitedNestedConvertibleFunctions = ts.createMap();
    function computeSuggestionDiagnostics(sourceFile, program, cancellationToken) {
        program.getSemanticDiagnostics(sourceFile, cancellationToken);
        var diags = [];
        var checker = program.getTypeChecker();
        if (sourceFile.commonJsModuleIndicator &&
            (ts.programContainsEs6Modules(program) || ts.compilerOptionsIndicateEs6Modules(program.getCompilerOptions())) &&
            containsTopLevelCommonjs(sourceFile)) {
            diags.push(ts.createDiagnosticForNode(getErrorNodeFromCommonJsIndicator(sourceFile.commonJsModuleIndicator), ts.Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module));
        }
        var isJsFile = ts.isSourceFileJS(sourceFile);
        visitedNestedConvertibleFunctions.clear();
        check(sourceFile);
        if (ts.getAllowSyntheticDefaultImports(program.getCompilerOptions())) {
            for (var _i = 0, _a = sourceFile.imports; _i < _a.length; _i++) {
                var moduleSpecifier = _a[_i];
                var importNode = ts.importFromModuleSpecifier(moduleSpecifier);
                var name = importNameForConvertToDefaultImport(importNode);
                if (!name)
                    continue;
                var module = ts.getResolvedModule(sourceFile, moduleSpecifier.text);
                var resolvedFile = module && program.getSourceFile(module.resolvedFileName);
                if (resolvedFile && resolvedFile.externalModuleIndicator && ts.isExportAssignment(resolvedFile.externalModuleIndicator) && resolvedFile.externalModuleIndicator.isExportEquals) {
                    diags.push(ts.createDiagnosticForNode(name, ts.Diagnostics.Import_may_be_converted_to_a_default_import));
                }
            }
        }
        ts.addRange(diags, sourceFile.bindSuggestionDiagnostics);
        ts.addRange(diags, program.getSuggestionDiagnostics(sourceFile, cancellationToken));
        return diags.sort(function (d1, d2) { return d1.start - d2.start; });
        function check(node) {
            if (isJsFile) {
                switch (node.kind) {
                    case 197 /* FunctionExpression */:
                        var decl = ts.getDeclarationOfExpando(node);
                        if (decl) {
                            var symbol_1 = decl.symbol;
                            if (symbol_1 && (symbol_1.exports && symbol_1.exports.size || symbol_1.members && symbol_1.members.size)) {
                                diags.push(ts.createDiagnosticForNode(ts.isVariableDeclaration(node.parent) ? node.parent.name : node, ts.Diagnostics.This_constructor_function_may_be_converted_to_a_class_declaration));
                                break;
                            }
                        }
                    // falls through if no diagnostic was created
                    case 240 /* FunctionDeclaration */:
                        var symbol = node.symbol;
                        if (symbol.members && (symbol.members.size > 0)) {
                            diags.push(ts.createDiagnosticForNode(ts.isVariableDeclaration(node.parent) ? node.parent.name : node, ts.Diagnostics.This_constructor_function_may_be_converted_to_a_class_declaration));
                        }
                        break;
                }
            }
            else {
                if (ts.isVariableStatement(node) &&
                    node.parent === sourceFile &&
                    node.declarationList.flags & 2 /* Const */ &&
                    node.declarationList.declarations.length === 1) {
                    var init = node.declarationList.declarations[0].initializer;
                    if (init && ts.isRequireCall(init, /*checkArgumentIsStringLiteralLike*/ true)) {
                        diags.push(ts.createDiagnosticForNode(init, ts.Diagnostics.require_call_may_be_converted_to_an_import));
                    }
                }
                if (ts.codefix.parameterShouldGetTypeFromJSDoc(node)) {
                    diags.push(ts.createDiagnosticForNode(node.name || node, ts.Diagnostics.JSDoc_types_may_be_moved_to_TypeScript_types));
                }
            }
            if (ts.isFunctionLikeDeclaration(node)) {
                addConvertToAsyncFunctionDiagnostics(node, checker, diags);
            }
            node.forEachChild(check);
        }
    }
    ts.computeSuggestionDiagnostics = computeSuggestionDiagnostics;
    // convertToEs6Module only works on top-level, so don't trigger it if commonjs code only appears in nested scopes.
    function containsTopLevelCommonjs(sourceFile) {
        return sourceFile.statements.some(function (statement) {
            switch (statement.kind) {
                case 220 /* VariableStatement */:
                    return statement.declarationList.declarations.some(function (decl) {
                        return !!decl.initializer && ts.isRequireCall(propertyAccessLeftHandSide(decl.initializer), /*checkArgumentIsStringLiteralLike*/ true);
                    });
                case 222 /* ExpressionStatement */: {
                    var expression = statement.expression;
                    if (!ts.isBinaryExpression(expression))
                        return ts.isRequireCall(expression, /*checkArgumentIsStringLiteralLike*/ true);
                    var kind = ts.getAssignmentDeclarationKind(expression);
                    return kind === 1 /* ExportsProperty */ || kind === 2 /* ModuleExports */;
                }
                default:
                    return false;
            }
        });
    }
    function propertyAccessLeftHandSide(node) {
        return ts.isPropertyAccessExpression(node) ? propertyAccessLeftHandSide(node.expression) : node;
    }
    function importNameForConvertToDefaultImport(node) {
        switch (node.kind) {
            case 250 /* ImportDeclaration */:
                var importClause = node.importClause, moduleSpecifier = node.moduleSpecifier;
                return importClause && !importClause.name && importClause.namedBindings && importClause.namedBindings.kind === 252 /* NamespaceImport */ && ts.isStringLiteral(moduleSpecifier)
                    ? importClause.namedBindings.name
                    : undefined;
            case 249 /* ImportEqualsDeclaration */:
                return node.name;
            default:
                return undefined;
        }
    }
    function addConvertToAsyncFunctionDiagnostics(node, checker, diags) {
        // need to check function before checking map so that deeper levels of nested callbacks are checked
        if (isConvertibleFunction(node, checker) && !visitedNestedConvertibleFunctions.has(getKeyFromNode(node))) {
            diags.push(ts.createDiagnosticForNode(!node.name && ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name) ? node.parent.name : node, ts.Diagnostics.This_may_be_converted_to_an_async_function));
        }
    }
    function isConvertibleFunction(node, checker) {
        return !ts.isAsyncFunction(node) &&
            node.body &&
            ts.isBlock(node.body) &&
            hasReturnStatementWithPromiseHandler(node.body) &&
            returnsPromise(node, checker);
    }
    function returnsPromise(node, checker) {
        var functionType = checker.getTypeAtLocation(node);
        var callSignatures = checker.getSignaturesOfType(functionType, 0 /* Call */);
        var returnType = callSignatures.length ? checker.getReturnTypeOfSignature(callSignatures[0]) : undefined;
        return !!returnType && !!checker.getPromisedTypeOfPromise(returnType);
    }
    function getErrorNodeFromCommonJsIndicator(commonJsModuleIndicator) {
        return ts.isBinaryExpression(commonJsModuleIndicator) ? commonJsModuleIndicator.left : commonJsModuleIndicator;
    }
    function hasReturnStatementWithPromiseHandler(body) {
        return !!ts.forEachReturnStatement(body, isReturnStatementWithFixablePromiseHandler);
    }
    function isReturnStatementWithFixablePromiseHandler(node) {
        return ts.isReturnStatement(node) && !!node.expression && isFixablePromiseHandler(node.expression);
    }
    ts.isReturnStatementWithFixablePromiseHandler = isReturnStatementWithFixablePromiseHandler;
    // Should be kept up to date with transformExpression in convertToAsyncFunction.ts
    function isFixablePromiseHandler(node) {
        // ensure outermost call exists and is a promise handler
        if (!isPromiseHandler(node) || !node.arguments.every(isFixablePromiseArgument)) {
            return false;
        }
        // ensure all chained calls are valid
        var currentNode = node.expression;
        while (isPromiseHandler(currentNode) || ts.isPropertyAccessExpression(currentNode)) {
            if (ts.isCallExpression(currentNode) && !currentNode.arguments.every(isFixablePromiseArgument)) {
                return false;
            }
            currentNode = currentNode.expression;
        }
        return true;
    }
    ts.isFixablePromiseHandler = isFixablePromiseHandler;
    function isPromiseHandler(node) {
        return ts.isCallExpression(node) && (ts.hasPropertyAccessExpressionWithName(node, "then") || ts.hasPropertyAccessExpressionWithName(node, "catch"));
    }
    // should be kept up to date with getTransformationBody in convertToAsyncFunction.ts
    function isFixablePromiseArgument(arg) {
        switch (arg.kind) {
            case 240 /* FunctionDeclaration */:
            case 197 /* FunctionExpression */:
            case 198 /* ArrowFunction */:
                visitedNestedConvertibleFunctions.set(getKeyFromNode(arg), true);
            /* falls through */
            case 97 /* NullKeyword */:
            case 73 /* Identifier */: // identifier includes undefined
                return true;
            default:
                return false;
        }
    }
    function getKeyFromNode(exp) {
        return exp.pos.toString() + ":" + exp.end.toString();
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var SymbolDisplay;
    (function (SymbolDisplay) {
        // TODO(drosen): use contextual SemanticMeaning.
        function getSymbolKind(typeChecker, symbol, location) {
            var result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location);
            if (result !== "" /* unknown */) {
                return result;
            }
            var flags = ts.getCombinedLocalAndExportSymbolFlags(symbol);
            if (flags & 32 /* Class */) {
                return ts.getDeclarationOfKind(symbol, 210 /* ClassExpression */) ?
                    "local class" /* localClassElement */ : "class" /* classElement */;
            }
            if (flags & 384 /* Enum */)
                return "enum" /* enumElement */;
            if (flags & 524288 /* TypeAlias */)
                return "type" /* typeElement */;
            if (flags & 64 /* Interface */)
                return "interface" /* interfaceElement */;
            if (flags & 262144 /* TypeParameter */)
                return "type parameter" /* typeParameterElement */;
            if (flags & 262144 /* TypeParameter */)
                return "type parameter" /* typeParameterElement */;
            if (flags & 8 /* EnumMember */)
                return "enum member" /* enumMemberElement */;
            if (flags & 2097152 /* Alias */)
                return "alias" /* alias */;
            if (flags & 1536 /* Module */)
                return "module" /* moduleElement */;
            return result;
        }
        SymbolDisplay.getSymbolKind = getSymbolKind;
        function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location) {
            var roots = typeChecker.getRootSymbols(symbol);
            // If this is a method from a mapped type, leave as a method so long as it still has a call signature.
            if (roots.length === 1
                && ts.first(roots).flags & 8192 /* Method */
                // Ensure the mapped version is still a method, as opposed to `{ [K in keyof I]: number }`.
                && typeChecker.getTypeOfSymbolAtLocation(symbol, location).getNonNullableType().getCallSignatures().length !== 0) {
                return "method" /* memberFunctionElement */;
            }
            if (typeChecker.isUndefinedSymbol(symbol)) {
                return "var" /* variableElement */;
            }
            if (typeChecker.isArgumentsSymbol(symbol)) {
                return "local var" /* localVariableElement */;
            }
            if (location.kind === 101 /* ThisKeyword */ && ts.isExpression(location)) {
                return "parameter" /* parameterElement */;
            }
            var flags = ts.getCombinedLocalAndExportSymbolFlags(symbol);
            if (flags & 3 /* Variable */) {
                if (ts.isFirstDeclarationOfSymbolParameter(symbol)) {
                    return "parameter" /* parameterElement */;
                }
                else if (symbol.valueDeclaration && ts.isVarConst(symbol.valueDeclaration)) {
                    return "const" /* constElement */;
                }
                else if (ts.forEach(symbol.declarations, ts.isLet)) {
                    return "let" /* letElement */;
                }
                return isLocalVariableOrFunction(symbol) ? "local var" /* localVariableElement */ : "var" /* variableElement */;
            }
            if (flags & 16 /* Function */)
                return isLocalVariableOrFunction(symbol) ? "local function" /* localFunctionElement */ : "function" /* functionElement */;
            if (flags & 32768 /* GetAccessor */)
                return "getter" /* memberGetAccessorElement */;
            if (flags & 65536 /* SetAccessor */)
                return "setter" /* memberSetAccessorElement */;
            if (flags & 8192 /* Method */)
                return "method" /* memberFunctionElement */;
            if (flags & 16384 /* Constructor */)
                return "constructor" /* constructorImplementationElement */;
            if (flags & 4 /* Property */) {
                if (flags & 33554432 /* Transient */ && symbol.checkFlags & 6 /* Synthetic */) {
                    // If union property is result of union of non method (property/accessors/variables), it is labeled as property
                    var unionPropertyKind = ts.forEach(typeChecker.getRootSymbols(symbol), function (rootSymbol) {
                        var rootSymbolFlags = rootSymbol.getFlags();
                        if (rootSymbolFlags & (98308 /* PropertyOrAccessor */ | 3 /* Variable */)) {
                            return "property" /* memberVariableElement */;
                        }
                        // May be a Function if this was from `typeof N` with `namespace N { function f();. }`.
                        ts.Debug.assert(!!(rootSymbolFlags & (8192 /* Method */ | 16 /* Function */)));
                    });
                    if (!unionPropertyKind) {
                        // If this was union of all methods,
                        // make sure it has call signatures before we can label it as method
                        var typeOfUnionProperty = typeChecker.getTypeOfSymbolAtLocation(symbol, location);
                        if (typeOfUnionProperty.getCallSignatures().length) {
                            return "method" /* memberFunctionElement */;
                        }
                        return "property" /* memberVariableElement */;
                    }
                    return unionPropertyKind;
                }
                // If we requested completions after `x.` at the top-level, we may be at a source file location.
                switch (location.parent && location.parent.kind) {
                    // If we've typed a character of the attribute name, will be 'JsxAttribute', else will be 'JsxOpeningElement'.
                    case 263 /* JsxOpeningElement */:
                    case 261 /* JsxElement */:
                    case 262 /* JsxSelfClosingElement */:
                        return location.kind === 73 /* Identifier */ ? "property" /* memberVariableElement */ : "JSX attribute" /* jsxAttribute */;
                    case 268 /* JsxAttribute */:
                        return "JSX attribute" /* jsxAttribute */;
                    default:
                        return "property" /* memberVariableElement */;
                }
            }
            return "" /* unknown */;
        }
        function getSymbolModifiers(symbol) {
            var nodeModifiers = symbol && symbol.declarations && symbol.declarations.length > 0
                ? ts.getNodeModifiers(symbol.declarations[0])
                : "" /* none */;
            var symbolModifiers = symbol && symbol.flags & 16777216 /* Optional */ ?
                "optional" /* optionalModifier */
                : "" /* none */;
            return nodeModifiers && symbolModifiers ? nodeModifiers + "," + symbolModifiers : nodeModifiers || symbolModifiers;
        }
        SymbolDisplay.getSymbolModifiers = getSymbolModifiers;
        // TODO(drosen): Currently completion entry details passes the SemanticMeaning.All instead of using semanticMeaning of location
        function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, enclosingDeclaration, location, semanticMeaning, alias) {
            if (semanticMeaning === void 0) { semanticMeaning = ts.getMeaningFromLocation(location); }
            var displayParts = [];
            var documentation;
            var tags;
            var symbolFlags = ts.getCombinedLocalAndExportSymbolFlags(symbol);
            var symbolKind = semanticMeaning & 1 /* Value */ ? getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location) : "" /* unknown */;
            var hasAddedSymbolInfo = false;
            var isThisExpression = location.kind === 101 /* ThisKeyword */ && ts.isInExpressionContext(location);
            var type;
            var printer;
            var documentationFromAlias;
            var tagsFromAlias;
            if (location.kind === 101 /* ThisKeyword */ && !isThisExpression) {
                return { displayParts: [ts.keywordPart(101 /* ThisKeyword */)], documentation: [], symbolKind: "primitive type" /* primitiveType */, tags: undefined };
            }
            // Class at constructor site need to be shown as constructor apart from property,method, vars
            if (symbolKind !== "" /* unknown */ || symbolFlags & 32 /* Class */ || symbolFlags & 2097152 /* Alias */) {
                // If it is accessor they are allowed only if location is at name of the accessor
                if (symbolKind === "getter" /* memberGetAccessorElement */ || symbolKind === "setter" /* memberSetAccessorElement */) {
                    symbolKind = "property" /* memberVariableElement */;
                }
                var signature = void 0;
                type = isThisExpression ? typeChecker.getTypeAtLocation(location) : typeChecker.getTypeOfSymbolAtLocation(symbol.exportSymbol || symbol, location);
                if (location.parent && location.parent.kind === 190 /* PropertyAccessExpression */) {
                    var right = location.parent.name;
                    // Either the location is on the right of a property access, or on the left and the right is missing
                    if (right === location || (right && right.getFullWidth() === 0)) {
                        location = location.parent;
                    }
                }
                // try get the call/construct signature from the type if it matches
                var callExpressionLike = void 0;
                if (ts.isCallOrNewExpression(location)) {
                    callExpressionLike = location;
                }
                else if (ts.isCallExpressionTarget(location) || ts.isNewExpressionTarget(location)) {
                    callExpressionLike = location.parent;
                }
                else if (location.parent && ts.isJsxOpeningLikeElement(location.parent) && ts.isFunctionLike(symbol.valueDeclaration)) {
                    callExpressionLike = location.parent;
                }
                if (callExpressionLike) {
                    signature = typeChecker.getResolvedSignature(callExpressionLike); // TODO: GH#18217
                    var useConstructSignatures = callExpressionLike.kind === 193 /* NewExpression */ || (ts.isCallExpression(callExpressionLike) && callExpressionLike.expression.kind === 99 /* SuperKeyword */);
                    var allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures();
                    if (!ts.contains(allSignatures, signature.target) && !ts.contains(allSignatures, signature)) {
                        // Get the first signature if there is one -- allSignatures may contain
                        // either the original signature or its target, so check for either
                        signature = allSignatures.length ? allSignatures[0] : undefined;
                    }
                    if (signature) {
                        if (useConstructSignatures && (symbolFlags & 32 /* Class */)) {
                            // Constructor
                            symbolKind = "constructor" /* constructorImplementationElement */;
                            addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
                        }
                        else if (symbolFlags & 2097152 /* Alias */) {
                            symbolKind = "alias" /* alias */;
                            pushSymbolKind(symbolKind);
                            displayParts.push(ts.spacePart());
                            if (useConstructSignatures) {
                                displayParts.push(ts.keywordPart(96 /* NewKeyword */));
                                displayParts.push(ts.spacePart());
                            }
                            addFullSymbolName(symbol);
                        }
                        else {
                            addPrefixForAnyFunctionOrVar(symbol, symbolKind);
                        }
                        switch (symbolKind) {
                            case "JSX attribute" /* jsxAttribute */:
                            case "property" /* memberVariableElement */:
                            case "var" /* variableElement */:
                            case "const" /* constElement */:
                            case "let" /* letElement */:
                            case "parameter" /* parameterElement */:
                            case "local var" /* localVariableElement */:
                                // If it is call or construct signature of lambda's write type name
                                displayParts.push(ts.punctuationPart(57 /* ColonToken */));
                                displayParts.push(ts.spacePart());
                                if (!(ts.getObjectFlags(type) & 16 /* Anonymous */) && type.symbol) {
                                    ts.addRange(displayParts, ts.symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, 4 /* AllowAnyNodeKind */ | 1 /* WriteTypeParametersOrArguments */));
                                    displayParts.push(ts.lineBreakPart());
                                }
                                if (useConstructSignatures) {
                                    displayParts.push(ts.keywordPart(96 /* NewKeyword */));
                                    displayParts.push(ts.spacePart());
                                }
                                addSignatureDisplayParts(signature, allSignatures, 262144 /* WriteArrowStyleSignature */);
                                break;
                            default:
                                // Just signature
                                addSignatureDisplayParts(signature, allSignatures);
                        }
                        hasAddedSymbolInfo = true;
                    }
                }
                else if ((ts.isNameOfFunctionDeclaration(location) && !(symbolFlags & 98304 /* Accessor */)) || // name of function declaration
                    (location.kind === 125 /* ConstructorKeyword */ && location.parent.kind === 158 /* Constructor */)) { // At constructor keyword of constructor declaration
                    // get the signature from the declaration and write it
                    var functionDeclaration_1 = location.parent;
                    // Use function declaration to write the signatures only if the symbol corresponding to this declaration
                    var locationIsSymbolDeclaration = ts.find(symbol.declarations, function (declaration) {
                        return declaration === (location.kind === 125 /* ConstructorKeyword */ ? functionDeclaration_1.parent : functionDeclaration_1);
                    });
                    if (locationIsSymbolDeclaration) {
                        var allSignatures = functionDeclaration_1.kind === 158 /* Constructor */ ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures();
                        if (!typeChecker.isImplementationOfOverload(functionDeclaration_1)) {
                            signature = typeChecker.getSignatureFromDeclaration(functionDeclaration_1); // TODO: GH#18217
                        }
                        else {
                            signature = allSignatures[0];
                        }
                        if (functionDeclaration_1.kind === 158 /* Constructor */) {
                            // show (constructor) Type(...) signature
                            symbolKind = "constructor" /* constructorImplementationElement */;
                            addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
                        }
                        else {
                            // (function/method) symbol(..signature)
                            addPrefixForAnyFunctionOrVar(functionDeclaration_1.kind === 161 /* CallSignature */ &&
                                !(type.symbol.flags & 2048 /* TypeLiteral */ || type.symbol.flags & 4096 /* ObjectLiteral */) ? type.symbol : symbol, symbolKind);
                        }
                        addSignatureDisplayParts(signature, allSignatures);
                        hasAddedSymbolInfo = true;
                    }
                }
            }
            if (symbolFlags & 32 /* Class */ && !hasAddedSymbolInfo && !isThisExpression) {
                addAliasPrefixIfNecessary();
                if (ts.getDeclarationOfKind(symbol, 210 /* ClassExpression */)) {
                    // Special case for class expressions because we would like to indicate that
                    // the class name is local to the class body (similar to function expression)
                    //      (local class) class <className>
                    pushSymbolKind("local class" /* localClassElement */);
                }
                else {
                    // Class declaration has name which is not local.
                    displayParts.push(ts.keywordPart(77 /* ClassKeyword */));
                }
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                writeTypeParametersOfSymbol(symbol, sourceFile);
            }
            if ((symbolFlags & 64 /* Interface */) && (semanticMeaning & 2 /* Type */)) {
                prefixNextMeaning();
                displayParts.push(ts.keywordPart(111 /* InterfaceKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                writeTypeParametersOfSymbol(symbol, sourceFile);
            }
            if ((symbolFlags & 524288 /* TypeAlias */) && (semanticMeaning & 2 /* Type */)) {
                prefixNextMeaning();
                displayParts.push(ts.keywordPart(141 /* TypeKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                writeTypeParametersOfSymbol(symbol, sourceFile);
                displayParts.push(ts.spacePart());
                displayParts.push(ts.operatorPart(60 /* EqualsToken */));
                displayParts.push(ts.spacePart());
                ts.addRange(displayParts, ts.typeToDisplayParts(typeChecker, typeChecker.getDeclaredTypeOfSymbol(symbol), enclosingDeclaration, 8388608 /* InTypeAlias */));
            }
            if (symbolFlags & 384 /* Enum */) {
                prefixNextMeaning();
                if (ts.some(symbol.declarations, function (d) { return ts.isEnumDeclaration(d) && ts.isEnumConst(d); })) {
                    displayParts.push(ts.keywordPart(78 /* ConstKeyword */));
                    displayParts.push(ts.spacePart());
                }
                displayParts.push(ts.keywordPart(85 /* EnumKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
            }
            if (symbolFlags & 1536 /* Module */ && !isThisExpression) {
                prefixNextMeaning();
                var declaration = ts.getDeclarationOfKind(symbol, 245 /* ModuleDeclaration */);
                var isNamespace = declaration && declaration.name && declaration.name.kind === 73 /* Identifier */;
                displayParts.push(ts.keywordPart(isNamespace ? 132 /* NamespaceKeyword */ : 131 /* ModuleKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
            }
            if ((symbolFlags & 262144 /* TypeParameter */) && (semanticMeaning & 2 /* Type */)) {
                prefixNextMeaning();
                displayParts.push(ts.punctuationPart(20 /* OpenParenToken */));
                displayParts.push(ts.textPart("type parameter"));
                displayParts.push(ts.punctuationPart(21 /* CloseParenToken */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                if (symbol.parent) {
                    // Class/Interface type parameter
                    addInPrefix();
                    addFullSymbolName(symbol.parent, enclosingDeclaration);
                    writeTypeParametersOfSymbol(symbol.parent, enclosingDeclaration);
                }
                else {
                    // Method/function type parameter
                    var decl = ts.getDeclarationOfKind(symbol, 151 /* TypeParameter */);
                    if (decl === undefined)
                        return ts.Debug.fail();
                    var declaration = decl.parent;
                    if (declaration) {
                        if (ts.isFunctionLikeKind(declaration.kind)) {
                            addInPrefix();
                            var signature = typeChecker.getSignatureFromDeclaration(declaration); // TODO: GH#18217
                            if (declaration.kind === 162 /* ConstructSignature */) {
                                displayParts.push(ts.keywordPart(96 /* NewKeyword */));
                                displayParts.push(ts.spacePart());
                            }
                            else if (declaration.kind !== 161 /* CallSignature */ && declaration.name) {
                                addFullSymbolName(declaration.symbol);
                            }
                            ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32 /* WriteTypeArgumentsOfSignature */));
                        }
                        else if (declaration.kind === 243 /* TypeAliasDeclaration */) {
                            // Type alias type parameter
                            // For example
                            //      type list<T> = T[]; // Both T will go through same code path
                            addInPrefix();
                            displayParts.push(ts.keywordPart(141 /* TypeKeyword */));
                            displayParts.push(ts.spacePart());
                            addFullSymbolName(declaration.symbol);
                            writeTypeParametersOfSymbol(declaration.symbol, sourceFile);
                        }
                    }
                }
            }
            if (symbolFlags & 8 /* EnumMember */) {
                symbolKind = "enum member" /* enumMemberElement */;
                addPrefixForAnyFunctionOrVar(symbol, "enum member");
                var declaration = symbol.declarations[0];
                if (declaration.kind === 279 /* EnumMember */) {
                    var constantValue = typeChecker.getConstantValue(declaration);
                    if (constantValue !== undefined) {
                        displayParts.push(ts.spacePart());
                        displayParts.push(ts.operatorPart(60 /* EqualsToken */));
                        displayParts.push(ts.spacePart());
                        displayParts.push(ts.displayPart(ts.getTextOfConstantValue(constantValue), typeof constantValue === "number" ? ts.SymbolDisplayPartKind.numericLiteral : ts.SymbolDisplayPartKind.stringLiteral));
                    }
                }
            }
            if (symbolFlags & 2097152 /* Alias */) {
                prefixNextMeaning();
                if (!hasAddedSymbolInfo) {
                    var resolvedSymbol = typeChecker.getAliasedSymbol(symbol);
                    if (resolvedSymbol !== symbol && resolvedSymbol.declarations && resolvedSymbol.declarations.length > 0) {
                        var resolvedNode = resolvedSymbol.declarations[0];
                        var declarationName = ts.getNameOfDeclaration(resolvedNode);
                        if (declarationName) {
                            var isExternalModuleDeclaration = ts.isModuleWithStringLiteralName(resolvedNode) &&
                                ts.hasModifier(resolvedNode, 2 /* Ambient */);
                            var shouldUseAliasName = symbol.name !== "default" && !isExternalModuleDeclaration;
                            var resolvedInfo = getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, resolvedSymbol, ts.getSourceFileOfNode(resolvedNode), resolvedNode, declarationName, semanticMeaning, shouldUseAliasName ? symbol : resolvedSymbol);
                            displayParts.push.apply(displayParts, resolvedInfo.displayParts);
                            displayParts.push(ts.lineBreakPart());
                            documentationFromAlias = resolvedInfo.documentation;
                            tagsFromAlias = resolvedInfo.tags;
                        }
                    }
                }
                switch (symbol.declarations[0].kind) {
                    case 248 /* NamespaceExportDeclaration */:
                        displayParts.push(ts.keywordPart(86 /* ExportKeyword */));
                        displayParts.push(ts.spacePart());
                        displayParts.push(ts.keywordPart(132 /* NamespaceKeyword */));
                        break;
                    case 255 /* ExportAssignment */:
                        displayParts.push(ts.keywordPart(86 /* ExportKeyword */));
                        displayParts.push(ts.spacePart());
                        displayParts.push(ts.keywordPart(symbol.declarations[0].isExportEquals ? 60 /* EqualsToken */ : 81 /* DefaultKeyword */));
                        break;
                    case 258 /* ExportSpecifier */:
                        displayParts.push(ts.keywordPart(86 /* ExportKeyword */));
                        break;
                    default:
                        displayParts.push(ts.keywordPart(93 /* ImportKeyword */));
                }
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                ts.forEach(symbol.declarations, function (declaration) {
                    if (declaration.kind === 249 /* ImportEqualsDeclaration */) {
                        var importEqualsDeclaration = declaration;
                        if (ts.isExternalModuleImportEqualsDeclaration(importEqualsDeclaration)) {
                            displayParts.push(ts.spacePart());
                            displayParts.push(ts.operatorPart(60 /* EqualsToken */));
                            displayParts.push(ts.spacePart());
                            displayParts.push(ts.keywordPart(135 /* RequireKeyword */));
                            displayParts.push(ts.punctuationPart(20 /* OpenParenToken */));
                            displayParts.push(ts.displayPart(ts.getTextOfNode(ts.getExternalModuleImportEqualsDeclarationExpression(importEqualsDeclaration)), ts.SymbolDisplayPartKind.stringLiteral));
                            displayParts.push(ts.punctuationPart(21 /* CloseParenToken */));
                        }
                        else {
                            var internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference);
                            if (internalAliasSymbol) {
                                displayParts.push(ts.spacePart());
                                displayParts.push(ts.operatorPart(60 /* EqualsToken */));
                                displayParts.push(ts.spacePart());
                                addFullSymbolName(internalAliasSymbol, enclosingDeclaration);
                            }
                        }
                        return true;
                    }
                });
            }
            if (!hasAddedSymbolInfo) {
                if (symbolKind !== "" /* unknown */) {
                    if (type) {
                        if (isThisExpression) {
                            prefixNextMeaning();
                            displayParts.push(ts.keywordPart(101 /* ThisKeyword */));
                        }
                        else {
                            addPrefixForAnyFunctionOrVar(symbol, symbolKind);
                        }
                        // For properties, variables and local vars: show the type
                        if (symbolKind === "property" /* memberVariableElement */ ||
                            symbolKind === "JSX attribute" /* jsxAttribute */ ||
                            symbolFlags & 3 /* Variable */ ||
                            symbolKind === "local var" /* localVariableElement */ ||
                            isThisExpression) {
                            displayParts.push(ts.punctuationPart(57 /* ColonToken */));
                            displayParts.push(ts.spacePart());
                            // If the type is type parameter, format it specially
                            if (type.symbol && type.symbol.flags & 262144 /* TypeParameter */) {
                                var typeParameterParts = ts.mapToDisplayParts(function (writer) {
                                    var param = typeChecker.typeParameterToDeclaration(type, enclosingDeclaration);
                                    getPrinter().writeNode(4 /* Unspecified */, param, ts.getSourceFileOfNode(ts.getParseTreeNode(enclosingDeclaration)), writer);
                                });
                                ts.addRange(displayParts, typeParameterParts);
                            }
                            else {
                                ts.addRange(displayParts, ts.typeToDisplayParts(typeChecker, type, enclosingDeclaration));
                            }
                        }
                        else if (symbolFlags & 16 /* Function */ ||
                            symbolFlags & 8192 /* Method */ ||
                            symbolFlags & 16384 /* Constructor */ ||
                            symbolFlags & 131072 /* Signature */ ||
                            symbolFlags & 98304 /* Accessor */ ||
                            symbolKind === "method" /* memberFunctionElement */) {
                            var allSignatures = type.getNonNullableType().getCallSignatures();
                            if (allSignatures.length) {
                                addSignatureDisplayParts(allSignatures[0], allSignatures);
                            }
                        }
                    }
                }
                else {
                    symbolKind = getSymbolKind(typeChecker, symbol, location);
                }
            }
            if (!documentation) {
                documentation = symbol.getDocumentationComment(typeChecker);
                tags = symbol.getJsDocTags();
                if (documentation.length === 0 && symbolFlags & 4 /* Property */) {
                    // For some special property access expressions like `exports.foo = foo` or `module.exports.foo = foo`
                    // there documentation comments might be attached to the right hand side symbol of their declarations.
                    // The pattern of such special property access is that the parent symbol is the symbol of the file.
                    if (symbol.parent && ts.forEach(symbol.parent.declarations, function (declaration) { return declaration.kind === 285 /* SourceFile */; })) {
                        for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                            var declaration = _a[_i];
                            if (!declaration.parent || declaration.parent.kind !== 205 /* BinaryExpression */) {
                                continue;
                            }
                            var rhsSymbol = typeChecker.getSymbolAtLocation(declaration.parent.right);
                            if (!rhsSymbol) {
                                continue;
                            }
                            documentation = rhsSymbol.getDocumentationComment(typeChecker);
                            tags = rhsSymbol.getJsDocTags();
                            if (documentation.length > 0) {
                                break;
                            }
                        }
                    }
                }
            }
            if (documentation.length === 0 && documentationFromAlias) {
                documentation = documentationFromAlias;
            }
            if (tags.length === 0 && tagsFromAlias) {
                tags = tagsFromAlias;
            }
            return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind, tags: tags.length === 0 ? undefined : tags };
            function getPrinter() {
                if (!printer) {
                    printer = ts.createPrinter({ removeComments: true });
                }
                return printer;
            }
            function prefixNextMeaning() {
                if (displayParts.length) {
                    displayParts.push(ts.lineBreakPart());
                }
                addAliasPrefixIfNecessary();
            }
            function addAliasPrefixIfNecessary() {
                if (alias) {
                    pushSymbolKind("alias" /* alias */);
                    displayParts.push(ts.spacePart());
                }
            }
            function addInPrefix() {
                displayParts.push(ts.spacePart());
                displayParts.push(ts.keywordPart(94 /* InKeyword */));
                displayParts.push(ts.spacePart());
            }
            function addFullSymbolName(symbolToDisplay, enclosingDeclaration) {
                if (alias && symbolToDisplay === symbol) {
                    symbolToDisplay = alias;
                }
                var fullSymbolDisplayParts = ts.symbolToDisplayParts(typeChecker, symbolToDisplay, enclosingDeclaration || sourceFile, /*meaning*/ undefined, 1 /* WriteTypeParametersOrArguments */ | 2 /* UseOnlyExternalAliasing */ | 4 /* AllowAnyNodeKind */);
                ts.addRange(displayParts, fullSymbolDisplayParts);
                if (symbol.flags & 16777216 /* Optional */) {
                    displayParts.push(ts.punctuationPart(56 /* QuestionToken */));
                }
            }
            function addPrefixForAnyFunctionOrVar(symbol, symbolKind) {
                prefixNextMeaning();
                if (symbolKind) {
                    pushSymbolKind(symbolKind);
                    if (symbol && !ts.some(symbol.declarations, function (d) { return ts.isArrowFunction(d) || (ts.isFunctionExpression(d) || ts.isClassExpression(d)) && !d.name; })) {
                        displayParts.push(ts.spacePart());
                        addFullSymbolName(symbol);
                    }
                }
            }
            function pushSymbolKind(symbolKind) {
                switch (symbolKind) {
                    case "var" /* variableElement */:
                    case "function" /* functionElement */:
                    case "let" /* letElement */:
                    case "const" /* constElement */:
                    case "constructor" /* constructorImplementationElement */:
                        displayParts.push(ts.textOrKeywordPart(symbolKind));
                        return;
                    default:
                        displayParts.push(ts.punctuationPart(20 /* OpenParenToken */));
                        displayParts.push(ts.textOrKeywordPart(symbolKind));
                        displayParts.push(ts.punctuationPart(21 /* CloseParenToken */));
                        return;
                }
            }
            function addSignatureDisplayParts(signature, allSignatures, flags) {
                if (flags === void 0) { flags = 0 /* None */; }
                ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, enclosingDeclaration, flags | 32 /* WriteTypeArgumentsOfSignature */));
                if (allSignatures.length > 1) {
                    displayParts.push(ts.spacePart());
                    displayParts.push(ts.punctuationPart(20 /* OpenParenToken */));
                    displayParts.push(ts.operatorPart(38 /* PlusToken */));
                    displayParts.push(ts.displayPart((allSignatures.length - 1).toString(), ts.SymbolDisplayPartKind.numericLiteral));
                    displayParts.push(ts.spacePart());
                    displayParts.push(ts.textPart(allSignatures.length === 2 ? "overload" : "overloads"));
                    displayParts.push(ts.punctuationPart(21 /* CloseParenToken */));
                }
                var docComment = signature.getDocumentationComment(typeChecker);
                documentation = docComment.length === 0 ? undefined : docComment;
                tags = signature.getJsDocTags();
            }
            function writeTypeParametersOfSymbol(symbol, enclosingDeclaration) {
                var typeParameterParts = ts.mapToDisplayParts(function (writer) {
                    var params = typeChecker.symbolToTypeParameterDeclarations(symbol, enclosingDeclaration);
                    getPrinter().writeList(53776 /* TypeParameters */, params, ts.getSourceFileOfNode(ts.getParseTreeNode(enclosingDeclaration)), writer);
                });
                ts.addRange(displayParts, typeParameterParts);
            }
        }
        SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind = getSymbolDisplayPartsDocumentationAndSymbolKind;
        function isLocalVariableOrFunction(symbol) {
            if (symbol.parent) {
                return false; // This is exported symbol
            }
            return ts.forEach(symbol.declarations, function (declaration) {
                // Function expressions are local
                if (declaration.kind === 197 /* FunctionExpression */) {
                    return true;
                }
                if (declaration.kind !== 238 /* VariableDeclaration */ && declaration.kind !== 240 /* FunctionDeclaration */) {
                    return false;
                }
                // If the parent is not sourceFile or module block it is local variable
                for (var parent = declaration.parent; !ts.isFunctionBlock(parent); parent = parent.parent) {
                    // Reached source file or module block
                    if (parent.kind === 285 /* SourceFile */ || parent.kind === 246 /* ModuleBlock */) {
                        return false;
                    }
                }
                // parent is in function block
                return true;
            });
        }
    })(SymbolDisplay = ts.SymbolDisplay || (ts.SymbolDisplay = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    /*
     * This function will compile source text from 'input' argument using specified compiler options.
     * If not options are provided - it will use a set of default compiler options.
     * Extra compiler options that will unconditionally be used by this function are:
     * - isolatedModules = true
     * - allowNonTsExtensions = true
     * - noLib = true
     * - noResolve = true
     */
    function transpileModule(input, transpileOptions) {
        var diagnostics = [];
        var options = transpileOptions.compilerOptions ? fixupCompilerOptions(transpileOptions.compilerOptions, diagnostics) : ts.getDefaultCompilerOptions();
        options.isolatedModules = true;
        // transpileModule does not write anything to disk so there is no need to verify that there are no conflicts between input and output paths.
        options.suppressOutputPathCheck = true;
        // Filename can be non-ts file.
        options.allowNonTsExtensions = true;
        // We are not returning a sourceFile for lib file when asked by the program,
        // so pass --noLib to avoid reporting a file not found error.
        options.noLib = true;
        // Clear out other settings that would not be used in transpiling this module
        options.lib = undefined;
        options.types = undefined;
        options.noEmit = undefined;
        options.noEmitOnError = undefined;
        options.paths = undefined;
        options.rootDirs = undefined;
        options.declaration = undefined;
        options.composite = undefined;
        options.declarationDir = undefined;
        options.out = undefined;
        options.outFile = undefined;
        // We are not doing a full typecheck, we are not resolving the whole context,
        // so pass --noResolve to avoid reporting missing file errors.
        options.noResolve = true;
        // if jsx is specified then treat file as .tsx
        var inputFileName = transpileOptions.fileName || (options.jsx ? "module.tsx" : "module.ts");
        var sourceFile = ts.createSourceFile(inputFileName, input, options.target); // TODO: GH#18217
        if (transpileOptions.moduleName) {
            sourceFile.moduleName = transpileOptions.moduleName;
        }
        if (transpileOptions.renamedDependencies) {
            sourceFile.renamedDependencies = ts.createMapFromTemplate(transpileOptions.renamedDependencies);
        }
        var newLine = ts.getNewLineCharacter(options);
        // Output
        var outputText;
        var sourceMapText;
        // Create a compilerHost object to allow the compiler to read and write files
        var compilerHost = {
            getSourceFile: function (fileName) { return fileName === ts.normalizePath(inputFileName) ? sourceFile : undefined; },
            writeFile: function (name, text) {
                if (ts.fileExtensionIs(name, ".map")) {
                    ts.Debug.assertEqual(sourceMapText, undefined, "Unexpected multiple source map outputs, file:", name);
                    sourceMapText = text;
                }
                else {
                    ts.Debug.assertEqual(outputText, undefined, "Unexpected multiple outputs, file:", name);
                    outputText = text;
                }
            },
            getDefaultLibFileName: function () { return "lib.d.ts"; },
            useCaseSensitiveFileNames: function () { return false; },
            getCanonicalFileName: function (fileName) { return fileName; },
            getCurrentDirectory: function () { return ""; },
            getNewLine: function () { return newLine; },
            fileExists: function (fileName) { return fileName === inputFileName; },
            readFile: function () { return ""; },
            directoryExists: function () { return true; },
            getDirectories: function () { return []; }
        };
        var program = ts.createProgram([inputFileName], options, compilerHost);
        if (transpileOptions.reportDiagnostics) {
            ts.addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile));
            ts.addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics());
        }
        // Emit
        program.emit(/*targetSourceFile*/ undefined, /*writeFile*/ undefined, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ undefined, transpileOptions.transformers);
        if (outputText === undefined)
            return ts.Debug.fail("Output generation failed");
        return { outputText: outputText, diagnostics: diagnostics, sourceMapText: sourceMapText };
    }
    ts.transpileModule = transpileModule;
    /*
     * This is a shortcut function for transpileModule - it accepts transpileOptions as parameters and returns only outputText part of the result.
     */
    function transpile(input, compilerOptions, fileName, diagnostics, moduleName) {
        var output = transpileModule(input, { compilerOptions: compilerOptions, fileName: fileName, reportDiagnostics: !!diagnostics, moduleName: moduleName });
        // addRange correctly handles cases when wither 'from' or 'to' argument is missing
        ts.addRange(diagnostics, output.diagnostics);
        return output.outputText;
    }
    ts.transpile = transpile;
    var commandLineOptionsStringToEnum;
    /** JS users may pass in string values for enum compiler options (such as ModuleKind), so convert. */
    /*@internal*/
    function fixupCompilerOptions(options, diagnostics) {
        // Lazily create this value to fix module loading errors.
        commandLineOptionsStringToEnum = commandLineOptionsStringToEnum || ts.filter(ts.optionDeclarations, function (o) {
            return typeof o.type === "object" && !ts.forEachEntry(o.type, function (v) { return typeof v !== "number"; });
        });
        options = ts.cloneCompilerOptions(options);
        var _loop_8 = function (opt) {
            if (!ts.hasProperty(options, opt.name)) {
                return "continue";
            }
            var value = options[opt.name];
            // Value should be a key of opt.type
            if (ts.isString(value)) {
                // If value is not a string, this will fail
                options[opt.name] = ts.parseCustomTypeOption(opt, value, diagnostics);
            }
            else {
                if (!ts.forEachEntry(opt.type, function (v) { return v === value; })) {
                    // Supplied value isn't a valid enum value.
                    diagnostics.push(ts.createCompilerDiagnosticForInvalidCustomType(opt));
                }
            }
        };
        for (var _i = 0, commandLineOptionsStringToEnum_1 = commandLineOptionsStringToEnum; _i < commandLineOptionsStringToEnum_1.length; _i++) {
            var opt = commandLineOptionsStringToEnum_1[_i];
            _loop_8(opt);
        }
        return options;
    }
    ts.fixupCompilerOptions = fixupCompilerOptions;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var FormattingRequestKind;
        (function (FormattingRequestKind) {
            FormattingRequestKind[FormattingRequestKind["FormatDocument"] = 0] = "FormatDocument";
            FormattingRequestKind[FormattingRequestKind["FormatSelection"] = 1] = "FormatSelection";
            FormattingRequestKind[FormattingRequestKind["FormatOnEnter"] = 2] = "FormatOnEnter";
            FormattingRequestKind[FormattingRequestKind["FormatOnSemicolon"] = 3] = "FormatOnSemicolon";
            FormattingRequestKind[FormattingRequestKind["FormatOnOpeningCurlyBrace"] = 4] = "FormatOnOpeningCurlyBrace";
            FormattingRequestKind[FormattingRequestKind["FormatOnClosingCurlyBrace"] = 5] = "FormatOnClosingCurlyBrace";
        })(FormattingRequestKind = formatting.FormattingRequestKind || (formatting.FormattingRequestKind = {}));
        var FormattingContext = /** @class */ (function () {
            function FormattingContext(sourceFile, formattingRequestKind, options) {
                this.sourceFile = sourceFile;
                this.formattingRequestKind = formattingRequestKind;
                this.options = options;
            }
            FormattingContext.prototype.updateContext = function (currentRange, currentTokenParent, nextRange, nextTokenParent, commonParent) {
                this.currentTokenSpan = ts.Debug.assertDefined(currentRange);
                this.currentTokenParent = ts.Debug.assertDefined(currentTokenParent);
                this.nextTokenSpan = ts.Debug.assertDefined(nextRange);
                this.nextTokenParent = ts.Debug.assertDefined(nextTokenParent);
                this.contextNode = ts.Debug.assertDefined(commonParent);
                // drop cached results
                this.contextNodeAllOnSameLine = undefined;
                this.nextNodeAllOnSameLine = undefined;
                this.tokensAreOnSameLine = undefined;
                this.contextNodeBlockIsOnOneLine = undefined;
                this.nextNodeBlockIsOnOneLine = undefined;
            };
            FormattingContext.prototype.ContextNodeAllOnSameLine = function () {
                if (this.contextNodeAllOnSameLine === undefined) {
                    this.contextNodeAllOnSameLine = this.NodeIsOnOneLine(this.contextNode);
                }
                return this.contextNodeAllOnSameLine;
            };
            FormattingContext.prototype.NextNodeAllOnSameLine = function () {
                if (this.nextNodeAllOnSameLine === undefined) {
                    this.nextNodeAllOnSameLine = this.NodeIsOnOneLine(this.nextTokenParent);
                }
                return this.nextNodeAllOnSameLine;
            };
            FormattingContext.prototype.TokensAreOnSameLine = function () {
                if (this.tokensAreOnSameLine === undefined) {
                    var startLine = this.sourceFile.getLineAndCharacterOfPosition(this.currentTokenSpan.pos).line;
                    var endLine = this.sourceFile.getLineAndCharacterOfPosition(this.nextTokenSpan.pos).line;
                    this.tokensAreOnSameLine = (startLine === endLine);
                }
                return this.tokensAreOnSameLine;
            };
            FormattingContext.prototype.ContextNodeBlockIsOnOneLine = function () {
                if (this.contextNodeBlockIsOnOneLine === undefined) {
                    this.contextNodeBlockIsOnOneLine = this.BlockIsOnOneLine(this.contextNode);
                }
                return this.contextNodeBlockIsOnOneLine;
            };
            FormattingContext.prototype.NextNodeBlockIsOnOneLine = function () {
                if (this.nextNodeBlockIsOnOneLine === undefined) {
                    this.nextNodeBlockIsOnOneLine = this.BlockIsOnOneLine(this.nextTokenParent);
                }
                return this.nextNodeBlockIsOnOneLine;
            };
            FormattingContext.prototype.NodeIsOnOneLine = function (node) {
                var startLine = this.sourceFile.getLineAndCharacterOfPosition(node.getStart(this.sourceFile)).line;
                var endLine = this.sourceFile.getLineAndCharacterOfPosition(node.getEnd()).line;
                return startLine === endLine;
            };
            FormattingContext.prototype.BlockIsOnOneLine = function (node) {
                var openBrace = ts.findChildOfKind(node, 18 /* OpenBraceToken */, this.sourceFile);
                var closeBrace = ts.findChildOfKind(node, 19 /* CloseBraceToken */, this.sourceFile);
                if (openBrace && closeBrace) {
                    var startLine = this.sourceFile.getLineAndCharacterOfPosition(openBrace.getEnd()).line;
                    var endLine = this.sourceFile.getLineAndCharacterOfPosition(closeBrace.getStart(this.sourceFile)).line;
                    return startLine === endLine;
                }
                return false;
            };
            return FormattingContext;
        }());
        formatting.FormattingContext = FormattingContext;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var standardScanner = ts.createScanner(8 /* Latest */, /*skipTrivia*/ false, 0 /* Standard */);
        var jsxScanner = ts.createScanner(8 /* Latest */, /*skipTrivia*/ false, 1 /* JSX */);
        var ScanAction;
        (function (ScanAction) {
            ScanAction[ScanAction["Scan"] = 0] = "Scan";
            ScanAction[ScanAction["RescanGreaterThanToken"] = 1] = "RescanGreaterThanToken";
            ScanAction[ScanAction["RescanSlashToken"] = 2] = "RescanSlashToken";
            ScanAction[ScanAction["RescanTemplateToken"] = 3] = "RescanTemplateToken";
            ScanAction[ScanAction["RescanJsxIdentifier"] = 4] = "RescanJsxIdentifier";
            ScanAction[ScanAction["RescanJsxText"] = 5] = "RescanJsxText";
        })(ScanAction || (ScanAction = {}));
        function getFormattingScanner(text, languageVariant, startPos, endPos, cb) {
            var scanner = languageVariant === 1 /* JSX */ ? jsxScanner : standardScanner;
            scanner.setText(text);
            scanner.setTextPos(startPos);
            var wasNewLine = true;
            var leadingTrivia;
            var trailingTrivia;
            var savedPos;
            var lastScanAction;
            var lastTokenInfo;
            var res = cb({
                advance: advance,
                readTokenInfo: readTokenInfo,
                isOnToken: isOnToken,
                getCurrentLeadingTrivia: function () { return leadingTrivia; },
                lastTrailingTriviaWasNewLine: function () { return wasNewLine; },
                skipToEndOf: skipToEndOf,
            });
            lastTokenInfo = undefined;
            scanner.setText(undefined);
            return res;
            function advance() {
                lastTokenInfo = undefined;
                var isStarted = scanner.getStartPos() !== startPos;
                if (isStarted) {
                    wasNewLine = !!trailingTrivia && ts.last(trailingTrivia).kind === 4 /* NewLineTrivia */;
                }
                else {
                    scanner.scan();
                }
                leadingTrivia = undefined;
                trailingTrivia = undefined;
                var pos = scanner.getStartPos();
                // Read leading trivia and token
                while (pos < endPos) {
                    var t = scanner.getToken();
                    if (!ts.isTrivia(t)) {
                        break;
                    }
                    // consume leading trivia
                    scanner.scan();
                    var item = {
                        pos: pos,
                        end: scanner.getStartPos(),
                        kind: t
                    };
                    pos = scanner.getStartPos();
                    leadingTrivia = ts.append(leadingTrivia, item);
                }
                savedPos = scanner.getStartPos();
            }
            function shouldRescanGreaterThanToken(node) {
                switch (node.kind) {
                    case 32 /* GreaterThanEqualsToken */:
                    case 68 /* GreaterThanGreaterThanEqualsToken */:
                    case 69 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                    case 48 /* GreaterThanGreaterThanGreaterThanToken */:
                    case 47 /* GreaterThanGreaterThanToken */:
                        return true;
                }
                return false;
            }
            function shouldRescanJsxIdentifier(node) {
                if (node.parent) {
                    switch (node.parent.kind) {
                        case 268 /* JsxAttribute */:
                        case 263 /* JsxOpeningElement */:
                        case 264 /* JsxClosingElement */:
                        case 262 /* JsxSelfClosingElement */:
                            // May parse an identifier like `module-layout`; that will be scanned as a keyword at first, but we should parse the whole thing to get an identifier.
                            return ts.isKeyword(node.kind) || node.kind === 73 /* Identifier */;
                    }
                }
                return false;
            }
            function shouldRescanJsxText(node) {
                return node.kind === 11 /* JsxText */;
            }
            function shouldRescanSlashToken(container) {
                return container.kind === 13 /* RegularExpressionLiteral */;
            }
            function shouldRescanTemplateToken(container) {
                return container.kind === 16 /* TemplateMiddle */ ||
                    container.kind === 17 /* TemplateTail */;
            }
            function startsWithSlashToken(t) {
                return t === 42 /* SlashToken */ || t === 65 /* SlashEqualsToken */;
            }
            function readTokenInfo(n) {
                ts.Debug.assert(isOnToken());
                // normally scanner returns the smallest available token
                // check the kind of context node to determine if scanner should have more greedy behavior and consume more text.
                var expectedScanAction = shouldRescanGreaterThanToken(n)
                    ? 1 /* RescanGreaterThanToken */
                    : shouldRescanSlashToken(n)
                        ? 2 /* RescanSlashToken */
                        : shouldRescanTemplateToken(n)
                            ? 3 /* RescanTemplateToken */
                            : shouldRescanJsxIdentifier(n)
                                ? 4 /* RescanJsxIdentifier */
                                : shouldRescanJsxText(n)
                                    ? 5 /* RescanJsxText */
                                    : 0 /* Scan */;
                if (lastTokenInfo && expectedScanAction === lastScanAction) {
                    // readTokenInfo was called before with the same expected scan action.
                    // No need to re-scan text, return existing 'lastTokenInfo'
                    // it is ok to call fixTokenKind here since it does not affect
                    // what portion of text is consumed. In contrast rescanning can change it,
                    // i.e. for '>=' when originally scanner eats just one character
                    // and rescanning forces it to consume more.
                    return fixTokenKind(lastTokenInfo, n);
                }
                if (scanner.getStartPos() !== savedPos) {
                    ts.Debug.assert(lastTokenInfo !== undefined);
                    // readTokenInfo was called before but scan action differs - rescan text
                    scanner.setTextPos(savedPos);
                    scanner.scan();
                }
                var currentToken = getNextToken(n, expectedScanAction);
                var token = {
                    pos: scanner.getStartPos(),
                    end: scanner.getTextPos(),
                    kind: currentToken
                };
                // consume trailing trivia
                if (trailingTrivia) {
                    trailingTrivia = undefined;
                }
                while (scanner.getStartPos() < endPos) {
                    currentToken = scanner.scan();
                    if (!ts.isTrivia(currentToken)) {
                        break;
                    }
                    var trivia = {
                        pos: scanner.getStartPos(),
                        end: scanner.getTextPos(),
                        kind: currentToken
                    };
                    if (!trailingTrivia) {
                        trailingTrivia = [];
                    }
                    trailingTrivia.push(trivia);
                    if (currentToken === 4 /* NewLineTrivia */) {
                        // move past new line
                        scanner.scan();
                        break;
                    }
                }
                lastTokenInfo = { leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia, token: token };
                return fixTokenKind(lastTokenInfo, n);
            }
            function getNextToken(n, expectedScanAction) {
                var token = scanner.getToken();
                lastScanAction = 0 /* Scan */;
                switch (expectedScanAction) {
                    case 1 /* RescanGreaterThanToken */:
                        if (token === 30 /* GreaterThanToken */) {
                            lastScanAction = 1 /* RescanGreaterThanToken */;
                            var newToken = scanner.reScanGreaterToken();
                            ts.Debug.assert(n.kind === newToken);
                            return newToken;
                        }
                        break;
                    case 2 /* RescanSlashToken */:
                        if (startsWithSlashToken(token)) {
                            lastScanAction = 2 /* RescanSlashToken */;
                            var newToken = scanner.reScanSlashToken();
                            ts.Debug.assert(n.kind === newToken);
                            return newToken;
                        }
                        break;
                    case 3 /* RescanTemplateToken */:
                        if (token === 19 /* CloseBraceToken */) {
                            lastScanAction = 3 /* RescanTemplateToken */;
                            return scanner.reScanTemplateToken();
                        }
                        break;
                    case 4 /* RescanJsxIdentifier */:
                        lastScanAction = 4 /* RescanJsxIdentifier */;
                        return scanner.scanJsxIdentifier();
                    case 5 /* RescanJsxText */:
                        lastScanAction = 5 /* RescanJsxText */;
                        return scanner.reScanJsxToken();
                    case 0 /* Scan */:
                        break;
                    default:
                        ts.Debug.assertNever(expectedScanAction);
                }
                return token;
            }
            function isOnToken() {
                var current = lastTokenInfo ? lastTokenInfo.token.kind : scanner.getToken();
                var startPos = lastTokenInfo ? lastTokenInfo.token.pos : scanner.getStartPos();
                return startPos < endPos && current !== 1 /* EndOfFileToken */ && !ts.isTrivia(current);
            }
            // when containing node in the tree is token
            // but its kind differs from the kind that was returned by the scanner,
            // then kind needs to be fixed. This might happen in cases
            // when parser interprets token differently, i.e keyword treated as identifier
            function fixTokenKind(tokenInfo, container) {
                if (ts.isToken(container) && tokenInfo.token.kind !== container.kind) {
                    tokenInfo.token.kind = container.kind;
                }
                return tokenInfo;
            }
            function skipToEndOf(node) {
                scanner.setTextPos(node.end);
                savedPos = scanner.getStartPos();
                lastScanAction = undefined;
                lastTokenInfo = undefined;
                wasNewLine = false;
                leadingTrivia = undefined;
                trailingTrivia = undefined;
            }
        }
        formatting.getFormattingScanner = getFormattingScanner;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        formatting.anyContext = ts.emptyArray;
        var RuleAction;
        (function (RuleAction) {
            RuleAction[RuleAction["Ignore"] = 1] = "Ignore";
            RuleAction[RuleAction["Space"] = 2] = "Space";
            RuleAction[RuleAction["NewLine"] = 4] = "NewLine";
            RuleAction[RuleAction["Delete"] = 8] = "Delete";
        })(RuleAction = formatting.RuleAction || (formatting.RuleAction = {}));
        var RuleFlags;
        (function (RuleFlags) {
            RuleFlags[RuleFlags["None"] = 0] = "None";
            RuleFlags[RuleFlags["CanDeleteNewLines"] = 1] = "CanDeleteNewLines";
        })(RuleFlags = formatting.RuleFlags || (formatting.RuleFlags = {}));
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        function getAllRules() {
            var allTokens = [];
            for (var token = 0 /* FirstToken */; token <= 148 /* LastToken */; token++) {
                allTokens.push(token);
            }
            function anyTokenExcept() {
                var tokens = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    tokens[_i] = arguments[_i];
                }
                return { tokens: allTokens.filter(function (t) { return !tokens.some(function (t2) { return t2 === t; }); }), isSpecific: false };
            }
            var anyToken = { tokens: allTokens, isSpecific: false };
            var anyTokenIncludingMultilineComments = tokenRangeFrom(allTokens.concat([3 /* MultiLineCommentTrivia */]));
            var keywords = tokenRangeFromRange(74 /* FirstKeyword */, 148 /* LastKeyword */);
            var binaryOperators = tokenRangeFromRange(28 /* FirstBinaryOperator */, 72 /* LastBinaryOperator */);
            var binaryKeywordOperators = [94 /* InKeyword */, 95 /* InstanceOfKeyword */, 148 /* OfKeyword */, 120 /* AsKeyword */, 129 /* IsKeyword */];
            var unaryPrefixOperators = [44 /* PlusPlusToken */, 45 /* MinusMinusToken */, 53 /* TildeToken */, 52 /* ExclamationToken */];
            var unaryPrefixExpressions = [
                8 /* NumericLiteral */, 9 /* BigIntLiteral */, 73 /* Identifier */, 20 /* OpenParenToken */,
                22 /* OpenBracketToken */, 18 /* OpenBraceToken */, 101 /* ThisKeyword */, 96 /* NewKeyword */
            ];
            var unaryPreincrementExpressions = [73 /* Identifier */, 20 /* OpenParenToken */, 101 /* ThisKeyword */, 96 /* NewKeyword */];
            var unaryPostincrementExpressions = [73 /* Identifier */, 21 /* CloseParenToken */, 23 /* CloseBracketToken */, 96 /* NewKeyword */];
            var unaryPredecrementExpressions = [73 /* Identifier */, 20 /* OpenParenToken */, 101 /* ThisKeyword */, 96 /* NewKeyword */];
            var unaryPostdecrementExpressions = [73 /* Identifier */, 21 /* CloseParenToken */, 23 /* CloseBracketToken */, 96 /* NewKeyword */];
            var comments = [2 /* SingleLineCommentTrivia */, 3 /* MultiLineCommentTrivia */];
            var typeNames = [73 /* Identifier */].concat(ts.typeKeywords);
            // Place a space before open brace in a function declaration
            // TypeScript: Function can have return types, which can be made of tons of different token kinds
            var functionOpenBraceLeftTokenRange = anyTokenIncludingMultilineComments;
            // Place a space before open brace in a TypeScript declaration that has braces as children (class, module, enum, etc)
            var typeScriptOpenBraceLeftTokenRange = tokenRangeFrom([73 /* Identifier */, 3 /* MultiLineCommentTrivia */, 77 /* ClassKeyword */, 86 /* ExportKeyword */, 93 /* ImportKeyword */]);
            // Place a space before open brace in a control flow construct
            var controlOpenBraceLeftTokenRange = tokenRangeFrom([21 /* CloseParenToken */, 3 /* MultiLineCommentTrivia */, 83 /* DoKeyword */, 104 /* TryKeyword */, 89 /* FinallyKeyword */, 84 /* ElseKeyword */]);
            // These rules are higher in priority than user-configurable
            var highPriorityCommonRules = [
                // Leave comments alone
                rule("IgnoreBeforeComment", anyToken, comments, formatting.anyContext, 1 /* Ignore */),
                rule("IgnoreAfterLineComment", 2 /* SingleLineCommentTrivia */, anyToken, formatting.anyContext, 1 /* Ignore */),
                rule("NotSpaceBeforeColon", anyToken, 57 /* ColonToken */, [isNonJsxSameLineTokenContext, isNotBinaryOpContext, isNotTypeAnnotationContext], 8 /* Delete */),
                rule("SpaceAfterColon", 57 /* ColonToken */, anyToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], 2 /* Space */),
                rule("NoSpaceBeforeQuestionMark", anyToken, 56 /* QuestionToken */, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], 8 /* Delete */),
                // insert space after '?' only when it is used in conditional operator
                rule("SpaceAfterQuestionMarkInConditionalOperator", 56 /* QuestionToken */, anyToken, [isNonJsxSameLineTokenContext, isConditionalOperatorContext], 2 /* Space */),
                // in other cases there should be no space between '?' and next token
                rule("NoSpaceAfterQuestionMark", 56 /* QuestionToken */, anyToken, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceBeforeDot", anyToken, 24 /* DotToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceAfterDot", 24 /* DotToken */, anyToken, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceBetweenImportParenInImportType", 93 /* ImportKeyword */, 20 /* OpenParenToken */, [isNonJsxSameLineTokenContext, isImportTypeContext], 8 /* Delete */),
                // Special handling of unary operators.
                // Prefix operators generally shouldn't have a space between
                // them and their target unary expression.
                rule("NoSpaceAfterUnaryPrefixOperator", unaryPrefixOperators, unaryPrefixExpressions, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], 8 /* Delete */),
                rule("NoSpaceAfterUnaryPreincrementOperator", 44 /* PlusPlusToken */, unaryPreincrementExpressions, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceAfterUnaryPredecrementOperator", 45 /* MinusMinusToken */, unaryPredecrementExpressions, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceBeforeUnaryPostincrementOperator", unaryPostincrementExpressions, 44 /* PlusPlusToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceBeforeUnaryPostdecrementOperator", unaryPostdecrementExpressions, 45 /* MinusMinusToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                // More unary operator special-casing.
                // DevDiv 181814: Be careful when removing leading whitespace
                // around unary operators.  Examples:
                //      1 - -2  --X--> 1--2
                //      a + ++b --X--> a+++b
                rule("SpaceAfterPostincrementWhenFollowedByAdd", 44 /* PlusPlusToken */, 38 /* PlusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */),
                rule("SpaceAfterAddWhenFollowedByUnaryPlus", 38 /* PlusToken */, 38 /* PlusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */),
                rule("SpaceAfterAddWhenFollowedByPreincrement", 38 /* PlusToken */, 44 /* PlusPlusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */),
                rule("SpaceAfterPostdecrementWhenFollowedBySubtract", 45 /* MinusMinusToken */, 39 /* MinusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */),
                rule("SpaceAfterSubtractWhenFollowedByUnaryMinus", 39 /* MinusToken */, 39 /* MinusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */),
                rule("SpaceAfterSubtractWhenFollowedByPredecrement", 39 /* MinusToken */, 45 /* MinusMinusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */),
                rule("NoSpaceAfterCloseBrace", 19 /* CloseBraceToken */, [27 /* CommaToken */, 26 /* SemicolonToken */], [isNonJsxSameLineTokenContext], 8 /* Delete */),
                // For functions and control block place } on a new line [multi-line rule]
                rule("NewLineBeforeCloseBraceInBlockContext", anyTokenIncludingMultilineComments, 19 /* CloseBraceToken */, [isMultilineBlockContext], 4 /* NewLine */),
                // Space/new line after }.
                rule("SpaceAfterCloseBrace", 19 /* CloseBraceToken */, anyTokenExcept(21 /* CloseParenToken */), [isNonJsxSameLineTokenContext, isAfterCodeBlockContext], 2 /* Space */),
                // Special case for (}, else) and (}, while) since else & while tokens are not part of the tree which makes SpaceAfterCloseBrace rule not applied
                // Also should not apply to })
                rule("SpaceBetweenCloseBraceAndElse", 19 /* CloseBraceToken */, 84 /* ElseKeyword */, [isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("SpaceBetweenCloseBraceAndWhile", 19 /* CloseBraceToken */, 108 /* WhileKeyword */, [isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("NoSpaceBetweenEmptyBraceBrackets", 18 /* OpenBraceToken */, 19 /* CloseBraceToken */, [isNonJsxSameLineTokenContext, isObjectContext], 8 /* Delete */),
                // Add a space after control dec context if the next character is an open bracket ex: 'if (false)[a, b] = [1, 2];' -> 'if (false) [a, b] = [1, 2];'
                rule("SpaceAfterConditionalClosingParen", 21 /* CloseParenToken */, 22 /* OpenBracketToken */, [isControlDeclContext], 2 /* Space */),
                rule("NoSpaceBetweenFunctionKeywordAndStar", 91 /* FunctionKeyword */, 40 /* AsteriskToken */, [isFunctionDeclarationOrFunctionExpressionContext], 8 /* Delete */),
                rule("SpaceAfterStarInGeneratorDeclaration", 40 /* AsteriskToken */, 73 /* Identifier */, [isFunctionDeclarationOrFunctionExpressionContext], 2 /* Space */),
                rule("SpaceAfterFunctionInFuncDecl", 91 /* FunctionKeyword */, anyToken, [isFunctionDeclContext], 2 /* Space */),
                // Insert new line after { and before } in multi-line contexts.
                rule("NewLineAfterOpenBraceInBlockContext", 18 /* OpenBraceToken */, anyToken, [isMultilineBlockContext], 4 /* NewLine */),
                // For get/set members, we check for (identifier,identifier) since get/set don't have tokens and they are represented as just an identifier token.
                // Though, we do extra check on the context to make sure we are dealing with get/set node. Example:
                //      get x() {}
                //      set x(val) {}
                rule("SpaceAfterGetSetInMember", [127 /* GetKeyword */, 138 /* SetKeyword */], 73 /* Identifier */, [isFunctionDeclContext], 2 /* Space */),
                rule("NoSpaceBetweenYieldKeywordAndStar", 118 /* YieldKeyword */, 40 /* AsteriskToken */, [isNonJsxSameLineTokenContext, isYieldOrYieldStarWithOperand], 8 /* Delete */),
                rule("SpaceBetweenYieldOrYieldStarAndOperand", [118 /* YieldKeyword */, 40 /* AsteriskToken */], anyToken, [isNonJsxSameLineTokenContext, isYieldOrYieldStarWithOperand], 2 /* Space */),
                rule("NoSpaceBetweenReturnAndSemicolon", 98 /* ReturnKeyword */, 26 /* SemicolonToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("SpaceAfterCertainKeywords", [106 /* VarKeyword */, 102 /* ThrowKeyword */, 96 /* NewKeyword */, 82 /* DeleteKeyword */, 98 /* ReturnKeyword */, 105 /* TypeOfKeyword */, 123 /* AwaitKeyword */], anyToken, [isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("SpaceAfterLetConstInVariableDeclaration", [112 /* LetKeyword */, 78 /* ConstKeyword */], anyToken, [isNonJsxSameLineTokenContext, isStartOfVariableDeclarationList], 2 /* Space */),
                rule("NoSpaceBeforeOpenParenInFuncCall", anyToken, 20 /* OpenParenToken */, [isNonJsxSameLineTokenContext, isFunctionCallOrNewContext, isPreviousTokenNotComma], 8 /* Delete */),
                // Special case for binary operators (that are keywords). For these we have to add a space and shouldn't follow any user options.
                rule("SpaceBeforeBinaryKeywordOperator", anyToken, binaryKeywordOperators, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */),
                rule("SpaceAfterBinaryKeywordOperator", binaryKeywordOperators, anyToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */),
                rule("SpaceAfterVoidOperator", 107 /* VoidKeyword */, anyToken, [isNonJsxSameLineTokenContext, isVoidOpContext], 2 /* Space */),
                // Async-await
                rule("SpaceBetweenAsyncAndOpenParen", 122 /* AsyncKeyword */, 20 /* OpenParenToken */, [isArrowFunctionContext, isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("SpaceBetweenAsyncAndFunctionKeyword", 122 /* AsyncKeyword */, 91 /* FunctionKeyword */, [isNonJsxSameLineTokenContext], 2 /* Space */),
                // Template string
                rule("NoSpaceBetweenTagAndTemplateString", [73 /* Identifier */, 21 /* CloseParenToken */], [14 /* NoSubstitutionTemplateLiteral */, 15 /* TemplateHead */], [isNonJsxSameLineTokenContext], 8 /* Delete */),
                // JSX opening elements
                rule("SpaceBeforeJsxAttribute", anyToken, 73 /* Identifier */, [isNextTokenParentJsxAttribute, isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("SpaceBeforeSlashInJsxOpeningElement", anyToken, 42 /* SlashToken */, [isJsxSelfClosingElementContext, isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("NoSpaceBeforeGreaterThanTokenInJsxOpeningElement", 42 /* SlashToken */, 30 /* GreaterThanToken */, [isJsxSelfClosingElementContext, isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceBeforeEqualInJsxAttribute", anyToken, 60 /* EqualsToken */, [isJsxAttributeContext, isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceAfterEqualInJsxAttribute", 60 /* EqualsToken */, anyToken, [isJsxAttributeContext, isNonJsxSameLineTokenContext], 8 /* Delete */),
                // TypeScript-specific rules
                // Use of module as a function call. e.g.: import m2 = module("m2");
                rule("NoSpaceAfterModuleImport", [131 /* ModuleKeyword */, 135 /* RequireKeyword */], 20 /* OpenParenToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                // Add a space around certain TypeScript keywords
                rule("SpaceAfterCertainTypeScriptKeywords", [
                    119 /* AbstractKeyword */,
                    77 /* ClassKeyword */,
                    126 /* DeclareKeyword */,
                    81 /* DefaultKeyword */,
                    85 /* EnumKeyword */,
                    86 /* ExportKeyword */,
                    87 /* ExtendsKeyword */,
                    127 /* GetKeyword */,
                    110 /* ImplementsKeyword */,
                    93 /* ImportKeyword */,
                    111 /* InterfaceKeyword */,
                    131 /* ModuleKeyword */,
                    132 /* NamespaceKeyword */,
                    114 /* PrivateKeyword */,
                    116 /* PublicKeyword */,
                    115 /* ProtectedKeyword */,
                    134 /* ReadonlyKeyword */,
                    138 /* SetKeyword */,
                    117 /* StaticKeyword */,
                    141 /* TypeKeyword */,
                    145 /* FromKeyword */,
                    130 /* KeyOfKeyword */,
                    128 /* InferKeyword */,
                ], anyToken, [isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("SpaceBeforeCertainTypeScriptKeywords", anyToken, [87 /* ExtendsKeyword */, 110 /* ImplementsKeyword */, 145 /* FromKeyword */], [isNonJsxSameLineTokenContext], 2 /* Space */),
                // Treat string literals in module names as identifiers, and add a space between the literal and the opening Brace braces, e.g.: module "m2" {
                rule("SpaceAfterModuleName", 10 /* StringLiteral */, 18 /* OpenBraceToken */, [isModuleDeclContext], 2 /* Space */),
                // Lambda expressions
                rule("SpaceBeforeArrow", anyToken, 37 /* EqualsGreaterThanToken */, [isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("SpaceAfterArrow", 37 /* EqualsGreaterThanToken */, anyToken, [isNonJsxSameLineTokenContext], 2 /* Space */),
                // Optional parameters and let args
                rule("NoSpaceAfterEllipsis", 25 /* DotDotDotToken */, 73 /* Identifier */, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceAfterOptionalParameters", 56 /* QuestionToken */, [21 /* CloseParenToken */, 27 /* CommaToken */], [isNonJsxSameLineTokenContext, isNotBinaryOpContext], 8 /* Delete */),
                // Remove spaces in empty interface literals. e.g.: x: {}
                rule("NoSpaceBetweenEmptyInterfaceBraceBrackets", 18 /* OpenBraceToken */, 19 /* CloseBraceToken */, [isNonJsxSameLineTokenContext, isObjectTypeContext], 8 /* Delete */),
                // generics and type assertions
                rule("NoSpaceBeforeOpenAngularBracket", typeNames, 28 /* LessThanToken */, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], 8 /* Delete */),
                rule("NoSpaceBetweenCloseParenAndAngularBracket", 21 /* CloseParenToken */, 28 /* LessThanToken */, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], 8 /* Delete */),
                rule("NoSpaceAfterOpenAngularBracket", 28 /* LessThanToken */, anyToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], 8 /* Delete */),
                rule("NoSpaceBeforeCloseAngularBracket", anyToken, 30 /* GreaterThanToken */, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], 8 /* Delete */),
                rule("NoSpaceAfterCloseAngularBracket", 30 /* GreaterThanToken */, [20 /* OpenParenToken */, 22 /* OpenBracketToken */, 30 /* GreaterThanToken */, 27 /* CommaToken */], [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext, isNotFunctionDeclContext /*To prevent an interference with the SpaceBeforeOpenParenInFuncDecl rule*/], 8 /* Delete */),
                // decorators
                rule("SpaceBeforeAt", [21 /* CloseParenToken */, 73 /* Identifier */], 58 /* AtToken */, [isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("NoSpaceAfterAt", 58 /* AtToken */, anyToken, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                // Insert space after @ in decorator
                rule("SpaceAfterDecorator", anyToken, [
                    119 /* AbstractKeyword */,
                    73 /* Identifier */,
                    86 /* ExportKeyword */,
                    81 /* DefaultKeyword */,
                    77 /* ClassKeyword */,
                    117 /* StaticKeyword */,
                    116 /* PublicKeyword */,
                    114 /* PrivateKeyword */,
                    115 /* ProtectedKeyword */,
                    127 /* GetKeyword */,
                    138 /* SetKeyword */,
                    22 /* OpenBracketToken */,
                    40 /* AsteriskToken */,
                ], [isEndOfDecoratorContextOnSameLine], 2 /* Space */),
                rule("NoSpaceBeforeNonNullAssertionOperator", anyToken, 52 /* ExclamationToken */, [isNonJsxSameLineTokenContext, isNonNullAssertionContext], 8 /* Delete */),
                rule("NoSpaceAfterNewKeywordOnConstructorSignature", 96 /* NewKeyword */, 20 /* OpenParenToken */, [isNonJsxSameLineTokenContext, isConstructorSignatureContext], 8 /* Delete */),
            ];
            // These rules are applied after high priority
            var userConfigurableRules = [
                // Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses
                rule("SpaceAfterConstructor", 125 /* ConstructorKeyword */, 20 /* OpenParenToken */, [isOptionEnabled("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("NoSpaceAfterConstructor", 125 /* ConstructorKeyword */, 20 /* OpenParenToken */, [isOptionDisabledOrUndefined("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("SpaceAfterComma", 27 /* CommaToken */, anyToken, [isOptionEnabled("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext, isNextTokenNotCloseBracket], 2 /* Space */),
                rule("NoSpaceAfterComma", 27 /* CommaToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext], 8 /* Delete */),
                // Insert space after function keyword for anonymous functions
                rule("SpaceAfterAnonymousFunctionKeyword", [91 /* FunctionKeyword */, 40 /* AsteriskToken */], 20 /* OpenParenToken */, [isOptionEnabled("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], 2 /* Space */),
                rule("NoSpaceAfterAnonymousFunctionKeyword", [91 /* FunctionKeyword */, 40 /* AsteriskToken */], 20 /* OpenParenToken */, [isOptionDisabledOrUndefined("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], 8 /* Delete */),
                // Insert space after keywords in control flow statements
                rule("SpaceAfterKeywordInControl", keywords, 20 /* OpenParenToken */, [isOptionEnabled("insertSpaceAfterKeywordsInControlFlowStatements"), isControlDeclContext], 2 /* Space */),
                rule("NoSpaceAfterKeywordInControl", keywords, 20 /* OpenParenToken */, [isOptionDisabledOrUndefined("insertSpaceAfterKeywordsInControlFlowStatements"), isControlDeclContext], 8 /* Delete */),
                // Insert space after opening and before closing nonempty parenthesis
                rule("SpaceAfterOpenParen", 20 /* OpenParenToken */, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("SpaceBeforeCloseParen", anyToken, 21 /* CloseParenToken */, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("SpaceBetweenOpenParens", 20 /* OpenParenToken */, 20 /* OpenParenToken */, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("NoSpaceBetweenParens", 20 /* OpenParenToken */, 21 /* CloseParenToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceAfterOpenParen", 20 /* OpenParenToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceBeforeCloseParen", anyToken, 21 /* CloseParenToken */, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], 8 /* Delete */),
                // Insert space after opening and before closing nonempty brackets
                rule("SpaceAfterOpenBracket", 22 /* OpenBracketToken */, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("SpaceBeforeCloseBracket", anyToken, 23 /* CloseBracketToken */, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("NoSpaceBetweenBrackets", 22 /* OpenBracketToken */, 23 /* CloseBracketToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceAfterOpenBracket", 22 /* OpenBracketToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceBeforeCloseBracket", anyToken, 23 /* CloseBracketToken */, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], 8 /* Delete */),
                // Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}.
                rule("SpaceAfterOpenBrace", 18 /* OpenBraceToken */, anyToken, [isOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isBraceWrappedContext], 2 /* Space */),
                rule("SpaceBeforeCloseBrace", anyToken, 19 /* CloseBraceToken */, [isOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isBraceWrappedContext], 2 /* Space */),
                rule("NoSpaceBetweenEmptyBraceBrackets", 18 /* OpenBraceToken */, 19 /* CloseBraceToken */, [isNonJsxSameLineTokenContext, isObjectContext], 8 /* Delete */),
                rule("NoSpaceAfterOpenBrace", 18 /* OpenBraceToken */, anyToken, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceBeforeCloseBrace", anyToken, 19 /* CloseBraceToken */, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isNonJsxSameLineTokenContext], 8 /* Delete */),
                // Insert space after opening and before closing template string braces
                rule("SpaceAfterTemplateHeadAndMiddle", [15 /* TemplateHead */, 16 /* TemplateMiddle */], anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("SpaceBeforeTemplateMiddleAndTail", anyToken, [16 /* TemplateMiddle */, 17 /* TemplateTail */], [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], 2 /* Space */),
                rule("NoSpaceAfterTemplateHeadAndMiddle", [15 /* TemplateHead */, 16 /* TemplateMiddle */], anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceBeforeTemplateMiddleAndTail", anyToken, [16 /* TemplateMiddle */, 17 /* TemplateTail */], [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], 8 /* Delete */),
                // No space after { and before } in JSX expression
                rule("SpaceAfterOpenBraceInJsxExpression", 18 /* OpenBraceToken */, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], 2 /* Space */),
                rule("SpaceBeforeCloseBraceInJsxExpression", anyToken, 19 /* CloseBraceToken */, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], 2 /* Space */),
                rule("NoSpaceAfterOpenBraceInJsxExpression", 18 /* OpenBraceToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], 8 /* Delete */),
                rule("NoSpaceBeforeCloseBraceInJsxExpression", anyToken, 19 /* CloseBraceToken */, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], 8 /* Delete */),
                // Insert space after semicolon in for statement
                rule("SpaceAfterSemicolonInFor", 26 /* SemicolonToken */, anyToken, [isOptionEnabled("insertSpaceAfterSemicolonInForStatements"), isNonJsxSameLineTokenContext, isForContext], 2 /* Space */),
                rule("NoSpaceAfterSemicolonInFor", 26 /* SemicolonToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterSemicolonInForStatements"), isNonJsxSameLineTokenContext, isForContext], 8 /* Delete */),
                // Insert space before and after binary operators
                rule("SpaceBeforeBinaryOperator", anyToken, binaryOperators, [isOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */),
                rule("SpaceAfterBinaryOperator", binaryOperators, anyToken, [isOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */),
                rule("NoSpaceBeforeBinaryOperator", anyToken, binaryOperators, [isOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], 8 /* Delete */),
                rule("NoSpaceAfterBinaryOperator", binaryOperators, anyToken, [isOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], 8 /* Delete */),
                rule("SpaceBeforeOpenParenInFuncDecl", anyToken, 20 /* OpenParenToken */, [isOptionEnabled("insertSpaceBeforeFunctionParenthesis"), isNonJsxSameLineTokenContext, isFunctionDeclContext], 2 /* Space */),
                rule("NoSpaceBeforeOpenParenInFuncDecl", anyToken, 20 /* OpenParenToken */, [isOptionDisabledOrUndefined("insertSpaceBeforeFunctionParenthesis"), isNonJsxSameLineTokenContext, isFunctionDeclContext], 8 /* Delete */),
                // Open Brace braces after control block
                rule("NewLineBeforeOpenBraceInControl", controlOpenBraceLeftTokenRange, 18 /* OpenBraceToken */, [isOptionEnabled("placeOpenBraceOnNewLineForControlBlocks"), isControlDeclContext, isBeforeMultilineBlockContext], 4 /* NewLine */, 1 /* CanDeleteNewLines */),
                // Open Brace braces after function
                // TypeScript: Function can have return types, which can be made of tons of different token kinds
                rule("NewLineBeforeOpenBraceInFunction", functionOpenBraceLeftTokenRange, 18 /* OpenBraceToken */, [isOptionEnabled("placeOpenBraceOnNewLineForFunctions"), isFunctionDeclContext, isBeforeMultilineBlockContext], 4 /* NewLine */, 1 /* CanDeleteNewLines */),
                // Open Brace braces after TypeScript module/class/interface
                rule("NewLineBeforeOpenBraceInTypeScriptDeclWithBlock", typeScriptOpenBraceLeftTokenRange, 18 /* OpenBraceToken */, [isOptionEnabled("placeOpenBraceOnNewLineForFunctions"), isTypeScriptDeclWithBlockContext, isBeforeMultilineBlockContext], 4 /* NewLine */, 1 /* CanDeleteNewLines */),
                rule("SpaceAfterTypeAssertion", 30 /* GreaterThanToken */, anyToken, [isOptionEnabled("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], 2 /* Space */),
                rule("NoSpaceAfterTypeAssertion", 30 /* GreaterThanToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], 8 /* Delete */),
                rule("SpaceBeforeTypeAnnotation", anyToken, 57 /* ColonToken */, [isOptionEnabled("insertSpaceBeforeTypeAnnotation"), isNonJsxSameLineTokenContext, isTypeAnnotationContext], 2 /* Space */),
                rule("NoSpaceBeforeTypeAnnotation", anyToken, 57 /* ColonToken */, [isOptionDisabledOrUndefined("insertSpaceBeforeTypeAnnotation"), isNonJsxSameLineTokenContext, isTypeAnnotationContext], 8 /* Delete */),
            ];
            // These rules are lower in priority than user-configurable. Rules earlier in this list have priority over rules later in the list.
            var lowPriorityCommonRules = [
                // Space after keyword but not before ; or : or ?
                rule("NoSpaceBeforeSemicolon", anyToken, 26 /* SemicolonToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("SpaceBeforeOpenBraceInControl", controlOpenBraceLeftTokenRange, 18 /* OpenBraceToken */, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForControlBlocks"), isControlDeclContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], 2 /* Space */, 1 /* CanDeleteNewLines */),
                rule("SpaceBeforeOpenBraceInFunction", functionOpenBraceLeftTokenRange, 18 /* OpenBraceToken */, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), isFunctionDeclContext, isBeforeBlockContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], 2 /* Space */, 1 /* CanDeleteNewLines */),
                rule("SpaceBeforeOpenBraceInTypeScriptDeclWithBlock", typeScriptOpenBraceLeftTokenRange, 18 /* OpenBraceToken */, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), isTypeScriptDeclWithBlockContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], 2 /* Space */, 1 /* CanDeleteNewLines */),
                rule("NoSpaceBeforeComma", anyToken, 27 /* CommaToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                // No space before and after indexer `x[]`
                rule("NoSpaceBeforeOpenBracket", anyTokenExcept(122 /* AsyncKeyword */, 75 /* CaseKeyword */), 22 /* OpenBracketToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */),
                rule("NoSpaceAfterCloseBracket", 23 /* CloseBracketToken */, anyToken, [isNonJsxSameLineTokenContext, isNotBeforeBlockInFunctionDeclarationContext], 8 /* Delete */),
                rule("SpaceAfterSemicolon", 26 /* SemicolonToken */, anyToken, [isNonJsxSameLineTokenContext], 2 /* Space */),
                // Remove extra space between for and await
                rule("SpaceBetweenForAndAwaitKeyword", 90 /* ForKeyword */, 123 /* AwaitKeyword */, [isNonJsxSameLineTokenContext], 2 /* Space */),
                // Add a space between statements. All keywords except (do,else,case) has open/close parens after them.
                // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any]
                rule("SpaceBetweenStatements", [21 /* CloseParenToken */, 83 /* DoKeyword */, 84 /* ElseKeyword */, 75 /* CaseKeyword */], anyToken, [isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext, isNotForContext], 2 /* Space */),
                // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter.
                rule("SpaceAfterTryFinally", [104 /* TryKeyword */, 89 /* FinallyKeyword */], 18 /* OpenBraceToken */, [isNonJsxSameLineTokenContext], 2 /* Space */),
            ];
            return highPriorityCommonRules.concat(userConfigurableRules, lowPriorityCommonRules);
        }
        formatting.getAllRules = getAllRules;
        function rule(debugName, left, right, context, action, flags) {
            if (flags === void 0) { flags = 0 /* None */; }
            return { leftTokenRange: toTokenRange(left), rightTokenRange: toTokenRange(right), rule: { debugName: debugName, context: context, action: action, flags: flags } };
        }
        function tokenRangeFrom(tokens) {
            return { tokens: tokens, isSpecific: true };
        }
        function toTokenRange(arg) {
            return typeof arg === "number" ? tokenRangeFrom([arg]) : ts.isArray(arg) ? tokenRangeFrom(arg) : arg;
        }
        function tokenRangeFromRange(from, to, except) {
            if (except === void 0) { except = []; }
            var tokens = [];
            for (var token = from; token <= to; token++) {
                if (!ts.contains(except, token)) {
                    tokens.push(token);
                }
            }
            return tokenRangeFrom(tokens);
        }
        ///
        /// Contexts
        ///
        function isOptionEnabled(optionName) {
            return function (context) { return context.options && context.options.hasOwnProperty(optionName) && !!context.options[optionName]; };
        }
        function isOptionDisabled(optionName) {
            return function (context) { return context.options && context.options.hasOwnProperty(optionName) && !context.options[optionName]; };
        }
        function isOptionDisabledOrUndefined(optionName) {
            return function (context) { return !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName]; };
        }
        function isOptionDisabledOrUndefinedOrTokensOnSameLine(optionName) {
            return function (context) { return !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName] || context.TokensAreOnSameLine(); };
        }
        function isOptionEnabledOrUndefined(optionName) {
            return function (context) { return !context.options || !context.options.hasOwnProperty(optionName) || !!context.options[optionName]; };
        }
        function isForContext(context) {
            return context.contextNode.kind === 226 /* ForStatement */;
        }
        function isNotForContext(context) {
            return !isForContext(context);
        }
        function isBinaryOpContext(context) {
            switch (context.contextNode.kind) {
                case 205 /* BinaryExpression */:
                case 206 /* ConditionalExpression */:
                case 176 /* ConditionalType */:
                case 213 /* AsExpression */:
                case 258 /* ExportSpecifier */:
                case 254 /* ImportSpecifier */:
                case 164 /* TypePredicate */:
                case 174 /* UnionType */:
                case 175 /* IntersectionType */:
                    return true;
                // equals in binding elements: function foo([[x, y] = [1, 2]])
                case 187 /* BindingElement */:
                // equals in type X = ...
                case 243 /* TypeAliasDeclaration */:
                // equal in import a = module('a');
                case 249 /* ImportEqualsDeclaration */:
                // equal in let a = 0;
                case 238 /* VariableDeclaration */:
                // equal in p = 0;
                case 152 /* Parameter */:
                case 279 /* EnumMember */:
                case 155 /* PropertyDeclaration */:
                case 154 /* PropertySignature */:
                    return context.currentTokenSpan.kind === 60 /* EqualsToken */ || context.nextTokenSpan.kind === 60 /* EqualsToken */;
                // "in" keyword in for (let x in []) { }
                case 227 /* ForInStatement */:
                // "in" keyword in [P in keyof T]: T[P]
                case 151 /* TypeParameter */:
                    return context.currentTokenSpan.kind === 94 /* InKeyword */ || context.nextTokenSpan.kind === 94 /* InKeyword */ || context.currentTokenSpan.kind === 60 /* EqualsToken */ || context.nextTokenSpan.kind === 60 /* EqualsToken */;
                // Technically, "of" is not a binary operator, but format it the same way as "in"
                case 228 /* ForOfStatement */:
                    return context.currentTokenSpan.kind === 148 /* OfKeyword */ || context.nextTokenSpan.kind === 148 /* OfKeyword */;
            }
            return false;
        }
        function isNotBinaryOpContext(context) {
            return !isBinaryOpContext(context);
        }
        function isNotTypeAnnotationContext(context) {
            return !isTypeAnnotationContext(context);
        }
        function isTypeAnnotationContext(context) {
            var contextKind = context.contextNode.kind;
            return contextKind === 155 /* PropertyDeclaration */ ||
                contextKind === 154 /* PropertySignature */ ||
                contextKind === 152 /* Parameter */ ||
                contextKind === 238 /* VariableDeclaration */ ||
                ts.isFunctionLikeKind(contextKind);
        }
        function isConditionalOperatorContext(context) {
            return context.contextNode.kind === 206 /* ConditionalExpression */ ||
                context.contextNode.kind === 176 /* ConditionalType */;
        }
        function isSameLineTokenOrBeforeBlockContext(context) {
            return context.TokensAreOnSameLine() || isBeforeBlockContext(context);
        }
        function isBraceWrappedContext(context) {
            return context.contextNode.kind === 185 /* ObjectBindingPattern */ ||
                context.contextNode.kind === 182 /* MappedType */ ||
                isSingleLineBlockContext(context);
        }
        // This check is done before an open brace in a control construct, a function, or a typescript block declaration
        function isBeforeMultilineBlockContext(context) {
            return isBeforeBlockContext(context) && !(context.NextNodeAllOnSameLine() || context.NextNodeBlockIsOnOneLine());
        }
        function isMultilineBlockContext(context) {
            return isBlockContext(context) && !(context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine());
        }
        function isSingleLineBlockContext(context) {
            return isBlockContext(context) && (context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine());
        }
        function isBlockContext(context) {
            return nodeIsBlockContext(context.contextNode);
        }
        function isBeforeBlockContext(context) {
            return nodeIsBlockContext(context.nextTokenParent);
        }
        // IMPORTANT!!! This method must return true ONLY for nodes with open and close braces as immediate children
        function nodeIsBlockContext(node) {
            if (nodeIsTypeScriptDeclWithBlockContext(node)) {
                // This means we are in a context that looks like a block to the user, but in the grammar is actually not a node (it's a class, module, enum, object type literal, etc).
                return true;
            }
            switch (node.kind) {
                case 219 /* Block */:
                case 247 /* CaseBlock */:
                case 189 /* ObjectLiteralExpression */:
                case 246 /* ModuleBlock */:
                    return true;
            }
            return false;
        }
        function isFunctionDeclContext(context) {
            switch (context.contextNode.kind) {
                case 240 /* FunctionDeclaration */:
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                // case SyntaxKind.MemberFunctionDeclaration:
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                // case SyntaxKind.MethodSignature:
                case 161 /* CallSignature */:
                case 197 /* FunctionExpression */:
                case 158 /* Constructor */:
                case 198 /* ArrowFunction */:
                // case SyntaxKind.ConstructorDeclaration:
                // case SyntaxKind.SimpleArrowFunctionExpression:
                // case SyntaxKind.ParenthesizedArrowFunctionExpression:
                case 242 /* InterfaceDeclaration */: // This one is not truly a function, but for formatting purposes, it acts just like one
                    return true;
            }
            return false;
        }
        function isNotFunctionDeclContext(context) {
            return !isFunctionDeclContext(context);
        }
        function isFunctionDeclarationOrFunctionExpressionContext(context) {
            return context.contextNode.kind === 240 /* FunctionDeclaration */ || context.contextNode.kind === 197 /* FunctionExpression */;
        }
        function isTypeScriptDeclWithBlockContext(context) {
            return nodeIsTypeScriptDeclWithBlockContext(context.contextNode);
        }
        function nodeIsTypeScriptDeclWithBlockContext(node) {
            switch (node.kind) {
                case 241 /* ClassDeclaration */:
                case 210 /* ClassExpression */:
                case 242 /* InterfaceDeclaration */:
                case 244 /* EnumDeclaration */:
                case 169 /* TypeLiteral */:
                case 245 /* ModuleDeclaration */:
                case 256 /* ExportDeclaration */:
                case 257 /* NamedExports */:
                case 250 /* ImportDeclaration */:
                case 253 /* NamedImports */:
                    return true;
            }
            return false;
        }
        function isAfterCodeBlockContext(context) {
            switch (context.currentTokenParent.kind) {
                case 241 /* ClassDeclaration */:
                case 245 /* ModuleDeclaration */:
                case 244 /* EnumDeclaration */:
                case 275 /* CatchClause */:
                case 246 /* ModuleBlock */:
                case 233 /* SwitchStatement */:
                    return true;
                case 219 /* Block */: {
                    var blockParent = context.currentTokenParent.parent;
                    // In a codefix scenario, we can't rely on parents being set. So just always return true.
                    if (!blockParent || blockParent.kind !== 198 /* ArrowFunction */ && blockParent.kind !== 197 /* FunctionExpression */) {
                        return true;
                    }
                }
            }
            return false;
        }
        function isControlDeclContext(context) {
            switch (context.contextNode.kind) {
                case 223 /* IfStatement */:
                case 233 /* SwitchStatement */:
                case 226 /* ForStatement */:
                case 227 /* ForInStatement */:
                case 228 /* ForOfStatement */:
                case 225 /* WhileStatement */:
                case 236 /* TryStatement */:
                case 224 /* DoStatement */:
                case 232 /* WithStatement */:
                // TODO
                // case SyntaxKind.ElseClause:
                case 275 /* CatchClause */:
                    return true;
                default:
                    return false;
            }
        }
        function isObjectContext(context) {
            return context.contextNode.kind === 189 /* ObjectLiteralExpression */;
        }
        function isFunctionCallContext(context) {
            return context.contextNode.kind === 192 /* CallExpression */;
        }
        function isNewContext(context) {
            return context.contextNode.kind === 193 /* NewExpression */;
        }
        function isFunctionCallOrNewContext(context) {
            return isFunctionCallContext(context) || isNewContext(context);
        }
        function isPreviousTokenNotComma(context) {
            return context.currentTokenSpan.kind !== 27 /* CommaToken */;
        }
        function isNextTokenNotCloseBracket(context) {
            return context.nextTokenSpan.kind !== 23 /* CloseBracketToken */;
        }
        function isArrowFunctionContext(context) {
            return context.contextNode.kind === 198 /* ArrowFunction */;
        }
        function isImportTypeContext(context) {
            return context.contextNode.kind === 184 /* ImportType */;
        }
        function isNonJsxSameLineTokenContext(context) {
            return context.TokensAreOnSameLine() && context.contextNode.kind !== 11 /* JsxText */;
        }
        function isNonJsxElementOrFragmentContext(context) {
            return context.contextNode.kind !== 261 /* JsxElement */ && context.contextNode.kind !== 265 /* JsxFragment */;
        }
        function isJsxExpressionContext(context) {
            return context.contextNode.kind === 271 /* JsxExpression */ || context.contextNode.kind === 270 /* JsxSpreadAttribute */;
        }
        function isNextTokenParentJsxAttribute(context) {
            return context.nextTokenParent.kind === 268 /* JsxAttribute */;
        }
        function isJsxAttributeContext(context) {
            return context.contextNode.kind === 268 /* JsxAttribute */;
        }
        function isJsxSelfClosingElementContext(context) {
            return context.contextNode.kind === 262 /* JsxSelfClosingElement */;
        }
        function isNotBeforeBlockInFunctionDeclarationContext(context) {
            return !isFunctionDeclContext(context) && !isBeforeBlockContext(context);
        }
        function isEndOfDecoratorContextOnSameLine(context) {
            return context.TokensAreOnSameLine() &&
                !!context.contextNode.decorators &&
                nodeIsInDecoratorContext(context.currentTokenParent) &&
                !nodeIsInDecoratorContext(context.nextTokenParent);
        }
        function nodeIsInDecoratorContext(node) {
            while (ts.isExpressionNode(node)) {
                node = node.parent;
            }
            return node.kind === 153 /* Decorator */;
        }
        function isStartOfVariableDeclarationList(context) {
            return context.currentTokenParent.kind === 239 /* VariableDeclarationList */ &&
                context.currentTokenParent.getStart(context.sourceFile) === context.currentTokenSpan.pos;
        }
        function isNotFormatOnEnter(context) {
            return context.formattingRequestKind !== 2 /* FormatOnEnter */;
        }
        function isModuleDeclContext(context) {
            return context.contextNode.kind === 245 /* ModuleDeclaration */;
        }
        function isObjectTypeContext(context) {
            return context.contextNode.kind === 169 /* TypeLiteral */; // && context.contextNode.parent.kind !== SyntaxKind.InterfaceDeclaration;
        }
        function isConstructorSignatureContext(context) {
            return context.contextNode.kind === 162 /* ConstructSignature */;
        }
        function isTypeArgumentOrParameterOrAssertion(token, parent) {
            if (token.kind !== 28 /* LessThanToken */ && token.kind !== 30 /* GreaterThanToken */) {
                return false;
            }
            switch (parent.kind) {
                case 165 /* TypeReference */:
                case 195 /* TypeAssertionExpression */:
                case 243 /* TypeAliasDeclaration */:
                case 241 /* ClassDeclaration */:
                case 210 /* ClassExpression */:
                case 242 /* InterfaceDeclaration */:
                case 240 /* FunctionDeclaration */:
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */:
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                case 161 /* CallSignature */:
                case 162 /* ConstructSignature */:
                case 192 /* CallExpression */:
                case 193 /* NewExpression */:
                case 212 /* ExpressionWithTypeArguments */:
                    return true;
                default:
                    return false;
            }
        }
        function isTypeArgumentOrParameterOrAssertionContext(context) {
            return isTypeArgumentOrParameterOrAssertion(context.currentTokenSpan, context.currentTokenParent) ||
                isTypeArgumentOrParameterOrAssertion(context.nextTokenSpan, context.nextTokenParent);
        }
        function isTypeAssertionContext(context) {
            return context.contextNode.kind === 195 /* TypeAssertionExpression */;
        }
        function isVoidOpContext(context) {
            return context.currentTokenSpan.kind === 107 /* VoidKeyword */ && context.currentTokenParent.kind === 201 /* VoidExpression */;
        }
        function isYieldOrYieldStarWithOperand(context) {
            return context.contextNode.kind === 208 /* YieldExpression */ && context.contextNode.expression !== undefined;
        }
        function isNonNullAssertionContext(context) {
            return context.contextNode.kind === 214 /* NonNullExpression */;
        }
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        function getFormatContext(options) {
            return { options: options, getRule: getRulesMap() };
        }
        formatting.getFormatContext = getFormatContext;
        var rulesMapCache;
        function getRulesMap() {
            if (rulesMapCache === undefined) {
                rulesMapCache = createRulesMap(formatting.getAllRules());
            }
            return rulesMapCache;
        }
        function createRulesMap(rules) {
            var map = buildMap(rules);
            return function (context) {
                var bucket = map[getRuleBucketIndex(context.currentTokenSpan.kind, context.nextTokenSpan.kind)];
                return bucket && ts.find(bucket, function (rule) { return ts.every(rule.context, function (c) { return c(context); }); });
            };
        }
        function buildMap(rules) {
            // Map from bucket index to array of rules
            var map = new Array(mapRowLength * mapRowLength);
            // This array is used only during construction of the rulesbucket in the map
            var rulesBucketConstructionStateList = new Array(map.length);
            for (var _i = 0, rules_1 = rules; _i < rules_1.length; _i++) {
                var rule = rules_1[_i];
                var specificRule = rule.leftTokenRange.isSpecific && rule.rightTokenRange.isSpecific;
                for (var _a = 0, _b = rule.leftTokenRange.tokens; _a < _b.length; _a++) {
                    var left = _b[_a];
                    for (var _c = 0, _d = rule.rightTokenRange.tokens; _c < _d.length; _c++) {
                        var right = _d[_c];
                        var index = getRuleBucketIndex(left, right);
                        var rulesBucket = map[index];
                        if (rulesBucket === undefined) {
                            rulesBucket = map[index] = [];
                        }
                        addRule(rulesBucket, rule.rule, specificRule, rulesBucketConstructionStateList, index);
                    }
                }
            }
            return map;
        }
        function getRuleBucketIndex(row, column) {
            ts.Debug.assert(row <= 148 /* LastKeyword */ && column <= 148 /* LastKeyword */, "Must compute formatting context from tokens");
            return (row * mapRowLength) + column;
        }
        var maskBitSize = 5;
        var mask = 31; // MaskBitSize bits
        var mapRowLength = 148 /* LastToken */ + 1;
        var RulesPosition;
        (function (RulesPosition) {
            RulesPosition[RulesPosition["IgnoreRulesSpecific"] = 0] = "IgnoreRulesSpecific";
            RulesPosition[RulesPosition["IgnoreRulesAny"] = maskBitSize * 1] = "IgnoreRulesAny";
            RulesPosition[RulesPosition["ContextRulesSpecific"] = maskBitSize * 2] = "ContextRulesSpecific";
            RulesPosition[RulesPosition["ContextRulesAny"] = maskBitSize * 3] = "ContextRulesAny";
            RulesPosition[RulesPosition["NoContextRulesSpecific"] = maskBitSize * 4] = "NoContextRulesSpecific";
            RulesPosition[RulesPosition["NoContextRulesAny"] = maskBitSize * 5] = "NoContextRulesAny";
        })(RulesPosition || (RulesPosition = {}));
        // The Rules list contains all the inserted rules into a rulebucket in the following order:
        //    1- Ignore rules with specific token combination
        //    2- Ignore rules with any token combination
        //    3- Context rules with specific token combination
        //    4- Context rules with any token combination
        //    5- Non-context rules with specific token combination
        //    6- Non-context rules with any token combination
        //
        // The member rulesInsertionIndexBitmap is used to describe the number of rules
        // in each sub-bucket (above) hence can be used to know the index of where to insert
        // the next rule. It's a bitmap which contains 6 different sections each is given 5 bits.
        //
        // Example:
        // In order to insert a rule to the end of sub-bucket (3), we get the index by adding
        // the values in the bitmap segments 3rd, 2nd, and 1st.
        function addRule(rules, rule, specificTokens, constructionState, rulesBucketIndex) {
            var position = rule.action === 1 /* Ignore */
                ? specificTokens ? RulesPosition.IgnoreRulesSpecific : RulesPosition.IgnoreRulesAny
                : rule.context !== formatting.anyContext
                    ? specificTokens ? RulesPosition.ContextRulesSpecific : RulesPosition.ContextRulesAny
                    : specificTokens ? RulesPosition.NoContextRulesSpecific : RulesPosition.NoContextRulesAny;
            var state = constructionState[rulesBucketIndex] || 0;
            rules.splice(getInsertionIndex(state, position), 0, rule);
            constructionState[rulesBucketIndex] = increaseInsertionIndex(state, position);
        }
        function getInsertionIndex(indexBitmap, maskPosition) {
            var index = 0;
            for (var pos = 0; pos <= maskPosition; pos += maskBitSize) {
                index += indexBitmap & mask;
                indexBitmap >>= maskBitSize;
            }
            return index;
        }
        function increaseInsertionIndex(indexBitmap, maskPosition) {
            var value = ((indexBitmap >> maskPosition) & mask) + 1;
            ts.Debug.assert((value & mask) === value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules.");
            return (indexBitmap & ~(mask << maskPosition)) | (value << maskPosition);
        }
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var Constants;
        (function (Constants) {
            Constants[Constants["Unknown"] = -1] = "Unknown";
        })(Constants || (Constants = {}));
        function formatOnEnter(position, sourceFile, formatContext) {
            var line = sourceFile.getLineAndCharacterOfPosition(position).line;
            if (line === 0) {
                return [];
            }
            // After the enter key, the cursor is now at a new line. The new line may or may not contain non-whitespace characters.
            // If the new line has only whitespaces, we won't want to format this line, because that would remove the indentation as
            // trailing whitespaces. So the end of the formatting span should be the later one between:
            //  1. the end of the previous line
            //  2. the last non-whitespace character in the current line
            var endOfFormatSpan = ts.getEndLinePosition(line, sourceFile);
            while (ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(endOfFormatSpan))) {
                endOfFormatSpan--;
            }
            // if the character at the end of the span is a line break, we shouldn't include it, because it indicates we don't want to
            // touch the current line at all. Also, on some OSes the line break consists of two characters (\r\n), we should test if the
            // previous character before the end of format span is line break character as well.
            if (ts.isLineBreak(sourceFile.text.charCodeAt(endOfFormatSpan))) {
                endOfFormatSpan--;
            }
            var span = {
                // get start position for the previous line
                pos: ts.getStartPositionOfLine(line - 1, sourceFile),
                // end value is exclusive so add 1 to the result
                end: endOfFormatSpan + 1
            };
            return formatSpan(span, sourceFile, formatContext, 2 /* FormatOnEnter */);
        }
        formatting.formatOnEnter = formatOnEnter;
        function formatOnSemicolon(position, sourceFile, formatContext) {
            var semicolon = findImmediatelyPrecedingTokenOfKind(position, 26 /* SemicolonToken */, sourceFile);
            return formatNodeLines(findOutermostNodeWithinListLevel(semicolon), sourceFile, formatContext, 3 /* FormatOnSemicolon */);
        }
        formatting.formatOnSemicolon = formatOnSemicolon;
        function formatOnOpeningCurly(position, sourceFile, formatContext) {
            var openingCurly = findImmediatelyPrecedingTokenOfKind(position, 18 /* OpenBraceToken */, sourceFile);
            if (!openingCurly) {
                return [];
            }
            var curlyBraceRange = openingCurly.parent;
            var outermostNode = findOutermostNodeWithinListLevel(curlyBraceRange);
            /**
             * We limit the span to end at the opening curly to handle the case where
             * the brace matched to that just typed will be incorrect after further edits.
             * For example, we could type the opening curly for the following method
             * body without brace-matching activated:
             * ```
             * class C {
             *     foo()
             * }
             * ```
             * and we wouldn't want to move the closing brace.
             */
            var textRange = {
                pos: ts.getLineStartPositionForPosition(outermostNode.getStart(sourceFile), sourceFile),
                end: position
            };
            return formatSpan(textRange, sourceFile, formatContext, 4 /* FormatOnOpeningCurlyBrace */);
        }
        formatting.formatOnOpeningCurly = formatOnOpeningCurly;
        function formatOnClosingCurly(position, sourceFile, formatContext) {
            var precedingToken = findImmediatelyPrecedingTokenOfKind(position, 19 /* CloseBraceToken */, sourceFile);
            return formatNodeLines(findOutermostNodeWithinListLevel(precedingToken), sourceFile, formatContext, 5 /* FormatOnClosingCurlyBrace */);
        }
        formatting.formatOnClosingCurly = formatOnClosingCurly;
        function formatDocument(sourceFile, formatContext) {
            var span = {
                pos: 0,
                end: sourceFile.text.length
            };
            return formatSpan(span, sourceFile, formatContext, 0 /* FormatDocument */);
        }
        formatting.formatDocument = formatDocument;
        function formatSelection(start, end, sourceFile, formatContext) {
            // format from the beginning of the line
            var span = {
                pos: ts.getLineStartPositionForPosition(start, sourceFile),
                end: end,
            };
            return formatSpan(span, sourceFile, formatContext, 1 /* FormatSelection */);
        }
        formatting.formatSelection = formatSelection;
        /**
         * Validating `expectedTokenKind` ensures the token was typed in the context we expect (eg: not a comment).
         * @param expectedTokenKind The kind of the last token constituting the desired parent node.
         */
        function findImmediatelyPrecedingTokenOfKind(end, expectedTokenKind, sourceFile) {
            var precedingToken = ts.findPrecedingToken(end, sourceFile);
            return precedingToken && precedingToken.kind === expectedTokenKind && end === precedingToken.getEnd() ?
                precedingToken :
                undefined;
        }
        /**
         * Finds the highest node enclosing `node` at the same list level as `node`
         * and whose end does not exceed `node.end`.
         *
         * Consider typing the following
         * ```
         * let x = 1;
         * while (true) {
         * }
         * ```
         * Upon typing the closing curly, we want to format the entire `while`-statement, but not the preceding
         * variable declaration.
         */
        function findOutermostNodeWithinListLevel(node) {
            var current = node;
            while (current &&
                current.parent &&
                current.parent.end === node.end &&
                !isListElement(current.parent, current)) {
                current = current.parent;
            }
            return current;
        }
        // Returns true if node is a element in some list in parent
        // i.e. parent is class declaration with the list of members and node is one of members.
        function isListElement(parent, node) {
            switch (parent.kind) {
                case 241 /* ClassDeclaration */:
                case 242 /* InterfaceDeclaration */:
                    return ts.rangeContainsRange(parent.members, node);
                case 245 /* ModuleDeclaration */:
                    var body = parent.body;
                    return !!body && body.kind === 246 /* ModuleBlock */ && ts.rangeContainsRange(body.statements, node);
                case 285 /* SourceFile */:
                case 219 /* Block */:
                case 246 /* ModuleBlock */:
                    return ts.rangeContainsRange(parent.statements, node);
                case 275 /* CatchClause */:
                    return ts.rangeContainsRange(parent.block.statements, node);
            }
            return false;
        }
        /** find node that fully contains given text range */
        function findEnclosingNode(range, sourceFile) {
            return find(sourceFile);
            function find(n) {
                var candidate = ts.forEachChild(n, function (c) { return ts.startEndContainsRange(c.getStart(sourceFile), c.end, range) && c; });
                if (candidate) {
                    var result = find(candidate);
                    if (result) {
                        return result;
                    }
                }
                return n;
            }
        }
        /** formatting is not applied to ranges that contain parse errors.
         * This function will return a predicate that for a given text range will tell
         * if there are any parse errors that overlap with the range.
         */
        function prepareRangeContainsErrorFunction(errors, originalRange) {
            if (!errors.length) {
                return rangeHasNoErrors;
            }
            // pick only errors that fall in range
            var sorted = errors
                .filter(function (d) { return ts.rangeOverlapsWithStartEnd(originalRange, d.start, d.start + d.length); }) // TODO: GH#18217
                .sort(function (e1, e2) { return e1.start - e2.start; });
            if (!sorted.length) {
                return rangeHasNoErrors;
            }
            var index = 0;
            return function (r) {
                // in current implementation sequence of arguments [r1, r2...] is monotonically increasing.
                // 'index' tracks the index of the most recent error that was checked.
                while (true) {
                    if (index >= sorted.length) {
                        // all errors in the range were already checked -> no error in specified range
                        return false;
                    }
                    var error = sorted[index];
                    if (r.end <= error.start) {
                        // specified range ends before the error refered by 'index' - no error in range
                        return false;
                    }
                    if (ts.startEndOverlapsWithStartEnd(r.pos, r.end, error.start, error.start + error.length)) {
                        // specified range overlaps with error range
                        return true;
                    }
                    index++;
                }
            };
            function rangeHasNoErrors() {
                return false;
            }
        }
        /**
         * Start of the original range might fall inside the comment - scanner will not yield appropriate results
         * This function will look for token that is located before the start of target range
         * and return its end as start position for the scanner.
         */
        function getScanStartPosition(enclosingNode, originalRange, sourceFile) {
            var start = enclosingNode.getStart(sourceFile);
            if (start === originalRange.pos && enclosingNode.end === originalRange.end) {
                return start;
            }
            var precedingToken = ts.findPrecedingToken(originalRange.pos, sourceFile);
            if (!precedingToken) {
                // no preceding token found - start from the beginning of enclosing node
                return enclosingNode.pos;
            }
            // preceding token ends after the start of original range (i.e when originalRange.pos falls in the middle of literal)
            // start from the beginning of enclosingNode to handle the entire 'originalRange'
            if (precedingToken.end >= originalRange.pos) {
                return enclosingNode.pos;
            }
            return precedingToken.end;
        }
        /*
         * For cases like
         * if (a ||
         *     b ||$
         *     c) {...}
         * If we hit Enter at $ we want line '    b ||' to be indented.
         * Formatting will be applied to the last two lines.
         * Node that fully encloses these lines is binary expression 'a ||...'.
         * Initial indentation for this node will be 0.
         * Binary expressions don't introduce new indentation scopes, however it is possible
         * that some parent node on the same line does - like if statement in this case.
         * Note that we are considering parents only from the same line with initial node -
         * if parent is on the different line - its delta was already contributed
         * to the initial indentation.
         */
        function getOwnOrInheritedDelta(n, options, sourceFile) {
            var previousLine = -1 /* Unknown */;
            var child;
            while (n) {
                var line = sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile)).line;
                if (previousLine !== -1 /* Unknown */ && line !== previousLine) {
                    break;
                }
                if (formatting.SmartIndenter.shouldIndentChildNode(options, n, child, sourceFile)) {
                    return options.indentSize;
                }
                previousLine = line;
                child = n;
                n = n.parent;
            }
            return 0;
        }
        function formatNodeGivenIndentation(node, sourceFileLike, languageVariant, initialIndentation, delta, formatContext) {
            var range = { pos: 0, end: sourceFileLike.text.length };
            return formatting.getFormattingScanner(sourceFileLike.text, languageVariant, range.pos, range.end, function (scanner) { return formatSpanWorker(range, node, initialIndentation, delta, scanner, formatContext, 1 /* FormatSelection */, function (_) { return false; }, // assume that node does not have any errors
            sourceFileLike); });
        }
        formatting.formatNodeGivenIndentation = formatNodeGivenIndentation;
        function formatNodeLines(node, sourceFile, formatContext, requestKind) {
            if (!node) {
                return [];
            }
            var span = {
                pos: ts.getLineStartPositionForPosition(node.getStart(sourceFile), sourceFile),
                end: node.end
            };
            return formatSpan(span, sourceFile, formatContext, requestKind);
        }
        function formatSpan(originalRange, sourceFile, formatContext, requestKind) {
            // find the smallest node that fully wraps the range and compute the initial indentation for the node
            var enclosingNode = findEnclosingNode(originalRange, sourceFile);
            return formatting.getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end, function (scanner) { return formatSpanWorker(originalRange, enclosingNode, formatting.SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, formatContext.options), getOwnOrInheritedDelta(enclosingNode, formatContext.options, sourceFile), scanner, formatContext, requestKind, prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange), sourceFile); });
        }
        function formatSpanWorker(originalRange, enclosingNode, initialIndentation, delta, formattingScanner, _a, requestKind, rangeContainsError, sourceFile) {
            var options = _a.options, getRule = _a.getRule;
            // formatting context is used by rules provider
            var formattingContext = new formatting.FormattingContext(sourceFile, requestKind, options);
            var previousRange;
            var previousParent;
            var previousRangeStartLine;
            var lastIndentedLine;
            var indentationOnLastIndentedLine = -1 /* Unknown */;
            var edits = [];
            formattingScanner.advance();
            if (formattingScanner.isOnToken()) {
                var startLine = sourceFile.getLineAndCharacterOfPosition(enclosingNode.getStart(sourceFile)).line;
                var undecoratedStartLine = startLine;
                if (enclosingNode.decorators) {
                    undecoratedStartLine = sourceFile.getLineAndCharacterOfPosition(ts.getNonDecoratorTokenPosOfNode(enclosingNode, sourceFile)).line;
                }
                processNode(enclosingNode, enclosingNode, startLine, undecoratedStartLine, initialIndentation, delta);
            }
            if (!formattingScanner.isOnToken()) {
                var leadingTrivia = formattingScanner.getCurrentLeadingTrivia();
                if (leadingTrivia) {
                    indentTriviaItems(leadingTrivia, initialIndentation, /*indentNextTokenOrTrivia*/ false, function (item) { return processRange(item, sourceFile.getLineAndCharacterOfPosition(item.pos), enclosingNode, enclosingNode, /*dynamicIndentation*/ undefined); });
                    trimTrailingWhitespacesForRemainingRange();
                }
            }
            return edits;
            // local functions
            /** Tries to compute the indentation for a list element.
             * If list element is not in range then
             * function will pick its actual indentation
             * so it can be pushed downstream as inherited indentation.
             * If list element is in the range - its indentation will be equal
             * to inherited indentation from its predecessors.
             */
            function tryComputeIndentationForListItem(startPos, endPos, parentStartLine, range, inheritedIndentation) {
                if (ts.rangeOverlapsWithStartEnd(range, startPos, endPos) ||
                    ts.rangeContainsStartEnd(range, startPos, endPos) /* Not to miss zero-range nodes e.g. JsxText */) {
                    if (inheritedIndentation !== -1 /* Unknown */) {
                        return inheritedIndentation;
                    }
                }
                else {
                    var startLine = sourceFile.getLineAndCharacterOfPosition(startPos).line;
                    var startLinePosition = ts.getLineStartPositionForPosition(startPos, sourceFile);
                    var column = formatting.SmartIndenter.findFirstNonWhitespaceColumn(startLinePosition, startPos, sourceFile, options);
                    if (startLine !== parentStartLine || startPos === column) {
                        // Use the base indent size if it is greater than
                        // the indentation of the inherited predecessor.
                        var baseIndentSize = formatting.SmartIndenter.getBaseIndentation(options);
                        return baseIndentSize > column ? baseIndentSize : column;
                    }
                }
                return -1 /* Unknown */;
            }
            function computeIndentation(node, startLine, inheritedIndentation, parent, parentDynamicIndentation, effectiveParentStartLine) {
                var delta = formatting.SmartIndenter.shouldIndentChildNode(options, node) ? options.indentSize : 0;
                if (effectiveParentStartLine === startLine) {
                    // if node is located on the same line with the parent
                    // - inherit indentation from the parent
                    // - push children if either parent of node itself has non-zero delta
                    return {
                        indentation: startLine === lastIndentedLine ? indentationOnLastIndentedLine : parentDynamicIndentation.getIndentation(),
                        delta: Math.min(options.indentSize, parentDynamicIndentation.getDelta(node) + delta)
                    };
                }
                else if (inheritedIndentation === -1 /* Unknown */) {
                    if (node.kind === 20 /* OpenParenToken */ && startLine === lastIndentedLine) {
                        // the is used for chaining methods formatting
                        // - we need to get the indentation on last line and the delta of parent
                        return { indentation: indentationOnLastIndentedLine, delta: parentDynamicIndentation.getDelta(node) };
                    }
                    else if (formatting.SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) {
                        return { indentation: parentDynamicIndentation.getIndentation(), delta: delta };
                    }
                    else {
                        return { indentation: parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(node), delta: delta };
                    }
                }
                else {
                    return { indentation: inheritedIndentation, delta: delta };
                }
            }
            function getFirstNonDecoratorTokenOfNode(node) {
                if (node.modifiers && node.modifiers.length) {
                    return node.modifiers[0].kind;
                }
                switch (node.kind) {
                    case 241 /* ClassDeclaration */: return 77 /* ClassKeyword */;
                    case 242 /* InterfaceDeclaration */: return 111 /* InterfaceKeyword */;
                    case 240 /* FunctionDeclaration */: return 91 /* FunctionKeyword */;
                    case 244 /* EnumDeclaration */: return 244 /* EnumDeclaration */;
                    case 159 /* GetAccessor */: return 127 /* GetKeyword */;
                    case 160 /* SetAccessor */: return 138 /* SetKeyword */;
                    case 157 /* MethodDeclaration */:
                        if (node.asteriskToken) {
                            return 40 /* AsteriskToken */;
                        }
                    // falls through
                    case 155 /* PropertyDeclaration */:
                    case 152 /* Parameter */:
                        var name = ts.getNameOfDeclaration(node);
                        if (name) {
                            return name.kind;
                        }
                }
            }
            function getDynamicIndentation(node, nodeStartLine, indentation, delta) {
                return {
                    getIndentationForComment: function (kind, tokenIndentation, container) {
                        switch (kind) {
                            // preceding comment to the token that closes the indentation scope inherits the indentation from the scope
                            // ..  {
                            //     // comment
                            // }
                            case 19 /* CloseBraceToken */:
                            case 23 /* CloseBracketToken */:
                            case 21 /* CloseParenToken */:
                                return indentation + getDelta(container);
                        }
                        return tokenIndentation !== -1 /* Unknown */ ? tokenIndentation : indentation;
                    },
                    // if list end token is LessThanToken '>' then its delta should be explicitly suppressed
                    // so that LessThanToken as a binary operator can still be indented.
                    // foo.then
                    //     <
                    //         number,
                    //         string,
                    //     >();
                    // vs
                    // var a = xValue
                    //     > yValue;
                    getIndentationForToken: function (line, kind, container, suppressDelta) {
                        return !suppressDelta && shouldAddDelta(line, kind, container) ? indentation + getDelta(container) : indentation;
                    },
                    getIndentation: function () { return indentation; },
                    getDelta: getDelta,
                    recomputeIndentation: function (lineAdded) {
                        if (node.parent && formatting.SmartIndenter.shouldIndentChildNode(options, node.parent, node, sourceFile)) {
                            indentation += lineAdded ? options.indentSize : -options.indentSize;
                            delta = formatting.SmartIndenter.shouldIndentChildNode(options, node) ? options.indentSize : 0;
                        }
                    }
                };
                function shouldAddDelta(line, kind, container) {
                    switch (kind) {
                        // open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent
                        case 18 /* OpenBraceToken */:
                        case 19 /* CloseBraceToken */:
                        case 21 /* CloseParenToken */:
                        case 84 /* ElseKeyword */:
                        case 108 /* WhileKeyword */:
                        case 58 /* AtToken */:
                            return false;
                        case 42 /* SlashToken */:
                        case 30 /* GreaterThanToken */:
                            switch (container.kind) {
                                case 263 /* JsxOpeningElement */:
                                case 264 /* JsxClosingElement */:
                                case 262 /* JsxSelfClosingElement */:
                                    return false;
                            }
                            break;
                        case 22 /* OpenBracketToken */:
                        case 23 /* CloseBracketToken */:
                            if (container.kind !== 182 /* MappedType */) {
                                return false;
                            }
                            break;
                    }
                    // if token line equals to the line of containing node (this is a first token in the node) - use node indentation
                    return nodeStartLine !== line
                        // if this token is the first token following the list of decorators, we do not need to indent
                        && !(node.decorators && kind === getFirstNonDecoratorTokenOfNode(node));
                }
                function getDelta(child) {
                    // Delta value should be zero when the node explicitly prevents indentation of the child node
                    return formatting.SmartIndenter.nodeWillIndentChild(options, node, child, sourceFile, /*indentByDefault*/ true) ? delta : 0;
                }
            }
            function processNode(node, contextNode, nodeStartLine, undecoratedNodeStartLine, indentation, delta) {
                if (!ts.rangeOverlapsWithStartEnd(originalRange, node.getStart(sourceFile), node.getEnd())) {
                    return;
                }
                var nodeDynamicIndentation = getDynamicIndentation(node, nodeStartLine, indentation, delta);
                // a useful observations when tracking context node
                //        /
                //      [a]
                //   /   |   \
                //  [b] [c] [d]
                // node 'a' is a context node for nodes 'b', 'c', 'd'
                // except for the leftmost leaf token in [b] - in this case context node ('e') is located somewhere above 'a'
                // this rule can be applied recursively to child nodes of 'a'.
                //
                // context node is set to parent node value after processing every child node
                // context node is set to parent of the token after processing every token
                var childContextNode = contextNode;
                // if there are any tokens that logically belong to node and interleave child nodes
                // such tokens will be consumed in processChildNode for the child that follows them
                ts.forEachChild(node, function (child) {
                    processChildNode(child, /*inheritedIndentation*/ -1 /* Unknown */, node, nodeDynamicIndentation, nodeStartLine, undecoratedNodeStartLine, /*isListItem*/ false);
                }, function (nodes) {
                    processChildNodes(nodes, node, nodeStartLine, nodeDynamicIndentation);
                });
                // proceed any tokens in the node that are located after child nodes
                while (formattingScanner.isOnToken()) {
                    var tokenInfo = formattingScanner.readTokenInfo(node);
                    if (tokenInfo.token.end > node.end) {
                        break;
                    }
                    consumeTokenAndAdvanceScanner(tokenInfo, node, nodeDynamicIndentation, node);
                }
                function processChildNode(child, inheritedIndentation, parent, parentDynamicIndentation, parentStartLine, undecoratedParentStartLine, isListItem, isFirstListItem) {
                    var childStartPos = child.getStart(sourceFile);
                    var childStartLine = sourceFile.getLineAndCharacterOfPosition(childStartPos).line;
                    var undecoratedChildStartLine = childStartLine;
                    if (child.decorators) {
                        undecoratedChildStartLine = sourceFile.getLineAndCharacterOfPosition(ts.getNonDecoratorTokenPosOfNode(child, sourceFile)).line;
                    }
                    // if child is a list item - try to get its indentation, only if parent is within the original range.
                    var childIndentationAmount = -1 /* Unknown */;
                    if (isListItem && ts.rangeContainsRange(originalRange, parent)) {
                        childIndentationAmount = tryComputeIndentationForListItem(childStartPos, child.end, parentStartLine, originalRange, inheritedIndentation);
                        if (childIndentationAmount !== -1 /* Unknown */) {
                            inheritedIndentation = childIndentationAmount;
                        }
                    }
                    // child node is outside the target range - do not dive inside
                    if (!ts.rangeOverlapsWithStartEnd(originalRange, child.pos, child.end)) {
                        if (child.end < originalRange.pos) {
                            formattingScanner.skipToEndOf(child);
                        }
                        return inheritedIndentation;
                    }
                    if (child.getFullWidth() === 0) {
                        return inheritedIndentation;
                    }
                    while (formattingScanner.isOnToken()) {
                        // proceed any parent tokens that are located prior to child.getStart()
                        var tokenInfo = formattingScanner.readTokenInfo(node);
                        if (tokenInfo.token.end > childStartPos) {
                            // stop when formatting scanner advances past the beginning of the child
                            break;
                        }
                        consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, node);
                    }
                    if (!formattingScanner.isOnToken()) {
                        return inheritedIndentation;
                    }
                    // JSX text shouldn't affect indenting
                    if (ts.isToken(child) && child.kind !== 11 /* JsxText */) {
                        // if child node is a token, it does not impact indentation, proceed it using parent indentation scope rules
                        var tokenInfo = formattingScanner.readTokenInfo(child);
                        ts.Debug.assert(tokenInfo.token.end === child.end, "Token end is child end");
                        consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, child);
                        return inheritedIndentation;
                    }
                    var effectiveParentStartLine = child.kind === 153 /* Decorator */ ? childStartLine : undecoratedParentStartLine;
                    var childIndentation = computeIndentation(child, childStartLine, childIndentationAmount, node, parentDynamicIndentation, effectiveParentStartLine);
                    processNode(child, childContextNode, childStartLine, undecoratedChildStartLine, childIndentation.indentation, childIndentation.delta);
                    if (child.kind === 11 /* JsxText */) {
                        var range = { pos: child.getStart(), end: child.getEnd() };
                        indentMultilineCommentOrJsxText(range, childIndentation.indentation, /*firstLineIsIndented*/ true, /*indentFinalLine*/ false);
                    }
                    childContextNode = node;
                    if (isFirstListItem && parent.kind === 188 /* ArrayLiteralExpression */ && inheritedIndentation === -1 /* Unknown */) {
                        inheritedIndentation = childIndentation.indentation;
                    }
                    return inheritedIndentation;
                }
                function processChildNodes(nodes, parent, parentStartLine, parentDynamicIndentation) {
                    ts.Debug.assert(ts.isNodeArray(nodes));
                    var listStartToken = getOpenTokenForList(parent, nodes);
                    var listDynamicIndentation = parentDynamicIndentation;
                    var startLine = parentStartLine;
                    if (listStartToken !== 0 /* Unknown */) {
                        // introduce a new indentation scope for lists (including list start and end tokens)
                        while (formattingScanner.isOnToken()) {
                            var tokenInfo = formattingScanner.readTokenInfo(parent);
                            if (tokenInfo.token.end > nodes.pos) {
                                // stop when formatting scanner moves past the beginning of node list
                                break;
                            }
                            else if (tokenInfo.token.kind === listStartToken) {
                                // consume list start token
                                startLine = sourceFile.getLineAndCharacterOfPosition(tokenInfo.token.pos).line;
                                consumeTokenAndAdvanceScanner(tokenInfo, parent, parentDynamicIndentation, parent);
                                var indentationOnListStartToken = void 0;
                                if (indentationOnLastIndentedLine !== -1 /* Unknown */) {
                                    // scanner just processed list start token so consider last indentation as list indentation
                                    // function foo(): { // last indentation was 0, list item will be indented based on this value
                                    //   foo: number;
                                    // }: {};
                                    indentationOnListStartToken = indentationOnLastIndentedLine;
                                }
                                else {
                                    var startLinePosition = ts.getLineStartPositionForPosition(tokenInfo.token.pos, sourceFile);
                                    indentationOnListStartToken = formatting.SmartIndenter.findFirstNonWhitespaceColumn(startLinePosition, tokenInfo.token.pos, sourceFile, options);
                                }
                                listDynamicIndentation = getDynamicIndentation(parent, parentStartLine, indentationOnListStartToken, options.indentSize); // TODO: GH#18217
                            }
                            else {
                                // consume any tokens that precede the list as child elements of 'node' using its indentation scope
                                consumeTokenAndAdvanceScanner(tokenInfo, parent, parentDynamicIndentation, parent);
                            }
                        }
                    }
                    var inheritedIndentation = -1 /* Unknown */;
                    for (var i = 0; i < nodes.length; i++) {
                        var child = nodes[i];
                        inheritedIndentation = processChildNode(child, inheritedIndentation, node, listDynamicIndentation, startLine, startLine, /*isListItem*/ true, /*isFirstListItem*/ i === 0);
                    }
                    var listEndToken = getCloseTokenForOpenToken(listStartToken);
                    if (listEndToken !== 0 /* Unknown */ && formattingScanner.isOnToken()) {
                        var tokenInfo = formattingScanner.readTokenInfo(parent);
                        if (tokenInfo.token.kind === 27 /* CommaToken */ && ts.isCallLikeExpression(parent)) {
                            formattingScanner.advance();
                            tokenInfo = formattingScanner.isOnToken() ? formattingScanner.readTokenInfo(parent) : undefined;
                        }
                        // consume the list end token only if it is still belong to the parent
                        // there might be the case when current token matches end token but does not considered as one
                        // function (x: function) <--
                        // without this check close paren will be interpreted as list end token for function expression which is wrong
                        if (tokenInfo && tokenInfo.token.kind === listEndToken && ts.rangeContainsRange(parent, tokenInfo.token)) {
                            // consume list end token
                            consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent, /*isListEndToken*/ true);
                        }
                    }
                }
                function consumeTokenAndAdvanceScanner(currentTokenInfo, parent, dynamicIndentation, container, isListEndToken) {
                    ts.Debug.assert(ts.rangeContainsRange(parent, currentTokenInfo.token));
                    var lastTriviaWasNewLine = formattingScanner.lastTrailingTriviaWasNewLine();
                    var indentToken = false;
                    if (currentTokenInfo.leadingTrivia) {
                        processTrivia(currentTokenInfo.leadingTrivia, parent, childContextNode, dynamicIndentation);
                    }
                    var lineAction = 0 /* None */;
                    var isTokenInRange = ts.rangeContainsRange(originalRange, currentTokenInfo.token);
                    var tokenStart = sourceFile.getLineAndCharacterOfPosition(currentTokenInfo.token.pos);
                    if (isTokenInRange) {
                        var rangeHasError = rangeContainsError(currentTokenInfo.token);
                        // save previousRange since processRange will overwrite this value with current one
                        var savePreviousRange = previousRange;
                        lineAction = processRange(currentTokenInfo.token, tokenStart, parent, childContextNode, dynamicIndentation);
                        // do not indent comments\token if token range overlaps with some error
                        if (!rangeHasError) {
                            if (lineAction === 0 /* None */) {
                                // indent token only if end line of previous range does not match start line of the token
                                var prevEndLine = savePreviousRange && sourceFile.getLineAndCharacterOfPosition(savePreviousRange.end).line;
                                indentToken = lastTriviaWasNewLine && tokenStart.line !== prevEndLine;
                            }
                            else {
                                indentToken = lineAction === 1 /* LineAdded */;
                            }
                        }
                    }
                    if (currentTokenInfo.trailingTrivia) {
                        processTrivia(currentTokenInfo.trailingTrivia, parent, childContextNode, dynamicIndentation);
                    }
                    if (indentToken) {
                        var tokenIndentation = (isTokenInRange && !rangeContainsError(currentTokenInfo.token)) ?
                            dynamicIndentation.getIndentationForToken(tokenStart.line, currentTokenInfo.token.kind, container, !!isListEndToken) :
                            -1 /* Unknown */;
                        var indentNextTokenOrTrivia = true;
                        if (currentTokenInfo.leadingTrivia) {
                            var commentIndentation_1 = dynamicIndentation.getIndentationForComment(currentTokenInfo.token.kind, tokenIndentation, container);
                            indentNextTokenOrTrivia = indentTriviaItems(currentTokenInfo.leadingTrivia, commentIndentation_1, indentNextTokenOrTrivia, function (item) { return insertIndentation(item.pos, commentIndentation_1, /*lineAdded*/ false); });
                        }
                        // indent token only if is it is in target range and does not overlap with any error ranges
                        if (tokenIndentation !== -1 /* Unknown */ && indentNextTokenOrTrivia) {
                            insertIndentation(currentTokenInfo.token.pos, tokenIndentation, lineAction === 1 /* LineAdded */);
                            lastIndentedLine = tokenStart.line;
                            indentationOnLastIndentedLine = tokenIndentation;
                        }
                    }
                    formattingScanner.advance();
                    childContextNode = parent;
                }
            }
            function indentTriviaItems(trivia, commentIndentation, indentNextTokenOrTrivia, indentSingleLine) {
                for (var _i = 0, trivia_1 = trivia; _i < trivia_1.length; _i++) {
                    var triviaItem = trivia_1[_i];
                    var triviaInRange = ts.rangeContainsRange(originalRange, triviaItem);
                    switch (triviaItem.kind) {
                        case 3 /* MultiLineCommentTrivia */:
                            if (triviaInRange) {
                                indentMultilineCommentOrJsxText(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia);
                            }
                            indentNextTokenOrTrivia = false;
                            break;
                        case 2 /* SingleLineCommentTrivia */:
                            if (indentNextTokenOrTrivia && triviaInRange) {
                                indentSingleLine(triviaItem);
                            }
                            indentNextTokenOrTrivia = false;
                            break;
                        case 4 /* NewLineTrivia */:
                            indentNextTokenOrTrivia = true;
                            break;
                    }
                }
                return indentNextTokenOrTrivia;
            }
            function processTrivia(trivia, parent, contextNode, dynamicIndentation) {
                for (var _i = 0, trivia_2 = trivia; _i < trivia_2.length; _i++) {
                    var triviaItem = trivia_2[_i];
                    if (ts.isComment(triviaItem.kind) && ts.rangeContainsRange(originalRange, triviaItem)) {
                        var triviaItemStart = sourceFile.getLineAndCharacterOfPosition(triviaItem.pos);
                        processRange(triviaItem, triviaItemStart, parent, contextNode, dynamicIndentation);
                    }
                }
            }
            function processRange(range, rangeStart, parent, contextNode, dynamicIndentation) {
                var rangeHasError = rangeContainsError(range);
                var lineAction = 0 /* None */;
                if (!rangeHasError) {
                    if (!previousRange) {
                        // trim whitespaces starting from the beginning of the span up to the current line
                        var originalStart = sourceFile.getLineAndCharacterOfPosition(originalRange.pos);
                        trimTrailingWhitespacesForLines(originalStart.line, rangeStart.line);
                    }
                    else {
                        lineAction =
                            processPair(range, rangeStart.line, parent, previousRange, previousRangeStartLine, previousParent, contextNode, dynamicIndentation);
                    }
                }
                previousRange = range;
                previousParent = parent;
                previousRangeStartLine = rangeStart.line;
                return lineAction;
            }
            function processPair(currentItem, currentStartLine, currentParent, previousItem, previousStartLine, previousParent, contextNode, dynamicIndentation) {
                formattingContext.updateContext(previousItem, previousParent, currentItem, currentParent, contextNode);
                var rule = getRule(formattingContext);
                var trimTrailingWhitespaces;
                var lineAction = 0 /* None */;
                if (rule) {
                    lineAction = applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine);
                    switch (lineAction) {
                        case 2 /* LineRemoved */:
                            // Handle the case where the next line is moved to be the end of this line.
                            // In this case we don't indent the next line in the next pass.
                            if (currentParent.getStart(sourceFile) === currentItem.pos) {
                                dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ false);
                            }
                            break;
                        case 1 /* LineAdded */:
                            // Handle the case where token2 is moved to the new line.
                            // In this case we indent token2 in the next pass but we set
                            // sameLineIndent flag to notify the indenter that the indentation is within the line.
                            if (currentParent.getStart(sourceFile) === currentItem.pos) {
                                dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ true);
                            }
                            break;
                        default:
                            ts.Debug.assert(lineAction === 0 /* None */);
                    }
                    // We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line
                    trimTrailingWhitespaces = !(rule.action & 8 /* Delete */) && rule.flags !== 1 /* CanDeleteNewLines */;
                }
                else {
                    trimTrailingWhitespaces = true;
                }
                if (currentStartLine !== previousStartLine && trimTrailingWhitespaces) {
                    // We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line
                    trimTrailingWhitespacesForLines(previousStartLine, currentStartLine, previousItem);
                }
                return lineAction;
            }
            function insertIndentation(pos, indentation, lineAdded) {
                var indentationString = getIndentationString(indentation, options);
                if (lineAdded) {
                    // new line is added before the token by the formatting rules
                    // insert indentation string at the very beginning of the token
                    recordReplace(pos, 0, indentationString);
                }
                else {
                    var tokenStart = sourceFile.getLineAndCharacterOfPosition(pos);
                    var startLinePosition = ts.getStartPositionOfLine(tokenStart.line, sourceFile);
                    if (indentation !== characterToColumn(startLinePosition, tokenStart.character) || indentationIsDifferent(indentationString, startLinePosition)) {
                        recordReplace(startLinePosition, tokenStart.character, indentationString);
                    }
                }
            }
            function characterToColumn(startLinePosition, characterInLine) {
                var column = 0;
                for (var i = 0; i < characterInLine; i++) {
                    if (sourceFile.text.charCodeAt(startLinePosition + i) === 9 /* tab */) {
                        column += options.tabSize - column % options.tabSize;
                    }
                    else {
                        column++;
                    }
                }
                return column;
            }
            function indentationIsDifferent(indentationString, startLinePosition) {
                return indentationString !== sourceFile.text.substr(startLinePosition, indentationString.length);
            }
            function indentMultilineCommentOrJsxText(commentRange, indentation, firstLineIsIndented, indentFinalLine) {
                if (indentFinalLine === void 0) { indentFinalLine = true; }
                // split comment in lines
                var startLine = sourceFile.getLineAndCharacterOfPosition(commentRange.pos).line;
                var endLine = sourceFile.getLineAndCharacterOfPosition(commentRange.end).line;
                if (startLine === endLine) {
                    if (!firstLineIsIndented) {
                        // treat as single line comment
                        insertIndentation(commentRange.pos, indentation, /*lineAdded*/ false);
                    }
                    return;
                }
                var parts = [];
                var startPos = commentRange.pos;
                for (var line = startLine; line < endLine; line++) {
                    var endOfLine = ts.getEndLinePosition(line, sourceFile);
                    parts.push({ pos: startPos, end: endOfLine });
                    startPos = ts.getStartPositionOfLine(line + 1, sourceFile);
                }
                if (indentFinalLine) {
                    parts.push({ pos: startPos, end: commentRange.end });
                }
                if (parts.length === 0)
                    return;
                var startLinePos = ts.getStartPositionOfLine(startLine, sourceFile);
                var nonWhitespaceColumnInFirstPart = formatting.SmartIndenter.findFirstNonWhitespaceCharacterAndColumn(startLinePos, parts[0].pos, sourceFile, options);
                if (indentation === nonWhitespaceColumnInFirstPart.column) {
                    return;
                }
                var startIndex = 0;
                if (firstLineIsIndented) {
                    startIndex = 1;
                    startLine++;
                }
                // shift all parts on the delta size
                var delta = indentation - nonWhitespaceColumnInFirstPart.column;
                for (var i = startIndex; i < parts.length; i++, startLine++) {
                    var startLinePos_1 = ts.getStartPositionOfLine(startLine, sourceFile);
                    var nonWhitespaceCharacterAndColumn = i === 0
                        ? nonWhitespaceColumnInFirstPart
                        : formatting.SmartIndenter.findFirstNonWhitespaceCharacterAndColumn(parts[i].pos, parts[i].end, sourceFile, options);
                    var newIndentation = nonWhitespaceCharacterAndColumn.column + delta;
                    if (newIndentation > 0) {
                        var indentationString = getIndentationString(newIndentation, options);
                        recordReplace(startLinePos_1, nonWhitespaceCharacterAndColumn.character, indentationString);
                    }
                    else {
                        recordDelete(startLinePos_1, nonWhitespaceCharacterAndColumn.character);
                    }
                }
            }
            function trimTrailingWhitespacesForLines(line1, line2, range) {
                for (var line = line1; line < line2; line++) {
                    var lineStartPosition = ts.getStartPositionOfLine(line, sourceFile);
                    var lineEndPosition = ts.getEndLinePosition(line, sourceFile);
                    // do not trim whitespaces in comments or template expression
                    if (range && (ts.isComment(range.kind) || ts.isStringOrRegularExpressionOrTemplateLiteral(range.kind)) && range.pos <= lineEndPosition && range.end > lineEndPosition) {
                        continue;
                    }
                    var whitespaceStart = getTrailingWhitespaceStartPosition(lineStartPosition, lineEndPosition);
                    if (whitespaceStart !== -1) {
                        ts.Debug.assert(whitespaceStart === lineStartPosition || !ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(whitespaceStart - 1)));
                        recordDelete(whitespaceStart, lineEndPosition + 1 - whitespaceStart);
                    }
                }
            }
            /**
             * @param start The position of the first character in range
             * @param end The position of the last character in range
             */
            function getTrailingWhitespaceStartPosition(start, end) {
                var pos = end;
                while (pos >= start && ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(pos))) {
                    pos--;
                }
                if (pos !== end) {
                    return pos + 1;
                }
                return -1;
            }
            /**
             * Trimming will be done for lines after the previous range
             */
            function trimTrailingWhitespacesForRemainingRange() {
                var startPosition = previousRange ? previousRange.end : originalRange.pos;
                var startLine = sourceFile.getLineAndCharacterOfPosition(startPosition).line;
                var endLine = sourceFile.getLineAndCharacterOfPosition(originalRange.end).line;
                trimTrailingWhitespacesForLines(startLine, endLine + 1, previousRange);
            }
            function recordDelete(start, len) {
                if (len) {
                    edits.push(ts.createTextChangeFromStartLength(start, len, ""));
                }
            }
            function recordReplace(start, len, newText) {
                if (len || newText) {
                    edits.push(ts.createTextChangeFromStartLength(start, len, newText));
                }
            }
            function applyRuleEdits(rule, previousRange, previousStartLine, currentRange, currentStartLine) {
                var onLaterLine = currentStartLine !== previousStartLine;
                switch (rule.action) {
                    case 1 /* Ignore */:
                        // no action required
                        return 0 /* None */;
                    case 8 /* Delete */:
                        if (previousRange.end !== currentRange.pos) {
                            // delete characters starting from t1.end up to t2.pos exclusive
                            recordDelete(previousRange.end, currentRange.pos - previousRange.end);
                            return onLaterLine ? 2 /* LineRemoved */ : 0 /* None */;
                        }
                        break;
                    case 4 /* NewLine */:
                        // exit early if we on different lines and rule cannot change number of newlines
                        // if line1 and line2 are on subsequent lines then no edits are required - ok to exit
                        // if line1 and line2 are separated with more than one newline - ok to exit since we cannot delete extra new lines
                        if (rule.flags !== 1 /* CanDeleteNewLines */ && previousStartLine !== currentStartLine) {
                            return 0 /* None */;
                        }
                        // edit should not be applied if we have one line feed between elements
                        var lineDelta = currentStartLine - previousStartLine;
                        if (lineDelta !== 1) {
                            recordReplace(previousRange.end, currentRange.pos - previousRange.end, options.newLineCharacter);
                            return onLaterLine ? 0 /* None */ : 1 /* LineAdded */;
                        }
                        break;
                    case 2 /* Space */:
                        // exit early if we on different lines and rule cannot change number of newlines
                        if (rule.flags !== 1 /* CanDeleteNewLines */ && previousStartLine !== currentStartLine) {
                            return 0 /* None */;
                        }
                        var posDelta = currentRange.pos - previousRange.end;
                        if (posDelta !== 1 || sourceFile.text.charCodeAt(previousRange.end) !== 32 /* space */) {
                            recordReplace(previousRange.end, currentRange.pos - previousRange.end, " ");
                            return onLaterLine ? 2 /* LineRemoved */ : 0 /* None */;
                        }
                }
                return 0 /* None */;
            }
        }
        var LineAction;
        (function (LineAction) {
            LineAction[LineAction["None"] = 0] = "None";
            LineAction[LineAction["LineAdded"] = 1] = "LineAdded";
            LineAction[LineAction["LineRemoved"] = 2] = "LineRemoved";
        })(LineAction || (LineAction = {}));
        /**
         * @param precedingToken pass `null` if preceding token was already computed and result was `undefined`.
         */
        function getRangeOfEnclosingComment(sourceFile, position, precedingToken, // tslint:disable-line:no-null-keyword
        tokenAtPosition) {
            if (tokenAtPosition === void 0) { tokenAtPosition = ts.getTokenAtPosition(sourceFile, position); }
            var jsdoc = ts.findAncestor(tokenAtPosition, ts.isJSDoc);
            if (jsdoc)
                tokenAtPosition = jsdoc.parent;
            var tokenStart = tokenAtPosition.getStart(sourceFile);
            if (tokenStart <= position && position < tokenAtPosition.getEnd()) {
                return undefined;
            }
            precedingToken = precedingToken === null ? undefined : precedingToken === undefined ? ts.findPrecedingToken(position, sourceFile) : precedingToken;
            // Between two consecutive tokens, all comments are either trailing on the former
            // or leading on the latter (and none are in both lists).
            var trailingRangesOfPreviousToken = precedingToken && ts.getTrailingCommentRanges(sourceFile.text, precedingToken.end);
            var leadingCommentRangesOfNextToken = ts.getLeadingCommentRangesOfNode(tokenAtPosition, sourceFile);
            var commentRanges = ts.concatenate(trailingRangesOfPreviousToken, leadingCommentRangesOfNextToken);
            return commentRanges && ts.find(commentRanges, function (range) { return ts.rangeContainsPositionExclusive(range, position) ||
                // The end marker of a single-line comment does not include the newline character.
                // With caret at `^`, in the following case, we are inside a comment (^ denotes the cursor position):
                //
                //    // asdf   ^\n
                //
                // But for closed multi-line comments, we don't want to be inside the comment in the following case:
                //
                //    /* asdf */^
                //
                // However, unterminated multi-line comments *do* contain their end.
                //
                // Internally, we represent the end of the comment at the newline and closing '/', respectively.
                //
                position === range.end && (range.kind === 2 /* SingleLineCommentTrivia */ || position === sourceFile.getFullWidth()); });
        }
        formatting.getRangeOfEnclosingComment = getRangeOfEnclosingComment;
        function getOpenTokenForList(node, list) {
            switch (node.kind) {
                case 158 /* Constructor */:
                case 240 /* FunctionDeclaration */:
                case 197 /* FunctionExpression */:
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                case 198 /* ArrowFunction */:
                    if (node.typeParameters === list) {
                        return 28 /* LessThanToken */;
                    }
                    else if (node.parameters === list) {
                        return 20 /* OpenParenToken */;
                    }
                    break;
                case 192 /* CallExpression */:
                case 193 /* NewExpression */:
                    if (node.typeArguments === list) {
                        return 28 /* LessThanToken */;
                    }
                    else if (node.arguments === list) {
                        return 20 /* OpenParenToken */;
                    }
                    break;
                case 165 /* TypeReference */:
                    if (node.typeArguments === list) {
                        return 28 /* LessThanToken */;
                    }
                    break;
                case 169 /* TypeLiteral */:
                    return 18 /* OpenBraceToken */;
            }
            return 0 /* Unknown */;
        }
        function getCloseTokenForOpenToken(kind) {
            switch (kind) {
                case 20 /* OpenParenToken */:
                    return 21 /* CloseParenToken */;
                case 28 /* LessThanToken */:
                    return 30 /* GreaterThanToken */;
                case 18 /* OpenBraceToken */:
                    return 19 /* CloseBraceToken */;
            }
            return 0 /* Unknown */;
        }
        var internedSizes;
        var internedTabsIndentation;
        var internedSpacesIndentation;
        function getIndentationString(indentation, options) {
            // reset interned strings if FormatCodeOptions were changed
            var resetInternedStrings = !internedSizes || (internedSizes.tabSize !== options.tabSize || internedSizes.indentSize !== options.indentSize);
            if (resetInternedStrings) {
                internedSizes = { tabSize: options.tabSize, indentSize: options.indentSize };
                internedTabsIndentation = internedSpacesIndentation = undefined;
            }
            if (!options.convertTabsToSpaces) {
                var tabs = Math.floor(indentation / options.tabSize);
                var spaces = indentation - tabs * options.tabSize;
                var tabString = void 0;
                if (!internedTabsIndentation) {
                    internedTabsIndentation = [];
                }
                if (internedTabsIndentation[tabs] === undefined) {
                    internedTabsIndentation[tabs] = tabString = ts.repeatString("\t", tabs);
                }
                else {
                    tabString = internedTabsIndentation[tabs];
                }
                return spaces ? tabString + ts.repeatString(" ", spaces) : tabString;
            }
            else {
                var spacesString = void 0;
                var quotient = Math.floor(indentation / options.indentSize);
                var remainder = indentation % options.indentSize;
                if (!internedSpacesIndentation) {
                    internedSpacesIndentation = [];
                }
                if (internedSpacesIndentation[quotient] === undefined) {
                    spacesString = ts.repeatString(" ", options.indentSize * quotient);
                    internedSpacesIndentation[quotient] = spacesString;
                }
                else {
                    spacesString = internedSpacesIndentation[quotient];
                }
                return remainder ? spacesString + ts.repeatString(" ", remainder) : spacesString;
            }
        }
        formatting.getIndentationString = getIndentationString;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var SmartIndenter;
        (function (SmartIndenter) {
            var Value;
            (function (Value) {
                Value[Value["Unknown"] = -1] = "Unknown";
            })(Value || (Value = {}));
            /**
             * @param assumeNewLineBeforeCloseBrace
             * `false` when called on text from a real source file.
             * `true` when we need to assume `position` is on a newline.
             *
             * This is useful for codefixes. Consider
             * ```
             * function f() {
             * |}
             * ```
             * with `position` at `|`.
             *
             * When inserting some text after an open brace, we would like to get indentation as if a newline was already there.
             * By default indentation at `position` will be 0 so 'assumeNewLineBeforeCloseBrace' overrides this behavior.
             */
            function getIndentation(position, sourceFile, options, assumeNewLineBeforeCloseBrace) {
                if (assumeNewLineBeforeCloseBrace === void 0) { assumeNewLineBeforeCloseBrace = false; }
                if (position > sourceFile.text.length) {
                    return getBaseIndentation(options); // past EOF
                }
                // no indentation when the indent style is set to none,
                // so we can return fast
                if (options.indentStyle === ts.IndentStyle.None) {
                    return 0;
                }
                var precedingToken = ts.findPrecedingToken(position, sourceFile, /*startNode*/ undefined, /*excludeJsdoc*/ true);
                var enclosingCommentRange = formatting.getRangeOfEnclosingComment(sourceFile, position, precedingToken || null); // tslint:disable-line:no-null-keyword
                if (enclosingCommentRange && enclosingCommentRange.kind === 3 /* MultiLineCommentTrivia */) {
                    return getCommentIndent(sourceFile, position, options, enclosingCommentRange);
                }
                if (!precedingToken) {
                    return getBaseIndentation(options);
                }
                // no indentation in string \regex\template literals
                var precedingTokenIsLiteral = ts.isStringOrRegularExpressionOrTemplateLiteral(precedingToken.kind);
                if (precedingTokenIsLiteral && precedingToken.getStart(sourceFile) <= position && position < precedingToken.end) {
                    return 0;
                }
                var lineAtPosition = sourceFile.getLineAndCharacterOfPosition(position).line;
                // indentation is first non-whitespace character in a previous line
                // for block indentation, we should look for a line which contains something that's not
                // whitespace.
                if (options.indentStyle === ts.IndentStyle.Block) {
                    return getBlockIndent(sourceFile, position, options);
                }
                if (precedingToken.kind === 27 /* CommaToken */ && precedingToken.parent.kind !== 205 /* BinaryExpression */) {
                    // previous token is comma that separates items in list - find the previous item and try to derive indentation from it
                    var actualIndentation = getActualIndentationForListItemBeforeComma(precedingToken, sourceFile, options);
                    if (actualIndentation !== -1 /* Unknown */) {
                        return actualIndentation;
                    }
                }
                var containerList = getListByPosition(position, precedingToken.parent, sourceFile);
                // use list position if the preceding token is before any list items
                if (containerList && !ts.rangeContainsRange(containerList, precedingToken)) {
                    return getActualIndentationForListStartLine(containerList, sourceFile, options) + options.indentSize; // TODO: GH#18217
                }
                return getSmartIndent(sourceFile, position, precedingToken, lineAtPosition, assumeNewLineBeforeCloseBrace, options);
            }
            SmartIndenter.getIndentation = getIndentation;
            function getCommentIndent(sourceFile, position, options, enclosingCommentRange) {
                var previousLine = ts.getLineAndCharacterOfPosition(sourceFile, position).line - 1;
                var commentStartLine = ts.getLineAndCharacterOfPosition(sourceFile, enclosingCommentRange.pos).line;
                ts.Debug.assert(commentStartLine >= 0);
                if (previousLine <= commentStartLine) {
                    return findFirstNonWhitespaceColumn(ts.getStartPositionOfLine(commentStartLine, sourceFile), position, sourceFile, options);
                }
                var startPositionOfLine = ts.getStartPositionOfLine(previousLine, sourceFile);
                var _a = findFirstNonWhitespaceCharacterAndColumn(startPositionOfLine, position, sourceFile, options), column = _a.column, character = _a.character;
                if (column === 0) {
                    return column;
                }
                var firstNonWhitespaceCharacterCode = sourceFile.text.charCodeAt(startPositionOfLine + character);
                return firstNonWhitespaceCharacterCode === 42 /* asterisk */ ? column - 1 : column;
            }
            function getBlockIndent(sourceFile, position, options) {
                // move backwards until we find a line with a non-whitespace character,
                // then find the first non-whitespace character for that line.
                var current = position;
                while (current > 0) {
                    var char = sourceFile.text.charCodeAt(current);
                    if (!ts.isWhiteSpaceLike(char)) {
                        break;
                    }
                    current--;
                }
                var lineStart = ts.getLineStartPositionForPosition(current, sourceFile);
                return findFirstNonWhitespaceColumn(lineStart, current, sourceFile, options);
            }
            function getSmartIndent(sourceFile, position, precedingToken, lineAtPosition, assumeNewLineBeforeCloseBrace, options) {
                // try to find node that can contribute to indentation and includes 'position' starting from 'precedingToken'
                // if such node is found - compute initial indentation for 'position' inside this node
                var previous;
                var current = precedingToken;
                while (current) {
                    if (ts.positionBelongsToNode(current, position, sourceFile) && shouldIndentChildNode(options, current, previous, sourceFile, /*isNextChild*/ true)) {
                        var currentStart = getStartLineAndCharacterForNode(current, sourceFile);
                        var nextTokenKind = nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile);
                        var indentationDelta = nextTokenKind !== 0 /* Unknown */
                            // handle cases when codefix is about to be inserted before the close brace
                            ? assumeNewLineBeforeCloseBrace && nextTokenKind === 2 /* CloseBrace */ ? options.indentSize : 0
                            : lineAtPosition !== currentStart.line ? options.indentSize : 0;
                        return getIndentationForNodeWorker(current, currentStart, /*ignoreActualIndentationRange*/ undefined, indentationDelta, sourceFile, /*isNextChild*/ true, options); // TODO: GH#18217
                    }
                    // check if current node is a list item - if yes, take indentation from it
                    // do not consider parent-child line sharing yet:
                    // function foo(a
                    //    | preceding node 'a' does share line with its parent but indentation is expected
                    var actualIndentation = getActualIndentationForListItem(current, sourceFile, options, /*listIndentsChild*/ true);
                    if (actualIndentation !== -1 /* Unknown */) {
                        return actualIndentation;
                    }
                    previous = current;
                    current = current.parent;
                }
                // no parent was found - return the base indentation of the SourceFile
                return getBaseIndentation(options);
            }
            function getIndentationForNode(n, ignoreActualIndentationRange, sourceFile, options) {
                var start = sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile));
                return getIndentationForNodeWorker(n, start, ignoreActualIndentationRange, /*indentationDelta*/ 0, sourceFile, /*isNextChild*/ false, options);
            }
            SmartIndenter.getIndentationForNode = getIndentationForNode;
            function getBaseIndentation(options) {
                return options.baseIndentSize || 0;
            }
            SmartIndenter.getBaseIndentation = getBaseIndentation;
            function getIndentationForNodeWorker(current, currentStart, ignoreActualIndentationRange, indentationDelta, sourceFile, isNextChild, options) {
                var parent = current.parent;
                // Walk up the tree and collect indentation for parent-child node pairs. Indentation is not added if
                // * parent and child nodes start on the same line, or
                // * parent is an IfStatement and child starts on the same line as an 'else clause'.
                while (parent) {
                    var useActualIndentation = true;
                    if (ignoreActualIndentationRange) {
                        var start = current.getStart(sourceFile);
                        useActualIndentation = start < ignoreActualIndentationRange.pos || start > ignoreActualIndentationRange.end;
                    }
                    var containingListOrParentStart = getContainingListOrParentStart(parent, current, sourceFile);
                    var parentAndChildShareLine = containingListOrParentStart.line === currentStart.line ||
                        childStartsOnTheSameLineWithElseInIfStatement(parent, current, currentStart.line, sourceFile);
                    if (useActualIndentation) {
                        // check if current node is a list item - if yes, take indentation from it
                        var actualIndentation = getActualIndentationForListItem(current, sourceFile, options, !parentAndChildShareLine);
                        if (actualIndentation !== -1 /* Unknown */) {
                            return actualIndentation + indentationDelta;
                        }
                        // try to fetch actual indentation for current node from source text
                        actualIndentation = getActualIndentationForNode(current, parent, currentStart, parentAndChildShareLine, sourceFile, options);
                        if (actualIndentation !== -1 /* Unknown */) {
                            return actualIndentation + indentationDelta;
                        }
                    }
                    // increase indentation if parent node wants its content to be indented and parent and child nodes don't start on the same line
                    if (shouldIndentChildNode(options, parent, current, sourceFile, isNextChild) && !parentAndChildShareLine) {
                        indentationDelta += options.indentSize;
                    }
                    // In our AST, a call argument's `parent` is the call-expression, not the argument list.
                    // We would like to increase indentation based on the relationship between an argument and its argument-list,
                    // so we spoof the starting position of the (parent) call-expression to match the (non-parent) argument-list.
                    // But, the spoofed start-value could then cause a problem when comparing the start position of the call-expression
                    // to *its* parent (in the case of an iife, an expression statement), adding an extra level of indentation.
                    //
                    // Instead, when at an argument, we unspoof the starting position of the enclosing call expression
                    // *after* applying indentation for the argument.
                    var useTrueStart = isArgumentAndStartLineOverlapsExpressionBeingCalled(parent, current, currentStart.line, sourceFile);
                    current = parent;
                    parent = current.parent;
                    currentStart = useTrueStart ? sourceFile.getLineAndCharacterOfPosition(current.getStart(sourceFile)) : containingListOrParentStart;
                }
                return indentationDelta + getBaseIndentation(options);
            }
            function getContainingListOrParentStart(parent, child, sourceFile) {
                var containingList = getContainingList(child, sourceFile);
                var startPos = containingList ? containingList.pos : parent.getStart(sourceFile);
                return sourceFile.getLineAndCharacterOfPosition(startPos);
            }
            /*
             * Function returns Value.Unknown if indentation cannot be determined
             */
            function getActualIndentationForListItemBeforeComma(commaToken, sourceFile, options) {
                // previous token is comma that separates items in list - find the previous item and try to derive indentation from it
                var commaItemInfo = ts.findListItemInfo(commaToken);
                if (commaItemInfo && commaItemInfo.listItemIndex > 0) {
                    return deriveActualIndentationFromList(commaItemInfo.list.getChildren(), commaItemInfo.listItemIndex - 1, sourceFile, options);
                }
                else {
                    // handle broken code gracefully
                    return -1 /* Unknown */;
                }
            }
            /*
             * Function returns Value.Unknown if actual indentation for node should not be used (i.e because node is nested expression)
             */
            function getActualIndentationForNode(current, parent, currentLineAndChar, parentAndChildShareLine, sourceFile, options) {
                // actual indentation is used for statements\declarations if one of cases below is true:
                // - parent is SourceFile - by default immediate children of SourceFile are not indented except when user indents them manually
                // - parent and child are not on the same line
                var useActualIndentation = (ts.isDeclaration(current) || ts.isStatementButNotDeclaration(current)) &&
                    (parent.kind === 285 /* SourceFile */ || !parentAndChildShareLine);
                if (!useActualIndentation) {
                    return -1 /* Unknown */;
                }
                return findColumnForFirstNonWhitespaceCharacterInLine(currentLineAndChar, sourceFile, options);
            }
            var NextTokenKind;
            (function (NextTokenKind) {
                NextTokenKind[NextTokenKind["Unknown"] = 0] = "Unknown";
                NextTokenKind[NextTokenKind["OpenBrace"] = 1] = "OpenBrace";
                NextTokenKind[NextTokenKind["CloseBrace"] = 2] = "CloseBrace";
            })(NextTokenKind || (NextTokenKind = {}));
            function nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile) {
                var nextToken = ts.findNextToken(precedingToken, current, sourceFile);
                if (!nextToken) {
                    return 0 /* Unknown */;
                }
                if (nextToken.kind === 18 /* OpenBraceToken */) {
                    // open braces are always indented at the parent level
                    return 1 /* OpenBrace */;
                }
                else if (nextToken.kind === 19 /* CloseBraceToken */) {
                    // close braces are indented at the parent level if they are located on the same line with cursor
                    // this means that if new line will be added at $ position, this case will be indented
                    // class A {
                    //    $
                    // }
                    /// and this one - not
                    // class A {
                    // $}
                    var nextTokenStartLine = getStartLineAndCharacterForNode(nextToken, sourceFile).line;
                    return lineAtPosition === nextTokenStartLine ? 2 /* CloseBrace */ : 0 /* Unknown */;
                }
                return 0 /* Unknown */;
            }
            function getStartLineAndCharacterForNode(n, sourceFile) {
                return sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile));
            }
            function isArgumentAndStartLineOverlapsExpressionBeingCalled(parent, child, childStartLine, sourceFile) {
                if (!(ts.isCallExpression(parent) && ts.contains(parent.arguments, child))) {
                    return false;
                }
                var expressionOfCallExpressionEnd = parent.expression.getEnd();
                var expressionOfCallExpressionEndLine = ts.getLineAndCharacterOfPosition(sourceFile, expressionOfCallExpressionEnd).line;
                return expressionOfCallExpressionEndLine === childStartLine;
            }
            SmartIndenter.isArgumentAndStartLineOverlapsExpressionBeingCalled = isArgumentAndStartLineOverlapsExpressionBeingCalled;
            function childStartsOnTheSameLineWithElseInIfStatement(parent, child, childStartLine, sourceFile) {
                if (parent.kind === 223 /* IfStatement */ && parent.elseStatement === child) {
                    var elseKeyword = ts.findChildOfKind(parent, 84 /* ElseKeyword */, sourceFile);
                    ts.Debug.assert(elseKeyword !== undefined);
                    var elseKeywordStartLine = getStartLineAndCharacterForNode(elseKeyword, sourceFile).line;
                    return elseKeywordStartLine === childStartLine;
                }
                return false;
            }
            SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement = childStartsOnTheSameLineWithElseInIfStatement;
            function getContainingList(node, sourceFile) {
                return node.parent && getListByRange(node.getStart(sourceFile), node.getEnd(), node.parent, sourceFile);
            }
            SmartIndenter.getContainingList = getContainingList;
            function getListByPosition(pos, node, sourceFile) {
                return node && getListByRange(pos, pos, node, sourceFile);
            }
            function getListByRange(start, end, node, sourceFile) {
                switch (node.kind) {
                    case 165 /* TypeReference */:
                        return getList(node.typeArguments);
                    case 189 /* ObjectLiteralExpression */:
                        return getList(node.properties);
                    case 188 /* ArrayLiteralExpression */:
                        return getList(node.elements);
                    case 169 /* TypeLiteral */:
                        return getList(node.members);
                    case 240 /* FunctionDeclaration */:
                    case 197 /* FunctionExpression */:
                    case 198 /* ArrowFunction */:
                    case 157 /* MethodDeclaration */:
                    case 156 /* MethodSignature */:
                    case 161 /* CallSignature */:
                    case 158 /* Constructor */:
                    case 167 /* ConstructorType */:
                    case 162 /* ConstructSignature */:
                        return getList(node.typeParameters) || getList(node.parameters);
                    case 241 /* ClassDeclaration */:
                    case 210 /* ClassExpression */:
                    case 242 /* InterfaceDeclaration */:
                    case 243 /* TypeAliasDeclaration */:
                    case 309 /* JSDocTemplateTag */:
                        return getList(node.typeParameters);
                    case 193 /* NewExpression */:
                    case 192 /* CallExpression */:
                        return getList(node.typeArguments) || getList(node.arguments);
                    case 239 /* VariableDeclarationList */:
                        return getList(node.declarations);
                    case 253 /* NamedImports */:
                    case 257 /* NamedExports */:
                        return getList(node.elements);
                    case 185 /* ObjectBindingPattern */:
                    case 186 /* ArrayBindingPattern */:
                        return getList(node.elements);
                }
                function getList(list) {
                    return list && ts.rangeContainsStartEnd(getVisualListRange(node, list, sourceFile), start, end) ? list : undefined;
                }
            }
            function getVisualListRange(node, list, sourceFile) {
                var children = node.getChildren(sourceFile);
                for (var i = 1; i < children.length - 1; i++) {
                    if (children[i].pos === list.pos && children[i].end === list.end) {
                        return { pos: children[i - 1].end, end: children[i + 1].getStart(sourceFile) };
                    }
                }
                return list;
            }
            function getActualIndentationForListStartLine(list, sourceFile, options) {
                if (!list) {
                    return -1 /* Unknown */;
                }
                return findColumnForFirstNonWhitespaceCharacterInLine(sourceFile.getLineAndCharacterOfPosition(list.pos), sourceFile, options);
            }
            function getActualIndentationForListItem(node, sourceFile, options, listIndentsChild) {
                if (node.parent && node.parent.kind === 239 /* VariableDeclarationList */) {
                    // VariableDeclarationList has no wrapping tokens
                    return -1 /* Unknown */;
                }
                var containingList = getContainingList(node, sourceFile);
                if (containingList) {
                    var index = containingList.indexOf(node);
                    if (index !== -1) {
                        var result = deriveActualIndentationFromList(containingList, index, sourceFile, options);
                        if (result !== -1 /* Unknown */) {
                            return result;
                        }
                    }
                    return getActualIndentationForListStartLine(containingList, sourceFile, options) + (listIndentsChild ? options.indentSize : 0); // TODO: GH#18217
                }
                return -1 /* Unknown */;
            }
            function deriveActualIndentationFromList(list, index, sourceFile, options) {
                ts.Debug.assert(index >= 0 && index < list.length);
                var node = list[index];
                // walk toward the start of the list starting from current node and check if the line is the same for all items.
                // if end line for item [i - 1] differs from the start line for item [i] - find column of the first non-whitespace character on the line of item [i]
                var lineAndCharacter = getStartLineAndCharacterForNode(node, sourceFile);
                for (var i = index - 1; i >= 0; i--) {
                    if (list[i].kind === 27 /* CommaToken */) {
                        continue;
                    }
                    // skip list items that ends on the same line with the current list element
                    var prevEndLine = sourceFile.getLineAndCharacterOfPosition(list[i].end).line;
                    if (prevEndLine !== lineAndCharacter.line) {
                        return findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options);
                    }
                    lineAndCharacter = getStartLineAndCharacterForNode(list[i], sourceFile);
                }
                return -1 /* Unknown */;
            }
            function findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options) {
                var lineStart = sourceFile.getPositionOfLineAndCharacter(lineAndCharacter.line, 0);
                return findFirstNonWhitespaceColumn(lineStart, lineStart + lineAndCharacter.character, sourceFile, options);
            }
            /**
             * Character is the actual index of the character since the beginning of the line.
             * Column - position of the character after expanding tabs to spaces.
             * "0\t2$"
             * value of 'character' for '$' is 3
             * value of 'column' for '$' is 6 (assuming that tab size is 4)
             */
            function findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options) {
                var character = 0;
                var column = 0;
                for (var pos = startPos; pos < endPos; pos++) {
                    var ch = sourceFile.text.charCodeAt(pos);
                    if (!ts.isWhiteSpaceSingleLine(ch)) {
                        break;
                    }
                    if (ch === 9 /* tab */) {
                        column += options.tabSize + (column % options.tabSize);
                    }
                    else {
                        column++;
                    }
                    character++;
                }
                return { column: column, character: character };
            }
            SmartIndenter.findFirstNonWhitespaceCharacterAndColumn = findFirstNonWhitespaceCharacterAndColumn;
            function findFirstNonWhitespaceColumn(startPos, endPos, sourceFile, options) {
                return findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options).column;
            }
            SmartIndenter.findFirstNonWhitespaceColumn = findFirstNonWhitespaceColumn;
            function nodeWillIndentChild(settings, parent, child, sourceFile, indentByDefault) {
                var childKind = child ? child.kind : 0 /* Unknown */;
                switch (parent.kind) {
                    case 222 /* ExpressionStatement */:
                    case 241 /* ClassDeclaration */:
                    case 210 /* ClassExpression */:
                    case 242 /* InterfaceDeclaration */:
                    case 244 /* EnumDeclaration */:
                    case 243 /* TypeAliasDeclaration */:
                    case 188 /* ArrayLiteralExpression */:
                    case 219 /* Block */:
                    case 246 /* ModuleBlock */:
                    case 189 /* ObjectLiteralExpression */:
                    case 169 /* TypeLiteral */:
                    case 182 /* MappedType */:
                    case 171 /* TupleType */:
                    case 247 /* CaseBlock */:
                    case 273 /* DefaultClause */:
                    case 272 /* CaseClause */:
                    case 196 /* ParenthesizedExpression */:
                    case 190 /* PropertyAccessExpression */:
                    case 192 /* CallExpression */:
                    case 193 /* NewExpression */:
                    case 220 /* VariableStatement */:
                    case 255 /* ExportAssignment */:
                    case 231 /* ReturnStatement */:
                    case 206 /* ConditionalExpression */:
                    case 186 /* ArrayBindingPattern */:
                    case 185 /* ObjectBindingPattern */:
                    case 263 /* JsxOpeningElement */:
                    case 266 /* JsxOpeningFragment */:
                    case 262 /* JsxSelfClosingElement */:
                    case 271 /* JsxExpression */:
                    case 156 /* MethodSignature */:
                    case 161 /* CallSignature */:
                    case 162 /* ConstructSignature */:
                    case 152 /* Parameter */:
                    case 166 /* FunctionType */:
                    case 167 /* ConstructorType */:
                    case 178 /* ParenthesizedType */:
                    case 194 /* TaggedTemplateExpression */:
                    case 202 /* AwaitExpression */:
                    case 257 /* NamedExports */:
                    case 253 /* NamedImports */:
                    case 258 /* ExportSpecifier */:
                    case 254 /* ImportSpecifier */:
                    case 155 /* PropertyDeclaration */:
                        return true;
                    case 238 /* VariableDeclaration */:
                    case 276 /* PropertyAssignment */:
                        if (!settings.indentMultiLineObjectLiteralBeginningOnBlankLine && sourceFile && childKind === 189 /* ObjectLiteralExpression */) { // TODO: GH#18217
                            return rangeIsOnOneLine(sourceFile, child);
                        }
                        return true;
                    case 224 /* DoStatement */:
                    case 225 /* WhileStatement */:
                    case 227 /* ForInStatement */:
                    case 228 /* ForOfStatement */:
                    case 226 /* ForStatement */:
                    case 223 /* IfStatement */:
                    case 240 /* FunctionDeclaration */:
                    case 197 /* FunctionExpression */:
                    case 157 /* MethodDeclaration */:
                    case 198 /* ArrowFunction */:
                    case 158 /* Constructor */:
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                        return childKind !== 219 /* Block */;
                    case 256 /* ExportDeclaration */:
                        return childKind !== 257 /* NamedExports */;
                    case 250 /* ImportDeclaration */:
                        return childKind !== 251 /* ImportClause */ ||
                            (!!child.namedBindings && child.namedBindings.kind !== 253 /* NamedImports */);
                    case 261 /* JsxElement */:
                        return childKind !== 264 /* JsxClosingElement */;
                    case 265 /* JsxFragment */:
                        return childKind !== 267 /* JsxClosingFragment */;
                    case 175 /* IntersectionType */:
                    case 174 /* UnionType */:
                        if (childKind === 169 /* TypeLiteral */) {
                            return false;
                        }
                    // falls through
                }
                // No explicit rule for given nodes so the result will follow the default value argument
                return indentByDefault;
            }
            SmartIndenter.nodeWillIndentChild = nodeWillIndentChild;
            function isControlFlowEndingStatement(kind, parent) {
                switch (kind) {
                    case 231 /* ReturnStatement */:
                    case 235 /* ThrowStatement */:
                    case 229 /* ContinueStatement */:
                    case 230 /* BreakStatement */:
                        return parent.kind !== 219 /* Block */;
                    default:
                        return false;
                }
            }
            /**
             * True when the parent node should indent the given child by an explicit rule.
             * @param isNextChild If true, we are judging indent of a hypothetical child *after* this one, not the current child.
             */
            function shouldIndentChildNode(settings, parent, child, sourceFile, isNextChild) {
                if (isNextChild === void 0) { isNextChild = false; }
                return nodeWillIndentChild(settings, parent, child, sourceFile, /*indentByDefault*/ false)
                    && !(isNextChild && child && isControlFlowEndingStatement(child.kind, parent));
            }
            SmartIndenter.shouldIndentChildNode = shouldIndentChildNode;
            function rangeIsOnOneLine(sourceFile, range) {
                var rangeStart = ts.skipTrivia(sourceFile.text, range.pos);
                var startLine = sourceFile.getLineAndCharacterOfPosition(rangeStart).line;
                var endLine = sourceFile.getLineAndCharacterOfPosition(range.end).line;
                return startLine === endLine;
            }
        })(SmartIndenter = formatting.SmartIndenter || (formatting.SmartIndenter = {}));
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var textChanges;
    (function (textChanges_3) {
        /**
         * Currently for simplicity we store recovered positions on the node itself.
         * It can be changed to side-table later if we decide that current design is too invasive.
         */
        function getPos(n) {
            var result = n.__pos;
            ts.Debug.assert(typeof result === "number");
            return result;
        }
        function setPos(n, pos) {
            ts.Debug.assert(typeof pos === "number");
            n.__pos = pos;
        }
        function getEnd(n) {
            var result = n.__end;
            ts.Debug.assert(typeof result === "number");
            return result;
        }
        function setEnd(n, end) {
            ts.Debug.assert(typeof end === "number");
            n.__end = end;
        }
        var LeadingTriviaOption;
        (function (LeadingTriviaOption) {
            /** Exclude all leading trivia (use getStart()) */
            LeadingTriviaOption[LeadingTriviaOption["Exclude"] = 0] = "Exclude";
            /** Include leading trivia and,
             * if there are no line breaks between the node and the previous token,
             * include all trivia between the node and the previous token
             */
            LeadingTriviaOption[LeadingTriviaOption["IncludeAll"] = 1] = "IncludeAll";
        })(LeadingTriviaOption = textChanges_3.LeadingTriviaOption || (textChanges_3.LeadingTriviaOption = {}));
        var TrailingTriviaOption;
        (function (TrailingTriviaOption) {
            /** Exclude all trailing trivia (use getEnd()) */
            TrailingTriviaOption[TrailingTriviaOption["Exclude"] = 0] = "Exclude";
            /** Include trailing trivia */
            TrailingTriviaOption[TrailingTriviaOption["Include"] = 1] = "Include";
        })(TrailingTriviaOption = textChanges_3.TrailingTriviaOption || (textChanges_3.TrailingTriviaOption = {}));
        function skipWhitespacesAndLineBreaks(text, start) {
            return ts.skipTrivia(text, start, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
        }
        function hasCommentsBeforeLineBreak(text, start) {
            var i = start;
            while (i < text.length) {
                var ch = text.charCodeAt(i);
                if (ts.isWhiteSpaceSingleLine(ch)) {
                    i++;
                    continue;
                }
                return ch === 47 /* slash */;
            }
            return false;
        }
        var useNonAdjustedPositions = {
            leadingTriviaOption: LeadingTriviaOption.Exclude,
            trailingTriviaOption: TrailingTriviaOption.Exclude,
        };
        var ChangeKind;
        (function (ChangeKind) {
            ChangeKind[ChangeKind["Remove"] = 0] = "Remove";
            ChangeKind[ChangeKind["ReplaceWithSingleNode"] = 1] = "ReplaceWithSingleNode";
            ChangeKind[ChangeKind["ReplaceWithMultipleNodes"] = 2] = "ReplaceWithMultipleNodes";
            ChangeKind[ChangeKind["Text"] = 3] = "Text";
        })(ChangeKind || (ChangeKind = {}));
        function getAdjustedRange(sourceFile, startNode, endNode, options) {
            return { pos: getAdjustedStartPosition(sourceFile, startNode, options), end: getAdjustedEndPosition(sourceFile, endNode, options) };
        }
        function getAdjustedStartPosition(sourceFile, node, options) {
            var leadingTriviaOption = options.leadingTriviaOption;
            if (leadingTriviaOption === LeadingTriviaOption.Exclude) {
                return node.getStart(sourceFile);
            }
            var fullStart = node.getFullStart();
            var start = node.getStart(sourceFile);
            if (fullStart === start) {
                return start;
            }
            var fullStartLine = ts.getLineStartPositionForPosition(fullStart, sourceFile);
            var startLine = ts.getLineStartPositionForPosition(start, sourceFile);
            if (startLine === fullStartLine) {
                // full start and start of the node are on the same line
                //   a,     b;
                //    ^     ^
                //    |   start
                // fullstart
                // when b is replaced - we usually want to keep the leading trvia
                // when b is deleted - we delete it
                return leadingTriviaOption === LeadingTriviaOption.IncludeAll ? fullStart : start;
            }
            // get start position of the line following the line that contains fullstart position
            // (but only if the fullstart isn't the very beginning of the file)
            var nextLineStart = fullStart > 0 ? 1 : 0;
            var adjustedStartPosition = ts.getStartPositionOfLine(ts.getLineOfLocalPosition(sourceFile, fullStartLine) + nextLineStart, sourceFile);
            // skip whitespaces/newlines
            adjustedStartPosition = skipWhitespacesAndLineBreaks(sourceFile.text, adjustedStartPosition);
            return ts.getStartPositionOfLine(ts.getLineOfLocalPosition(sourceFile, adjustedStartPosition), sourceFile);
        }
        function getAdjustedEndPosition(sourceFile, node, options) {
            var end = node.end;
            var trailingTriviaOption = options.trailingTriviaOption;
            if (trailingTriviaOption === TrailingTriviaOption.Exclude || (ts.isExpression(node) && trailingTriviaOption !== TrailingTriviaOption.Include)) {
                return end;
            }
            var newEnd = ts.skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true);
            return newEnd !== end && (trailingTriviaOption === TrailingTriviaOption.Include || ts.isLineBreak(sourceFile.text.charCodeAt(newEnd - 1)))
                ? newEnd
                : end;
        }
        /**
         * Checks if 'candidate' argument is a legal separator in the list that contains 'node' as an element
         */
        function isSeparator(node, candidate) {
            return !!candidate && !!node.parent && (candidate.kind === 27 /* CommaToken */ || (candidate.kind === 26 /* SemicolonToken */ && node.parent.kind === 189 /* ObjectLiteralExpression */));
        }
        function spaces(count) {
            var s = "";
            for (var i = 0; i < count; i++) {
                s += " ";
            }
            return s;
        }
        var ChangeTracker = /** @class */ (function () {
            /** Public for tests only. Other callers should use `ChangeTracker.with`. */
            function ChangeTracker(newLineCharacter, formatContext) {
                this.newLineCharacter = newLineCharacter;
                this.formatContext = formatContext;
                this.changes = [];
                this.newFiles = [];
                this.classesWithNodesInsertedAtStart = ts.createMap(); // Set<ClassDeclaration> implemented as Map<node id, ClassDeclaration>
                this.deletedNodes = [];
            }
            ChangeTracker.fromContext = function (context) {
                return new ChangeTracker(ts.getNewLineOrDefaultFromHost(context.host, context.formatContext.options), context.formatContext);
            };
            ChangeTracker.with = function (context, cb) {
                var tracker = ChangeTracker.fromContext(context);
                cb(tracker);
                return tracker.getChanges();
            };
            ChangeTracker.prototype.deleteRange = function (sourceFile, range) {
                this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: range });
            };
            ChangeTracker.prototype.delete = function (sourceFile, node) {
                this.deletedNodes.push({ sourceFile: sourceFile, node: node });
            };
            ChangeTracker.prototype.deleteModifier = function (sourceFile, modifier) {
                this.deleteRange(sourceFile, { pos: modifier.getStart(sourceFile), end: ts.skipTrivia(sourceFile.text, modifier.end, /*stopAfterLineBreak*/ true) });
            };
            ChangeTracker.prototype.deleteNodeRange = function (sourceFile, startNode, endNode, options) {
                if (options === void 0) { options = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }; }
                var startPosition = getAdjustedStartPosition(sourceFile, startNode, options);
                var endPosition = getAdjustedEndPosition(sourceFile, endNode, options);
                this.deleteRange(sourceFile, { pos: startPosition, end: endPosition });
            };
            ChangeTracker.prototype.deleteNodeRangeExcludingEnd = function (sourceFile, startNode, afterEndNode, options) {
                if (options === void 0) { options = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }; }
                var startPosition = getAdjustedStartPosition(sourceFile, startNode, options);
                var endPosition = afterEndNode === undefined ? sourceFile.text.length : getAdjustedStartPosition(sourceFile, afterEndNode, options);
                this.deleteRange(sourceFile, { pos: startPosition, end: endPosition });
            };
            ChangeTracker.prototype.replaceRange = function (sourceFile, range, newNode, options) {
                if (options === void 0) { options = {}; }
                this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: range, options: options, node: newNode });
            };
            ChangeTracker.prototype.replaceNode = function (sourceFile, oldNode, newNode, options) {
                if (options === void 0) { options = useNonAdjustedPositions; }
                this.replaceRange(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, options), newNode, options);
            };
            ChangeTracker.prototype.replaceNodeRange = function (sourceFile, startNode, endNode, newNode, options) {
                if (options === void 0) { options = useNonAdjustedPositions; }
                this.replaceRange(sourceFile, getAdjustedRange(sourceFile, startNode, endNode, options), newNode, options);
            };
            ChangeTracker.prototype.replaceRangeWithNodes = function (sourceFile, range, newNodes, options) {
                if (options === void 0) { options = {}; }
                this.changes.push({ kind: ChangeKind.ReplaceWithMultipleNodes, sourceFile: sourceFile, range: range, options: options, nodes: newNodes });
            };
            ChangeTracker.prototype.replaceNodeWithNodes = function (sourceFile, oldNode, newNodes, options) {
                if (options === void 0) { options = useNonAdjustedPositions; }
                this.replaceRangeWithNodes(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, options), newNodes, options);
            };
            ChangeTracker.prototype.replaceNodeWithText = function (sourceFile, oldNode, text) {
                this.replaceRangeWithText(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, useNonAdjustedPositions), text);
            };
            ChangeTracker.prototype.replaceNodeRangeWithNodes = function (sourceFile, startNode, endNode, newNodes, options) {
                if (options === void 0) { options = useNonAdjustedPositions; }
                this.replaceRangeWithNodes(sourceFile, getAdjustedRange(sourceFile, startNode, endNode, options), newNodes, options);
            };
            ChangeTracker.prototype.nextCommaToken = function (sourceFile, node) {
                var next = ts.findNextToken(node, node.parent, sourceFile);
                return next && next.kind === 27 /* CommaToken */ ? next : undefined;
            };
            ChangeTracker.prototype.replacePropertyAssignment = function (sourceFile, oldNode, newNode) {
                var suffix = this.nextCommaToken(sourceFile, oldNode) ? "" : ("," + this.newLineCharacter);
                this.replaceNode(sourceFile, oldNode, newNode, { suffix: suffix });
            };
            ChangeTracker.prototype.insertNodeAt = function (sourceFile, pos, newNode, options) {
                if (options === void 0) { options = {}; }
                this.replaceRange(sourceFile, ts.createRange(pos), newNode, options);
            };
            ChangeTracker.prototype.insertNodesAt = function (sourceFile, pos, newNodes, options) {
                if (options === void 0) { options = {}; }
                this.replaceRangeWithNodes(sourceFile, ts.createRange(pos), newNodes, options);
            };
            ChangeTracker.prototype.insertNodeAtTopOfFile = function (sourceFile, newNode, blankLineBetween) {
                var pos = getInsertionPositionAtSourceFileTop(sourceFile);
                this.insertNodeAt(sourceFile, pos, newNode, {
                    prefix: pos === 0 ? undefined : this.newLineCharacter,
                    suffix: (ts.isLineBreak(sourceFile.text.charCodeAt(pos)) ? "" : this.newLineCharacter) + (blankLineBetween ? this.newLineCharacter : ""),
                });
            };
            ChangeTracker.prototype.insertNodeBefore = function (sourceFile, before, newNode, blankLineBetween) {
                if (blankLineBetween === void 0) { blankLineBetween = false; }
                this.insertNodeAt(sourceFile, getAdjustedStartPosition(sourceFile, before, {}), newNode, this.getOptionsForInsertNodeBefore(before, blankLineBetween));
            };
            ChangeTracker.prototype.insertModifierBefore = function (sourceFile, modifier, before) {
                var pos = before.getStart(sourceFile);
                this.insertNodeAt(sourceFile, pos, ts.createToken(modifier), { suffix: " " });
            };
            ChangeTracker.prototype.insertLastModifierBefore = function (sourceFile, modifier, before) {
                if (!before.modifiers) {
                    this.insertModifierBefore(sourceFile, modifier, before);
                    return;
                }
                var pos = before.modifiers.end;
                this.insertNodeAt(sourceFile, pos, ts.createToken(modifier), { prefix: " " });
            };
            ChangeTracker.prototype.insertCommentBeforeLine = function (sourceFile, lineNumber, position, commentText) {
                var lineStartPosition = ts.getStartPositionOfLine(lineNumber, sourceFile);
                var startPosition = ts.getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition);
                // First try to see if we can put the comment on the previous line.
                // We need to make sure that we are not in the middle of a string literal or a comment.
                // If so, we do not want to separate the node from its comment if we can.
                // Otherwise, add an extra new line immediately before the error span.
                var insertAtLineStart = isValidLocationToAddComment(sourceFile, startPosition);
                var token = ts.getTouchingToken(sourceFile, insertAtLineStart ? startPosition : position);
                var indent = sourceFile.text.slice(lineStartPosition, startPosition);
                var text = (insertAtLineStart ? "" : this.newLineCharacter) + "//" + commentText + this.newLineCharacter + indent;
                this.insertText(sourceFile, token.getStart(sourceFile), text);
            };
            ChangeTracker.prototype.insertJsdocCommentBefore = function (sourceFile, node, tag) {
                var fnStart = node.getStart(sourceFile);
                if (node.jsDoc) {
                    for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                        var jsdoc = _a[_i];
                        this.deleteRange(sourceFile, {
                            pos: ts.getLineStartPositionForPosition(jsdoc.getStart(sourceFile), sourceFile),
                            end: getAdjustedEndPosition(sourceFile, jsdoc, /*options*/ {})
                        });
                    }
                }
                var startPosition = ts.getPrecedingNonSpaceCharacterPosition(sourceFile.text, fnStart - 1);
                var indent = sourceFile.text.slice(startPosition, fnStart);
                this.insertNodeAt(sourceFile, fnStart, tag, { preserveLeadingWhitespace: false, suffix: this.newLineCharacter + indent });
            };
            ChangeTracker.prototype.replaceRangeWithText = function (sourceFile, range, text) {
                this.changes.push({ kind: ChangeKind.Text, sourceFile: sourceFile, range: range, text: text });
            };
            ChangeTracker.prototype.insertText = function (sourceFile, pos, text) {
                this.replaceRangeWithText(sourceFile, ts.createRange(pos), text);
            };
            /** Prefer this over replacing a node with another that has a type annotation, as it avoids reformatting the other parts of the node. */
            ChangeTracker.prototype.tryInsertTypeAnnotation = function (sourceFile, node, type) {
                var endNode;
                if (ts.isFunctionLike(node)) {
                    endNode = ts.findChildOfKind(node, 21 /* CloseParenToken */, sourceFile);
                    if (!endNode) {
                        if (!ts.isArrowFunction(node))
                            return; // Function missing parentheses, give up
                        // If no `)`, is an arrow function `x => x`, so use the end of the first parameter
                        endNode = ts.first(node.parameters);
                    }
                }
                else {
                    endNode = node.kind !== 238 /* VariableDeclaration */ && node.questionToken ? node.questionToken : node.name;
                }
                this.insertNodeAt(sourceFile, endNode.end, type, { prefix: ": " });
            };
            ChangeTracker.prototype.insertTypeParameters = function (sourceFile, node, typeParameters) {
                // If no `(`, is an arrow function `x => x`, so use the pos of the first parameter
                var start = (ts.findChildOfKind(node, 20 /* OpenParenToken */, sourceFile) || ts.first(node.parameters)).getStart(sourceFile);
                this.insertNodesAt(sourceFile, start, typeParameters, { prefix: "<", suffix: ">" });
            };
            ChangeTracker.prototype.getOptionsForInsertNodeBefore = function (before, doubleNewlines) {
                if (ts.isStatement(before) || ts.isClassElement(before)) {
                    return { suffix: doubleNewlines ? this.newLineCharacter + this.newLineCharacter : this.newLineCharacter };
                }
                else if (ts.isVariableDeclaration(before)) { // insert `x = 1, ` into `const x = 1, y = 2;
                    return { suffix: ", " };
                }
                else if (ts.isParameter(before)) {
                    return {};
                }
                else if (ts.isStringLiteral(before) && ts.isImportDeclaration(before.parent) || ts.isNamedImports(before)) {
                    return { suffix: ", " };
                }
                return ts.Debug.failBadSyntaxKind(before); // We haven't handled this kind of node yet -- add it
            };
            ChangeTracker.prototype.insertNodeAtConstructorStart = function (sourceFile, ctr, newStatement) {
                var firstStatement = ts.firstOrUndefined(ctr.body.statements);
                if (!firstStatement || !ctr.body.multiLine) {
                    this.replaceConstructorBody(sourceFile, ctr, [newStatement].concat(ctr.body.statements));
                }
                else {
                    this.insertNodeBefore(sourceFile, firstStatement, newStatement);
                }
            };
            ChangeTracker.prototype.insertNodeAtConstructorEnd = function (sourceFile, ctr, newStatement) {
                var lastStatement = ts.lastOrUndefined(ctr.body.statements);
                if (!lastStatement || !ctr.body.multiLine) {
                    this.replaceConstructorBody(sourceFile, ctr, ctr.body.statements.concat([newStatement]));
                }
                else {
                    this.insertNodeAfter(sourceFile, lastStatement, newStatement);
                }
            };
            ChangeTracker.prototype.replaceConstructorBody = function (sourceFile, ctr, statements) {
                this.replaceNode(sourceFile, ctr.body, ts.createBlock(statements, /*multiLine*/ true));
            };
            ChangeTracker.prototype.insertNodeAtEndOfScope = function (sourceFile, scope, newNode) {
                var pos = getAdjustedStartPosition(sourceFile, scope.getLastToken(), {});
                this.insertNodeAt(sourceFile, pos, newNode, {
                    prefix: ts.isLineBreak(sourceFile.text.charCodeAt(scope.getLastToken().pos)) ? this.newLineCharacter : this.newLineCharacter + this.newLineCharacter,
                    suffix: this.newLineCharacter
                });
            };
            ChangeTracker.prototype.insertNodeAtClassStart = function (sourceFile, cls, newElement) {
                this.insertNodeAtStartWorker(sourceFile, cls, newElement);
            };
            ChangeTracker.prototype.insertNodeAtObjectStart = function (sourceFile, obj, newElement) {
                this.insertNodeAtStartWorker(sourceFile, obj, newElement);
            };
            ChangeTracker.prototype.insertNodeAtStartWorker = function (sourceFile, cls, newElement) {
                var clsStart = cls.getStart(sourceFile);
                var indentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options)
                    + this.formatContext.options.indentSize;
                this.insertNodeAt(sourceFile, getMembersOrProperties(cls).pos, newElement, __assign({ indentation: indentation }, this.getInsertNodeAtStartPrefixSuffix(sourceFile, cls)));
            };
            ChangeTracker.prototype.getInsertNodeAtStartPrefixSuffix = function (sourceFile, cls) {
                var comma = ts.isObjectLiteralExpression(cls) ? "," : "";
                if (getMembersOrProperties(cls).length === 0) {
                    if (ts.addToSeen(this.classesWithNodesInsertedAtStart, ts.getNodeId(cls), { node: cls, sourceFile: sourceFile })) {
                        // For `class C {\n}`, don't add the trailing "\n"
                        var shouldSuffix = ts.positionsAreOnSameLine.apply(void 0, getClassOrObjectBraceEnds(cls, sourceFile).concat([sourceFile])); // TODO: GH#4130 remove 'as any'
                        return { prefix: this.newLineCharacter, suffix: comma + (shouldSuffix ? this.newLineCharacter : "") };
                    }
                    else {
                        return { prefix: "", suffix: comma + this.newLineCharacter };
                    }
                }
                else {
                    return { prefix: this.newLineCharacter, suffix: comma };
                }
            };
            ChangeTracker.prototype.insertNodeAfterComma = function (sourceFile, after, newNode) {
                var endPosition = this.insertNodeAfterWorker(sourceFile, this.nextCommaToken(sourceFile, after) || after, newNode);
                this.insertNodeAt(sourceFile, endPosition, newNode, this.getInsertNodeAfterOptions(sourceFile, after));
            };
            ChangeTracker.prototype.insertNodeAfter = function (sourceFile, after, newNode) {
                var endPosition = this.insertNodeAfterWorker(sourceFile, after, newNode);
                this.insertNodeAt(sourceFile, endPosition, newNode, this.getInsertNodeAfterOptions(sourceFile, after));
            };
            ChangeTracker.prototype.insertNodeAtEndOfList = function (sourceFile, list, newNode) {
                this.insertNodeAt(sourceFile, list.end, newNode, { prefix: ", " });
            };
            ChangeTracker.prototype.insertNodesAfter = function (sourceFile, after, newNodes) {
                var endPosition = this.insertNodeAfterWorker(sourceFile, after, ts.first(newNodes));
                this.insertNodesAt(sourceFile, endPosition, newNodes, this.getInsertNodeAfterOptions(sourceFile, after));
            };
            ChangeTracker.prototype.insertNodeAfterWorker = function (sourceFile, after, newNode) {
                if (needSemicolonBetween(after, newNode)) {
                    // check if previous statement ends with semicolon
                    // if not - insert semicolon to preserve the code from changing the meaning due to ASI
                    if (sourceFile.text.charCodeAt(after.end - 1) !== 59 /* semicolon */) {
                        this.replaceRange(sourceFile, ts.createRange(after.end), ts.createToken(26 /* SemicolonToken */));
                    }
                }
                var endPosition = getAdjustedEndPosition(sourceFile, after, {});
                return endPosition;
            };
            ChangeTracker.prototype.getInsertNodeAfterOptions = function (sourceFile, after) {
                var options = this.getInsertNodeAfterOptionsWorker(after);
                return __assign({}, options, { prefix: after.end === sourceFile.end && ts.isStatement(after) ? (options.prefix ? "\n" + options.prefix : "\n") : options.prefix });
            };
            ChangeTracker.prototype.getInsertNodeAfterOptionsWorker = function (node) {
                switch (node.kind) {
                    case 241 /* ClassDeclaration */:
                    case 245 /* ModuleDeclaration */:
                        return { prefix: this.newLineCharacter, suffix: this.newLineCharacter };
                    case 238 /* VariableDeclaration */:
                    case 10 /* StringLiteral */:
                    case 73 /* Identifier */:
                        return { prefix: ", " };
                    case 276 /* PropertyAssignment */:
                        return { suffix: "," + this.newLineCharacter };
                    case 86 /* ExportKeyword */:
                        return { prefix: " " };
                    case 152 /* Parameter */:
                        return {};
                    default:
                        ts.Debug.assert(ts.isStatement(node) || ts.isClassOrTypeElement(node)); // Else we haven't handled this kind of node yet -- add it
                        return { suffix: this.newLineCharacter };
                }
            };
            ChangeTracker.prototype.insertName = function (sourceFile, node, name) {
                ts.Debug.assert(!node.name);
                if (node.kind === 198 /* ArrowFunction */) {
                    var arrow = ts.findChildOfKind(node, 37 /* EqualsGreaterThanToken */, sourceFile);
                    var lparen = ts.findChildOfKind(node, 20 /* OpenParenToken */, sourceFile);
                    if (lparen) {
                        // `() => {}` --> `function f() {}`
                        this.insertNodesAt(sourceFile, lparen.getStart(sourceFile), [ts.createToken(91 /* FunctionKeyword */), ts.createIdentifier(name)], { joiner: " " });
                        deleteNode(this, sourceFile, arrow);
                    }
                    else {
                        // `x => {}` -> `function f(x) {}`
                        this.insertText(sourceFile, ts.first(node.parameters).getStart(sourceFile), "function " + name + "(");
                        // Replacing full range of arrow to get rid of the leading space -- replace ` =>` with `)`
                        this.replaceRange(sourceFile, arrow, ts.createToken(21 /* CloseParenToken */));
                    }
                    if (node.body.kind !== 219 /* Block */) {
                        // `() => 0` => `function f() { return 0; }`
                        this.insertNodesAt(sourceFile, node.body.getStart(sourceFile), [ts.createToken(18 /* OpenBraceToken */), ts.createToken(98 /* ReturnKeyword */)], { joiner: " ", suffix: " " });
                        this.insertNodesAt(sourceFile, node.body.end, [ts.createToken(26 /* SemicolonToken */), ts.createToken(19 /* CloseBraceToken */)], { joiner: " " });
                    }
                }
                else {
                    var pos = ts.findChildOfKind(node, node.kind === 197 /* FunctionExpression */ ? 91 /* FunctionKeyword */ : 77 /* ClassKeyword */, sourceFile).end;
                    this.insertNodeAt(sourceFile, pos, ts.createIdentifier(name), { prefix: " " });
                }
            };
            ChangeTracker.prototype.insertExportModifier = function (sourceFile, node) {
                this.insertText(sourceFile, node.getStart(sourceFile), "export ");
            };
            /**
             * This function should be used to insert nodes in lists when nodes don't carry separators as the part of the node range,
             * i.e. arguments in arguments lists, parameters in parameter lists etc.
             * Note that separators are part of the node in statements and class elements.
             */
            ChangeTracker.prototype.insertNodeInListAfter = function (sourceFile, after, newNode, containingList) {
                if (containingList === void 0) { containingList = ts.formatting.SmartIndenter.getContainingList(after, sourceFile); }
                if (!containingList) {
                    ts.Debug.fail("node is not a list element");
                    return;
                }
                var index = ts.indexOfNode(containingList, after);
                if (index < 0) {
                    return;
                }
                var end = after.getEnd();
                if (index !== containingList.length - 1) {
                    // any element except the last one
                    // use next sibling as an anchor
                    var nextToken = ts.getTokenAtPosition(sourceFile, after.end);
                    if (nextToken && isSeparator(after, nextToken)) {
                        // for list
                        // a, b, c
                        // create change for adding 'e' after 'a' as
                        // - find start of next element after a (it is b)
                        // - use this start as start and end position in final change
                        // - build text of change by formatting the text of node + separator + whitespace trivia of b
                        // in multiline case it will work as
                        //   a,
                        //   b,
                        //   c,
                        // result - '*' denotes leading trivia that will be inserted after new text (displayed as '#')
                        //   a,*
                        // ***insertedtext<separator>#
                        // ###b,
                        //   c,
                        // find line and character of the next element
                        var lineAndCharOfNextElement = ts.getLineAndCharacterOfPosition(sourceFile, skipWhitespacesAndLineBreaks(sourceFile.text, containingList[index + 1].getFullStart()));
                        // find line and character of the token that precedes next element (usually it is separator)
                        var lineAndCharOfNextToken = ts.getLineAndCharacterOfPosition(sourceFile, nextToken.end);
                        var prefix = void 0;
                        var startPos = void 0;
                        if (lineAndCharOfNextToken.line === lineAndCharOfNextElement.line) {
                            // next element is located on the same line with separator:
                            // a,$$$$b
                            //  ^    ^
                            //  |    |-next element
                            //  |-separator
                            // where $$$ is some leading trivia
                            // for a newly inserted node we'll maintain the same relative position comparing to separator and replace leading trivia with spaces
                            // a,    x,$$$$b
                            //  ^    ^     ^
                            //  |    |     |-next element
                            //  |    |-new inserted node padded with spaces
                            //  |-separator
                            startPos = nextToken.end;
                            prefix = spaces(lineAndCharOfNextElement.character - lineAndCharOfNextToken.character);
                        }
                        else {
                            // next element is located on different line that separator
                            // let insert position be the beginning of the line that contains next element
                            startPos = ts.getStartPositionOfLine(lineAndCharOfNextElement.line, sourceFile);
                        }
                        // write separator and leading trivia of the next element as suffix
                        var suffix = "" + ts.tokenToString(nextToken.kind) + sourceFile.text.substring(nextToken.end, containingList[index + 1].getStart(sourceFile));
                        this.replaceRange(sourceFile, ts.createRange(startPos, containingList[index + 1].getStart(sourceFile)), newNode, { prefix: prefix, suffix: suffix });
                    }
                }
                else {
                    var afterStart = after.getStart(sourceFile);
                    var afterStartLinePosition = ts.getLineStartPositionForPosition(afterStart, sourceFile);
                    var separator = void 0;
                    var multilineList = false;
                    // insert element after the last element in the list that has more than one item
                    // pick the element preceding the after element to:
                    // - pick the separator
                    // - determine if list is a multiline
                    if (containingList.length === 1) {
                        // if list has only one element then we'll format is as multiline if node has comment in trailing trivia, or as singleline otherwise
                        // i.e. var x = 1 // this is x
                        //     | new element will be inserted at this position
                        separator = 27 /* CommaToken */;
                    }
                    else {
                        // element has more than one element, pick separator from the list
                        var tokenBeforeInsertPosition = ts.findPrecedingToken(after.pos, sourceFile);
                        separator = isSeparator(after, tokenBeforeInsertPosition) ? tokenBeforeInsertPosition.kind : 27 /* CommaToken */;
                        // determine if list is multiline by checking lines of after element and element that precedes it.
                        var afterMinusOneStartLinePosition = ts.getLineStartPositionForPosition(containingList[index - 1].getStart(sourceFile), sourceFile);
                        multilineList = afterMinusOneStartLinePosition !== afterStartLinePosition;
                    }
                    if (hasCommentsBeforeLineBreak(sourceFile.text, after.end)) {
                        // in this case we'll always treat containing list as multiline
                        multilineList = true;
                    }
                    if (multilineList) {
                        // insert separator immediately following the 'after' node to preserve comments in trailing trivia
                        this.replaceRange(sourceFile, ts.createRange(end), ts.createToken(separator));
                        // use the same indentation as 'after' item
                        var indentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.formatContext.options);
                        // insert element before the line break on the line that contains 'after' element
                        var insertPos = ts.skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true, /*stopAtComments*/ false);
                        if (insertPos !== end && ts.isLineBreak(sourceFile.text.charCodeAt(insertPos - 1))) {
                            insertPos--;
                        }
                        this.replaceRange(sourceFile, ts.createRange(insertPos), newNode, { indentation: indentation, prefix: this.newLineCharacter });
                    }
                    else {
                        this.replaceRange(sourceFile, ts.createRange(end), newNode, { prefix: ts.tokenToString(separator) + " " });
                    }
                }
            };
            ChangeTracker.prototype.finishClassesWithNodesInsertedAtStart = function () {
                var _this = this;
                this.classesWithNodesInsertedAtStart.forEach(function (_a) {
                    var node = _a.node, sourceFile = _a.sourceFile;
                    var _b = getClassOrObjectBraceEnds(node, sourceFile), openBraceEnd = _b[0], closeBraceEnd = _b[1];
                    // For `class C { }` remove the whitespace inside the braces.
                    if (ts.positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile) && openBraceEnd !== closeBraceEnd - 1) {
                        _this.deleteRange(sourceFile, ts.createRange(openBraceEnd, closeBraceEnd - 1));
                    }
                });
            };
            ChangeTracker.prototype.finishDeleteDeclarations = function () {
                var _this = this;
                var deletedNodesInLists = new ts.NodeSet(); // Stores nodes in lists that we already deleted. Used to avoid deleting `, ` twice in `a, b`.
                var _loop_9 = function (sourceFile, node) {
                    if (!this_1.deletedNodes.some(function (d) { return d.sourceFile === sourceFile && ts.rangeContainsRangeExclusive(d.node, node); })) {
                        if (ts.isArray(node)) {
                            this_1.deleteRange(sourceFile, ts.rangeOfTypeParameters(node));
                        }
                        else {
                            deleteDeclaration.deleteDeclaration(this_1, deletedNodesInLists, sourceFile, node);
                        }
                    }
                };
                var this_1 = this;
                for (var _i = 0, _a = this.deletedNodes; _i < _a.length; _i++) {
                    var _b = _a[_i], sourceFile = _b.sourceFile, node = _b.node;
                    _loop_9(sourceFile, node);
                }
                deletedNodesInLists.forEach(function (node) {
                    var sourceFile = node.getSourceFile();
                    var list = ts.formatting.SmartIndenter.getContainingList(node, sourceFile);
                    if (node !== ts.last(list))
                        return;
                    var lastNonDeletedIndex = ts.findLastIndex(list, function (n) { return !deletedNodesInLists.has(n); }, list.length - 2);
                    if (lastNonDeletedIndex !== -1) {
                        _this.deleteRange(sourceFile, { pos: list[lastNonDeletedIndex].end, end: startPositionToDeleteNodeInList(sourceFile, list[lastNonDeletedIndex + 1]) });
                    }
                });
            };
            /**
             * Note: after calling this, the TextChanges object must be discarded!
             * @param validate only for tests
             *    The reason we must validate as part of this method is that `getNonFormattedText` changes the node's positions,
             *    so we can only call this once and can't get the non-formatted text separately.
             */
            ChangeTracker.prototype.getChanges = function (validate) {
                this.finishDeleteDeclarations();
                this.finishClassesWithNodesInsertedAtStart();
                var changes = changesToText.getTextChangesFromChanges(this.changes, this.newLineCharacter, this.formatContext, validate);
                for (var _i = 0, _a = this.newFiles; _i < _a.length; _i++) {
                    var _b = _a[_i], oldFile = _b.oldFile, fileName = _b.fileName, statements = _b.statements;
                    changes.push(changesToText.newFileChanges(oldFile, fileName, statements, this.newLineCharacter, this.formatContext));
                }
                return changes;
            };
            ChangeTracker.prototype.createNewFile = function (oldFile, fileName, statements) {
                this.newFiles.push({ oldFile: oldFile, fileName: fileName, statements: statements });
            };
            return ChangeTracker;
        }());
        textChanges_3.ChangeTracker = ChangeTracker;
        // find first non-whitespace position in the leading trivia of the node
        function startPositionToDeleteNodeInList(sourceFile, node) {
            return ts.skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, { leadingTriviaOption: LeadingTriviaOption.IncludeAll }), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
        }
        function getClassOrObjectBraceEnds(cls, sourceFile) {
            return [ts.findChildOfKind(cls, 18 /* OpenBraceToken */, sourceFile).end, ts.findChildOfKind(cls, 19 /* CloseBraceToken */, sourceFile).end];
        }
        function getMembersOrProperties(cls) {
            return ts.isObjectLiteralExpression(cls) ? cls.properties : cls.members;
        }
        function getNewFileText(statements, scriptKind, newLineCharacter, formatContext) {
            return changesToText.newFileChangesWorker(/*oldFile*/ undefined, scriptKind, statements, newLineCharacter, formatContext);
        }
        textChanges_3.getNewFileText = getNewFileText;
        var changesToText;
        (function (changesToText) {
            function getTextChangesFromChanges(changes, newLineCharacter, formatContext, validate) {
                return ts.group(changes, function (c) { return c.sourceFile.path; }).map(function (changesInFile) {
                    var sourceFile = changesInFile[0].sourceFile;
                    // order changes by start position
                    // If the start position is the same, put the shorter range first, since an empty range (x, x) may precede (x, y) but not vice-versa.
                    var normalized = ts.stableSort(changesInFile, function (a, b) { return (a.range.pos - b.range.pos) || (a.range.end - b.range.end); });
                    var _loop_10 = function (i) {
                        ts.Debug.assert(normalized[i].range.end <= normalized[i + 1].range.pos, "Changes overlap", function () {
                            return JSON.stringify(normalized[i].range) + " and " + JSON.stringify(normalized[i + 1].range);
                        });
                    };
                    // verify that change intervals do not overlap, except possibly at end points.
                    for (var i = 0; i < normalized.length - 1; i++) {
                        _loop_10(i);
                    }
                    var textChanges = normalized.map(function (c) {
                        return ts.createTextChange(ts.createTextSpanFromRange(c.range), computeNewText(c, sourceFile, newLineCharacter, formatContext, validate));
                    });
                    return { fileName: sourceFile.fileName, textChanges: textChanges };
                });
            }
            changesToText.getTextChangesFromChanges = getTextChangesFromChanges;
            function newFileChanges(oldFile, fileName, statements, newLineCharacter, formatContext) {
                var text = newFileChangesWorker(oldFile, ts.getScriptKindFromFileName(fileName), statements, newLineCharacter, formatContext);
                return { fileName: fileName, textChanges: [ts.createTextChange(ts.createTextSpan(0, 0), text)], isNewFile: true };
            }
            changesToText.newFileChanges = newFileChanges;
            function newFileChangesWorker(oldFile, scriptKind, statements, newLineCharacter, formatContext) {
                // TODO: this emits the file, parses it back, then formats it that -- may be a less roundabout way to do this
                var nonFormattedText = statements.map(function (s) { return getNonformattedText(s, oldFile, newLineCharacter).text; }).join(newLineCharacter);
                var sourceFile = ts.createSourceFile("any file name", nonFormattedText, 8 /* ESNext */, /*setParentNodes*/ true, scriptKind);
                var changes = ts.formatting.formatDocument(sourceFile, formatContext);
                return applyChanges(nonFormattedText, changes) + newLineCharacter;
            }
            changesToText.newFileChangesWorker = newFileChangesWorker;
            function computeNewText(change, sourceFile, newLineCharacter, formatContext, validate) {
                if (change.kind === ChangeKind.Remove) {
                    return "";
                }
                if (change.kind === ChangeKind.Text) {
                    return change.text;
                }
                var _a = change.options, options = _a === void 0 ? {} : _a, pos = change.range.pos;
                var format = function (n) { return getFormattedTextOfNode(n, sourceFile, pos, options, newLineCharacter, formatContext, validate); };
                var text = change.kind === ChangeKind.ReplaceWithMultipleNodes
                    ? change.nodes.map(function (n) { return ts.removeSuffix(format(n), newLineCharacter); }).join(change.options.joiner || newLineCharacter) // TODO: GH#18217
                    : format(change.node);
                // strip initial indentation (spaces or tabs) if text will be inserted in the middle of the line
                var noIndent = (options.preserveLeadingWhitespace || options.indentation !== undefined || ts.getLineStartPositionForPosition(pos, sourceFile) === pos) ? text : text.replace(/^\s+/, "");
                return (options.prefix || "") + noIndent + (options.suffix || "");
            }
            /** Note: this may mutate `nodeIn`. */
            function getFormattedTextOfNode(nodeIn, sourceFile, pos, _a, newLineCharacter, formatContext, validate) {
                var indentation = _a.indentation, prefix = _a.prefix, delta = _a.delta;
                var _b = getNonformattedText(nodeIn, sourceFile, newLineCharacter), node = _b.node, text = _b.text;
                if (validate)
                    validate(node, text);
                var formatOptions = formatContext.options;
                var initialIndentation = indentation !== undefined
                    ? indentation
                    : ts.formatting.SmartIndenter.getIndentation(pos, sourceFile, formatOptions, prefix === newLineCharacter || ts.getLineStartPositionForPosition(pos, sourceFile) === pos);
                if (delta === undefined) {
                    delta = ts.formatting.SmartIndenter.shouldIndentChildNode(formatContext.options, nodeIn) ? (formatOptions.indentSize || 0) : 0;
                }
                var file = { text: text, getLineAndCharacterOfPosition: function (pos) { return ts.getLineAndCharacterOfPosition(this, pos); } };
                var changes = ts.formatting.formatNodeGivenIndentation(node, file, sourceFile.languageVariant, initialIndentation, delta, formatContext);
                return applyChanges(text, changes);
            }
            /** Note: output node may be mutated input node. */
            function getNonformattedText(node, sourceFile, newLineCharacter) {
                var writer = new Writer(newLineCharacter);
                var newLine = newLineCharacter === "\n" ? 1 /* LineFeed */ : 0 /* CarriageReturnLineFeed */;
                ts.createPrinter({ newLine: newLine, neverAsciiEscape: true }, writer).writeNode(4 /* Unspecified */, node, sourceFile, writer);
                return { text: writer.getText(), node: assignPositionsToNode(node) };
            }
            changesToText.getNonformattedText = getNonformattedText;
        })(changesToText || (changesToText = {}));
        function applyChanges(text, changes) {
            for (var i = changes.length - 1; i >= 0; i--) {
                var _a = changes[i], span = _a.span, newText = _a.newText;
                text = "" + text.substring(0, span.start) + newText + text.substring(ts.textSpanEnd(span));
            }
            return text;
        }
        textChanges_3.applyChanges = applyChanges;
        function isTrivia(s) {
            return ts.skipTrivia(s, 0) === s.length;
        }
        function assignPositionsToNode(node) {
            var visited = ts.visitEachChild(node, assignPositionsToNode, ts.nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode); // TODO: GH#18217
            // create proxy node for non synthesized nodes
            var newNode = ts.nodeIsSynthesized(visited) ? visited : Object.create(visited);
            newNode.pos = getPos(node);
            newNode.end = getEnd(node);
            return newNode;
        }
        function assignPositionsToNodeArray(nodes, visitor, test, start, count) {
            var visited = ts.visitNodes(nodes, visitor, test, start, count);
            if (!visited) {
                return visited;
            }
            // clone nodearray if necessary
            var nodeArray = visited === nodes ? ts.createNodeArray(visited.slice(0)) : visited;
            nodeArray.pos = getPos(nodes);
            nodeArray.end = getEnd(nodes);
            return nodeArray;
        }
        var Writer = /** @class */ (function () {
            function Writer(newLine) {
                var _this = this;
                this.lastNonTriviaPosition = 0;
                this.writer = ts.createTextWriter(newLine);
                this.onEmitNode = function (hint, node, printCallback) {
                    if (node) {
                        setPos(node, _this.lastNonTriviaPosition);
                    }
                    printCallback(hint, node);
                    if (node) {
                        setEnd(node, _this.lastNonTriviaPosition);
                    }
                };
                this.onBeforeEmitNodeArray = function (nodes) {
                    if (nodes) {
                        setPos(nodes, _this.lastNonTriviaPosition);
                    }
                };
                this.onAfterEmitNodeArray = function (nodes) {
                    if (nodes) {
                        setEnd(nodes, _this.lastNonTriviaPosition);
                    }
                };
                this.onBeforeEmitToken = function (node) {
                    if (node) {
                        setPos(node, _this.lastNonTriviaPosition);
                    }
                };
                this.onAfterEmitToken = function (node) {
                    if (node) {
                        setEnd(node, _this.lastNonTriviaPosition);
                    }
                };
            }
            Writer.prototype.setLastNonTriviaPosition = function (s, force) {
                if (force || !isTrivia(s)) {
                    this.lastNonTriviaPosition = this.writer.getTextPos();
                    var i = 0;
                    while (ts.isWhiteSpaceLike(s.charCodeAt(s.length - i - 1))) {
                        i++;
                    }
                    // trim trailing whitespaces
                    this.lastNonTriviaPosition -= i;
                }
            };
            Writer.prototype.write = function (s) {
                this.writer.write(s);
                this.setLastNonTriviaPosition(s, /*force*/ false);
            };
            Writer.prototype.writeComment = function (s) {
                this.writer.writeComment(s);
            };
            Writer.prototype.writeKeyword = function (s) {
                this.writer.writeKeyword(s);
                this.setLastNonTriviaPosition(s, /*force*/ false);
            };
            Writer.prototype.writeOperator = function (s) {
                this.writer.writeOperator(s);
                this.setLastNonTriviaPosition(s, /*force*/ false);
            };
            Writer.prototype.writePunctuation = function (s) {
                this.writer.writePunctuation(s);
                this.setLastNonTriviaPosition(s, /*force*/ false);
            };
            Writer.prototype.writeTrailingSemicolon = function (s) {
                this.writer.writeTrailingSemicolon(s);
                this.setLastNonTriviaPosition(s, /*force*/ false);
            };
            Writer.prototype.writeParameter = function (s) {
                this.writer.writeParameter(s);
                this.setLastNonTriviaPosition(s, /*force*/ false);
            };
            Writer.prototype.writeProperty = function (s) {
                this.writer.writeProperty(s);
                this.setLastNonTriviaPosition(s, /*force*/ false);
            };
            Writer.prototype.writeSpace = function (s) {
                this.writer.writeSpace(s);
                this.setLastNonTriviaPosition(s, /*force*/ false);
            };
            Writer.prototype.writeStringLiteral = function (s) {
                this.writer.writeStringLiteral(s);
                this.setLastNonTriviaPosition(s, /*force*/ false);
            };
            Writer.prototype.writeSymbol = function (s, sym) {
                this.writer.writeSymbol(s, sym);
                this.setLastNonTriviaPosition(s, /*force*/ false);
            };
            Writer.prototype.writeLine = function () {
                this.writer.writeLine();
            };
            Writer.prototype.increaseIndent = function () {
                this.writer.increaseIndent();
            };
            Writer.prototype.decreaseIndent = function () {
                this.writer.decreaseIndent();
            };
            Writer.prototype.getText = function () {
                return this.writer.getText();
            };
            Writer.prototype.rawWrite = function (s) {
                this.writer.rawWrite(s);
                this.setLastNonTriviaPosition(s, /*force*/ false);
            };
            Writer.prototype.writeLiteral = function (s) {
                this.writer.writeLiteral(s);
                this.setLastNonTriviaPosition(s, /*force*/ true);
            };
            Writer.prototype.getTextPos = function () {
                return this.writer.getTextPos();
            };
            Writer.prototype.getLine = function () {
                return this.writer.getLine();
            };
            Writer.prototype.getColumn = function () {
                return this.writer.getColumn();
            };
            Writer.prototype.getIndent = function () {
                return this.writer.getIndent();
            };
            Writer.prototype.isAtStartOfLine = function () {
                return this.writer.isAtStartOfLine();
            };
            Writer.prototype.clear = function () {
                this.writer.clear();
                this.lastNonTriviaPosition = 0;
            };
            return Writer;
        }());
        function getInsertionPositionAtSourceFileTop(sourceFile) {
            var lastPrologue;
            for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
                var node = _a[_i];
                if (ts.isPrologueDirective(node)) {
                    lastPrologue = node;
                }
                else {
                    break;
                }
            }
            var position = 0;
            var text = sourceFile.text;
            if (lastPrologue) {
                position = lastPrologue.end;
                advancePastLineBreak();
                return position;
            }
            var shebang = ts.getShebang(text);
            if (shebang !== undefined) {
                position = shebang.length;
                advancePastLineBreak();
            }
            // For a source file, it is possible there are detached comments we should not skip
            var ranges = ts.getLeadingCommentRanges(text, position);
            if (!ranges)
                return position;
            // However we should still skip a pinned comment at the top
            if (ranges.length && ranges[0].kind === 3 /* MultiLineCommentTrivia */ && ts.isPinnedComment(text, ranges[0].pos)) {
                position = ranges[0].end;
                advancePastLineBreak();
                ranges = ranges.slice(1);
            }
            // As well as any triple slash references
            for (var _b = 0, ranges_1 = ranges; _b < ranges_1.length; _b++) {
                var range = ranges_1[_b];
                if (range.kind === 2 /* SingleLineCommentTrivia */ && ts.isRecognizedTripleSlashComment(text, range.pos, range.end)) {
                    position = range.end;
                    advancePastLineBreak();
                    continue;
                }
                break;
            }
            return position;
            function advancePastLineBreak() {
                if (position < text.length) {
                    var charCode = text.charCodeAt(position);
                    if (ts.isLineBreak(charCode)) {
                        position++;
                        if (position < text.length && charCode === 13 /* carriageReturn */ && text.charCodeAt(position) === 10 /* lineFeed */) {
                            position++;
                        }
                    }
                }
            }
        }
        function isValidLocationToAddComment(sourceFile, position) {
            return !ts.isInComment(sourceFile, position) && !ts.isInString(sourceFile, position) && !ts.isInTemplateString(sourceFile, position) && !ts.isInJSXText(sourceFile, position);
        }
        textChanges_3.isValidLocationToAddComment = isValidLocationToAddComment;
        function needSemicolonBetween(a, b) {
            return (ts.isPropertySignature(a) || ts.isPropertyDeclaration(a)) && ts.isClassOrTypeElement(b) && b.name.kind === 150 /* ComputedPropertyName */
                || ts.isStatementButNotDeclaration(a) && ts.isStatementButNotDeclaration(b); // TODO: only if b would start with a `(` or `[`
        }
        var deleteDeclaration;
        (function (deleteDeclaration_1) {
            function deleteDeclaration(changes, deletedNodesInLists, sourceFile, node) {
                switch (node.kind) {
                    case 152 /* Parameter */: {
                        var oldFunction = node.parent;
                        if (ts.isArrowFunction(oldFunction) &&
                            oldFunction.parameters.length === 1 &&
                            !ts.findChildOfKind(oldFunction, 20 /* OpenParenToken */, sourceFile)) {
                            // Lambdas with exactly one parameter are special because, after removal, there
                            // must be an empty parameter list (i.e. `()`) and this won't necessarily be the
                            // case if the parameter is simply removed (e.g. in `x => 1`).
                            changes.replaceNodeWithText(sourceFile, node, "()");
                        }
                        else {
                            deleteNodeInList(changes, deletedNodesInLists, sourceFile, node);
                        }
                        break;
                    }
                    case 250 /* ImportDeclaration */:
                        deleteNode(changes, sourceFile, node, 
                        // For first import, leave header comment in place
                        node === sourceFile.imports[0].parent ? { leadingTriviaOption: LeadingTriviaOption.Exclude } : undefined);
                        break;
                    case 187 /* BindingElement */:
                        var pattern = node.parent;
                        var preserveComma = pattern.kind === 186 /* ArrayBindingPattern */ && node !== ts.last(pattern.elements);
                        if (preserveComma) {
                            deleteNode(changes, sourceFile, node);
                        }
                        else {
                            deleteNodeInList(changes, deletedNodesInLists, sourceFile, node);
                        }
                        break;
                    case 238 /* VariableDeclaration */:
                        deleteVariableDeclaration(changes, deletedNodesInLists, sourceFile, node);
                        break;
                    case 151 /* TypeParameter */:
                        deleteNodeInList(changes, deletedNodesInLists, sourceFile, node);
                        break;
                    case 254 /* ImportSpecifier */:
                        var namedImports = node.parent;
                        if (namedImports.elements.length === 1) {
                            deleteImportBinding(changes, sourceFile, namedImports);
                        }
                        else {
                            deleteNodeInList(changes, deletedNodesInLists, sourceFile, node);
                        }
                        break;
                    case 252 /* NamespaceImport */:
                        deleteImportBinding(changes, sourceFile, node);
                        break;
                    default:
                        if (ts.isImportClause(node.parent) && node.parent.name === node) {
                            deleteDefaultImport(changes, sourceFile, node.parent);
                        }
                        else if (ts.isCallLikeExpression(node.parent)) {
                            deleteNodeInList(changes, deletedNodesInLists, sourceFile, node);
                        }
                        else {
                            deleteNode(changes, sourceFile, node, node.kind === 26 /* SemicolonToken */ ? { trailingTriviaOption: TrailingTriviaOption.Exclude } : undefined);
                        }
                }
            }
            deleteDeclaration_1.deleteDeclaration = deleteDeclaration;
            function deleteDefaultImport(changes, sourceFile, importClause) {
                if (!importClause.namedBindings) {
                    // Delete the whole import
                    deleteNode(changes, sourceFile, importClause.parent);
                }
                else {
                    // import |d,| * as ns from './file'
                    var start = importClause.name.getStart(sourceFile);
                    var nextToken = ts.getTokenAtPosition(sourceFile, importClause.name.end);
                    if (nextToken && nextToken.kind === 27 /* CommaToken */) {
                        // shift first non-whitespace position after comma to the start position of the node
                        var end = ts.skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/ true);
                        changes.deleteRange(sourceFile, { pos: start, end: end });
                    }
                    else {
                        deleteNode(changes, sourceFile, importClause.name);
                    }
                }
            }
            function deleteImportBinding(changes, sourceFile, node) {
                if (node.parent.name) {
                    // Delete named imports while preserving the default import
                    // import d|, * as ns| from './file'
                    // import d|, { a }| from './file'
                    var previousToken = ts.Debug.assertDefined(ts.getTokenAtPosition(sourceFile, node.pos - 1));
                    changes.deleteRange(sourceFile, { pos: previousToken.getStart(sourceFile), end: node.end });
                }
                else {
                    // Delete the entire import declaration
                    // |import * as ns from './file'|
                    // |import { a } from './file'|
                    var importDecl = ts.getAncestor(node, 250 /* ImportDeclaration */);
                    deleteNode(changes, sourceFile, importDecl);
                }
            }
            function deleteVariableDeclaration(changes, deletedNodesInLists, sourceFile, node) {
                var parent = node.parent;
                if (parent.kind === 275 /* CatchClause */) {
                    // TODO: There's currently no unused diagnostic for this, could be a suggestion
                    changes.deleteNodeRange(sourceFile, ts.findChildOfKind(parent, 20 /* OpenParenToken */, sourceFile), ts.findChildOfKind(parent, 21 /* CloseParenToken */, sourceFile));
                    return;
                }
                if (parent.declarations.length !== 1) {
                    deleteNodeInList(changes, deletedNodesInLists, sourceFile, node);
                    return;
                }
                var gp = parent.parent;
                switch (gp.kind) {
                    case 228 /* ForOfStatement */:
                    case 227 /* ForInStatement */:
                        changes.replaceNode(sourceFile, node, ts.createObjectLiteral());
                        break;
                    case 226 /* ForStatement */:
                        deleteNode(changes, sourceFile, parent);
                        break;
                    case 220 /* VariableStatement */:
                        deleteNode(changes, sourceFile, gp);
                        break;
                    default:
                        ts.Debug.assertNever(gp);
                }
            }
        })(deleteDeclaration || (deleteDeclaration = {}));
        /** Warning: This deletes comments too. See `copyComments` in `convertFunctionToEs6Class`. */
        // Exported for tests only! (TODO: improve tests to not need this)
        function deleteNode(changes, sourceFile, node, options) {
            if (options === void 0) { options = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }; }
            var startPosition = getAdjustedStartPosition(sourceFile, node, options);
            var endPosition = getAdjustedEndPosition(sourceFile, node, options);
            changes.deleteRange(sourceFile, { pos: startPosition, end: endPosition });
        }
        textChanges_3.deleteNode = deleteNode;
        function deleteNodeInList(changes, deletedNodesInLists, sourceFile, node) {
            var containingList = ts.Debug.assertDefined(ts.formatting.SmartIndenter.getContainingList(node, sourceFile));
            var index = ts.indexOfNode(containingList, node);
            ts.Debug.assert(index !== -1);
            if (containingList.length === 1) {
                deleteNode(changes, sourceFile, node);
                return;
            }
            // Note: We will only delete a comma *after* a node. This will leave a trailing comma if we delete the last node.
            // That's handled in the end by `finishTrailingCommaAfterDeletingNodesInList`.
            ts.Debug.assert(!deletedNodesInLists.has(node), "Deleting a node twice");
            deletedNodesInLists.add(node);
            changes.deleteRange(sourceFile, {
                pos: startPositionToDeleteNodeInList(sourceFile, node),
                end: index === containingList.length - 1 ? getAdjustedEndPosition(sourceFile, node, {}) : startPositionToDeleteNodeInList(sourceFile, containingList[index + 1]),
            });
        }
    })(textChanges = ts.textChanges || (ts.textChanges = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var errorCodeToFixes = ts.createMultiMap();
        var fixIdToRegistration = ts.createMap();
        function diagnosticToString(diag) {
            return ts.isArray(diag)
                ? ts.formatStringFromArgs(ts.getLocaleSpecificMessage(diag[0]), diag.slice(1))
                : ts.getLocaleSpecificMessage(diag);
        }
        function createCodeFixActionNoFixId(fixName, changes, description) {
            return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, /*fixId*/ undefined, /*fixAllDescription*/ undefined);
        }
        codefix.createCodeFixActionNoFixId = createCodeFixActionNoFixId;
        function createCodeFixAction(fixName, changes, description, fixId, fixAllDescription, command) {
            return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, fixId, diagnosticToString(fixAllDescription), command);
        }
        codefix.createCodeFixAction = createCodeFixAction;
        function createCodeFixActionWorker(fixName, description, changes, fixId, fixAllDescription, command) {
            return { fixName: fixName, description: description, changes: changes, fixId: fixId, fixAllDescription: fixAllDescription, commands: command ? [command] : undefined };
        }
        function registerCodeFix(reg) {
            for (var _i = 0, _a = reg.errorCodes; _i < _a.length; _i++) {
                var error = _a[_i];
                errorCodeToFixes.add(String(error), reg);
            }
            if (reg.fixIds) {
                for (var _b = 0, _c = reg.fixIds; _b < _c.length; _b++) {
                    var fixId = _c[_b];
                    ts.Debug.assert(!fixIdToRegistration.has(fixId));
                    fixIdToRegistration.set(fixId, reg);
                }
            }
        }
        codefix.registerCodeFix = registerCodeFix;
        function getSupportedErrorCodes() {
            return ts.arrayFrom(errorCodeToFixes.keys());
        }
        codefix.getSupportedErrorCodes = getSupportedErrorCodes;
        function getFixes(context) {
            return ts.flatMap(errorCodeToFixes.get(String(context.errorCode)) || ts.emptyArray, function (f) { return f.getCodeActions(context); });
        }
        codefix.getFixes = getFixes;
        function getAllFixes(context) {
            // Currently fixId is always a string.
            return fixIdToRegistration.get(ts.cast(context.fixId, ts.isString)).getAllCodeActions(context);
        }
        codefix.getAllFixes = getAllFixes;
        function createCombinedCodeActions(changes, commands) {
            return { changes: changes, commands: commands };
        }
        codefix.createCombinedCodeActions = createCombinedCodeActions;
        function createFileTextChanges(fileName, textChanges) {
            return { fileName: fileName, textChanges: textChanges };
        }
        codefix.createFileTextChanges = createFileTextChanges;
        function codeFixAll(context, errorCodes, use) {
            var commands = [];
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return eachDiagnostic(context, errorCodes, function (diag) { return use(t, diag, commands); }); });
            return createCombinedCodeActions(changes, commands.length === 0 ? undefined : commands);
        }
        codefix.codeFixAll = codeFixAll;
        function eachDiagnostic(_a, errorCodes, cb) {
            var program = _a.program, sourceFile = _a.sourceFile, cancellationToken = _a.cancellationToken;
            for (var _i = 0, _b = program.getSemanticDiagnostics(sourceFile, cancellationToken).concat(ts.computeSuggestionDiagnostics(sourceFile, program, cancellationToken)); _i < _b.length; _i++) {
                var diag = _b[_i];
                if (ts.contains(errorCodes, diag.code)) {
                    cb(diag);
                }
            }
        }
        codefix.eachDiagnostic = eachDiagnostic;
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor_1) {
        // A map with the refactor code as key, the refactor itself as value
        // e.g.  nonSuggestableRefactors[refactorCode] -> the refactor you want
        var refactors = ts.createMap();
        /** @param name An unique code associated with each refactor. Does not have to be human-readable. */
        function registerRefactor(name, refactor) {
            refactors.set(name, refactor);
        }
        refactor_1.registerRefactor = registerRefactor;
        function getApplicableRefactors(context) {
            return ts.arrayFrom(ts.flatMapIterator(refactors.values(), function (refactor) {
                return context.cancellationToken && context.cancellationToken.isCancellationRequested() ? undefined : refactor.getAvailableActions(context);
            }));
        }
        refactor_1.getApplicableRefactors = getApplicableRefactors;
        function getEditsForRefactor(context, refactorName, actionName) {
            var refactor = refactors.get(refactorName);
            return refactor && refactor.getEditsForAction(context, actionName);
        }
        refactor_1.getEditsForRefactor = getEditsForRefactor;
    })(refactor = ts.refactor || (ts.refactor = {}));
    function getRefactorContextSpan(_a) {
        var startPosition = _a.startPosition, endPosition = _a.endPosition;
        return ts.createTextSpanFromBounds(startPosition, endPosition === undefined ? startPosition : endPosition);
    }
    ts.getRefactorContextSpan = getRefactorContextSpan;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "addConvertToUnknownForNonOverlappingTypes";
        var errorCodes = [ts.Diagnostics.Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the_other_If_this_was_intentional_convert_the_expression_to_unknown_first.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return makeChange(t, context.sourceFile, context.span.start); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_unknown_conversion_for_non_overlapping_types, fixId, ts.Diagnostics.Add_unknown_to_all_conversions_of_non_overlapping_types)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return makeChange(changes, diag.file, diag.start); }); },
        });
        function makeChange(changeTracker, sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            var assertion = ts.Debug.assertDefined(ts.findAncestor(token, function (n) { return ts.isAsExpression(n) || ts.isTypeAssertion(n); }));
            var replacement = ts.isAsExpression(assertion)
                ? ts.createAsExpression(assertion.expression, ts.createKeywordTypeNode(144 /* UnknownKeyword */))
                : ts.createTypeAssertion(ts.createKeywordTypeNode(144 /* UnknownKeyword */), assertion.expression);
            changeTracker.replaceNode(sourceFile, assertion.expression, replacement);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "addMissingInvocationForDecorator";
        var errorCodes = [ts.Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return makeChange(t, context.sourceFile, context.span.start); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Call_decorator_expression, fixId, ts.Diagnostics.Add_to_all_uncalled_decorators)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return makeChange(changes, diag.file, diag.start); }); },
        });
        function makeChange(changeTracker, sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            var decorator = ts.findAncestor(token, ts.isDecorator);
            ts.Debug.assert(!!decorator, "Expected position to be owned by a decorator.");
            var replacement = ts.createCall(decorator.expression, /*typeArguments*/ undefined, /*argumentsArray*/ undefined);
            changeTracker.replaceNode(sourceFile, decorator.expression, replacement);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "addNameToNamelessParameter";
        var errorCodes = [ts.Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return makeChange(t, context.sourceFile, context.span.start); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_parameter_name, fixId, ts.Diagnostics.Add_names_to_all_parameters_without_names)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return makeChange(changes, diag.file, diag.start); }); },
        });
        function makeChange(changeTracker, sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            if (!ts.isIdentifier(token)) {
                return ts.Debug.fail("add-name-to-nameless-parameter operates on identifiers, but got a " + ts.Debug.formatSyntaxKind(token.kind));
            }
            var param = token.parent;
            if (!ts.isParameter(param)) {
                return ts.Debug.fail("Tried to add a parameter name to a non-parameter: " + ts.Debug.formatSyntaxKind(token.kind));
            }
            var i = param.parent.parameters.indexOf(param);
            ts.Debug.assert(!param.type, "Tried to add a parameter name to a parameter that already had one.");
            ts.Debug.assert(i > -1, "Parameter not found in parent parameter list.");
            var replacement = ts.createParameter(
            /*decorators*/ undefined, param.modifiers, param.dotDotDotToken, "arg" + i, param.questionToken, ts.createTypeReferenceNode(token, /*typeArguments*/ undefined), param.initializer);
            changeTracker.replaceNode(sourceFile, token, replacement);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "annotateWithTypeFromJSDoc";
        var errorCodes = [ts.Diagnostics.JSDoc_types_may_be_moved_to_TypeScript_types.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var decl = getDeclaration(context.sourceFile, context.span.start);
                if (!decl)
                    return;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, context.sourceFile, decl); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Annotate_with_type_from_JSDoc, fixId, ts.Diagnostics.Annotate_everything_with_types_from_JSDoc)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var decl = getDeclaration(diag.file, diag.start);
                if (decl)
                    doChange(changes, diag.file, decl);
            }); },
        });
        function getDeclaration(file, pos) {
            var name = ts.getTokenAtPosition(file, pos);
            // For an arrow function with no name, 'name' lands on the first parameter.
            return ts.tryCast(ts.isParameter(name.parent) ? name.parent.parent : name.parent, parameterShouldGetTypeFromJSDoc);
        }
        function parameterShouldGetTypeFromJSDoc(node) {
            return isDeclarationWithType(node) && hasUsableJSDoc(node);
        }
        codefix.parameterShouldGetTypeFromJSDoc = parameterShouldGetTypeFromJSDoc;
        function hasUsableJSDoc(decl) {
            return ts.isFunctionLikeDeclaration(decl)
                ? decl.parameters.some(hasUsableJSDoc) || (!decl.type && !!ts.getJSDocReturnType(decl))
                : !decl.type && !!ts.getJSDocType(decl);
        }
        function doChange(changes, sourceFile, decl) {
            if (ts.isFunctionLikeDeclaration(decl) && (ts.getJSDocReturnType(decl) || decl.parameters.some(function (p) { return !!ts.getJSDocType(p); }))) {
                if (!decl.typeParameters) {
                    var typeParameters = ts.getJSDocTypeParameterDeclarations(decl);
                    if (typeParameters.length)
                        changes.insertTypeParameters(sourceFile, decl, typeParameters);
                }
                var needParens = ts.isArrowFunction(decl) && !ts.findChildOfKind(decl, 20 /* OpenParenToken */, sourceFile);
                if (needParens)
                    changes.insertNodeBefore(sourceFile, ts.first(decl.parameters), ts.createToken(20 /* OpenParenToken */));
                for (var _i = 0, _a = decl.parameters; _i < _a.length; _i++) {
                    var param = _a[_i];
                    if (!param.type) {
                        var paramType = ts.getJSDocType(param);
                        if (paramType)
                            changes.tryInsertTypeAnnotation(sourceFile, param, transformJSDocType(paramType));
                    }
                }
                if (needParens)
                    changes.insertNodeAfter(sourceFile, ts.last(decl.parameters), ts.createToken(21 /* CloseParenToken */));
                if (!decl.type) {
                    var returnType = ts.getJSDocReturnType(decl);
                    if (returnType)
                        changes.tryInsertTypeAnnotation(sourceFile, decl, transformJSDocType(returnType));
                }
            }
            else {
                var jsdocType = ts.Debug.assertDefined(ts.getJSDocType(decl)); // If not defined, shouldn't have been an error to fix
                ts.Debug.assert(!decl.type); // If defined, shouldn't have been an error to fix.
                changes.tryInsertTypeAnnotation(sourceFile, decl, transformJSDocType(jsdocType));
            }
        }
        function isDeclarationWithType(node) {
            return ts.isFunctionLikeDeclaration(node) ||
                node.kind === 238 /* VariableDeclaration */ ||
                node.kind === 154 /* PropertySignature */ ||
                node.kind === 155 /* PropertyDeclaration */;
        }
        function transformJSDocType(node) {
            switch (node.kind) {
                case 290 /* JSDocAllType */:
                case 291 /* JSDocUnknownType */:
                    return ts.createTypeReferenceNode("any", ts.emptyArray);
                case 294 /* JSDocOptionalType */:
                    return transformJSDocOptionalType(node);
                case 293 /* JSDocNonNullableType */:
                    return transformJSDocType(node.type);
                case 292 /* JSDocNullableType */:
                    return transformJSDocNullableType(node);
                case 296 /* JSDocVariadicType */:
                    return transformJSDocVariadicType(node);
                case 295 /* JSDocFunctionType */:
                    return transformJSDocFunctionType(node);
                case 165 /* TypeReference */:
                    return transformJSDocTypeReference(node);
                default:
                    var visited = ts.visitEachChild(node, transformJSDocType, /*context*/ undefined); // TODO: GH#18217
                    ts.setEmitFlags(visited, 1 /* SingleLine */);
                    return visited;
            }
        }
        function transformJSDocOptionalType(node) {
            return ts.createUnionTypeNode([ts.visitNode(node.type, transformJSDocType), ts.createTypeReferenceNode("undefined", ts.emptyArray)]);
        }
        function transformJSDocNullableType(node) {
            return ts.createUnionTypeNode([ts.visitNode(node.type, transformJSDocType), ts.createTypeReferenceNode("null", ts.emptyArray)]);
        }
        function transformJSDocVariadicType(node) {
            return ts.createArrayTypeNode(ts.visitNode(node.type, transformJSDocType));
        }
        function transformJSDocFunctionType(node) {
            return ts.createFunctionTypeNode(ts.emptyArray, node.parameters.map(transformJSDocParameter), node.type);
        }
        function transformJSDocParameter(node) {
            var index = node.parent.parameters.indexOf(node);
            var isRest = node.type.kind === 296 /* JSDocVariadicType */ && index === node.parent.parameters.length - 1; // TODO: GH#18217
            var name = node.name || (isRest ? "rest" : "arg" + index);
            var dotdotdot = isRest ? ts.createToken(25 /* DotDotDotToken */) : node.dotDotDotToken;
            return ts.createParameter(node.decorators, node.modifiers, dotdotdot, name, node.questionToken, ts.visitNode(node.type, transformJSDocType), node.initializer);
        }
        function transformJSDocTypeReference(node) {
            var name = node.typeName;
            var args = node.typeArguments;
            if (ts.isIdentifier(node.typeName)) {
                if (ts.isJSDocIndexSignature(node)) {
                    return transformJSDocIndexSignature(node);
                }
                var text = node.typeName.text;
                switch (node.typeName.text) {
                    case "String":
                    case "Boolean":
                    case "Object":
                    case "Number":
                        text = text.toLowerCase();
                        break;
                    case "array":
                    case "date":
                    case "promise":
                        text = text[0].toUpperCase() + text.slice(1);
                        break;
                }
                name = ts.createIdentifier(text);
                if ((text === "Array" || text === "Promise") && !node.typeArguments) {
                    args = ts.createNodeArray([ts.createTypeReferenceNode("any", ts.emptyArray)]);
                }
                else {
                    args = ts.visitNodes(node.typeArguments, transformJSDocType);
                }
            }
            return ts.createTypeReferenceNode(name, args);
        }
        function transformJSDocIndexSignature(node) {
            var index = ts.createParameter(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, 
            /*dotDotDotToken*/ undefined, node.typeArguments[0].kind === 136 /* NumberKeyword */ ? "n" : "s", 
            /*questionToken*/ undefined, ts.createTypeReferenceNode(node.typeArguments[0].kind === 136 /* NumberKeyword */ ? "number" : "string", []), 
            /*initializer*/ undefined);
            var indexSignature = ts.createTypeLiteralNode([ts.createIndexSignature(/*decorators*/ undefined, /*modifiers*/ undefined, [index], node.typeArguments[1])]);
            ts.setEmitFlags(indexSignature, 1 /* SingleLine */);
            return indexSignature;
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "inferFromUsage";
        var errorCodes = [
            // Variable declarations
            ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code,
            // Variable uses
            ts.Diagnostics.Variable_0_implicitly_has_an_1_type.code,
            // Parameter declarations
            ts.Diagnostics.Parameter_0_implicitly_has_an_1_type.code,
            ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code,
            // Get Accessor declarations
            ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code,
            ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code,
            // Set Accessor declarations
            ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code,
            // Property declarations
            ts.Diagnostics.Member_0_implicitly_has_an_1_type.code,
            //// Suggestions
            // Variable declarations
            ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_but_a_better_type_may_be_inferred_from_usage.code,
            // Variable uses
            ts.Diagnostics.Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code,
            // Parameter declarations
            ts.Diagnostics.Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code,
            ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage.code,
            // Get Accessor declarations
            ts.Diagnostics.Property_0_implicitly_has_type_any_but_a_better_type_for_its_get_accessor_may_be_inferred_from_usage.code,
            ts.Diagnostics._0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage.code,
            // Set Accessor declarations
            ts.Diagnostics.Property_0_implicitly_has_type_any_but_a_better_type_for_its_set_accessor_may_be_inferred_from_usage.code,
            // Property declarations
            ts.Diagnostics.Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, program = context.program, start = context.span.start, errorCode = context.errorCode, cancellationToken = context.cancellationToken, host = context.host;
                var token = ts.getTokenAtPosition(sourceFile, start);
                var declaration;
                var changes = ts.textChanges.ChangeTracker.with(context, function (changes) { declaration = doChange(changes, sourceFile, token, errorCode, program, cancellationToken, /*markSeen*/ ts.returnTrue, host); });
                var name = declaration && ts.getNameOfDeclaration(declaration);
                return !name || changes.length === 0 ? undefined
                    : [codefix.createCodeFixAction(fixId, changes, [getDiagnostic(errorCode, token), name.getText(sourceFile)], fixId, ts.Diagnostics.Infer_all_types_from_usage)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var sourceFile = context.sourceFile, program = context.program, cancellationToken = context.cancellationToken, host = context.host;
                var markSeen = ts.nodeSeenTracker();
                return codefix.codeFixAll(context, errorCodes, function (changes, err) {
                    doChange(changes, sourceFile, ts.getTokenAtPosition(err.file, err.start), err.code, program, cancellationToken, markSeen, host);
                });
            },
        });
        function getDiagnostic(errorCode, token) {
            switch (errorCode) {
                case ts.Diagnostics.Parameter_0_implicitly_has_an_1_type.code:
                case ts.Diagnostics.Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.isSetAccessorDeclaration(ts.getContainingFunction(token)) ? ts.Diagnostics.Infer_type_of_0_from_usage : ts.Diagnostics.Infer_parameter_types_from_usage; // TODO: GH#18217
                case ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code:
                case ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Infer_parameter_types_from_usage;
                default:
                    return ts.Diagnostics.Infer_type_of_0_from_usage;
            }
        }
        /** Map suggestion code to error code */
        function mapSuggestionDiagnostic(errorCode) {
            switch (errorCode) {
                case ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code;
                case ts.Diagnostics.Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Variable_0_implicitly_has_an_1_type.code;
                case ts.Diagnostics.Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Parameter_0_implicitly_has_an_1_type.code;
                case ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code;
                case ts.Diagnostics.Property_0_implicitly_has_type_any_but_a_better_type_for_its_get_accessor_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code;
                case ts.Diagnostics._0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code;
                case ts.Diagnostics.Property_0_implicitly_has_type_any_but_a_better_type_for_its_set_accessor_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code;
                case ts.Diagnostics.Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Member_0_implicitly_has_an_1_type.code;
            }
            return errorCode;
        }
        function doChange(changes, sourceFile, token, errorCode, program, cancellationToken, markSeen, host) {
            if (!ts.isParameterPropertyModifier(token.kind) && token.kind !== 73 /* Identifier */ && token.kind !== 25 /* DotDotDotToken */ && token.kind !== 101 /* ThisKeyword */) {
                return undefined;
            }
            var parent = token.parent;
            errorCode = mapSuggestionDiagnostic(errorCode);
            switch (errorCode) {
                // Variable and Property declarations
                case ts.Diagnostics.Member_0_implicitly_has_an_1_type.code:
                case ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code:
                    if ((ts.isVariableDeclaration(parent) && markSeen(parent)) || ts.isPropertyDeclaration(parent) || ts.isPropertySignature(parent)) { // handle bad location
                        annotateVariableDeclaration(changes, sourceFile, parent, program, host, cancellationToken);
                        return parent;
                    }
                    if (ts.isPropertyAccessExpression(parent)) {
                        var type = inferTypeForVariableFromUsage(parent.name, program, cancellationToken);
                        var typeNode = ts.getTypeNodeIfAccessible(type, parent, program, host);
                        if (typeNode) {
                            // Note that the codefix will never fire with an existing `@type` tag, so there is no need to merge tags
                            var typeTag = ts.createJSDocTypeTag(ts.createJSDocTypeExpression(typeNode), /*comment*/ "");
                            addJSDocTags(changes, sourceFile, ts.cast(parent.parent.parent, ts.isExpressionStatement), [typeTag]);
                        }
                        return parent;
                    }
                    return undefined;
                case ts.Diagnostics.Variable_0_implicitly_has_an_1_type.code: {
                    var symbol = program.getTypeChecker().getSymbolAtLocation(token);
                    if (symbol && symbol.valueDeclaration && ts.isVariableDeclaration(symbol.valueDeclaration) && markSeen(symbol.valueDeclaration)) {
                        annotateVariableDeclaration(changes, sourceFile, symbol.valueDeclaration, program, host, cancellationToken);
                        return symbol.valueDeclaration;
                    }
                    return undefined;
                }
            }
            var containingFunction = ts.getContainingFunction(token);
            if (containingFunction === undefined) {
                return undefined;
            }
            switch (errorCode) {
                // Parameter declarations
                case ts.Diagnostics.Parameter_0_implicitly_has_an_1_type.code:
                    if (ts.isSetAccessorDeclaration(containingFunction)) {
                        annotateSetAccessor(changes, sourceFile, containingFunction, program, host, cancellationToken);
                        return containingFunction;
                    }
                // falls through
                case ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code:
                    if (markSeen(containingFunction)) {
                        var param = ts.cast(parent, ts.isParameter);
                        annotateParameters(changes, sourceFile, param, containingFunction, program, host, cancellationToken);
                        return param;
                    }
                    return undefined;
                // Get Accessor declarations
                case ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code:
                case ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code:
                    if (ts.isGetAccessorDeclaration(containingFunction) && ts.isIdentifier(containingFunction.name)) {
                        annotate(changes, sourceFile, containingFunction, inferTypeForVariableFromUsage(containingFunction.name, program, cancellationToken), program, host);
                        return containingFunction;
                    }
                    return undefined;
                // Set Accessor declarations
                case ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code:
                    if (ts.isSetAccessorDeclaration(containingFunction)) {
                        annotateSetAccessor(changes, sourceFile, containingFunction, program, host, cancellationToken);
                        return containingFunction;
                    }
                    return undefined;
                default:
                    return ts.Debug.fail(String(errorCode));
            }
        }
        function annotateVariableDeclaration(changes, sourceFile, declaration, program, host, cancellationToken) {
            if (ts.isIdentifier(declaration.name)) {
                annotate(changes, sourceFile, declaration, inferTypeForVariableFromUsage(declaration.name, program, cancellationToken), program, host);
            }
        }
        function annotateParameters(changes, sourceFile, parameterDeclaration, containingFunction, program, host, cancellationToken) {
            if (!ts.isIdentifier(parameterDeclaration.name)) {
                return;
            }
            var parameterInferences = inferTypeForParametersFromUsage(containingFunction, sourceFile, program, cancellationToken) ||
                containingFunction.parameters.map(function (p) { return ({
                    declaration: p,
                    type: ts.isIdentifier(p.name) ? inferTypeForVariableFromUsage(p.name, program, cancellationToken) : program.getTypeChecker().getAnyType()
                }); });
            ts.Debug.assert(containingFunction.parameters.length === parameterInferences.length);
            if (ts.isInJSFile(containingFunction)) {
                annotateJSDocParameters(changes, sourceFile, parameterInferences, program, host);
            }
            else {
                var needParens = ts.isArrowFunction(containingFunction) && !ts.findChildOfKind(containingFunction, 20 /* OpenParenToken */, sourceFile);
                if (needParens)
                    changes.insertNodeBefore(sourceFile, ts.first(containingFunction.parameters), ts.createToken(20 /* OpenParenToken */));
                for (var _i = 0, parameterInferences_1 = parameterInferences; _i < parameterInferences_1.length; _i++) {
                    var _a = parameterInferences_1[_i], declaration = _a.declaration, type = _a.type;
                    if (declaration && !declaration.type && !declaration.initializer) {
                        annotate(changes, sourceFile, declaration, type, program, host);
                    }
                }
                if (needParens)
                    changes.insertNodeAfter(sourceFile, ts.last(containingFunction.parameters), ts.createToken(21 /* CloseParenToken */));
            }
        }
        function annotateSetAccessor(changes, sourceFile, setAccessorDeclaration, program, host, cancellationToken) {
            var param = ts.firstOrUndefined(setAccessorDeclaration.parameters);
            if (param && ts.isIdentifier(setAccessorDeclaration.name) && ts.isIdentifier(param.name)) {
                var type = inferTypeForVariableFromUsage(setAccessorDeclaration.name, program, cancellationToken);
                if (type === program.getTypeChecker().getAnyType()) {
                    type = inferTypeForVariableFromUsage(param.name, program, cancellationToken);
                }
                if (ts.isInJSFile(setAccessorDeclaration)) {
                    annotateJSDocParameters(changes, sourceFile, [{ declaration: param, type: type }], program, host);
                }
                else {
                    annotate(changes, sourceFile, param, type, program, host);
                }
            }
        }
        function annotate(changes, sourceFile, declaration, type, program, host) {
            var typeNode = ts.getTypeNodeIfAccessible(type, declaration, program, host);
            if (typeNode) {
                if (ts.isInJSFile(sourceFile) && declaration.kind !== 154 /* PropertySignature */) {
                    var parent = ts.isVariableDeclaration(declaration) ? ts.tryCast(declaration.parent.parent, ts.isVariableStatement) : declaration;
                    if (!parent) {
                        return;
                    }
                    var typeExpression = ts.createJSDocTypeExpression(typeNode);
                    var typeTag = ts.isGetAccessorDeclaration(declaration) ? ts.createJSDocReturnTag(typeExpression, "") : ts.createJSDocTypeTag(typeExpression, "");
                    addJSDocTags(changes, sourceFile, parent, [typeTag]);
                }
                else {
                    changes.tryInsertTypeAnnotation(sourceFile, declaration, typeNode);
                }
            }
        }
        function annotateJSDocParameters(changes, sourceFile, parameterInferences, program, host) {
            var signature = parameterInferences.length && parameterInferences[0].declaration.parent;
            if (!signature) {
                return;
            }
            var paramTags = ts.mapDefined(parameterInferences, function (inference) {
                var param = inference.declaration;
                // only infer parameters that have (1) no type and (2) an accessible inferred type
                if (param.initializer || ts.getJSDocType(param) || !ts.isIdentifier(param.name))
                    return;
                var typeNode = inference.type && ts.getTypeNodeIfAccessible(inference.type, param, program, host);
                var name = ts.getSynthesizedClone(param.name);
                ts.setEmitFlags(name, 1536 /* NoComments */ | 2048 /* NoNestedComments */);
                return typeNode && ts.createJSDocParamTag(name, !!inference.isOptional, ts.createJSDocTypeExpression(typeNode), "");
            });
            addJSDocTags(changes, sourceFile, signature, paramTags);
        }
        function addJSDocTags(changes, sourceFile, parent, newTags) {
            var comments = ts.mapDefined(parent.jsDoc, function (j) { return j.comment; });
            var oldTags = ts.flatMapToMutable(parent.jsDoc, function (j) { return j.tags; });
            var unmergedNewTags = newTags.filter(function (newTag) { return !oldTags || !oldTags.some(function (tag, i) {
                var merged = tryMergeJsdocTags(tag, newTag);
                if (merged)
                    oldTags[i] = merged;
                return !!merged;
            }); });
            var tag = ts.createJSDocComment(comments.join("\n"), ts.createNodeArray((oldTags || ts.emptyArray).concat(unmergedNewTags)));
            var jsDocNode = parent.kind === 198 /* ArrowFunction */ ? getJsDocNodeForArrowFunction(parent) : parent;
            jsDocNode.jsDoc = parent.jsDoc;
            jsDocNode.jsDocCache = parent.jsDocCache;
            changes.insertJsdocCommentBefore(sourceFile, jsDocNode, tag);
        }
        function getJsDocNodeForArrowFunction(signature) {
            if (signature.parent.kind === 155 /* PropertyDeclaration */) {
                return signature.parent;
            }
            return signature.parent.parent;
        }
        function tryMergeJsdocTags(oldTag, newTag) {
            if (oldTag.kind !== newTag.kind) {
                return undefined;
            }
            switch (oldTag.kind) {
                case 305 /* JSDocParameterTag */: {
                    var oldParam = oldTag;
                    var newParam = newTag;
                    return ts.isIdentifier(oldParam.name) && ts.isIdentifier(newParam.name) && oldParam.name.escapedText === newParam.name.escapedText
                        ? ts.createJSDocParamTag(newParam.name, newParam.isBracketed, newParam.typeExpression, oldParam.comment)
                        : undefined;
                }
                case 306 /* JSDocReturnTag */:
                    return ts.createJSDocReturnTag(newTag.typeExpression, oldTag.comment);
            }
        }
        function getReferences(token, program, cancellationToken) {
            // Position shouldn't matter since token is not a SourceFile.
            return ts.mapDefined(ts.FindAllReferences.getReferenceEntriesForNode(-1, token, program, program.getSourceFiles(), cancellationToken), function (entry) {
                return entry.kind !== 0 /* Span */ ? ts.tryCast(entry.node, ts.isIdentifier) : undefined;
            });
        }
        function inferTypeForVariableFromUsage(token, program, cancellationToken) {
            var references = getReferences(token, program, cancellationToken);
            var checker = program.getTypeChecker();
            var types = InferFromReference.inferTypesFromReferences(references, checker, cancellationToken);
            return InferFromReference.unifyFromContext(types, checker);
        }
        function inferTypeForParametersFromUsage(containingFunction, sourceFile, program, cancellationToken) {
            var searchToken;
            switch (containingFunction.kind) {
                case 158 /* Constructor */:
                    searchToken = ts.findChildOfKind(containingFunction, 125 /* ConstructorKeyword */, sourceFile);
                    break;
                case 198 /* ArrowFunction */:
                case 197 /* FunctionExpression */:
                    var parent = containingFunction.parent;
                    searchToken = ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name) ?
                        parent.name :
                        containingFunction.name;
                    break;
                case 240 /* FunctionDeclaration */:
                case 157 /* MethodDeclaration */:
                    searchToken = containingFunction.name;
                    break;
            }
            if (searchToken) {
                return InferFromReference.inferTypeForParametersFromReferences(getReferences(searchToken, program, cancellationToken), containingFunction, program, cancellationToken);
            }
        }
        var InferFromReference;
        (function (InferFromReference) {
            function inferTypesFromReferences(references, checker, cancellationToken) {
                var usageContext = {};
                for (var _i = 0, references_2 = references; _i < references_2.length; _i++) {
                    var reference = references_2[_i];
                    cancellationToken.throwIfCancellationRequested();
                    inferTypeFromContext(reference, checker, usageContext);
                }
                return inferFromContext(usageContext, checker);
            }
            InferFromReference.inferTypesFromReferences = inferTypesFromReferences;
            function inferTypeForParametersFromReferences(references, declaration, program, cancellationToken) {
                var checker = program.getTypeChecker();
                if (references.length === 0) {
                    return undefined;
                }
                if (!declaration.parameters) {
                    return undefined;
                }
                var usageContext = {};
                for (var _i = 0, references_3 = references; _i < references_3.length; _i++) {
                    var reference = references_3[_i];
                    cancellationToken.throwIfCancellationRequested();
                    inferTypeFromContext(reference, checker, usageContext);
                }
                var callContexts = (usageContext.constructContexts || []).concat(usageContext.callContexts || []);
                return declaration.parameters.map(function (parameter, parameterIndex) {
                    var types = [];
                    var isRest = ts.isRestParameter(parameter);
                    var isOptional = false;
                    for (var _i = 0, callContexts_1 = callContexts; _i < callContexts_1.length; _i++) {
                        var callContext = callContexts_1[_i];
                        if (callContext.argumentTypes.length <= parameterIndex) {
                            isOptional = ts.isInJSFile(declaration);
                            types.push(checker.getUndefinedType());
                        }
                        else if (isRest) {
                            for (var i = parameterIndex; i < callContext.argumentTypes.length; i++) {
                                types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[i]));
                            }
                        }
                        else {
                            types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[parameterIndex]));
                        }
                    }
                    if (ts.isIdentifier(parameter.name)) {
                        var inferred = inferTypesFromReferences(getReferences(parameter.name, program, cancellationToken), checker, cancellationToken);
                        types.push.apply(types, (isRest ? ts.mapDefined(inferred, checker.getElementTypeOfArrayType) : inferred));
                    }
                    var type = unifyFromContext(types, checker);
                    return {
                        type: isRest ? checker.createArrayType(type) : type,
                        isOptional: isOptional && !isRest,
                        declaration: parameter
                    };
                });
            }
            InferFromReference.inferTypeForParametersFromReferences = inferTypeForParametersFromReferences;
            function inferTypeFromContext(node, checker, usageContext) {
                while (ts.isRightSideOfQualifiedNameOrPropertyAccess(node)) {
                    node = node.parent;
                }
                switch (node.parent.kind) {
                    case 204 /* PostfixUnaryExpression */:
                        usageContext.isNumber = true;
                        break;
                    case 203 /* PrefixUnaryExpression */:
                        inferTypeFromPrefixUnaryExpressionContext(node.parent, usageContext);
                        break;
                    case 205 /* BinaryExpression */:
                        inferTypeFromBinaryExpressionContext(node, node.parent, checker, usageContext);
                        break;
                    case 272 /* CaseClause */:
                    case 273 /* DefaultClause */:
                        inferTypeFromSwitchStatementLabelContext(node.parent, checker, usageContext);
                        break;
                    case 192 /* CallExpression */:
                    case 193 /* NewExpression */:
                        if (node.parent.expression === node) {
                            inferTypeFromCallExpressionContext(node.parent, checker, usageContext);
                        }
                        else {
                            inferTypeFromContextualType(node, checker, usageContext);
                        }
                        break;
                    case 190 /* PropertyAccessExpression */:
                        inferTypeFromPropertyAccessExpressionContext(node.parent, checker, usageContext);
                        break;
                    case 191 /* ElementAccessExpression */:
                        inferTypeFromPropertyElementExpressionContext(node.parent, node, checker, usageContext);
                        break;
                    case 238 /* VariableDeclaration */: {
                        var _a = node.parent, name = _a.name, initializer = _a.initializer;
                        if (node === name) {
                            if (initializer) { // This can happen for `let x = null;` which still has an implicit-any error.
                                addCandidateType(usageContext, checker.getTypeAtLocation(initializer));
                            }
                            break;
                        }
                    }
                    // falls through
                    default:
                        return inferTypeFromContextualType(node, checker, usageContext);
                }
            }
            function inferTypeFromContextualType(node, checker, usageContext) {
                if (ts.isExpressionNode(node)) {
                    addCandidateType(usageContext, checker.getContextualType(node));
                }
            }
            function inferTypeFromPrefixUnaryExpressionContext(node, usageContext) {
                switch (node.operator) {
                    case 44 /* PlusPlusToken */:
                    case 45 /* MinusMinusToken */:
                    case 39 /* MinusToken */:
                    case 53 /* TildeToken */:
                        usageContext.isNumber = true;
                        break;
                    case 38 /* PlusToken */:
                        usageContext.isNumberOrString = true;
                        break;
                    // case SyntaxKind.ExclamationToken:
                    // no inferences here;
                }
            }
            function inferTypeFromBinaryExpressionContext(node, parent, checker, usageContext) {
                switch (parent.operatorToken.kind) {
                    // ExponentiationOperator
                    case 41 /* AsteriskAsteriskToken */:
                    // MultiplicativeOperator
                    case 40 /* AsteriskToken */:
                    case 42 /* SlashToken */:
                    case 43 /* PercentToken */:
                    // ShiftOperator
                    case 46 /* LessThanLessThanToken */:
                    case 47 /* GreaterThanGreaterThanToken */:
                    case 48 /* GreaterThanGreaterThanGreaterThanToken */:
                    // BitwiseOperator
                    case 49 /* AmpersandToken */:
                    case 50 /* BarToken */:
                    case 51 /* CaretToken */:
                    // CompoundAssignmentOperator
                    case 62 /* MinusEqualsToken */:
                    case 64 /* AsteriskAsteriskEqualsToken */:
                    case 63 /* AsteriskEqualsToken */:
                    case 65 /* SlashEqualsToken */:
                    case 66 /* PercentEqualsToken */:
                    case 70 /* AmpersandEqualsToken */:
                    case 71 /* BarEqualsToken */:
                    case 72 /* CaretEqualsToken */:
                    case 67 /* LessThanLessThanEqualsToken */:
                    case 69 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                    case 68 /* GreaterThanGreaterThanEqualsToken */:
                    // AdditiveOperator
                    case 39 /* MinusToken */:
                    // RelationalOperator
                    case 28 /* LessThanToken */:
                    case 31 /* LessThanEqualsToken */:
                    case 30 /* GreaterThanToken */:
                    case 32 /* GreaterThanEqualsToken */:
                        var operandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left);
                        if (operandType.flags & 1056 /* EnumLike */) {
                            addCandidateType(usageContext, operandType);
                        }
                        else {
                            usageContext.isNumber = true;
                        }
                        break;
                    case 61 /* PlusEqualsToken */:
                    case 38 /* PlusToken */:
                        var otherOperandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left);
                        if (otherOperandType.flags & 1056 /* EnumLike */) {
                            addCandidateType(usageContext, otherOperandType);
                        }
                        else if (otherOperandType.flags & 296 /* NumberLike */) {
                            usageContext.isNumber = true;
                        }
                        else if (otherOperandType.flags & 132 /* StringLike */) {
                            usageContext.isString = true;
                        }
                        else {
                            usageContext.isNumberOrString = true;
                        }
                        break;
                    //  AssignmentOperators
                    case 60 /* EqualsToken */:
                    case 33 /* EqualsEqualsToken */:
                    case 35 /* EqualsEqualsEqualsToken */:
                    case 36 /* ExclamationEqualsEqualsToken */:
                    case 34 /* ExclamationEqualsToken */:
                        addCandidateType(usageContext, checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left));
                        break;
                    case 94 /* InKeyword */:
                        if (node === parent.left) {
                            usageContext.isString = true;
                        }
                        break;
                    // LogicalOperator
                    case 55 /* BarBarToken */:
                        if (node === parent.left &&
                            (node.parent.parent.kind === 238 /* VariableDeclaration */ || ts.isAssignmentExpression(node.parent.parent, /*excludeCompoundAssignment*/ true))) {
                            // var x = x || {};
                            // TODO: use getFalsyflagsOfType
                            addCandidateType(usageContext, checker.getTypeAtLocation(parent.right));
                        }
                        break;
                    case 54 /* AmpersandAmpersandToken */:
                    case 27 /* CommaToken */:
                    case 95 /* InstanceOfKeyword */:
                        // nothing to infer here
                        break;
                }
            }
            function inferTypeFromSwitchStatementLabelContext(parent, checker, usageContext) {
                addCandidateType(usageContext, checker.getTypeAtLocation(parent.parent.parent.expression));
            }
            function inferTypeFromCallExpressionContext(parent, checker, usageContext) {
                var callContext = {
                    argumentTypes: [],
                    returnType: {}
                };
                if (parent.arguments) {
                    for (var _i = 0, _a = parent.arguments; _i < _a.length; _i++) {
                        var argument = _a[_i];
                        callContext.argumentTypes.push(checker.getTypeAtLocation(argument));
                    }
                }
                inferTypeFromContext(parent, checker, callContext.returnType);
                if (parent.kind === 192 /* CallExpression */) {
                    (usageContext.callContexts || (usageContext.callContexts = [])).push(callContext);
                }
                else {
                    (usageContext.constructContexts || (usageContext.constructContexts = [])).push(callContext);
                }
            }
            function inferTypeFromPropertyAccessExpressionContext(parent, checker, usageContext) {
                var name = ts.escapeLeadingUnderscores(parent.name.text);
                if (!usageContext.properties) {
                    usageContext.properties = ts.createUnderscoreEscapedMap();
                }
                var propertyUsageContext = usageContext.properties.get(name) || {};
                inferTypeFromContext(parent, checker, propertyUsageContext);
                usageContext.properties.set(name, propertyUsageContext);
            }
            function inferTypeFromPropertyElementExpressionContext(parent, node, checker, usageContext) {
                if (node === parent.argumentExpression) {
                    usageContext.isNumberOrString = true;
                    return;
                }
                else {
                    var indexType = checker.getTypeAtLocation(parent.argumentExpression);
                    var indexUsageContext = {};
                    inferTypeFromContext(parent, checker, indexUsageContext);
                    if (indexType.flags & 296 /* NumberLike */) {
                        usageContext.numberIndexContext = indexUsageContext;
                    }
                    else {
                        usageContext.stringIndexContext = indexUsageContext;
                    }
                }
            }
            function removeLowPriorityInferences(inferences, priorities) {
                var toRemove = [];
                for (var _i = 0, inferences_1 = inferences; _i < inferences_1.length; _i++) {
                    var i = inferences_1[_i];
                    for (var _a = 0, priorities_1 = priorities; _a < priorities_1.length; _a++) {
                        var _b = priorities_1[_a], high = _b.high, low = _b.low;
                        if (high(i)) {
                            ts.Debug.assert(!low(i));
                            toRemove.push(low);
                        }
                    }
                }
                return inferences.filter(function (i) { return toRemove.every(function (f) { return !f(i); }); });
            }
            function unifyFromContext(inferences, checker, fallback) {
                if (fallback === void 0) { fallback = checker.getAnyType(); }
                if (!inferences.length)
                    return fallback;
                // 1. string or number individually override string | number
                // 2. non-any, non-void overrides any or void
                // 3. non-nullable, non-any, non-void, non-anonymous overrides anonymous types
                var stringNumber = checker.getUnionType([checker.getStringType(), checker.getNumberType()]);
                var priorities = [
                    {
                        high: function (t) { return t === checker.getStringType() || t === checker.getNumberType(); },
                        low: function (t) { return t === stringNumber; }
                    },
                    {
                        high: function (t) { return !(t.flags & (1 /* Any */ | 16384 /* Void */)); },
                        low: function (t) { return !!(t.flags & (1 /* Any */ | 16384 /* Void */)); }
                    },
                    {
                        high: function (t) { return !(t.flags & (98304 /* Nullable */ | 1 /* Any */ | 16384 /* Void */)) && !(checker.getObjectFlags(t) & 16 /* Anonymous */); },
                        low: function (t) { return !!(checker.getObjectFlags(t) & 16 /* Anonymous */); }
                    }
                ];
                var good = removeLowPriorityInferences(inferences, priorities);
                var anons = good.filter(function (i) { return checker.getObjectFlags(i) & 16 /* Anonymous */; });
                if (anons.length) {
                    good = good.filter(function (i) { return !(checker.getObjectFlags(i) & 16 /* Anonymous */); });
                    good.push(unifyAnonymousTypes(anons, checker));
                }
                return checker.getWidenedType(checker.getUnionType(good));
            }
            InferFromReference.unifyFromContext = unifyFromContext;
            function unifyAnonymousTypes(anons, checker) {
                if (anons.length === 1) {
                    return anons[0];
                }
                var calls = [];
                var constructs = [];
                var stringIndices = [];
                var numberIndices = [];
                var stringIndexReadonly = false;
                var numberIndexReadonly = false;
                var props = ts.createMultiMap();
                for (var _i = 0, anons_1 = anons; _i < anons_1.length; _i++) {
                    var anon = anons_1[_i];
                    for (var _a = 0, _b = checker.getPropertiesOfType(anon); _a < _b.length; _a++) {
                        var p = _b[_a];
                        props.add(p.name, checker.getTypeOfSymbolAtLocation(p, p.valueDeclaration));
                    }
                    calls.push.apply(calls, checker.getSignaturesOfType(anon, 0 /* Call */));
                    constructs.push.apply(constructs, checker.getSignaturesOfType(anon, 1 /* Construct */));
                    if (anon.stringIndexInfo) {
                        stringIndices.push(anon.stringIndexInfo.type);
                        stringIndexReadonly = stringIndexReadonly || anon.stringIndexInfo.isReadonly;
                    }
                    if (anon.numberIndexInfo) {
                        numberIndices.push(anon.numberIndexInfo.type);
                        numberIndexReadonly = numberIndexReadonly || anon.numberIndexInfo.isReadonly;
                    }
                }
                var members = ts.mapEntries(props, function (name, types) {
                    var isOptional = types.length < anons.length ? 16777216 /* Optional */ : 0;
                    var s = checker.createSymbol(4 /* Property */ | isOptional, name);
                    s.type = checker.getUnionType(types);
                    return [name, s];
                });
                return checker.createAnonymousType(anons[0].symbol, members, calls, constructs, stringIndices.length ? checker.createIndexInfo(checker.getUnionType(stringIndices), stringIndexReadonly) : undefined, numberIndices.length ? checker.createIndexInfo(checker.getUnionType(numberIndices), numberIndexReadonly) : undefined);
            }
            function inferFromContext(usageContext, checker) {
                var types = [];
                if (usageContext.isNumber) {
                    types.push(checker.getNumberType());
                }
                if (usageContext.isString) {
                    types.push(checker.getStringType());
                }
                if (usageContext.isNumberOrString) {
                    types.push(checker.getUnionType([checker.getStringType(), checker.getNumberType()]));
                }
                types.push.apply(types, (usageContext.candidateTypes || []).map(function (t) { return checker.getBaseTypeOfLiteralType(t); }));
                if (usageContext.properties && hasCallContext(usageContext.properties.get("then"))) {
                    var paramType = getParameterTypeFromCallContexts(0, usageContext.properties.get("then").callContexts, /*isRestParameter*/ false, checker); // TODO: GH#18217
                    var types_1 = paramType.getCallSignatures().map(function (c) { return c.getReturnType(); });
                    types_1.push(checker.createPromiseType(types_1.length ? checker.getUnionType(types_1, 2 /* Subtype */) : checker.getAnyType()));
                }
                else if (usageContext.properties && hasCallContext(usageContext.properties.get("push"))) {
                    types.push(checker.createArrayType(getParameterTypeFromCallContexts(0, usageContext.properties.get("push").callContexts, /*isRestParameter*/ false, checker)));
                }
                if (usageContext.numberIndexContext) {
                    types.push(checker.createArrayType(recur(usageContext.numberIndexContext)));
                }
                else if (usageContext.properties || usageContext.callContexts || usageContext.constructContexts || usageContext.stringIndexContext) {
                    var members_1 = ts.createUnderscoreEscapedMap();
                    var callSignatures = [];
                    var constructSignatures = [];
                    var stringIndexInfo = void 0;
                    if (usageContext.properties) {
                        usageContext.properties.forEach(function (context, name) {
                            var symbol = checker.createSymbol(4 /* Property */, name);
                            symbol.type = recur(context);
                            members_1.set(name, symbol);
                        });
                    }
                    if (usageContext.callContexts) {
                        for (var _i = 0, _a = usageContext.callContexts; _i < _a.length; _i++) {
                            var callContext = _a[_i];
                            callSignatures.push(getSignatureFromCallContext(callContext, checker));
                        }
                    }
                    if (usageContext.constructContexts) {
                        for (var _b = 0, _c = usageContext.constructContexts; _b < _c.length; _b++) {
                            var constructContext = _c[_b];
                            constructSignatures.push(getSignatureFromCallContext(constructContext, checker));
                        }
                    }
                    if (usageContext.stringIndexContext) {
                        stringIndexInfo = checker.createIndexInfo(recur(usageContext.stringIndexContext), /*isReadonly*/ false);
                    }
                    types.push(checker.createAnonymousType(/*symbol*/ undefined, members_1, callSignatures, constructSignatures, stringIndexInfo, /*numberIndexInfo*/ undefined)); // TODO: GH#18217
                }
                return types;
                function recur(innerContext) {
                    return unifyFromContext(inferFromContext(innerContext, checker), checker);
                }
            }
            function getParameterTypeFromCallContexts(parameterIndex, callContexts, isRestParameter, checker) {
                var types = [];
                if (callContexts) {
                    for (var _i = 0, callContexts_2 = callContexts; _i < callContexts_2.length; _i++) {
                        var callContext = callContexts_2[_i];
                        if (callContext.argumentTypes.length > parameterIndex) {
                            if (isRestParameter) {
                                types = ts.concatenate(types, ts.map(callContext.argumentTypes.slice(parameterIndex), function (a) { return checker.getBaseTypeOfLiteralType(a); }));
                            }
                            else {
                                types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[parameterIndex]));
                            }
                        }
                    }
                }
                if (types.length) {
                    var type = checker.getWidenedType(checker.getUnionType(types, 2 /* Subtype */));
                    return isRestParameter ? checker.createArrayType(type) : type;
                }
                return undefined;
            }
            function getSignatureFromCallContext(callContext, checker) {
                var parameters = [];
                for (var i = 0; i < callContext.argumentTypes.length; i++) {
                    var symbol = checker.createSymbol(1 /* FunctionScopedVariable */, ts.escapeLeadingUnderscores("arg" + i));
                    symbol.type = checker.getWidenedType(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[i]));
                    parameters.push(symbol);
                }
                var returnType = unifyFromContext(inferFromContext(callContext.returnType, checker), checker, checker.getVoidType());
                // TODO: GH#18217
                return checker.createSignature(/*declaration*/ undefined, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, callContext.argumentTypes.length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
            }
            function addCandidateType(context, type) {
                if (type && !(type.flags & 1 /* Any */) && !(type.flags & 131072 /* Never */)) {
                    (context.candidateTypes || (context.candidateTypes = [])).push(type);
                }
            }
            function hasCallContext(usageContext) {
                return !!usageContext && !!usageContext.callContexts;
            }
        })(InferFromReference || (InferFromReference = {}));
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "convertFunctionToEs6Class";
        var errorCodes = [ts.Diagnostics.This_constructor_function_may_be_converted_to_a_class_declaration.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, context.sourceFile, context.span.start, context.program.getTypeChecker()); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Convert_function_to_an_ES2015_class, fixId, ts.Diagnostics.Convert_all_constructor_functions_to_classes)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, err) { return doChange(changes, err.file, err.start, context.program.getTypeChecker()); }); },
        });
        function doChange(changes, sourceFile, position, checker) {
            var ctorSymbol = checker.getSymbolAtLocation(ts.getTokenAtPosition(sourceFile, position));
            if (!ctorSymbol || !(ctorSymbol.flags & (16 /* Function */ | 3 /* Variable */))) {
                // Bad input
                return undefined;
            }
            var ctorDeclaration = ctorSymbol.valueDeclaration;
            var precedingNode;
            var newClassDeclaration;
            switch (ctorDeclaration.kind) {
                case 240 /* FunctionDeclaration */:
                    precedingNode = ctorDeclaration;
                    changes.delete(sourceFile, ctorDeclaration);
                    newClassDeclaration = createClassFromFunctionDeclaration(ctorDeclaration);
                    break;
                case 238 /* VariableDeclaration */:
                    precedingNode = ctorDeclaration.parent.parent;
                    newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration);
                    if (ctorDeclaration.parent.declarations.length === 1) {
                        ts.copyLeadingComments(precedingNode, newClassDeclaration, sourceFile); // TODO: GH#18217
                        changes.delete(sourceFile, precedingNode);
                    }
                    else {
                        changes.delete(sourceFile, ctorDeclaration);
                    }
                    break;
            }
            if (!newClassDeclaration) {
                return undefined;
            }
            ts.copyLeadingComments(ctorDeclaration, newClassDeclaration, sourceFile);
            // Because the preceding node could be touched, we need to insert nodes before delete nodes.
            changes.insertNodeAfter(sourceFile, precedingNode, newClassDeclaration);
            function createClassElementsFromSymbol(symbol) {
                var memberElements = [];
                // all instance members are stored in the "member" array of symbol
                if (symbol.members) {
                    symbol.members.forEach(function (member) {
                        var memberElement = createClassElement(member, /*modifiers*/ undefined);
                        if (memberElement) {
                            memberElements.push(memberElement);
                        }
                    });
                }
                // all static members are stored in the "exports" array of symbol
                if (symbol.exports) {
                    symbol.exports.forEach(function (member) {
                        var memberElement = createClassElement(member, [ts.createToken(117 /* StaticKeyword */)]);
                        if (memberElement) {
                            memberElements.push(memberElement);
                        }
                    });
                }
                return memberElements;
                function shouldConvertDeclaration(_target, source) {
                    // Right now the only thing we can convert are function expressions - other values shouldn't get
                    // transformed. We can update this once ES public class properties are available.
                    return ts.isFunctionLike(source);
                }
                function createClassElement(symbol, modifiers) {
                    // Right now the only thing we can convert are function expressions, which are marked as methods
                    if (!(symbol.flags & 8192 /* Method */)) {
                        return;
                    }
                    var memberDeclaration = symbol.valueDeclaration;
                    var assignmentBinaryExpression = memberDeclaration.parent;
                    if (!shouldConvertDeclaration(memberDeclaration, assignmentBinaryExpression.right)) {
                        return;
                    }
                    // delete the entire statement if this expression is the sole expression to take care of the semicolon at the end
                    var nodeToDelete = assignmentBinaryExpression.parent && assignmentBinaryExpression.parent.kind === 222 /* ExpressionStatement */
                        ? assignmentBinaryExpression.parent : assignmentBinaryExpression;
                    changes.delete(sourceFile, nodeToDelete);
                    if (!assignmentBinaryExpression.right) {
                        return ts.createProperty([], modifiers, symbol.name, /*questionToken*/ undefined, 
                        /*type*/ undefined, /*initializer*/ undefined);
                    }
                    switch (assignmentBinaryExpression.right.kind) {
                        case 197 /* FunctionExpression */: {
                            var functionExpression = assignmentBinaryExpression.right;
                            var fullModifiers = ts.concatenate(modifiers, getModifierKindFromSource(functionExpression, 122 /* AsyncKeyword */));
                            var method = ts.createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, 
                            /*typeParameters*/ undefined, functionExpression.parameters, /*type*/ undefined, functionExpression.body);
                            ts.copyLeadingComments(assignmentBinaryExpression, method, sourceFile);
                            return method;
                        }
                        case 198 /* ArrowFunction */: {
                            var arrowFunction = assignmentBinaryExpression.right;
                            var arrowFunctionBody = arrowFunction.body;
                            var bodyBlock = void 0;
                            // case 1: () => { return [1,2,3] }
                            if (arrowFunctionBody.kind === 219 /* Block */) {
                                bodyBlock = arrowFunctionBody;
                            }
                            // case 2: () => [1,2,3]
                            else {
                                bodyBlock = ts.createBlock([ts.createReturn(arrowFunctionBody)]);
                            }
                            var fullModifiers = ts.concatenate(modifiers, getModifierKindFromSource(arrowFunction, 122 /* AsyncKeyword */));
                            var method = ts.createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, 
                            /*typeParameters*/ undefined, arrowFunction.parameters, /*type*/ undefined, bodyBlock);
                            ts.copyLeadingComments(assignmentBinaryExpression, method, sourceFile);
                            return method;
                        }
                        default: {
                            // Don't try to declare members in JavaScript files
                            if (ts.isSourceFileJS(sourceFile)) {
                                return;
                            }
                            var prop = ts.createProperty(/*decorators*/ undefined, modifiers, memberDeclaration.name, /*questionToken*/ undefined, 
                            /*type*/ undefined, assignmentBinaryExpression.right);
                            ts.copyLeadingComments(assignmentBinaryExpression.parent, prop, sourceFile);
                            return prop;
                        }
                    }
                }
            }
            function createClassFromVariableDeclaration(node) {
                var initializer = node.initializer;
                if (!initializer || initializer.kind !== 197 /* FunctionExpression */) {
                    return undefined;
                }
                if (node.name.kind !== 73 /* Identifier */) {
                    return undefined;
                }
                var memberElements = createClassElementsFromSymbol(node.symbol);
                if (initializer.body) {
                    memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body));
                }
                var modifiers = getModifierKindFromSource(precedingNode, 86 /* ExportKeyword */);
                var cls = ts.createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, 
                /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements);
                // Don't call copyComments here because we'll already leave them in place
                return cls;
            }
            function createClassFromFunctionDeclaration(node) {
                var memberElements = createClassElementsFromSymbol(ctorSymbol);
                if (node.body) {
                    memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, node.parameters, node.body));
                }
                var modifiers = getModifierKindFromSource(node, 86 /* ExportKeyword */);
                var cls = ts.createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, 
                /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements);
                // Don't call copyComments here because we'll already leave them in place
                return cls;
            }
        }
        function getModifierKindFromSource(source, kind) {
            return ts.filter(source.modifiers, function (modifier) { return modifier.kind === kind; });
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "convertToAsyncFunction";
        var errorCodes = [ts.Diagnostics.This_may_be_converted_to_an_async_function.code];
        var codeActionSucceeded = true;
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                codeActionSucceeded = true;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return convertToAsyncFunction(t, context.sourceFile, context.span.start, context.program.getTypeChecker(), context); });
                return codeActionSucceeded ? [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Convert_to_async_function, fixId, ts.Diagnostics.Convert_all_to_async_functions)] : [];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, err) { return convertToAsyncFunction(changes, err.file, err.start, context.program.getTypeChecker(), context); }); },
        });
        var SynthBindingNameKind;
        (function (SynthBindingNameKind) {
            SynthBindingNameKind[SynthBindingNameKind["Identifier"] = 0] = "Identifier";
            SynthBindingNameKind[SynthBindingNameKind["BindingPattern"] = 1] = "BindingPattern";
        })(SynthBindingNameKind || (SynthBindingNameKind = {}));
        function convertToAsyncFunction(changes, sourceFile, position, checker, context) {
            // get the function declaration - returns a promise
            var tokenAtPosition = ts.getTokenAtPosition(sourceFile, position);
            var functionToConvert;
            // if the parent of a FunctionLikeDeclaration is a variable declaration, the convertToAsync diagnostic will be reported on the variable name
            if (ts.isIdentifier(tokenAtPosition) && ts.isVariableDeclaration(tokenAtPosition.parent) &&
                tokenAtPosition.parent.initializer && ts.isFunctionLikeDeclaration(tokenAtPosition.parent.initializer)) {
                functionToConvert = tokenAtPosition.parent.initializer;
            }
            else {
                functionToConvert = ts.tryCast(ts.getContainingFunction(ts.getTokenAtPosition(sourceFile, position)), ts.isFunctionLikeDeclaration);
            }
            if (!functionToConvert) {
                return;
            }
            var synthNamesMap = ts.createMap();
            var originalTypeMap = ts.createMap();
            var allVarNames = [];
            var isInJavascript = ts.isInJSFile(functionToConvert);
            var setOfExpressionsToReturn = getAllPromiseExpressionsToReturn(functionToConvert, checker);
            var functionToConvertRenamed = renameCollidingVarNames(functionToConvert, checker, synthNamesMap, context, setOfExpressionsToReturn, originalTypeMap, allVarNames);
            var constIdentifiers = getConstIdentifiers(synthNamesMap);
            var returnStatements = functionToConvertRenamed.body && ts.isBlock(functionToConvertRenamed.body) ? getReturnStatementsWithPromiseHandlers(functionToConvertRenamed.body) : ts.emptyArray;
            var transformer = { checker: checker, synthNamesMap: synthNamesMap, allVarNames: allVarNames, setOfExpressionsToReturn: setOfExpressionsToReturn, constIdentifiers: constIdentifiers, originalTypeMap: originalTypeMap, isInJSFile: isInJavascript };
            if (!returnStatements.length) {
                return;
            }
            // add the async keyword
            changes.insertLastModifierBefore(sourceFile, 122 /* AsyncKeyword */, functionToConvert);
            function startTransformation(node, nodeToReplace) {
                var newNodes = transformExpression(node, transformer, node);
                changes.replaceNodeWithNodes(sourceFile, nodeToReplace, newNodes);
            }
            var _loop_11 = function (statement) {
                ts.forEachChild(statement, function visit(node) {
                    if (ts.isCallExpression(node)) {
                        startTransformation(node, statement);
                    }
                    else if (!ts.isFunctionLike(node)) {
                        ts.forEachChild(node, visit);
                    }
                });
            };
            for (var _i = 0, returnStatements_1 = returnStatements; _i < returnStatements_1.length; _i++) {
                var statement = returnStatements_1[_i];
                _loop_11(statement);
            }
        }
        function getReturnStatementsWithPromiseHandlers(body) {
            var res = [];
            ts.forEachReturnStatement(body, function (ret) {
                if (ts.isReturnStatementWithFixablePromiseHandler(ret))
                    res.push(ret);
            });
            return res;
        }
        // Returns the identifiers that are never reassigned in the refactor
        function getConstIdentifiers(synthNamesMap) {
            var constIdentifiers = [];
            synthNamesMap.forEach(function (val) {
                if (val.numberOfAssignmentsOriginal === 0) {
                    constIdentifiers.push(val.identifier);
                }
            });
            return constIdentifiers;
        }
        /*
            Finds all of the expressions of promise type that should not be saved in a variable during the refactor
        */
        function getAllPromiseExpressionsToReturn(func, checker) {
            if (!func.body) {
                return ts.createMap();
            }
            var setOfExpressionsToReturn = ts.createMap();
            ts.forEachChild(func.body, function visit(node) {
                if (isPromiseReturningExpression(node, checker, "then")) {
                    setOfExpressionsToReturn.set(ts.getNodeId(node).toString(), true);
                    ts.forEach(node.arguments, visit);
                }
                else if (isPromiseReturningExpression(node, checker, "catch")) {
                    setOfExpressionsToReturn.set(ts.getNodeId(node).toString(), true);
                    // if .catch() is the last call in the chain, move leftward in the chain until we hit something else that should be returned
                    ts.forEachChild(node, visit);
                }
                else if (isPromiseReturningExpression(node, checker)) {
                    setOfExpressionsToReturn.set(ts.getNodeId(node).toString(), true);
                    // don't recurse here, since we won't refactor any children or arguments of the expression
                }
                else {
                    ts.forEachChild(node, visit);
                }
            });
            return setOfExpressionsToReturn;
        }
        /*
            Returns true if node is a promise returning expression
            If name is not undefined, node is a promise returning call of name
        */
        function isPromiseReturningExpression(node, checker, name) {
            var isNodeExpression = name ? ts.isCallExpression(node) : ts.isExpression(node);
            var isExpressionOfName = isNodeExpression && (!name || ts.hasPropertyAccessExpressionWithName(node, name));
            var nodeType = isExpressionOfName && checker.getTypeAtLocation(node);
            return !!(nodeType && checker.getPromisedTypeOfPromise(nodeType));
        }
        function declaredInFile(symbol, sourceFile) {
            return symbol.valueDeclaration && symbol.valueDeclaration.getSourceFile() === sourceFile;
        }
        /*
            Renaming of identifiers may be neccesary as the refactor changes scopes -
            This function collects all existing identifier names and names of identifiers that will be created in the refactor.
            It then checks for any collisions and renames them through getSynthesizedDeepClone
        */
        function renameCollidingVarNames(nodeToRename, checker, synthNamesMap, context, setOfAllExpressionsToReturn, originalType, allVarNames) {
            var identsToRenameMap = ts.createMap(); // key is the symbol id
            var collidingSymbolMap = ts.createMap();
            ts.forEachChild(nodeToRename, function visit(node) {
                if (!ts.isIdentifier(node)) {
                    ts.forEachChild(node, visit);
                    return;
                }
                var symbol = checker.getSymbolAtLocation(node);
                var isDefinedInFile = symbol && declaredInFile(symbol, context.sourceFile);
                if (symbol && isDefinedInFile) {
                    var type = checker.getTypeAtLocation(node);
                    var lastCallSignature = getLastCallSignature(type, checker);
                    var symbolIdString = ts.getSymbolId(symbol).toString();
                    // if the identifier refers to a function we want to add the new synthesized variable for the declaration (ex. blob in let blob = res(arg))
                    // Note - the choice of the last call signature is arbitrary
                    if (lastCallSignature && !ts.isFunctionLikeDeclaration(node.parent) && !synthNamesMap.has(symbolIdString)) {
                        var firstParameter = ts.firstOrUndefined(lastCallSignature.parameters);
                        var ident = firstParameter && ts.isParameter(firstParameter.valueDeclaration) && ts.tryCast(firstParameter.valueDeclaration.name, ts.isIdentifier) || ts.createOptimisticUniqueName("result");
                        var synthName = getNewNameIfConflict(ident, collidingSymbolMap);
                        synthNamesMap.set(symbolIdString, synthName);
                        allVarNames.push({ identifier: synthName.identifier, symbol: symbol });
                        addNameToFrequencyMap(collidingSymbolMap, ident.text, symbol);
                    }
                    // we only care about identifiers that are parameters, declarations, or binding elements (don't care about other uses)
                    else if (node.parent && (ts.isParameter(node.parent) || ts.isVariableDeclaration(node.parent) || ts.isBindingElement(node.parent))) {
                        var originalName = node.text;
                        var collidingSymbols = collidingSymbolMap.get(originalName);
                        // if the identifier name conflicts with a different identifier that we've already seen
                        if (collidingSymbols && collidingSymbols.some(function (prevSymbol) { return prevSymbol !== symbol; })) {
                            var newName = getNewNameIfConflict(node, collidingSymbolMap);
                            identsToRenameMap.set(symbolIdString, newName.identifier);
                            synthNamesMap.set(symbolIdString, newName);
                            allVarNames.push({ identifier: newName.identifier, symbol: symbol });
                            addNameToFrequencyMap(collidingSymbolMap, originalName, symbol);
                        }
                        else {
                            var identifier = ts.getSynthesizedDeepClone(node);
                            identsToRenameMap.set(symbolIdString, identifier);
                            synthNamesMap.set(symbolIdString, createSynthIdentifier(identifier, [], allVarNames.filter(function (elem) { return elem.identifier.text === node.text; }).length /*, numberOfAssignmentsSynthesized: 0*/));
                            if ((ts.isParameter(node.parent) && isExpressionOrCallOnTypePromise(node.parent.parent)) || ts.isVariableDeclaration(node.parent)) {
                                allVarNames.push({ identifier: identifier, symbol: symbol });
                                addNameToFrequencyMap(collidingSymbolMap, originalName, symbol);
                            }
                        }
                    }
                }
            });
            return ts.getSynthesizedDeepCloneWithRenames(nodeToRename, /*includeTrivia*/ true, identsToRenameMap, checker, deepCloneCallback);
            function isExpressionOrCallOnTypePromise(child) {
                var node = child.parent;
                if (ts.isCallExpression(node) || ts.isIdentifier(node) && !setOfAllExpressionsToReturn.get(ts.getNodeId(node).toString())) {
                    var nodeType = checker.getTypeAtLocation(node);
                    var isPromise = nodeType && checker.getPromisedTypeOfPromise(nodeType);
                    return !!isPromise;
                }
                return false;
            }
            function deepCloneCallback(node, clone) {
                if (ts.isIdentifier(node)) {
                    var symbol = checker.getSymbolAtLocation(node);
                    var symboldIdString = symbol && ts.getSymbolId(symbol).toString();
                    var renameInfo = symbol && synthNamesMap.get(symboldIdString);
                    if (renameInfo) {
                        var type = checker.getTypeAtLocation(node);
                        originalType.set(ts.getNodeId(clone).toString(), type);
                    }
                }
                var val = setOfAllExpressionsToReturn.get(ts.getNodeId(node).toString());
                if (val !== undefined) {
                    setOfAllExpressionsToReturn.delete(ts.getNodeId(node).toString());
                    setOfAllExpressionsToReturn.set(ts.getNodeId(clone).toString(), val);
                }
            }
        }
        function addNameToFrequencyMap(renamedVarNameFrequencyMap, originalName, symbol) {
            if (renamedVarNameFrequencyMap.has(originalName)) {
                renamedVarNameFrequencyMap.get(originalName).push(symbol);
            }
            else {
                renamedVarNameFrequencyMap.set(originalName, [symbol]);
            }
        }
        function getNewNameIfConflict(name, originalNames) {
            var numVarsSameName = (originalNames.get(name.text) || ts.emptyArray).length;
            var numberOfAssignmentsOriginal = 0;
            var identifier = numVarsSameName === 0 ? name : ts.createIdentifier(name.text + "_" + numVarsSameName);
            return createSynthIdentifier(identifier, [], numberOfAssignmentsOriginal);
        }
        // dispatch function to recursively build the refactoring
        // should be kept up to date with isFixablePromiseHandler in suggestionDiagnostics.ts
        function transformExpression(node, transformer, outermostParent, prevArgName) {
            if (!node) {
                return ts.emptyArray;
            }
            var originalType = ts.isIdentifier(node) && transformer.originalTypeMap.get(ts.getNodeId(node).toString());
            var nodeType = originalType || transformer.checker.getTypeAtLocation(node);
            if (ts.isCallExpression(node) && ts.hasPropertyAccessExpressionWithName(node, "then") && nodeType && !!transformer.checker.getPromisedTypeOfPromise(nodeType)) {
                return transformThen(node, transformer, outermostParent, prevArgName);
            }
            else if (ts.isCallExpression(node) && ts.hasPropertyAccessExpressionWithName(node, "catch") && nodeType && !!transformer.checker.getPromisedTypeOfPromise(nodeType)) {
                return transformCatch(node, transformer, prevArgName);
            }
            else if (ts.isPropertyAccessExpression(node)) {
                return transformExpression(node.expression, transformer, outermostParent, prevArgName);
            }
            else if (nodeType && transformer.checker.getPromisedTypeOfPromise(nodeType)) {
                return transformPromiseCall(node, transformer, prevArgName);
            }
            codeActionSucceeded = false;
            return ts.emptyArray;
        }
        function transformCatch(node, transformer, prevArgName) {
            var func = node.arguments[0];
            var argName = getArgBindingName(func, transformer);
            var shouldReturn = transformer.setOfExpressionsToReturn.get(ts.getNodeId(node).toString());
            var possibleNameForVarDecl;
            /*
                If there is another call in the chain after the .catch() we are transforming, we will need to save the result of both paths (try block and catch block)
                To do this, we will need to synthesize a variable that we were not aware of while we were adding identifiers to the synthNamesMap
                We will use the prevArgName and then update the synthNamesMap with a new variable name for the next transformation step
            */
            if (prevArgName && !shouldReturn) {
                if (isSynthIdentifier(prevArgName)) {
                    possibleNameForVarDecl = prevArgName;
                    transformer.synthNamesMap.forEach(function (val, key) {
                        if (val.identifier.text === prevArgName.identifier.text) {
                            var newSynthName = createUniqueSynthName(prevArgName);
                            transformer.synthNamesMap.set(key, newSynthName);
                        }
                    });
                }
                else {
                    possibleNameForVarDecl = createSynthIdentifier(ts.createOptimisticUniqueName("result"), prevArgName.types);
                }
                possibleNameForVarDecl.numberOfAssignmentsOriginal = 2; // Try block and catch block
                // update the constIdentifiers list
                if (transformer.constIdentifiers.some(function (elem) { return elem.text === possibleNameForVarDecl.identifier.text; })) {
                    transformer.constIdentifiers.push(createUniqueSynthName(possibleNameForVarDecl).identifier);
                }
            }
            var tryBlock = ts.createBlock(transformExpression(node.expression, transformer, node, possibleNameForVarDecl));
            var transformationBody = getTransformationBody(func, possibleNameForVarDecl, argName, node, transformer);
            var catchArg = argName ? isSynthIdentifier(argName) ? argName.identifier.text : argName.bindingPattern : "e";
            var catchVariableDeclaration = ts.createVariableDeclaration(catchArg);
            var catchClause = ts.createCatchClause(catchVariableDeclaration, ts.createBlock(transformationBody));
            /*
                In order to avoid an implicit any, we will synthesize a type for the declaration using the unions of the types of both paths (try block and catch block)
            */
            var varDeclList;
            var varDeclIdentifier;
            if (possibleNameForVarDecl && !shouldReturn) {
                varDeclIdentifier = ts.getSynthesizedDeepClone(possibleNameForVarDecl.identifier);
                var typeArray = possibleNameForVarDecl.types;
                var unionType = transformer.checker.getUnionType(typeArray, 2 /* Subtype */);
                var unionTypeNode = transformer.isInJSFile ? undefined : transformer.checker.typeToTypeNode(unionType);
                var varDecl = [ts.createVariableDeclaration(varDeclIdentifier, unionTypeNode)];
                varDeclList = ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList(varDecl, 1 /* Let */));
            }
            var tryStatement = ts.createTry(tryBlock, catchClause, /*finallyBlock*/ undefined);
            var destructuredResult = prevArgName && varDeclIdentifier && isSynthBindingPattern(prevArgName)
                && ts.createVariableStatement(/* modifiers */ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.getSynthesizedDeepCloneWithRenames(prevArgName.bindingPattern), /* type */ undefined, varDeclIdentifier)], 2 /* Const */));
            return ts.compact([varDeclList, tryStatement, destructuredResult]);
        }
        function getIdentifierTextsFromBindingName(bindingName) {
            if (ts.isIdentifier(bindingName))
                return [bindingName.text];
            return ts.flatMap(bindingName.elements, function (element) {
                if (ts.isOmittedExpression(element))
                    return [];
                return getIdentifierTextsFromBindingName(element.name);
            });
        }
        function createUniqueSynthName(prevArgName) {
            var renamedPrevArg = ts.createOptimisticUniqueName(prevArgName.identifier.text);
            return createSynthIdentifier(renamedPrevArg);
        }
        function transformThen(node, transformer, outermostParent, prevArgName) {
            var _a = node.arguments, res = _a[0], rej = _a[1];
            if (!res) {
                return transformExpression(node.expression, transformer, outermostParent);
            }
            var argNameRes = getArgBindingName(res, transformer);
            var transformationBody = getTransformationBody(res, prevArgName, argNameRes, node, transformer);
            if (rej) {
                var argNameRej = getArgBindingName(rej, transformer);
                var tryBlock = ts.createBlock(transformExpression(node.expression, transformer, node, argNameRes).concat(transformationBody));
                var transformationBody2 = getTransformationBody(rej, prevArgName, argNameRej, node, transformer);
                var catchArg = argNameRej ? isSynthIdentifier(argNameRej) ? argNameRej.identifier.text : argNameRej.bindingPattern : "e";
                var catchVariableDeclaration = ts.createVariableDeclaration(catchArg);
                var catchClause = ts.createCatchClause(catchVariableDeclaration, ts.createBlock(transformationBody2));
                return [ts.createTry(tryBlock, catchClause, /* finallyBlock */ undefined)];
            }
            return transformExpression(node.expression, transformer, node, argNameRes).concat(transformationBody);
        }
        function getFlagOfBindingName(bindingName, constIdentifiers) {
            var identifiers = getIdentifierTextsFromBindingName(getNode(bindingName));
            var inArr = constIdentifiers.some(function (elem) { return ts.contains(identifiers, elem.text); });
            return inArr ? 2 /* Const */ : 1 /* Let */;
        }
        function transformPromiseCall(node, transformer, prevArgName) {
            var shouldReturn = transformer.setOfExpressionsToReturn.get(ts.getNodeId(node).toString());
            // the identifier is empty when the handler (.then()) ignores the argument - In this situation we do not need to save the result of the promise returning call
            var originalNodeParent = node.original ? node.original.parent : node.parent;
            if (prevArgName && !shouldReturn && (!originalNodeParent || ts.isPropertyAccessExpression(originalNodeParent))) {
                return createTransformedStatement(prevArgName, ts.createAwait(node), transformer);
            }
            else if (!prevArgName && !shouldReturn && (!originalNodeParent || ts.isPropertyAccessExpression(originalNodeParent))) {
                return [ts.createStatement(ts.createAwait(node))];
            }
            return [ts.createReturn(ts.getSynthesizedDeepClone(node))];
        }
        function createTransformedStatement(prevArgName, rightHandSide, transformer) {
            if (!prevArgName || isEmpty(prevArgName)) {
                // if there's no argName to assign to, there still might be side effects
                return [ts.createStatement(rightHandSide)];
            }
            if (isSynthIdentifier(prevArgName) && prevArgName.types.length < prevArgName.numberOfAssignmentsOriginal) {
                // if the variable has already been declared, we don't need "let" or "const"
                return [ts.createStatement(ts.createAssignment(ts.getSynthesizedDeepClone(prevArgName.identifier), rightHandSide))];
            }
            return [ts.createVariableStatement(/*modifiers*/ undefined, (ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.getSynthesizedDeepClone(getNode(prevArgName)), /*type*/ undefined, rightHandSide)], getFlagOfBindingName(prevArgName, transformer.constIdentifiers))))];
        }
        // should be kept up to date with isFixablePromiseArgument in suggestionDiagnostics.ts
        function getTransformationBody(func, prevArgName, argName, parent, transformer) {
            var shouldReturn = transformer.setOfExpressionsToReturn.get(ts.getNodeId(parent).toString());
            switch (func.kind) {
                case 97 /* NullKeyword */:
                    // do not produce a transformed statement for a null argument
                    break;
                case 73 /* Identifier */: // identifier includes undefined
                    if (!argName) {
                        // undefined was argument passed to promise handler
                        break;
                    }
                    var synthCall = ts.createCall(ts.getSynthesizedDeepClone(func), /*typeArguments*/ undefined, isSynthIdentifier(argName) ? [argName.identifier] : []);
                    if (shouldReturn) {
                        return [ts.createReturn(synthCall)];
                    }
                    var type = transformer.originalTypeMap.get(ts.getNodeId(func).toString()) || transformer.checker.getTypeAtLocation(func);
                    var callSignatures = transformer.checker.getSignaturesOfType(type, 0 /* Call */);
                    if (!callSignatures.length) {
                        // if identifier in handler has no call signatures, it's invalid
                        codeActionSucceeded = false;
                        break;
                    }
                    var returnType = callSignatures[0].getReturnType();
                    var varDeclOrAssignment = createTransformedStatement(prevArgName, ts.createAwait(synthCall), transformer);
                    if (prevArgName) {
                        prevArgName.types.push(returnType);
                    }
                    return varDeclOrAssignment;
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */: {
                    var funcBody = func.body;
                    // Arrow functions with block bodies { } will enter this control flow
                    if (ts.isBlock(funcBody)) {
                        var refactoredStmts = [];
                        var seenReturnStatement = false;
                        for (var _i = 0, _a = funcBody.statements; _i < _a.length; _i++) {
                            var statement = _a[_i];
                            if (ts.isReturnStatement(statement)) {
                                seenReturnStatement = true;
                            }
                            if (ts.isReturnStatementWithFixablePromiseHandler(statement)) {
                                refactoredStmts = refactoredStmts.concat(getInnerTransformationBody(transformer, [statement], prevArgName));
                            }
                            else {
                                refactoredStmts.push(statement);
                            }
                        }
                        return shouldReturn ? refactoredStmts.map(function (s) { return ts.getSynthesizedDeepClone(s); }) :
                            removeReturns(refactoredStmts, prevArgName, transformer, seenReturnStatement);
                    }
                    else {
                        var innerRetStmts = ts.isFixablePromiseHandler(funcBody) ? [ts.createReturn(funcBody)] : ts.emptyArray;
                        var innerCbBody = getInnerTransformationBody(transformer, innerRetStmts, prevArgName);
                        if (innerCbBody.length > 0) {
                            return innerCbBody;
                        }
                        var type_1 = transformer.checker.getTypeAtLocation(func);
                        var returnType_1 = getLastCallSignature(type_1, transformer.checker).getReturnType();
                        var rightHandSide = ts.getSynthesizedDeepClone(funcBody);
                        var possiblyAwaitedRightHandSide = !!transformer.checker.getPromisedTypeOfPromise(returnType_1) ? ts.createAwait(rightHandSide) : rightHandSide;
                        if (!shouldReturn) {
                            var transformedStatement = createTransformedStatement(prevArgName, possiblyAwaitedRightHandSide, transformer);
                            if (prevArgName) {
                                prevArgName.types.push(returnType_1);
                            }
                            return transformedStatement;
                        }
                        else {
                            return [ts.createReturn(possiblyAwaitedRightHandSide)];
                        }
                    }
                }
                default:
                    // If no cases apply, we've found a transformation body we don't know how to handle, so the refactoring should no-op to avoid deleting code.
                    codeActionSucceeded = false;
                    break;
            }
            return ts.emptyArray;
        }
        function getLastCallSignature(type, checker) {
            var callSignatures = checker.getSignaturesOfType(type, 0 /* Call */);
            return ts.lastOrUndefined(callSignatures);
        }
        function removeReturns(stmts, prevArgName, transformer, seenReturnStatement) {
            var ret = [];
            for (var _i = 0, stmts_1 = stmts; _i < stmts_1.length; _i++) {
                var stmt = stmts_1[_i];
                if (ts.isReturnStatement(stmt)) {
                    if (stmt.expression) {
                        var possiblyAwaitedExpression = isPromiseReturningExpression(stmt.expression, transformer.checker) ? ts.createAwait(stmt.expression) : stmt.expression;
                        if (prevArgName === undefined) {
                            ret.push(ts.createExpressionStatement(possiblyAwaitedExpression));
                        }
                        else {
                            ret.push(ts.createVariableStatement(/*modifiers*/ undefined, (ts.createVariableDeclarationList([ts.createVariableDeclaration(getNode(prevArgName), /*type*/ undefined, possiblyAwaitedExpression)], getFlagOfBindingName(prevArgName, transformer.constIdentifiers)))));
                        }
                    }
                }
                else {
                    ret.push(ts.getSynthesizedDeepClone(stmt));
                }
            }
            // if block has no return statement, need to define prevArgName as undefined to prevent undeclared variables
            if (!seenReturnStatement && prevArgName !== undefined) {
                ret.push(ts.createVariableStatement(/*modifiers*/ undefined, (ts.createVariableDeclarationList([ts.createVariableDeclaration(getNode(prevArgName), /*type*/ undefined, ts.createIdentifier("undefined"))], getFlagOfBindingName(prevArgName, transformer.constIdentifiers)))));
            }
            return ret;
        }
        function getInnerTransformationBody(transformer, innerRetStmts, prevArgName) {
            var innerCbBody = [];
            for (var _i = 0, innerRetStmts_1 = innerRetStmts; _i < innerRetStmts_1.length; _i++) {
                var stmt = innerRetStmts_1[_i];
                ts.forEachChild(stmt, function visit(node) {
                    if (ts.isCallExpression(node)) {
                        var temp = transformExpression(node, transformer, node, prevArgName);
                        innerCbBody = innerCbBody.concat(temp);
                        if (innerCbBody.length > 0) {
                            return;
                        }
                    }
                    else if (!ts.isFunctionLike(node)) {
                        ts.forEachChild(node, visit);
                    }
                });
            }
            return innerCbBody;
        }
        function getArgBindingName(funcNode, transformer) {
            var numberOfAssignmentsOriginal = 0;
            var types = [];
            var name;
            if (ts.isFunctionLikeDeclaration(funcNode)) {
                if (funcNode.parameters.length > 0) {
                    var param = funcNode.parameters[0].name;
                    name = getMappedBindingNameOrDefault(param);
                }
            }
            else if (ts.isIdentifier(funcNode)) {
                name = getMapEntryOrDefault(funcNode);
            }
            // return undefined argName when arg is null or undefined
            if (!name || "identifier" in name && name.identifier.text === "undefined") {
                return undefined;
            }
            return name;
            function getMappedBindingNameOrDefault(bindingName) {
                if (ts.isIdentifier(bindingName))
                    return getMapEntryOrDefault(bindingName);
                var elements = ts.flatMap(bindingName.elements, function (element) {
                    if (ts.isOmittedExpression(element))
                        return [];
                    return [getMappedBindingNameOrDefault(element.name)];
                });
                return createSynthBindingPattern(bindingName, elements);
            }
            function getMapEntryOrDefault(identifier) {
                var originalNode = getOriginalNode(identifier);
                var symbol = getSymbol(originalNode);
                if (!symbol) {
                    return createSynthIdentifier(identifier, types, numberOfAssignmentsOriginal);
                }
                var mapEntry = transformer.synthNamesMap.get(ts.getSymbolId(symbol).toString());
                return mapEntry || createSynthIdentifier(identifier, types, numberOfAssignmentsOriginal);
            }
            function getSymbol(node) {
                return node.symbol ? node.symbol : transformer.checker.getSymbolAtLocation(node);
            }
            function getOriginalNode(node) {
                return node.original ? node.original : node;
            }
        }
        function isEmpty(bindingName) {
            if (!bindingName) {
                return true;
            }
            if (isSynthIdentifier(bindingName)) {
                return !bindingName.identifier.text;
            }
            return ts.every(bindingName.elements, isEmpty);
        }
        function getNode(bindingName) {
            return isSynthIdentifier(bindingName) ? bindingName.identifier : bindingName.bindingPattern;
        }
        function createSynthIdentifier(identifier, types, numberOfAssignmentsOriginal) {
            if (types === void 0) { types = []; }
            if (numberOfAssignmentsOriginal === void 0) { numberOfAssignmentsOriginal = 0; }
            return { kind: 0 /* Identifier */, identifier: identifier, types: types, numberOfAssignmentsOriginal: numberOfAssignmentsOriginal };
        }
        function createSynthBindingPattern(bindingPattern, elements, types) {
            if (elements === void 0) { elements = ts.emptyArray; }
            if (types === void 0) { types = []; }
            return { kind: 1 /* BindingPattern */, bindingPattern: bindingPattern, elements: elements, types: types };
        }
        function isSynthIdentifier(bindingName) {
            return bindingName.kind === 0 /* Identifier */;
        }
        function isSynthBindingPattern(bindingName) {
            return bindingName.kind === 1 /* BindingPattern */;
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module.code],
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, program = context.program, preferences = context.preferences;
                var changes = ts.textChanges.ChangeTracker.with(context, function (changes) {
                    var moduleExportsChangedToDefault = convertFileToEs6Module(sourceFile, program.getTypeChecker(), changes, program.getCompilerOptions().target, ts.getQuotePreference(sourceFile, preferences));
                    if (moduleExportsChangedToDefault) {
                        for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
                            var importingFile = _a[_i];
                            fixImportOfModuleExports(importingFile, sourceFile, changes, ts.getQuotePreference(importingFile, preferences));
                        }
                    }
                });
                // No support for fix-all since this applies to the whole file at once anyway.
                return [codefix.createCodeFixActionNoFixId("convertToEs6Module", changes, ts.Diagnostics.Convert_to_ES6_module)];
            },
        });
        function fixImportOfModuleExports(importingFile, exportingFile, changes, quotePreference) {
            for (var _i = 0, _a = importingFile.imports; _i < _a.length; _i++) {
                var moduleSpecifier = _a[_i];
                var imported = ts.getResolvedModule(importingFile, moduleSpecifier.text);
                if (!imported || imported.resolvedFileName !== exportingFile.fileName) {
                    continue;
                }
                var importNode = ts.importFromModuleSpecifier(moduleSpecifier);
                switch (importNode.kind) {
                    case 249 /* ImportEqualsDeclaration */:
                        changes.replaceNode(importingFile, importNode, ts.makeImport(importNode.name, /*namedImports*/ undefined, moduleSpecifier, quotePreference));
                        break;
                    case 192 /* CallExpression */:
                        if (ts.isRequireCall(importNode, /*checkArgumentIsStringLiteralLike*/ false)) {
                            changes.replaceNode(importingFile, importNode, ts.createPropertyAccess(ts.getSynthesizedDeepClone(importNode), "default"));
                        }
                        break;
                }
            }
        }
        /** @returns Whether we converted a `module.exports =` to a default export. */
        function convertFileToEs6Module(sourceFile, checker, changes, target, quotePreference) {
            var identifiers = { original: collectFreeIdentifiers(sourceFile), additional: ts.createMap() };
            var exports = collectExportRenames(sourceFile, checker, identifiers);
            convertExportsAccesses(sourceFile, exports, changes);
            var moduleExportsChangedToDefault = false;
            for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
                var statement = _a[_i];
                var moduleExportsChanged = convertStatement(sourceFile, statement, checker, changes, identifiers, target, exports, quotePreference);
                moduleExportsChangedToDefault = moduleExportsChangedToDefault || moduleExportsChanged;
            }
            return moduleExportsChangedToDefault;
        }
        function collectExportRenames(sourceFile, checker, identifiers) {
            var res = ts.createMap();
            forEachExportReference(sourceFile, function (node) {
                var _a = node.name, text = _a.text, originalKeywordKind = _a.originalKeywordKind;
                if (!res.has(text) && (originalKeywordKind !== undefined && ts.isNonContextualKeyword(originalKeywordKind)
                    || checker.resolveName(node.name.text, node, 67220415 /* Value */, /*excludeGlobals*/ true))) {
                    // Unconditionally add an underscore in case `text` is a keyword.
                    res.set(text, makeUniqueName("_" + text, identifiers));
                }
            });
            return res;
        }
        function convertExportsAccesses(sourceFile, exports, changes) {
            forEachExportReference(sourceFile, function (node, isAssignmentLhs) {
                if (isAssignmentLhs) {
                    return;
                }
                var text = node.name.text;
                changes.replaceNode(sourceFile, node, ts.createIdentifier(exports.get(text) || text));
            });
        }
        function forEachExportReference(sourceFile, cb) {
            sourceFile.forEachChild(function recur(node) {
                if (ts.isPropertyAccessExpression(node) && ts.isExportsOrModuleExportsOrAlias(sourceFile, node.expression)) {
                    var parent = node.parent;
                    cb(node, ts.isBinaryExpression(parent) && parent.left === node && parent.operatorToken.kind === 60 /* EqualsToken */);
                }
                node.forEachChild(recur);
            });
        }
        function convertStatement(sourceFile, statement, checker, changes, identifiers, target, exports, quotePreference) {
            switch (statement.kind) {
                case 220 /* VariableStatement */:
                    convertVariableStatement(sourceFile, statement, changes, checker, identifiers, target, quotePreference);
                    return false;
                case 222 /* ExpressionStatement */: {
                    var expression = statement.expression;
                    switch (expression.kind) {
                        case 192 /* CallExpression */: {
                            if (ts.isRequireCall(expression, /*checkArgumentIsStringLiteralLike*/ true)) {
                                // For side-effecting require() call, just make a side-effecting import.
                                changes.replaceNode(sourceFile, statement, ts.makeImport(/*name*/ undefined, /*namedImports*/ undefined, expression.arguments[0], quotePreference));
                            }
                            return false;
                        }
                        case 205 /* BinaryExpression */: {
                            var operatorToken = expression.operatorToken;
                            return operatorToken.kind === 60 /* EqualsToken */ && convertAssignment(sourceFile, checker, expression, changes, exports);
                        }
                    }
                }
                // falls through
                default:
                    return false;
            }
        }
        function convertVariableStatement(sourceFile, statement, changes, checker, identifiers, target, quotePreference) {
            var declarationList = statement.declarationList;
            var foundImport = false;
            var newNodes = ts.flatMap(declarationList.declarations, function (decl) {
                var name = decl.name, initializer = decl.initializer;
                if (initializer) {
                    if (ts.isExportsOrModuleExportsOrAlias(sourceFile, initializer)) {
                        // `const alias = module.exports;` can be removed.
                        foundImport = true;
                        return [];
                    }
                    else if (ts.isRequireCall(initializer, /*checkArgumentIsStringLiteralLike*/ true)) {
                        foundImport = true;
                        return convertSingleImport(sourceFile, name, initializer.arguments[0], changes, checker, identifiers, target, quotePreference);
                    }
                    else if (ts.isPropertyAccessExpression(initializer) && ts.isRequireCall(initializer.expression, /*checkArgumentIsStringLiteralLike*/ true)) {
                        foundImport = true;
                        return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0], identifiers, quotePreference);
                    }
                }
                // Move it out to its own variable statement. (This will not be used if `!foundImport`)
                return ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([decl], declarationList.flags));
            });
            if (foundImport) {
                // useNonAdjustedEndPosition to ensure we don't eat the newline after the statement.
                changes.replaceNodeWithNodes(sourceFile, statement, newNodes);
            }
        }
        /** Converts `const name = require("moduleSpecifier").propertyName` */
        function convertPropertyAccessImport(name, propertyName, moduleSpecifier, identifiers, quotePreference) {
            switch (name.kind) {
                case 185 /* ObjectBindingPattern */:
                case 186 /* ArrayBindingPattern */: {
                    // `const [a, b] = require("c").d` --> `import { d } from "c"; const [a, b] = d;`
                    var tmp = makeUniqueName(propertyName, identifiers);
                    return [
                        makeSingleImport(tmp, propertyName, moduleSpecifier, quotePreference),
                        makeConst(/*modifiers*/ undefined, name, ts.createIdentifier(tmp)),
                    ];
                }
                case 73 /* Identifier */:
                    // `const a = require("b").c` --> `import { c as a } from "./b";
                    return [makeSingleImport(name.text, propertyName, moduleSpecifier, quotePreference)];
                default:
                    return ts.Debug.assertNever(name);
            }
        }
        function convertAssignment(sourceFile, checker, assignment, changes, exports) {
            var left = assignment.left, right = assignment.right;
            if (!ts.isPropertyAccessExpression(left)) {
                return false;
            }
            if (ts.isExportsOrModuleExportsOrAlias(sourceFile, left)) {
                if (ts.isExportsOrModuleExportsOrAlias(sourceFile, right)) {
                    // `const alias = module.exports;` or `module.exports = alias;` can be removed.
                    changes.delete(sourceFile, assignment.parent);
                }
                else {
                    var replacement = ts.isObjectLiteralExpression(right) ? tryChangeModuleExportsObject(right)
                        : ts.isRequireCall(right, /*checkArgumentIsStringLiteralLike*/ true) ? convertReExportAll(right.arguments[0], checker)
                            : undefined;
                    if (replacement) {
                        changes.replaceNodeWithNodes(sourceFile, assignment.parent, replacement[0]);
                        return replacement[1];
                    }
                    else {
                        changes.replaceRangeWithText(sourceFile, ts.createRange(left.getStart(sourceFile), right.pos), "export default");
                        return true;
                    }
                }
            }
            else if (ts.isExportsOrModuleExportsOrAlias(sourceFile, left.expression)) {
                convertNamedExport(sourceFile, assignment, changes, exports);
            }
            return false;
        }
        /**
         * Convert `module.exports = { ... }` to individual exports..
         * We can't always do this if the module has interesting members -- then it will be a default export instead.
         */
        function tryChangeModuleExportsObject(object) {
            var statements = ts.mapAllOrFail(object.properties, function (prop) {
                switch (prop.kind) {
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                    // TODO: Maybe we should handle this? See fourslash test `refactorConvertToEs6Module_export_object_shorthand.ts`.
                    case 277 /* ShorthandPropertyAssignment */:
                    case 278 /* SpreadAssignment */:
                        return undefined;
                    case 276 /* PropertyAssignment */:
                        return !ts.isIdentifier(prop.name) ? undefined : convertExportsDotXEquals_replaceNode(prop.name.text, prop.initializer);
                    case 157 /* MethodDeclaration */:
                        return !ts.isIdentifier(prop.name) ? undefined : functionExpressionToDeclaration(prop.name.text, [ts.createToken(86 /* ExportKeyword */)], prop);
                    default:
                        ts.Debug.assertNever(prop);
                }
            });
            return statements && [statements, false];
        }
        function convertNamedExport(sourceFile, assignment, changes, exports) {
            // If "originalKeywordKind" was set, this is e.g. `exports.
            var text = assignment.left.name.text;
            var rename = exports.get(text);
            if (rename !== undefined) {
                /*
                const _class = 0;
                export { _class as class };
                */
                var newNodes = [
                    makeConst(/*modifiers*/ undefined, rename, assignment.right),
                    makeExportDeclaration([ts.createExportSpecifier(rename, text)]),
                ];
                changes.replaceNodeWithNodes(sourceFile, assignment.parent, newNodes);
            }
            else {
                convertExportsPropertyAssignment(assignment, sourceFile, changes);
            }
        }
        function convertReExportAll(reExported, checker) {
            // `module.exports = require("x");` ==> `export * from "x"; export { default } from "x";`
            var moduleSpecifier = reExported.text;
            var moduleSymbol = checker.getSymbolAtLocation(reExported);
            var exports = moduleSymbol ? moduleSymbol.exports : ts.emptyUnderscoreEscapedMap;
            return exports.has("export=")
                ? [[reExportDefault(moduleSpecifier)], true]
                : !exports.has("default")
                    ? [[reExportStar(moduleSpecifier)], false]
                    // If there's some non-default export, must include both `export *` and `export default`.
                    : exports.size > 1 ? [[reExportStar(moduleSpecifier), reExportDefault(moduleSpecifier)], true] : [[reExportDefault(moduleSpecifier)], true];
        }
        function reExportStar(moduleSpecifier) {
            return makeExportDeclaration(/*exportClause*/ undefined, moduleSpecifier);
        }
        function reExportDefault(moduleSpecifier) {
            return makeExportDeclaration([ts.createExportSpecifier(/*propertyName*/ undefined, "default")], moduleSpecifier);
        }
        function convertExportsPropertyAssignment(_a, sourceFile, changes) {
            var left = _a.left, right = _a.right, parent = _a.parent;
            var name = left.name.text;
            if ((ts.isFunctionExpression(right) || ts.isArrowFunction(right) || ts.isClassExpression(right)) && (!right.name || right.name.text === name)) {
                // `exports.f = function() {}` -> `export function f() {}` -- Replace `exports.f = ` with `export `, and insert the name after `function`.
                changes.replaceRange(sourceFile, { pos: left.getStart(sourceFile), end: right.getStart(sourceFile) }, ts.createToken(86 /* ExportKeyword */), { suffix: " " });
                if (!right.name)
                    changes.insertName(sourceFile, right, name);
                var semi = ts.findChildOfKind(parent, 26 /* SemicolonToken */, sourceFile);
                if (semi)
                    changes.delete(sourceFile, semi);
            }
            else {
                // `exports.f = function g() {}` -> `export const f = function g() {}` -- just replace `exports.` with `export const `
                changes.replaceNodeRangeWithNodes(sourceFile, left.expression, ts.findChildOfKind(left, 24 /* DotToken */, sourceFile), [ts.createToken(86 /* ExportKeyword */), ts.createToken(78 /* ConstKeyword */)], { joiner: " ", suffix: " " });
            }
        }
        // TODO: GH#22492 this will cause an error if a change has been made inside the body of the node.
        function convertExportsDotXEquals_replaceNode(name, exported) {
            var modifiers = [ts.createToken(86 /* ExportKeyword */)];
            switch (exported.kind) {
                case 197 /* FunctionExpression */: {
                    var expressionName = exported.name;
                    if (expressionName && expressionName.text !== name) {
                        // `exports.f = function g() {}` -> `export const f = function g() {}`
                        return exportConst();
                    }
                }
                // falls through
                case 198 /* ArrowFunction */:
                    // `exports.f = function() {}` --> `export function f() {}`
                    return functionExpressionToDeclaration(name, modifiers, exported);
                case 210 /* ClassExpression */:
                    // `exports.C = class {}` --> `export class C {}`
                    return classExpressionToDeclaration(name, modifiers, exported);
                default:
                    return exportConst();
            }
            function exportConst() {
                // `exports.x = 0;` --> `export const x = 0;`
                return makeConst(modifiers, ts.createIdentifier(name), exported); // TODO: GH#18217
            }
        }
        /**
         * Converts `const <<name>> = require("x");`.
         * Returns nodes that will replace the variable declaration for the commonjs import.
         * May also make use `changes` to remove qualifiers at the use sites of imports, to change `mod.x` to `x`.
         */
        function convertSingleImport(file, name, moduleSpecifier, changes, checker, identifiers, target, quotePreference) {
            switch (name.kind) {
                case 185 /* ObjectBindingPattern */: {
                    var importSpecifiers = ts.mapAllOrFail(name.elements, function (e) {
                        return e.dotDotDotToken || e.initializer || e.propertyName && !ts.isIdentifier(e.propertyName) || !ts.isIdentifier(e.name)
                            ? undefined
                            : makeImportSpecifier(e.propertyName && e.propertyName.text, e.name.text);
                    }); // tslint:disable-line no-unnecessary-type-assertion (TODO: GH#18217)
                    if (importSpecifiers) {
                        return [ts.makeImport(/*name*/ undefined, importSpecifiers, moduleSpecifier, quotePreference)];
                    }
                }
                // falls through -- object destructuring has an interesting pattern and must be a variable declaration
                case 186 /* ArrayBindingPattern */: {
                    /*
                    import x from "x";
                    const [a, b, c] = x;
                    */
                    var tmp = makeUniqueName(codefix.moduleSpecifierToValidIdentifier(moduleSpecifier.text, target), identifiers);
                    return [
                        ts.makeImport(ts.createIdentifier(tmp), /*namedImports*/ undefined, moduleSpecifier, quotePreference),
                        makeConst(/*modifiers*/ undefined, ts.getSynthesizedDeepClone(name), ts.createIdentifier(tmp)),
                    ];
                }
                case 73 /* Identifier */:
                    return convertSingleIdentifierImport(file, name, moduleSpecifier, changes, checker, identifiers, quotePreference);
                default:
                    return ts.Debug.assertNever(name);
            }
        }
        /**
         * Convert `import x = require("x").`
         * Also converts uses like `x.y()` to `y()` and uses a named import.
         */
        function convertSingleIdentifierImport(file, name, moduleSpecifier, changes, checker, identifiers, quotePreference) {
            var nameSymbol = checker.getSymbolAtLocation(name);
            // Maps from module property name to name actually used. (The same if there isn't shadowing.)
            var namedBindingsNames = ts.createMap();
            // True if there is some non-property use like `x()` or `f(x)`.
            var needDefaultImport = false;
            for (var _i = 0, _a = identifiers.original.get(name.text); _i < _a.length; _i++) {
                var use = _a[_i];
                if (checker.getSymbolAtLocation(use) !== nameSymbol || use === name) {
                    // This was a use of a different symbol with the same name, due to shadowing. Ignore.
                    continue;
                }
                var parent = use.parent;
                if (ts.isPropertyAccessExpression(parent)) {
                    var expression = parent.expression, propertyName = parent.name.text;
                    ts.Debug.assert(expression === use); // Else shouldn't have been in `collectIdentifiers`
                    var idName = namedBindingsNames.get(propertyName);
                    if (idName === undefined) {
                        idName = makeUniqueName(propertyName, identifiers);
                        namedBindingsNames.set(propertyName, idName);
                    }
                    changes.replaceNode(file, parent, ts.createIdentifier(idName));
                }
                else {
                    needDefaultImport = true;
                }
            }
            var namedBindings = namedBindingsNames.size === 0 ? undefined : ts.arrayFrom(ts.mapIterator(namedBindingsNames.entries(), function (_a) {
                var propertyName = _a[0], idName = _a[1];
                return ts.createImportSpecifier(propertyName === idName ? undefined : ts.createIdentifier(propertyName), ts.createIdentifier(idName));
            }));
            if (!namedBindings) {
                // If it was unused, ensure that we at least import *something*.
                needDefaultImport = true;
            }
            return [ts.makeImport(needDefaultImport ? ts.getSynthesizedDeepClone(name) : undefined, namedBindings, moduleSpecifier, quotePreference)];
        }
        // Identifiers helpers
        function makeUniqueName(name, identifiers) {
            while (identifiers.original.has(name) || identifiers.additional.has(name)) {
                name = "_" + name;
            }
            identifiers.additional.set(name, true);
            return name;
        }
        function collectFreeIdentifiers(file) {
            var map = ts.createMultiMap();
            forEachFreeIdentifier(file, function (id) { return map.add(id.text, id); });
            return map;
        }
        /**
         * A free identifier is an identifier that can be accessed through name lookup as a local variable.
         * In the expression `x.y`, `x` is a free identifier, but `y` is not.
         */
        function forEachFreeIdentifier(node, cb) {
            if (ts.isIdentifier(node) && isFreeIdentifier(node))
                cb(node);
            node.forEachChild(function (child) { return forEachFreeIdentifier(child, cb); });
        }
        function isFreeIdentifier(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 190 /* PropertyAccessExpression */:
                    return parent.name !== node;
                case 187 /* BindingElement */:
                    return parent.propertyName !== node;
                case 254 /* ImportSpecifier */:
                    return parent.propertyName !== node;
                default:
                    return true;
            }
        }
        // Node helpers
        function functionExpressionToDeclaration(name, additionalModifiers, fn) {
            return ts.createFunctionDeclaration(ts.getSynthesizedDeepClones(fn.decorators), // TODO: GH#19915 Don't think this is even legal.
            ts.concatenate(additionalModifiers, ts.getSynthesizedDeepClones(fn.modifiers)), ts.getSynthesizedDeepClone(fn.asteriskToken), name, ts.getSynthesizedDeepClones(fn.typeParameters), ts.getSynthesizedDeepClones(fn.parameters), ts.getSynthesizedDeepClone(fn.type), ts.convertToFunctionBody(ts.getSynthesizedDeepClone(fn.body)));
        }
        function classExpressionToDeclaration(name, additionalModifiers, cls) {
            return ts.createClassDeclaration(ts.getSynthesizedDeepClones(cls.decorators), // TODO: GH#19915 Don't think this is even legal.
            ts.concatenate(additionalModifiers, ts.getSynthesizedDeepClones(cls.modifiers)), name, ts.getSynthesizedDeepClones(cls.typeParameters), ts.getSynthesizedDeepClones(cls.heritageClauses), ts.getSynthesizedDeepClones(cls.members));
        }
        function makeSingleImport(localName, propertyName, moduleSpecifier, quotePreference) {
            return propertyName === "default"
                ? ts.makeImport(ts.createIdentifier(localName), /*namedImports*/ undefined, moduleSpecifier, quotePreference)
                : ts.makeImport(/*name*/ undefined, [makeImportSpecifier(propertyName, localName)], moduleSpecifier, quotePreference);
        }
        function makeImportSpecifier(propertyName, name) {
            return ts.createImportSpecifier(propertyName !== undefined && propertyName !== name ? ts.createIdentifier(propertyName) : undefined, ts.createIdentifier(name));
        }
        function makeConst(modifiers, name, init) {
            return ts.createVariableStatement(modifiers, ts.createVariableDeclarationList([ts.createVariableDeclaration(name, /*type*/ undefined, init)], 2 /* Const */));
        }
        function makeExportDeclaration(exportSpecifiers, moduleSpecifier) {
            return ts.createExportDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, exportSpecifiers && ts.createNamedExports(exportSpecifiers), moduleSpecifier === undefined ? undefined : ts.createLiteral(moduleSpecifier));
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "correctQualifiedNameToIndexedAccessType";
        var errorCodes = [ts.Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var qualifiedName = getQualifiedName(context.sourceFile, context.span.start);
                if (!qualifiedName)
                    return undefined;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, context.sourceFile, qualifiedName); });
                var newText = qualifiedName.left.text + "[\"" + qualifiedName.right.text + "\"]";
                return [codefix.createCodeFixAction(fixId, changes, [ts.Diagnostics.Rewrite_as_the_indexed_access_type_0, newText], fixId, ts.Diagnostics.Rewrite_all_as_indexed_access_types)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var q = getQualifiedName(diag.file, diag.start);
                if (q) {
                    doChange(changes, diag.file, q);
                }
            }); },
        });
        function getQualifiedName(sourceFile, pos) {
            var qualifiedName = ts.findAncestor(ts.getTokenAtPosition(sourceFile, pos), ts.isQualifiedName);
            ts.Debug.assert(!!qualifiedName, "Expected position to be owned by a qualified name.");
            return ts.isIdentifier(qualifiedName.left) ? qualifiedName : undefined;
        }
        function doChange(changeTracker, sourceFile, qualifiedName) {
            var rightText = qualifiedName.right.text;
            var replacement = ts.createIndexedAccessTypeNode(ts.createTypeReferenceNode(qualifiedName.left, /*typeArguments*/ undefined), ts.createLiteralTypeNode(ts.createLiteral(rightText)));
            changeTracker.replaceNode(sourceFile, qualifiedName, replacement);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var errorCodes = [ts.Diagnostics.Class_0_incorrectly_implements_interface_1.code,
            ts.Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass.code];
        var fixId = "fixClassIncorrectlyImplementsInterface"; // TODO: share a group with fixClassDoesntImplementInheritedAbstractMember?
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var classDeclaration = getClass(sourceFile, span.start);
                return ts.mapDefined(ts.getClassImplementsHeritageClauseElements(classDeclaration), function (implementedTypeNode) {
                    var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addMissingDeclarations(context, implementedTypeNode, sourceFile, classDeclaration, t, context.preferences); });
                    return changes.length === 0 ? undefined : codefix.createCodeFixAction(fixId, changes, [ts.Diagnostics.Implement_interface_0, implementedTypeNode.getText(sourceFile)], fixId, ts.Diagnostics.Implement_all_unimplemented_interfaces);
                });
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var seenClassDeclarations = ts.createMap();
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                    var classDeclaration = getClass(diag.file, diag.start);
                    if (ts.addToSeen(seenClassDeclarations, ts.getNodeId(classDeclaration))) {
                        for (var _i = 0, _a = ts.getClassImplementsHeritageClauseElements(classDeclaration); _i < _a.length; _i++) {
                            var implementedTypeNode = _a[_i];
                            addMissingDeclarations(context, implementedTypeNode, diag.file, classDeclaration, changes, context.preferences);
                        }
                    }
                });
            },
        });
        function getClass(sourceFile, pos) {
            return ts.Debug.assertDefined(ts.getContainingClass(ts.getTokenAtPosition(sourceFile, pos)));
        }
        function symbolPointsToNonPrivateMember(symbol) {
            return !(ts.getModifierFlags(symbol.valueDeclaration) & 8 /* Private */);
        }
        function addMissingDeclarations(context, implementedTypeNode, sourceFile, classDeclaration, changeTracker, preferences) {
            var checker = context.program.getTypeChecker();
            var maybeHeritageClauseSymbol = getHeritageClauseSymbolTable(classDeclaration, checker);
            // Note that this is ultimately derived from a map indexed by symbol names,
            // so duplicates cannot occur.
            var implementedType = checker.getTypeAtLocation(implementedTypeNode);
            var implementedTypeSymbols = checker.getPropertiesOfType(implementedType);
            var nonPrivateAndNotExistedInHeritageClauseMembers = implementedTypeSymbols.filter(ts.and(symbolPointsToNonPrivateMember, function (symbol) { return !maybeHeritageClauseSymbol.has(symbol.escapedName); }));
            var classType = checker.getTypeAtLocation(classDeclaration);
            if (!classType.getNumberIndexType()) {
                createMissingIndexSignatureDeclaration(implementedType, 1 /* Number */);
            }
            if (!classType.getStringIndexType()) {
                createMissingIndexSignatureDeclaration(implementedType, 0 /* String */);
            }
            codefix.createMissingMemberNodes(classDeclaration, nonPrivateAndNotExistedInHeritageClauseMembers, context, preferences, function (member) { return changeTracker.insertNodeAtClassStart(sourceFile, classDeclaration, member); });
            function createMissingIndexSignatureDeclaration(type, kind) {
                var indexInfoOfKind = checker.getIndexInfoOfType(type, kind);
                if (indexInfoOfKind) {
                    changeTracker.insertNodeAtClassStart(sourceFile, classDeclaration, checker.indexInfoToIndexSignatureDeclaration(indexInfoOfKind, kind, classDeclaration, /*flags*/ undefined, codefix.getNoopSymbolTrackerWithResolver(context)));
                }
            }
        }
        function getHeritageClauseSymbolTable(classDeclaration, checker) {
            var heritageClauseNode = ts.getEffectiveBaseTypeNode(classDeclaration);
            if (!heritageClauseNode)
                return ts.createSymbolTable();
            var heritageClauseType = checker.getTypeAtLocation(heritageClauseNode);
            var heritageClauseTypeSymbols = checker.getPropertiesOfType(heritageClauseType);
            return ts.createSymbolTable(heritageClauseTypeSymbols.filter(symbolPointsToNonPrivateMember));
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.importFixId = "fixMissingImport";
        var errorCodes = [
            ts.Diagnostics.Cannot_find_name_0.code,
            ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1.code,
            ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code,
            ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0.code,
            ts.Diagnostics.Cannot_find_namespace_0.code,
            ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code,
            ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var errorCode = context.errorCode, preferences = context.preferences, sourceFile = context.sourceFile, span = context.span;
                var info = getFixesInfo(context, errorCode, span.start);
                if (!info)
                    return undefined;
                var fixes = info.fixes, symbolName = info.symbolName;
                var quotePreference = ts.getQuotePreference(sourceFile, preferences);
                return fixes.map(function (fix) { return codeActionForFix(context, sourceFile, symbolName, fix, quotePreference); });
            },
            fixIds: [codefix.importFixId],
            getAllCodeActions: function (context) {
                var sourceFile = context.sourceFile, preferences = context.preferences;
                // Namespace fixes don't conflict, so just build a list.
                var addToNamespace = [];
                var importType = [];
                // Keys are import clause node IDs.
                var addToExisting = ts.createMap();
                // Keys are module specifiers.
                var newImports = ts.createMap();
                codefix.eachDiagnostic(context, errorCodes, function (diag) {
                    var info = getFixesInfo(context, diag.code, diag.start);
                    if (!info || !info.fixes.length)
                        return;
                    var fixes = info.fixes, symbolName = info.symbolName;
                    var fix = ts.first(fixes);
                    switch (fix.kind) {
                        case 0 /* UseNamespace */:
                            addToNamespace.push(fix);
                            break;
                        case 1 /* ImportType */:
                            importType.push(fix);
                            break;
                        case 2 /* AddToExisting */: {
                            var importClause = fix.importClause, importKind = fix.importKind;
                            var key = String(ts.getNodeId(importClause));
                            var entry = addToExisting.get(key);
                            if (!entry) {
                                addToExisting.set(key, entry = { importClause: importClause, defaultImport: undefined, namedImports: [] });
                            }
                            if (importKind === 0 /* Named */) {
                                ts.pushIfUnique(entry.namedImports, symbolName);
                            }
                            else {
                                ts.Debug.assert(entry.defaultImport === undefined || entry.defaultImport === symbolName);
                                entry.defaultImport = symbolName;
                            }
                            break;
                        }
                        case 3 /* AddNew */: {
                            var moduleSpecifier = fix.moduleSpecifier, importKind = fix.importKind;
                            var entry = newImports.get(moduleSpecifier);
                            if (!entry) {
                                newImports.set(moduleSpecifier, entry = { defaultImport: undefined, namedImports: [], namespaceLikeImport: undefined });
                            }
                            switch (importKind) {
                                case 1 /* Default */:
                                    ts.Debug.assert(entry.defaultImport === undefined || entry.defaultImport === symbolName);
                                    entry.defaultImport = symbolName;
                                    break;
                                case 0 /* Named */:
                                    ts.pushIfUnique(entry.namedImports, symbolName);
                                    break;
                                case 3 /* Equals */:
                                case 2 /* Namespace */:
                                    ts.Debug.assert(entry.namespaceLikeImport === undefined || entry.namespaceLikeImport.name === symbolName);
                                    entry.namespaceLikeImport = { importKind: importKind, name: symbolName };
                                    break;
                            }
                            break;
                        }
                        default:
                            ts.Debug.assertNever(fix);
                    }
                });
                return codefix.createCombinedCodeActions(ts.textChanges.ChangeTracker.with(context, function (changes) {
                    var quotePreference = ts.getQuotePreference(sourceFile, preferences);
                    for (var _i = 0, addToNamespace_1 = addToNamespace; _i < addToNamespace_1.length; _i++) {
                        var fix = addToNamespace_1[_i];
                        addNamespaceQualifier(changes, sourceFile, fix);
                    }
                    for (var _a = 0, importType_1 = importType; _a < importType_1.length; _a++) {
                        var fix = importType_1[_a];
                        addImportType(changes, sourceFile, fix, quotePreference);
                    }
                    addToExisting.forEach(function (_a) {
                        var importClause = _a.importClause, defaultImport = _a.defaultImport, namedImports = _a.namedImports;
                        doAddExistingFix(changes, sourceFile, importClause, defaultImport, namedImports);
                    });
                    newImports.forEach(function (imports, moduleSpecifier) {
                        addNewImports(changes, sourceFile, moduleSpecifier, quotePreference, imports);
                    });
                }));
            },
        });
        // Sorted with the preferred fix coming first.
        var ImportFixKind;
        (function (ImportFixKind) {
            ImportFixKind[ImportFixKind["UseNamespace"] = 0] = "UseNamespace";
            ImportFixKind[ImportFixKind["ImportType"] = 1] = "ImportType";
            ImportFixKind[ImportFixKind["AddToExisting"] = 2] = "AddToExisting";
            ImportFixKind[ImportFixKind["AddNew"] = 3] = "AddNew";
        })(ImportFixKind || (ImportFixKind = {}));
        var ImportKind;
        (function (ImportKind) {
            ImportKind[ImportKind["Named"] = 0] = "Named";
            ImportKind[ImportKind["Default"] = 1] = "Default";
            ImportKind[ImportKind["Namespace"] = 2] = "Namespace";
            ImportKind[ImportKind["Equals"] = 3] = "Equals";
        })(ImportKind || (ImportKind = {}));
        function getImportCompletionAction(exportedSymbol, moduleSymbol, sourceFile, symbolName, host, program, formatContext, position, preferences) {
            var exportInfos = getAllReExportingModules(exportedSymbol, moduleSymbol, symbolName, sourceFile, program.getCompilerOptions(), program.getTypeChecker(), program.getSourceFiles());
            ts.Debug.assert(exportInfos.some(function (info) { return info.moduleSymbol === moduleSymbol; }));
            // We sort the best codefixes first, so taking `first` is best for completions.
            var moduleSpecifier = ts.first(getNewImportInfos(program, sourceFile, position, exportInfos, host, preferences)).moduleSpecifier;
            var fix = ts.first(getFixForImport(exportInfos, symbolName, position, program, sourceFile, host, preferences));
            return { moduleSpecifier: moduleSpecifier, codeAction: codeFixActionToCodeAction(codeActionForFix({ host: host, formatContext: formatContext }, sourceFile, symbolName, fix, ts.getQuotePreference(sourceFile, preferences))) };
        }
        codefix.getImportCompletionAction = getImportCompletionAction;
        function codeFixActionToCodeAction(_a) {
            var description = _a.description, changes = _a.changes, commands = _a.commands;
            return { description: description, changes: changes, commands: commands };
        }
        function getAllReExportingModules(exportedSymbol, exportingModuleSymbol, symbolName, sourceFile, compilerOptions, checker, allSourceFiles) {
            var result = [];
            forEachExternalModule(checker, allSourceFiles, function (moduleSymbol, moduleFile) {
                // Don't import from a re-export when looking "up" like to `./index` or `../index`.
                if (moduleFile && moduleSymbol !== exportingModuleSymbol && ts.startsWith(sourceFile.fileName, ts.getDirectoryPath(moduleFile.fileName))) {
                    return;
                }
                var defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions);
                if (defaultInfo && defaultInfo.name === symbolName && ts.skipAlias(defaultInfo.symbol, checker) === exportedSymbol) {
                    result.push({ moduleSymbol: moduleSymbol, importKind: defaultInfo.kind, exportedSymbolIsTypeOnly: isTypeOnlySymbol(defaultInfo.symbol, checker) });
                }
                for (var _i = 0, _a = checker.getExportsOfModule(moduleSymbol); _i < _a.length; _i++) {
                    var exported = _a[_i];
                    if (exported.name === symbolName && ts.skipAlias(exported, checker) === exportedSymbol) {
                        result.push({ moduleSymbol: moduleSymbol, importKind: 0 /* Named */, exportedSymbolIsTypeOnly: isTypeOnlySymbol(exported, checker) });
                    }
                }
            });
            return result;
        }
        function isTypeOnlySymbol(s, checker) {
            return !(ts.skipAlias(s, checker).flags & 67220415 /* Value */);
        }
        function getFixForImport(exportInfos, symbolName, position, program, sourceFile, host, preferences) {
            var checker = program.getTypeChecker();
            var existingImports = ts.flatMap(exportInfos, function (info) { return getExistingImportDeclarations(info, checker, sourceFile); });
            var useNamespace = position === undefined ? undefined : tryUseExistingNamespaceImport(existingImports, symbolName, position, checker);
            var addToExisting = tryAddToExistingImport(existingImports);
            // Don't bother providing an action to add a new import if we can add to an existing one.
            var addImport = addToExisting ? [addToExisting] : getFixesForAddImport(exportInfos, existingImports, program, sourceFile, position, host, preferences);
            return (useNamespace ? [useNamespace] : ts.emptyArray).concat(addImport);
        }
        function tryUseExistingNamespaceImport(existingImports, symbolName, position, checker) {
            // It is possible that multiple import statements with the same specifier exist in the file.
            // e.g.
            //
            //     import * as ns from "foo";
            //     import { member1, member2 } from "foo";
            //
            //     member3/**/ <-- cusor here
            //
            // in this case we should provie 2 actions:
            //     1. change "member3" to "ns.member3"
            //     2. add "member3" to the second import statement's import list
            // and it is up to the user to decide which one fits best.
            return ts.firstDefined(existingImports, function (_a) {
                var declaration = _a.declaration;
                var namespace = getNamespaceImportName(declaration);
                if (namespace) {
                    var moduleSymbol = checker.getAliasedSymbol(checker.getSymbolAtLocation(namespace));
                    if (moduleSymbol && moduleSymbol.exports.has(ts.escapeLeadingUnderscores(symbolName))) {
                        return { kind: 0 /* UseNamespace */, namespacePrefix: namespace.text, position: position };
                    }
                }
            });
        }
        function tryAddToExistingImport(existingImports) {
            return ts.firstDefined(existingImports, function (_a) {
                var declaration = _a.declaration, importKind = _a.importKind;
                if (declaration.kind !== 250 /* ImportDeclaration */)
                    return undefined;
                var importClause = declaration.importClause;
                if (!importClause)
                    return undefined;
                var name = importClause.name, namedBindings = importClause.namedBindings;
                return importKind === 1 /* Default */ && !name || importKind === 0 /* Named */ && (!namedBindings || namedBindings.kind === 253 /* NamedImports */)
                    ? { kind: 2 /* AddToExisting */, importClause: importClause, importKind: importKind }
                    : undefined;
            });
        }
        function getNamespaceImportName(declaration) {
            if (declaration.kind === 250 /* ImportDeclaration */) {
                var namedBindings = declaration.importClause && ts.isImportClause(declaration.importClause) && declaration.importClause.namedBindings;
                return namedBindings && namedBindings.kind === 252 /* NamespaceImport */ ? namedBindings.name : undefined;
            }
            else {
                return declaration.name;
            }
        }
        function getExistingImportDeclarations(_a, checker, sourceFile) {
            var moduleSymbol = _a.moduleSymbol, importKind = _a.importKind, exportedSymbolIsTypeOnly = _a.exportedSymbolIsTypeOnly;
            // Can't use an es6 import for a type in JS.
            return exportedSymbolIsTypeOnly && ts.isSourceFileJS(sourceFile) ? ts.emptyArray : ts.mapDefined(sourceFile.imports, function (moduleSpecifier) {
                var i = ts.importFromModuleSpecifier(moduleSpecifier);
                return (i.kind === 250 /* ImportDeclaration */ || i.kind === 249 /* ImportEqualsDeclaration */)
                    && checker.getSymbolAtLocation(moduleSpecifier) === moduleSymbol ? { declaration: i, importKind: importKind } : undefined;
            });
        }
        function getNewImportInfos(program, sourceFile, position, moduleSymbols, host, preferences) {
            var isJs = ts.isSourceFileJS(sourceFile);
            var choicesForEachExportingModule = ts.flatMap(moduleSymbols, function (_a) {
                var moduleSymbol = _a.moduleSymbol, importKind = _a.importKind, exportedSymbolIsTypeOnly = _a.exportedSymbolIsTypeOnly;
                return ts.moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program.getCompilerOptions(), sourceFile, host, program.getSourceFiles(), preferences, program.redirectTargetsMap)
                    .map(function (moduleSpecifier) {
                    // `position` should only be undefined at a missing jsx namespace, in which case we shouldn't be looking for pure types.
                    return exportedSymbolIsTypeOnly && isJs ? { kind: 1 /* ImportType */, moduleSpecifier: moduleSpecifier, position: ts.Debug.assertDefined(position) } : { kind: 3 /* AddNew */, moduleSpecifier: moduleSpecifier, importKind: importKind };
                });
            });
            // Sort to keep the shortest paths first
            return ts.sort(choicesForEachExportingModule, function (a, b) { return a.moduleSpecifier.length - b.moduleSpecifier.length; });
        }
        function getFixesForAddImport(exportInfos, existingImports, program, sourceFile, position, host, preferences) {
            var existingDeclaration = ts.firstDefined(existingImports, newImportInfoFromExistingSpecifier);
            return existingDeclaration ? [existingDeclaration] : getNewImportInfos(program, sourceFile, position, exportInfos, host, preferences);
        }
        function newImportInfoFromExistingSpecifier(_a) {
            var declaration = _a.declaration, importKind = _a.importKind;
            var expression = declaration.kind === 250 /* ImportDeclaration */
                ? declaration.moduleSpecifier
                : declaration.moduleReference.kind === 260 /* ExternalModuleReference */
                    ? declaration.moduleReference.expression
                    : undefined;
            return expression && ts.isStringLiteral(expression) ? { kind: 3 /* AddNew */, moduleSpecifier: expression.text, importKind: importKind } : undefined;
        }
        function getFixesInfo(context, errorCode, pos) {
            var symbolToken = ts.getTokenAtPosition(context.sourceFile, pos);
            var info = errorCode === ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code
                ? getFixesInfoForUMDImport(context, symbolToken)
                : ts.isIdentifier(symbolToken) ? getFixesInfoForNonUMDImport(context, symbolToken) : undefined;
            return info && __assign({}, info, { fixes: ts.sort(info.fixes, function (a, b) { return a.kind - b.kind; }) });
        }
        function getFixesInfoForUMDImport(_a, token) {
            var sourceFile = _a.sourceFile, program = _a.program, host = _a.host, preferences = _a.preferences;
            var checker = program.getTypeChecker();
            var umdSymbol = getUmdSymbol(token, checker);
            if (!umdSymbol)
                return undefined;
            var symbol = checker.getAliasedSymbol(umdSymbol);
            var symbolName = umdSymbol.name;
            var exportInfos = [{ moduleSymbol: symbol, importKind: getUmdImportKind(program.getCompilerOptions()), exportedSymbolIsTypeOnly: false }];
            var fixes = getFixForImport(exportInfos, symbolName, ts.isIdentifier(token) ? token.getStart(sourceFile) : undefined, program, sourceFile, host, preferences);
            return { fixes: fixes, symbolName: symbolName };
        }
        function getUmdSymbol(token, checker) {
            // try the identifier to see if it is the umd symbol
            var umdSymbol = ts.isIdentifier(token) ? checker.getSymbolAtLocation(token) : undefined;
            if (ts.isUMDExportSymbol(umdSymbol))
                return umdSymbol;
            // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`.
            var parent = token.parent;
            return (ts.isJsxOpeningLikeElement(parent) && parent.tagName === token) || ts.isJsxOpeningFragment(parent)
                ? ts.tryCast(checker.resolveName(checker.getJsxNamespace(parent), ts.isJsxOpeningLikeElement(parent) ? token : parent, 67220415 /* Value */, /*excludeGlobals*/ false), ts.isUMDExportSymbol)
                : undefined;
        }
        function getUmdImportKind(compilerOptions) {
            // Import a synthetic `default` if enabled.
            if (ts.getAllowSyntheticDefaultImports(compilerOptions)) {
                return 1 /* Default */;
            }
            // When a synthetic `default` is unavailable, use `import..require` if the module kind supports it.
            var moduleKind = ts.getEmitModuleKind(compilerOptions);
            switch (moduleKind) {
                case ts.ModuleKind.AMD:
                case ts.ModuleKind.CommonJS:
                case ts.ModuleKind.UMD:
                    return 3 /* Equals */;
                case ts.ModuleKind.System:
                case ts.ModuleKind.ES2015:
                case ts.ModuleKind.ESNext:
                case ts.ModuleKind.None:
                    // Fall back to the `import * as ns` style import.
                    return 2 /* Namespace */;
                default:
                    return ts.Debug.assertNever(moduleKind);
            }
        }
        function getFixesInfoForNonUMDImport(_a, symbolToken) {
            var sourceFile = _a.sourceFile, program = _a.program, cancellationToken = _a.cancellationToken, host = _a.host, preferences = _a.preferences;
            var checker = program.getTypeChecker();
            // If we're at `<Foo/>`, we must check if `Foo` is already in scope, and if so, get an import for `React` instead.
            var symbolName = ts.isJsxOpeningLikeElement(symbolToken.parent)
                && symbolToken.parent.tagName === symbolToken
                && (ts.isIntrinsicJsxName(symbolToken.text) || checker.resolveName(symbolToken.text, symbolToken, 67108863 /* All */, /*excludeGlobals*/ false))
                ? checker.getJsxNamespace(sourceFile)
                : symbolToken.text;
            // "default" is a keyword and not a legal identifier for the import, so we don't expect it here
            ts.Debug.assert(symbolName !== "default" /* Default */);
            var fixes = ts.arrayFrom(ts.flatMapIterator(getExportInfos(symbolName, ts.getMeaningFromLocation(symbolToken), cancellationToken, sourceFile, checker, program).entries(), function (_a) {
                var _ = _a[0], exportInfos = _a[1];
                return getFixForImport(exportInfos, symbolName, symbolToken.getStart(sourceFile), program, sourceFile, host, preferences);
            }));
            return { fixes: fixes, symbolName: symbolName };
        }
        // Returns a map from an exported symbol's ID to a list of every way it's (re-)exported.
        function getExportInfos(symbolName, currentTokenMeaning, cancellationToken, sourceFile, checker, program) {
            // For each original symbol, keep all re-exports of that symbol together so we can call `getCodeActionsForImport` on the whole group at once.
            // Maps symbol id to info for modules providing that symbol (original export + re-exports).
            var originalSymbolToExportInfos = ts.createMultiMap();
            function addSymbol(moduleSymbol, exportedSymbol, importKind) {
                originalSymbolToExportInfos.add(ts.getUniqueSymbolId(exportedSymbol, checker).toString(), { moduleSymbol: moduleSymbol, importKind: importKind, exportedSymbolIsTypeOnly: isTypeOnlySymbol(exportedSymbol, checker) });
            }
            forEachExternalModuleToImportFrom(checker, sourceFile, program.getSourceFiles(), function (moduleSymbol) {
                cancellationToken.throwIfCancellationRequested();
                var defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, program.getCompilerOptions());
                if (defaultInfo && defaultInfo.name === symbolName && symbolHasMeaning(defaultInfo.symbolForMeaning, currentTokenMeaning)) {
                    addSymbol(moduleSymbol, defaultInfo.symbol, defaultInfo.kind);
                }
                // check exports with the same name
                var exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExportsAndProperties(symbolName, moduleSymbol);
                if (exportSymbolWithIdenticalName && symbolHasMeaning(exportSymbolWithIdenticalName, currentTokenMeaning)) {
                    addSymbol(moduleSymbol, exportSymbolWithIdenticalName, 0 /* Named */);
                }
            });
            return originalSymbolToExportInfos;
        }
        function getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions) {
            var exported = getDefaultLikeExportWorker(moduleSymbol, checker);
            if (!exported)
                return undefined;
            var symbol = exported.symbol, kind = exported.kind;
            var info = getDefaultExportInfoWorker(symbol, moduleSymbol, checker, compilerOptions);
            return info && __assign({ symbol: symbol, kind: kind }, info);
        }
        function getDefaultLikeExportWorker(moduleSymbol, checker) {
            var defaultExport = checker.tryGetMemberInModuleExports("default" /* Default */, moduleSymbol);
            if (defaultExport)
                return { symbol: defaultExport, kind: 1 /* Default */ };
            var exportEquals = checker.resolveExternalModuleSymbol(moduleSymbol);
            return exportEquals === moduleSymbol ? undefined : { symbol: exportEquals, kind: 3 /* Equals */ };
        }
        function getDefaultExportInfoWorker(defaultExport, moduleSymbol, checker, compilerOptions) {
            var localSymbol = ts.getLocalSymbolForExportDefault(defaultExport);
            if (localSymbol)
                return { symbolForMeaning: localSymbol, name: localSymbol.name };
            var name = getNameForExportDefault(defaultExport);
            if (name !== undefined)
                return { symbolForMeaning: defaultExport, name: name };
            if (defaultExport.flags & 2097152 /* Alias */) {
                var aliased = checker.getImmediateAliasedSymbol(defaultExport);
                return aliased && getDefaultExportInfoWorker(aliased, ts.Debug.assertDefined(aliased.parent), checker, compilerOptions);
            }
            else {
                return { symbolForMeaning: defaultExport, name: moduleSymbolToValidIdentifier(moduleSymbol, compilerOptions.target) };
            }
        }
        function getNameForExportDefault(symbol) {
            return symbol.declarations && ts.firstDefined(symbol.declarations, function (declaration) {
                if (ts.isExportAssignment(declaration)) {
                    if (ts.isIdentifier(declaration.expression)) {
                        return declaration.expression.text;
                    }
                }
                else if (ts.isExportSpecifier(declaration)) {
                    ts.Debug.assert(declaration.name.text === "default" /* Default */);
                    return declaration.propertyName && declaration.propertyName.text;
                }
            });
        }
        function codeActionForFix(context, sourceFile, symbolName, fix, quotePreference) {
            var diag;
            var changes = ts.textChanges.ChangeTracker.with(context, function (tracker) {
                diag = codeActionForFixWorker(tracker, sourceFile, symbolName, fix, quotePreference);
            });
            return codefix.createCodeFixAction("import", changes, diag, codefix.importFixId, ts.Diagnostics.Add_all_missing_imports);
        }
        function codeActionForFixWorker(changes, sourceFile, symbolName, fix, quotePreference) {
            switch (fix.kind) {
                case 0 /* UseNamespace */:
                    addNamespaceQualifier(changes, sourceFile, fix);
                    return [ts.Diagnostics.Change_0_to_1, symbolName, fix.namespacePrefix + "." + symbolName];
                case 1 /* ImportType */:
                    addImportType(changes, sourceFile, fix, quotePreference);
                    return [ts.Diagnostics.Change_0_to_1, symbolName, getImportTypePrefix(fix.moduleSpecifier, quotePreference) + symbolName];
                case 2 /* AddToExisting */: {
                    var importClause = fix.importClause, importKind = fix.importKind;
                    doAddExistingFix(changes, sourceFile, importClause, importKind === 1 /* Default */ ? symbolName : undefined, importKind === 0 /* Named */ ? [symbolName] : ts.emptyArray);
                    var moduleSpecifierWithoutQuotes = ts.stripQuotes(importClause.parent.moduleSpecifier.getText());
                    return [importKind === 1 /* Default */ ? ts.Diagnostics.Add_default_import_0_to_existing_import_declaration_from_1 : ts.Diagnostics.Add_0_to_existing_import_declaration_from_1, symbolName, moduleSpecifierWithoutQuotes]; // you too!
                }
                case 3 /* AddNew */: {
                    var importKind = fix.importKind, moduleSpecifier = fix.moduleSpecifier;
                    addNewImports(changes, sourceFile, moduleSpecifier, quotePreference, importKind === 1 /* Default */ ? { defaultImport: symbolName, namedImports: ts.emptyArray, namespaceLikeImport: undefined }
                        : importKind === 0 /* Named */ ? { defaultImport: undefined, namedImports: [symbolName], namespaceLikeImport: undefined }
                            : { defaultImport: undefined, namedImports: ts.emptyArray, namespaceLikeImport: { importKind: importKind, name: symbolName } });
                    return [importKind === 1 /* Default */ ? ts.Diagnostics.Import_default_0_from_module_1 : ts.Diagnostics.Import_0_from_module_1, symbolName, moduleSpecifier];
                }
                default:
                    return ts.Debug.assertNever(fix);
            }
        }
        function doAddExistingFix(changes, sourceFile, clause, defaultImport, namedImports) {
            if (defaultImport) {
                ts.Debug.assert(!clause.name);
                changes.insertNodeAt(sourceFile, clause.getStart(sourceFile), ts.createIdentifier(defaultImport), { suffix: ", " });
            }
            if (namedImports.length) {
                var specifiers = namedImports.map(function (name) { return ts.createImportSpecifier(/*propertyName*/ undefined, ts.createIdentifier(name)); });
                if (clause.namedBindings && ts.cast(clause.namedBindings, ts.isNamedImports).elements.length) {
                    for (var _i = 0, specifiers_1 = specifiers; _i < specifiers_1.length; _i++) {
                        var spec = specifiers_1[_i];
                        changes.insertNodeInListAfter(sourceFile, ts.last(ts.cast(clause.namedBindings, ts.isNamedImports).elements), spec);
                    }
                }
                else {
                    if (specifiers.length) {
                        var namedImports_1 = ts.createNamedImports(specifiers);
                        if (clause.namedBindings) {
                            changes.replaceNode(sourceFile, clause.namedBindings, namedImports_1);
                        }
                        else {
                            changes.insertNodeAfter(sourceFile, ts.Debug.assertDefined(clause.name), namedImports_1);
                        }
                    }
                }
            }
        }
        function addNamespaceQualifier(changes, sourceFile, _a) {
            var namespacePrefix = _a.namespacePrefix, position = _a.position;
            changes.insertText(sourceFile, position, namespacePrefix + ".");
        }
        function addImportType(changes, sourceFile, _a, quotePreference) {
            var moduleSpecifier = _a.moduleSpecifier, position = _a.position;
            changes.insertText(sourceFile, position, getImportTypePrefix(moduleSpecifier, quotePreference));
        }
        function getImportTypePrefix(moduleSpecifier, quotePreference) {
            var quote = ts.getQuoteFromPreference(quotePreference);
            return "import(" + quote + moduleSpecifier + quote + ").";
        }
        function addNewImports(changes, sourceFile, moduleSpecifier, quotePreference, _a) {
            var defaultImport = _a.defaultImport, namedImports = _a.namedImports, namespaceLikeImport = _a.namespaceLikeImport;
            var quotedModuleSpecifier = ts.makeStringLiteral(moduleSpecifier, quotePreference);
            if (defaultImport !== undefined || namedImports.length) {
                ts.insertImport(changes, sourceFile, ts.makeImport(defaultImport === undefined ? undefined : ts.createIdentifier(defaultImport), namedImports.map(function (n) { return ts.createImportSpecifier(/*propertyName*/ undefined, ts.createIdentifier(n)); }), moduleSpecifier, quotePreference));
            }
            if (namespaceLikeImport) {
                ts.insertImport(changes, sourceFile, namespaceLikeImport.importKind === 3 /* Equals */
                    ? ts.createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, ts.createIdentifier(namespaceLikeImport.name), ts.createExternalModuleReference(quotedModuleSpecifier))
                    : ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(ts.createIdentifier(namespaceLikeImport.name))), quotedModuleSpecifier));
            }
        }
        function symbolHasMeaning(_a, meaning) {
            var declarations = _a.declarations;
            return ts.some(declarations, function (decl) { return !!(ts.getMeaningFromDeclaration(decl) & meaning); });
        }
        function forEachExternalModuleToImportFrom(checker, from, allSourceFiles, cb) {
            forEachExternalModule(checker, allSourceFiles, function (module, sourceFile) {
                if (sourceFile === undefined || sourceFile !== from && isImportablePath(from.fileName, sourceFile.fileName)) {
                    cb(module);
                }
            });
        }
        codefix.forEachExternalModuleToImportFrom = forEachExternalModuleToImportFrom;
        function forEachExternalModule(checker, allSourceFiles, cb) {
            for (var _i = 0, _a = checker.getAmbientModules(); _i < _a.length; _i++) {
                var ambient = _a[_i];
                cb(ambient, /*sourceFile*/ undefined);
            }
            for (var _b = 0, allSourceFiles_1 = allSourceFiles; _b < allSourceFiles_1.length; _b++) {
                var sourceFile = allSourceFiles_1[_b];
                if (ts.isExternalOrCommonJsModule(sourceFile)) {
                    cb(checker.getMergedSymbol(sourceFile.symbol), sourceFile);
                }
            }
        }
        /**
         * Don't include something from a `node_modules` that isn't actually reachable by a global import.
         * A relative import to node_modules is usually a bad idea.
         */
        function isImportablePath(fromPath, toPath) {
            // If it's in a `node_modules` but is not reachable from here via a global import, don't bother.
            var toNodeModules = ts.forEachAncestorDirectory(toPath, function (ancestor) { return ts.getBaseFileName(ancestor) === "node_modules" ? ancestor : undefined; });
            return toNodeModules === undefined || ts.startsWith(fromPath, ts.getDirectoryPath(toNodeModules));
        }
        function moduleSymbolToValidIdentifier(moduleSymbol, target) {
            return moduleSpecifierToValidIdentifier(ts.removeFileExtension(ts.stripQuotes(moduleSymbol.name)), target);
        }
        codefix.moduleSymbolToValidIdentifier = moduleSymbolToValidIdentifier;
        function moduleSpecifierToValidIdentifier(moduleSpecifier, target) {
            var baseName = ts.getBaseFileName(ts.removeSuffix(moduleSpecifier, "/index"));
            var res = "";
            var lastCharWasValid = true;
            var firstCharCode = baseName.charCodeAt(0);
            if (ts.isIdentifierStart(firstCharCode, target)) {
                res += String.fromCharCode(firstCharCode);
            }
            else {
                lastCharWasValid = false;
            }
            for (var i = 1; i < baseName.length; i++) {
                var ch = baseName.charCodeAt(i);
                var isValid = ts.isIdentifierPart(ch, target);
                if (isValid) {
                    var char = String.fromCharCode(ch);
                    if (!lastCharWasValid) {
                        char = char.toUpperCase();
                    }
                    res += char;
                }
                lastCharWasValid = isValid;
            }
            // Need `|| "_"` to ensure result isn't empty.
            return !ts.isStringANonContextualKeyword(res) ? res || "_" : "_" + res;
        }
        codefix.moduleSpecifierToValidIdentifier = moduleSpecifierToValidIdentifier;
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "fixSpelling";
        var errorCodes = [
            ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2.code,
            ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1.code,
            ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code,
            ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0.code,
            ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_2.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var info = getInfo(sourceFile, context.span.start, context);
                if (!info)
                    return undefined;
                var node = info.node, suggestion = info.suggestion;
                var target = context.host.getCompilationSettings().target;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, node, suggestion, target); });
                return [codefix.createCodeFixAction("spelling", changes, [ts.Diagnostics.Change_spelling_to_0, suggestion], fixId, ts.Diagnostics.Fix_all_detected_spelling_errors)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var info = getInfo(diag.file, diag.start, context);
                var target = context.host.getCompilationSettings().target;
                if (info)
                    doChange(changes, context.sourceFile, info.node, info.suggestion, target);
            }); },
        });
        function getInfo(sourceFile, pos, context) {
            // This is the identifier of the misspelled word. eg:
            // this.speling = 1;
            //      ^^^^^^^
            var node = ts.getTokenAtPosition(sourceFile, pos);
            var checker = context.program.getTypeChecker();
            var suggestion;
            if (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) {
                ts.Debug.assert(node.kind === 73 /* Identifier */);
                var containingType = checker.getTypeAtLocation(node.parent.expression);
                suggestion = checker.getSuggestionForNonexistentProperty(node, containingType);
            }
            else if (ts.isImportSpecifier(node.parent) && node.parent.name === node) {
                ts.Debug.assert(node.kind === 73 /* Identifier */);
                var importDeclaration = ts.findAncestor(node, ts.isImportDeclaration);
                var resolvedSourceFile = getResolvedSourceFileFromImportDeclaration(sourceFile, context, importDeclaration);
                if (resolvedSourceFile && resolvedSourceFile.symbol) {
                    suggestion = checker.getSuggestionForNonexistentExport(node, resolvedSourceFile.symbol);
                }
            }
            else {
                var meaning = ts.getMeaningFromLocation(node);
                var name = ts.getTextOfNode(node);
                ts.Debug.assert(name !== undefined, "name should be defined");
                suggestion = checker.getSuggestionForNonexistentSymbol(node, name, convertSemanticMeaningToSymbolFlags(meaning));
            }
            return suggestion === undefined ? undefined : { node: node, suggestion: suggestion };
        }
        function doChange(changes, sourceFile, node, suggestion, target) {
            if (!ts.isIdentifierText(suggestion, target) && ts.isPropertyAccessExpression(node.parent)) {
                changes.replaceNode(sourceFile, node.parent, ts.createElementAccess(node.parent.expression, ts.createLiteral(suggestion)));
            }
            else {
                changes.replaceNode(sourceFile, node, ts.createIdentifier(suggestion));
            }
        }
        function convertSemanticMeaningToSymbolFlags(meaning) {
            var flags = 0;
            if (meaning & 4 /* Namespace */) {
                flags |= 1920 /* Namespace */;
            }
            if (meaning & 2 /* Type */) {
                flags |= 67897832 /* Type */;
            }
            if (meaning & 1 /* Value */) {
                flags |= 67220415 /* Value */;
            }
            return flags;
        }
        function getResolvedSourceFileFromImportDeclaration(sourceFile, context, importDeclaration) {
            if (!importDeclaration || !ts.isStringLiteralLike(importDeclaration.moduleSpecifier))
                return undefined;
            var resolvedModule = ts.getResolvedModule(sourceFile, importDeclaration.moduleSpecifier.text);
            if (!resolvedModule)
                return undefined;
            return context.program.getSourceFile(resolvedModule.resolvedFileName);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixName = "addMissingMember";
        var errorCodes = [
            ts.Diagnostics.Property_0_does_not_exist_on_type_1.code,
            ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2.code,
            ts.Diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2.code,
            ts.Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2.code,
            ts.Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more.code
        ];
        var fixId = "addMissingMember";
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var info = getInfo(context.sourceFile, context.span.start, context.program.getTypeChecker(), context.program);
                if (!info)
                    return undefined;
                if (info.kind === 0 /* Enum */) {
                    var token_1 = info.token, parentDeclaration_1 = info.parentDeclaration;
                    var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addEnumMemberDeclaration(t, context.program.getTypeChecker(), token_1, parentDeclaration_1); });
                    return [codefix.createCodeFixAction(fixName, changes, [ts.Diagnostics.Add_missing_enum_member_0, token_1.text], fixId, ts.Diagnostics.Add_all_missing_members)];
                }
                var parentDeclaration = info.parentDeclaration, declSourceFile = info.declSourceFile, inJs = info.inJs, makeStatic = info.makeStatic, token = info.token, call = info.call;
                var methodCodeAction = call && getActionForMethodDeclaration(context, declSourceFile, parentDeclaration, token, call, makeStatic, inJs, context.preferences);
                var addMember = inJs && !ts.isInterfaceDeclaration(parentDeclaration) ?
                    ts.singleElementArray(getActionsForAddMissingMemberInJavascriptFile(context, declSourceFile, parentDeclaration, token.text, makeStatic)) :
                    getActionsForAddMissingMemberInTypeScriptFile(context, declSourceFile, parentDeclaration, token, makeStatic);
                return ts.concatenate(ts.singleElementArray(methodCodeAction), addMember);
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var program = context.program, preferences = context.preferences;
                var checker = program.getTypeChecker();
                var seen = ts.createMap();
                var typeDeclToMembers = new ts.NodeMap();
                return codefix.createCombinedCodeActions(ts.textChanges.ChangeTracker.with(context, function (changes) {
                    codefix.eachDiagnostic(context, errorCodes, function (diag) {
                        var info = getInfo(diag.file, diag.start, checker, context.program);
                        if (!info || !ts.addToSeen(seen, ts.getNodeId(info.parentDeclaration) + "#" + info.token.text)) {
                            return;
                        }
                        if (info.kind === 0 /* Enum */) {
                            var token = info.token, parentDeclaration = info.parentDeclaration;
                            addEnumMemberDeclaration(changes, checker, token, parentDeclaration);
                        }
                        else {
                            var parentDeclaration = info.parentDeclaration, token_2 = info.token;
                            var infos = typeDeclToMembers.getOrUpdate(parentDeclaration, function () { return []; });
                            if (!infos.some(function (i) { return i.token.text === token_2.text; }))
                                infos.push(info);
                        }
                    });
                    typeDeclToMembers.forEach(function (infos, classDeclaration) {
                        var supers = getAllSupers(classDeclaration, checker);
                        var _loop_12 = function (info) {
                            // If some superclass added this property, don't add it again.
                            if (supers.some(function (superClassOrInterface) {
                                var superInfos = typeDeclToMembers.get(superClassOrInterface);
                                return !!superInfos && superInfos.some(function (_a) {
                                    var token = _a.token;
                                    return token.text === info.token.text;
                                });
                            }))
                                return "continue";
                            var parentDeclaration = info.parentDeclaration, declSourceFile = info.declSourceFile, inJs = info.inJs, makeStatic = info.makeStatic, token = info.token, call = info.call;
                            // Always prefer to add a method declaration if possible.
                            if (call) {
                                addMethodDeclaration(context, changes, declSourceFile, parentDeclaration, token, call, makeStatic, inJs, preferences);
                            }
                            else {
                                if (inJs && !ts.isInterfaceDeclaration(parentDeclaration)) {
                                    addMissingMemberInJs(changes, declSourceFile, parentDeclaration, token.text, makeStatic);
                                }
                                else {
                                    var typeNode = getTypeNode(program.getTypeChecker(), parentDeclaration, token);
                                    addPropertyDeclaration(changes, declSourceFile, parentDeclaration, token.text, typeNode, makeStatic);
                                }
                            }
                        };
                        for (var _i = 0, infos_1 = infos; _i < infos_1.length; _i++) {
                            var info = infos_1[_i];
                            _loop_12(info);
                        }
                    });
                }));
            },
        });
        function getAllSupers(decl, checker) {
            var res = [];
            while (decl) {
                var superElement = ts.getClassExtendsHeritageElement(decl);
                var superSymbol = superElement && checker.getSymbolAtLocation(superElement.expression);
                var superDecl = superSymbol && ts.find(superSymbol.declarations, ts.isClassLike);
                if (superDecl) {
                    res.push(superDecl);
                }
                decl = superDecl;
            }
            return res;
        }
        var InfoKind;
        (function (InfoKind) {
            InfoKind[InfoKind["Enum"] = 0] = "Enum";
            InfoKind[InfoKind["ClassOrInterface"] = 1] = "ClassOrInterface";
        })(InfoKind || (InfoKind = {}));
        function getInfo(tokenSourceFile, tokenPos, checker, program) {
            // The identifier of the missing property. eg:
            // this.missing = 1;
            //      ^^^^^^^
            var token = ts.getTokenAtPosition(tokenSourceFile, tokenPos);
            if (!ts.isIdentifier(token)) {
                return undefined;
            }
            var parent = token.parent;
            if (!ts.isPropertyAccessExpression(parent))
                return undefined;
            var leftExpressionType = ts.skipConstraint(checker.getTypeAtLocation(parent.expression));
            var symbol = leftExpressionType.symbol;
            if (!symbol || !symbol.declarations)
                return undefined;
            // Prefer to change the class instead of the interface if they are merged
            var classOrInterface = ts.find(symbol.declarations, ts.isClassLike) || ts.find(symbol.declarations, ts.isInterfaceDeclaration);
            if (classOrInterface && !program.isSourceFileFromExternalLibrary(classOrInterface.getSourceFile())) {
                var makeStatic = (leftExpressionType.target || leftExpressionType) !== checker.getDeclaredTypeOfSymbol(symbol);
                var declSourceFile = classOrInterface.getSourceFile();
                var inJs = ts.isSourceFileJS(declSourceFile);
                var call = ts.tryCast(parent.parent, ts.isCallExpression);
                return { kind: 1 /* ClassOrInterface */, token: token, parentDeclaration: classOrInterface, makeStatic: makeStatic, declSourceFile: declSourceFile, inJs: inJs, call: call };
            }
            var enumDeclaration = ts.find(symbol.declarations, ts.isEnumDeclaration);
            if (enumDeclaration && !program.isSourceFileFromExternalLibrary(enumDeclaration.getSourceFile())) {
                return { kind: 0 /* Enum */, token: token, parentDeclaration: enumDeclaration };
            }
            return undefined;
        }
        function getActionsForAddMissingMemberInJavascriptFile(context, declSourceFile, classDeclaration, tokenName, makeStatic) {
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addMissingMemberInJs(t, declSourceFile, classDeclaration, tokenName, makeStatic); });
            return changes.length === 0 ? undefined
                : codefix.createCodeFixAction(fixName, changes, [makeStatic ? ts.Diagnostics.Initialize_static_property_0 : ts.Diagnostics.Initialize_property_0_in_the_constructor, tokenName], fixId, ts.Diagnostics.Add_all_missing_members);
        }
        function addMissingMemberInJs(changeTracker, declSourceFile, classDeclaration, tokenName, makeStatic) {
            if (makeStatic) {
                if (classDeclaration.kind === 210 /* ClassExpression */) {
                    return;
                }
                var className = classDeclaration.name.getText();
                var staticInitialization = initializePropertyToUndefined(ts.createIdentifier(className), tokenName);
                changeTracker.insertNodeAfter(declSourceFile, classDeclaration, staticInitialization);
            }
            else {
                var classConstructor = ts.getFirstConstructorWithBody(classDeclaration);
                if (!classConstructor) {
                    return;
                }
                var propertyInitialization = initializePropertyToUndefined(ts.createThis(), tokenName);
                changeTracker.insertNodeAtConstructorEnd(declSourceFile, classConstructor, propertyInitialization);
            }
        }
        function initializePropertyToUndefined(obj, propertyName) {
            return ts.createStatement(ts.createAssignment(ts.createPropertyAccess(obj, propertyName), ts.createIdentifier("undefined")));
        }
        function getActionsForAddMissingMemberInTypeScriptFile(context, declSourceFile, classDeclaration, token, makeStatic) {
            var typeNode = getTypeNode(context.program.getTypeChecker(), classDeclaration, token);
            var addProp = createAddPropertyDeclarationAction(context, declSourceFile, classDeclaration, makeStatic, token.text, typeNode);
            return makeStatic ? [addProp] : [addProp, createAddIndexSignatureAction(context, declSourceFile, classDeclaration, token.text, typeNode)];
        }
        function getTypeNode(checker, classDeclaration, token) {
            var typeNode;
            if (token.parent.parent.kind === 205 /* BinaryExpression */) {
                var binaryExpression = token.parent.parent;
                var otherExpression = token.parent === binaryExpression.left ? binaryExpression.right : binaryExpression.left;
                var widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(otherExpression)));
                typeNode = checker.typeToTypeNode(widenedType, classDeclaration);
            }
            else {
                var contextualType = checker.getContextualType(token.parent);
                typeNode = contextualType ? checker.typeToTypeNode(contextualType) : undefined;
            }
            return typeNode || ts.createKeywordTypeNode(121 /* AnyKeyword */);
        }
        function createAddPropertyDeclarationAction(context, declSourceFile, classDeclaration, makeStatic, tokenName, typeNode) {
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addPropertyDeclaration(t, declSourceFile, classDeclaration, tokenName, typeNode, makeStatic); });
            return codefix.createCodeFixAction(fixName, changes, [makeStatic ? ts.Diagnostics.Declare_static_property_0 : ts.Diagnostics.Declare_property_0, tokenName], fixId, ts.Diagnostics.Add_all_missing_members);
        }
        function addPropertyDeclaration(changeTracker, declSourceFile, classDeclaration, tokenName, typeNode, makeStatic) {
            var property = ts.createProperty(
            /*decorators*/ undefined, 
            /*modifiers*/ makeStatic ? [ts.createToken(117 /* StaticKeyword */)] : undefined, tokenName, 
            /*questionToken*/ undefined, typeNode, 
            /*initializer*/ undefined);
            var lastProp = getNodeToInsertPropertyAfter(classDeclaration);
            if (lastProp) {
                changeTracker.insertNodeAfter(declSourceFile, lastProp, property);
            }
            else {
                changeTracker.insertNodeAtClassStart(declSourceFile, classDeclaration, property);
            }
        }
        // Gets the last of the first run of PropertyDeclarations, or undefined if the class does not start with a PropertyDeclaration.
        function getNodeToInsertPropertyAfter(cls) {
            var res;
            for (var _i = 0, _a = cls.members; _i < _a.length; _i++) {
                var member = _a[_i];
                if (!ts.isPropertyDeclaration(member))
                    break;
                res = member;
            }
            return res;
        }
        function createAddIndexSignatureAction(context, declSourceFile, classDeclaration, tokenName, typeNode) {
            // Index signatures cannot have the static modifier.
            var stringTypeNode = ts.createKeywordTypeNode(139 /* StringKeyword */);
            var indexingParameter = ts.createParameter(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, 
            /*dotDotDotToken*/ undefined, "x", 
            /*questionToken*/ undefined, stringTypeNode, 
            /*initializer*/ undefined);
            var indexSignature = ts.createIndexSignature(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, [indexingParameter], typeNode);
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.insertNodeAtClassStart(declSourceFile, classDeclaration, indexSignature); });
            // No fixId here because code-fix-all currently only works on adding individual named properties.
            return codefix.createCodeFixActionNoFixId(fixName, changes, [ts.Diagnostics.Add_index_signature_for_property_0, tokenName]);
        }
        function getActionForMethodDeclaration(context, declSourceFile, classDeclaration, token, callExpression, makeStatic, inJs, preferences) {
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addMethodDeclaration(context, t, declSourceFile, classDeclaration, token, callExpression, makeStatic, inJs, preferences); });
            return codefix.createCodeFixAction(fixName, changes, [makeStatic ? ts.Diagnostics.Declare_static_method_0 : ts.Diagnostics.Declare_method_0, token.text], fixId, ts.Diagnostics.Add_all_missing_members);
        }
        function addMethodDeclaration(context, changeTracker, declSourceFile, typeDecl, token, callExpression, makeStatic, inJs, preferences) {
            var methodDeclaration = codefix.createMethodFromCallExpression(context, callExpression, token.text, inJs, makeStatic, preferences, typeDecl);
            var containingMethodDeclaration = ts.getAncestor(callExpression, 157 /* MethodDeclaration */);
            if (containingMethodDeclaration && containingMethodDeclaration.parent === typeDecl) {
                changeTracker.insertNodeAfter(declSourceFile, containingMethodDeclaration, methodDeclaration);
            }
            else {
                changeTracker.insertNodeAtClassStart(declSourceFile, typeDecl, methodDeclaration);
            }
        }
        function addEnumMemberDeclaration(changes, checker, token, enumDeclaration) {
            /**
             * create initializer only literal enum that has string initializer.
             * value of initializer is a string literal that equal to name of enum member.
             * numeric enum or empty enum will not create initializer.
             */
            var hasStringInitializer = ts.some(enumDeclaration.members, function (member) {
                var type = checker.getTypeAtLocation(member);
                return !!(type && type.flags & 132 /* StringLike */);
            });
            var enumMember = ts.createEnumMember(token, hasStringInitializer ? ts.createStringLiteral(token.text) : undefined);
            changes.replaceNode(enumDeclaration.getSourceFile(), enumDeclaration, ts.updateEnumDeclaration(enumDeclaration, enumDeclaration.decorators, enumDeclaration.modifiers, enumDeclaration.name, ts.concatenate(enumDeclaration.members, ts.singleElementArray(enumMember))));
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "addMissingNewOperator";
        var errorCodes = [ts.Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addMissingNewOperator(t, sourceFile, span); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_missing_new_operator_to_call, fixId, ts.Diagnostics.Add_missing_new_operator_to_all_calls)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                return addMissingNewOperator(changes, context.sourceFile, diag);
            }); },
        });
        function addMissingNewOperator(changes, sourceFile, span) {
            var call = ts.cast(findAncestorMatchingSpan(sourceFile, span), ts.isCallExpression);
            var newExpression = ts.createNew(call.expression, call.typeArguments, call.arguments);
            changes.replaceNode(sourceFile, call, newExpression);
        }
        function findAncestorMatchingSpan(sourceFile, span) {
            var token = ts.getTokenAtPosition(sourceFile, span.start);
            var end = ts.textSpanEnd(span);
            while (token.end < end) {
                token = token.parent;
            }
            return token;
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixName = "fixCannotFindModule";
        var fixIdInstallTypesPackage = "installTypesPackage";
        var errorCodeCannotFindModule = ts.Diagnostics.Cannot_find_module_0.code;
        var errorCodes = [
            errorCodeCannotFindModule,
            ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var host = context.host, sourceFile = context.sourceFile, start = context.span.start;
                var packageName = tryGetImportedPackageName(sourceFile, start);
                if (packageName === undefined)
                    return undefined;
                var typesPackageName = getTypesPackageNameToInstall(packageName, host, context.errorCode);
                return typesPackageName === undefined
                    ? []
                    : [codefix.createCodeFixAction(fixName, /*changes*/ [], [ts.Diagnostics.Install_0, typesPackageName], fixIdInstallTypesPackage, ts.Diagnostics.Install_all_missing_types_packages, getInstallCommand(sourceFile.fileName, typesPackageName))];
            },
            fixIds: [fixIdInstallTypesPackage],
            getAllCodeActions: function (context) {
                return codefix.codeFixAll(context, errorCodes, function (_changes, diag, commands) {
                    var packageName = tryGetImportedPackageName(diag.file, diag.start);
                    if (packageName === undefined)
                        return undefined;
                    switch (context.fixId) {
                        case fixIdInstallTypesPackage: {
                            var pkg = getTypesPackageNameToInstall(packageName, context.host, diag.code);
                            if (pkg) {
                                commands.push(getInstallCommand(diag.file.fileName, pkg));
                            }
                            break;
                        }
                        default:
                            ts.Debug.fail("Bad fixId: " + context.fixId);
                    }
                });
            },
        });
        function getInstallCommand(fileName, packageName) {
            return { type: "install package", file: fileName, packageName: packageName };
        }
        function tryGetImportedPackageName(sourceFile, pos) {
            var moduleName = ts.cast(ts.getTokenAtPosition(sourceFile, pos), ts.isStringLiteral).text;
            var packageName = ts.parsePackageName(moduleName).packageName;
            return ts.isExternalModuleNameRelative(packageName) ? undefined : packageName;
        }
        function getTypesPackageNameToInstall(packageName, host, diagCode) {
            return diagCode === errorCodeCannotFindModule
                ? (ts.JsTyping.nodeCoreModules.has(packageName) ? "@types/node" : undefined)
                : (host.isKnownTypesPackageName(packageName) ? ts.getTypesPackageName(packageName) : undefined); // TODO: GH#18217
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var errorCodes = [
            ts.Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2.code,
            ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1.code,
        ];
        var fixId = "fixClassDoesntImplementInheritedAbstractMember";
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) {
                    return addMissingMembers(getClass(sourceFile, span.start), sourceFile, context, t, context.preferences);
                });
                return changes.length === 0 ? undefined : [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Implement_inherited_abstract_class, fixId, ts.Diagnostics.Implement_all_inherited_abstract_classes)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var seenClassDeclarations = ts.createMap();
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                    var classDeclaration = getClass(diag.file, diag.start);
                    if (ts.addToSeen(seenClassDeclarations, ts.getNodeId(classDeclaration))) {
                        addMissingMembers(classDeclaration, context.sourceFile, context, changes, context.preferences);
                    }
                });
            },
        });
        function getClass(sourceFile, pos) {
            // Token is the identifier in the case of a class declaration
            // or the class keyword token in the case of a class expression.
            var token = ts.getTokenAtPosition(sourceFile, pos);
            return ts.cast(token.parent, ts.isClassLike);
        }
        function addMissingMembers(classDeclaration, sourceFile, context, changeTracker, preferences) {
            var extendsNode = ts.getEffectiveBaseTypeNode(classDeclaration);
            var checker = context.program.getTypeChecker();
            var instantiatedExtendsType = checker.getTypeAtLocation(extendsNode);
            // Note that this is ultimately derived from a map indexed by symbol names,
            // so duplicates cannot occur.
            var abstractAndNonPrivateExtendsSymbols = checker.getPropertiesOfType(instantiatedExtendsType).filter(symbolPointsToNonPrivateAndAbstractMember);
            codefix.createMissingMemberNodes(classDeclaration, abstractAndNonPrivateExtendsSymbols, context, preferences, function (member) { return changeTracker.insertNodeAtClassStart(sourceFile, classDeclaration, member); });
        }
        function symbolPointsToNonPrivateAndAbstractMember(symbol) {
            // See `codeFixClassExtendAbstractProtectedProperty.ts` in https://github.com/Microsoft/TypeScript/pull/11547/files
            // (now named `codeFixClassExtendAbstractPrivateProperty.ts`)
            var flags = ts.getModifierFlags(ts.first(symbol.getDeclarations()));
            return !(flags & 8 /* Private */) && !!(flags & 128 /* Abstract */);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "classSuperMustPrecedeThisAccess";
        var errorCodes = [ts.Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var nodes = getNodes(sourceFile, span.start);
                if (!nodes)
                    return undefined;
                var constructor = nodes.constructor, superCall = nodes.superCall;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, constructor, superCall); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Make_super_call_the_first_statement_in_the_constructor, fixId, ts.Diagnostics.Make_all_super_calls_the_first_statement_in_their_constructor)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var seenClasses = ts.createMap(); // Ensure we only do this once per class.
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                    var nodes = getNodes(diag.file, diag.start);
                    if (!nodes)
                        return;
                    var constructor = nodes.constructor, superCall = nodes.superCall;
                    if (ts.addToSeen(seenClasses, ts.getNodeId(constructor.parent))) {
                        doChange(changes, sourceFile, constructor, superCall);
                    }
                });
            },
        });
        function doChange(changes, sourceFile, constructor, superCall) {
            changes.insertNodeAtConstructorStart(sourceFile, constructor, superCall);
            changes.delete(sourceFile, superCall);
        }
        function getNodes(sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            if (token.kind !== 101 /* ThisKeyword */)
                return undefined;
            var constructor = ts.getContainingFunction(token);
            var superCall = findSuperCall(constructor.body);
            // figure out if the `this` access is actually inside the supercall
            // i.e. super(this.a), since in that case we won't suggest a fix
            return superCall && !superCall.expression.arguments.some(function (arg) { return ts.isPropertyAccessExpression(arg) && arg.expression === token; }) ? { constructor: constructor, superCall: superCall } : undefined;
        }
        function findSuperCall(n) {
            return ts.isExpressionStatement(n) && ts.isSuperCall(n.expression)
                ? n
                : ts.isFunctionLike(n)
                    ? undefined
                    : ts.forEachChild(n, findSuperCall);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "constructorForDerivedNeedSuperCall";
        var errorCodes = [ts.Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var ctr = getNode(sourceFile, span.start);
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, ctr); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_missing_super_call, fixId, ts.Diagnostics.Add_all_missing_super_calls)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                return doChange(changes, context.sourceFile, getNode(diag.file, diag.start));
            }); },
        });
        function getNode(sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            ts.Debug.assert(token.kind === 125 /* ConstructorKeyword */);
            return token.parent;
        }
        function doChange(changes, sourceFile, ctr) {
            var superCall = ts.createStatement(ts.createCall(ts.createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ ts.emptyArray));
            changes.insertNodeAtConstructorStart(sourceFile, ctr, superCall);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "enableExperimentalDecorators";
        var errorCodes = [
            ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning.code
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var configFile = context.program.getCompilerOptions().configFile;
                if (configFile === undefined) {
                    return undefined;
                }
                var changes = ts.textChanges.ChangeTracker.with(context, function (changeTracker) { return doChange(changeTracker, configFile); });
                return [codefix.createCodeFixActionNoFixId(fixId, changes, ts.Diagnostics.Enable_the_experimentalDecorators_option_in_your_configuration_file)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes) {
                var configFile = context.program.getCompilerOptions().configFile;
                if (configFile === undefined) {
                    return undefined;
                }
                doChange(changes, configFile);
            }); },
        });
        function doChange(changeTracker, configFile) {
            codefix.setJsonCompilerOptionValue(changeTracker, configFile, "experimentalDecorators", ts.createTrue());
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "extendsInterfaceBecomesImplements";
        var errorCodes = [ts.Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var nodes = getNodes(sourceFile, context.span.start);
                if (!nodes)
                    return undefined;
                var extendsToken = nodes.extendsToken, heritageClauses = nodes.heritageClauses;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChanges(t, sourceFile, extendsToken, heritageClauses); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Change_extends_to_implements, fixId, ts.Diagnostics.Change_all_extended_interfaces_to_implements)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var nodes = getNodes(diag.file, diag.start);
                if (nodes)
                    doChanges(changes, diag.file, nodes.extendsToken, nodes.heritageClauses);
            }); },
        });
        function getNodes(sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            var heritageClauses = ts.getContainingClass(token).heritageClauses;
            var extendsToken = heritageClauses[0].getFirstToken();
            return extendsToken.kind === 87 /* ExtendsKeyword */ ? { extendsToken: extendsToken, heritageClauses: heritageClauses } : undefined;
        }
        function doChanges(changes, sourceFile, extendsToken, heritageClauses) {
            changes.replaceNode(sourceFile, extendsToken, ts.createToken(110 /* ImplementsKeyword */));
            // If there is already an implements clause, replace the implements keyword with a comma.
            if (heritageClauses.length === 2 &&
                heritageClauses[0].token === 87 /* ExtendsKeyword */ &&
                heritageClauses[1].token === 110 /* ImplementsKeyword */) {
                var implementsToken = heritageClauses[1].getFirstToken();
                var implementsFullStart = implementsToken.getFullStart();
                changes.replaceRange(sourceFile, { pos: implementsFullStart, end: implementsFullStart }, ts.createToken(27 /* CommaToken */));
                // Rough heuristic: delete trailing whitespace after keyword so that it's not excessive.
                // (Trailing because leading might be indentation, which is more sensitive.)
                var text = sourceFile.text;
                var end = implementsToken.end;
                while (end < text.length && ts.isWhiteSpaceSingleLine(text.charCodeAt(end))) {
                    end++;
                }
                changes.deleteRange(sourceFile, { pos: implementsToken.getStart(), end: end });
            }
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "forgottenThisPropertyAccess";
        var didYouMeanStaticMemberCode = ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0.code;
        var errorCodes = [
            ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code,
            didYouMeanStaticMemberCode,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var info = getInfo(sourceFile, context.span.start, context.errorCode);
                if (!info) {
                    return undefined;
                }
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, info); });
                return [codefix.createCodeFixAction(fixId, changes, [ts.Diagnostics.Add_0_to_unresolved_variable, info.className || "this"], fixId, ts.Diagnostics.Add_qualifier_to_all_unresolved_variables_matching_a_member_name)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var info = getInfo(diag.file, diag.start, diag.code);
                if (info)
                    doChange(changes, context.sourceFile, info);
            }); },
        });
        function getInfo(sourceFile, pos, diagCode) {
            var node = ts.getTokenAtPosition(sourceFile, pos);
            if (!ts.isIdentifier(node))
                return undefined;
            return { node: node, className: diagCode === didYouMeanStaticMemberCode ? ts.getContainingClass(node).name.text : undefined };
        }
        function doChange(changes, sourceFile, _a) {
            var node = _a.node, className = _a.className;
            // TODO (https://github.com/Microsoft/TypeScript/issues/21246): use shared helper
            ts.suppressLeadingAndTrailingTrivia(node);
            changes.replaceNode(sourceFile, node, ts.createPropertyAccess(className ? ts.createIdentifier(className) : ts.createThis(), node));
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixName = "unusedIdentifier";
        var fixIdPrefix = "unusedIdentifier_prefix";
        var fixIdDelete = "unusedIdentifier_delete";
        var fixIdInfer = "unusedIdentifier_infer";
        var errorCodes = [
            ts.Diagnostics._0_is_declared_but_its_value_is_never_read.code,
            ts.Diagnostics._0_is_declared_but_never_used.code,
            ts.Diagnostics.Property_0_is_declared_but_its_value_is_never_read.code,
            ts.Diagnostics.All_imports_in_import_declaration_are_unused.code,
            ts.Diagnostics.All_destructured_elements_are_unused.code,
            ts.Diagnostics.All_variables_are_unused.code,
            ts.Diagnostics.All_type_parameters_are_unused.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var errorCode = context.errorCode, sourceFile = context.sourceFile, program = context.program;
                var checker = program.getTypeChecker();
                var sourceFiles = program.getSourceFiles();
                var token = ts.getTokenAtPosition(sourceFile, context.span.start);
                if (ts.isJSDocTemplateTag(token)) {
                    return [createDeleteFix(ts.textChanges.ChangeTracker.with(context, function (t) { return t.delete(sourceFile, token); }), ts.Diagnostics.Remove_template_tag)];
                }
                if (token.kind === 28 /* LessThanToken */) {
                    var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return deleteTypeParameters(t, sourceFile, token); });
                    return [createDeleteFix(changes, ts.Diagnostics.Remove_type_parameters)];
                }
                var importDecl = tryGetFullImport(token);
                if (importDecl) {
                    var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.delete(sourceFile, importDecl); });
                    return [createDeleteFix(changes, [ts.Diagnostics.Remove_import_from_0, ts.showModuleSpecifier(importDecl)])];
                }
                var delDestructure = ts.textChanges.ChangeTracker.with(context, function (t) {
                    return tryDeleteFullDestructure(token, t, sourceFile, checker, sourceFiles, /*isFixAll*/ false);
                });
                if (delDestructure.length) {
                    return [createDeleteFix(delDestructure, ts.Diagnostics.Remove_destructuring)];
                }
                var delVar = ts.textChanges.ChangeTracker.with(context, function (t) { return tryDeleteFullVariableStatement(sourceFile, token, t); });
                if (delVar.length) {
                    return [createDeleteFix(delVar, ts.Diagnostics.Remove_variable_statement)];
                }
                var result = [];
                if (token.kind === 128 /* InferKeyword */) {
                    var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return changeInferToUnknown(t, sourceFile, token); });
                    var name = ts.cast(token.parent, ts.isInferTypeNode).typeParameter.name.text;
                    result.push(codefix.createCodeFixAction(fixName, changes, [ts.Diagnostics.Replace_infer_0_with_unknown, name], fixIdInfer, ts.Diagnostics.Replace_all_unused_infer_with_unknown));
                }
                else {
                    var deletion = ts.textChanges.ChangeTracker.with(context, function (t) {
                        return tryDeleteDeclaration(sourceFile, token, t, checker, sourceFiles, /*isFixAll*/ false);
                    });
                    if (deletion.length) {
                        var name = ts.isComputedPropertyName(token.parent) ? token.parent : token;
                        result.push(createDeleteFix(deletion, [ts.Diagnostics.Remove_declaration_for_Colon_0, name.getText(sourceFile)]));
                    }
                }
                var prefix = ts.textChanges.ChangeTracker.with(context, function (t) { return tryPrefixDeclaration(t, errorCode, sourceFile, token); });
                if (prefix.length) {
                    result.push(codefix.createCodeFixAction(fixName, prefix, [ts.Diagnostics.Prefix_0_with_an_underscore, token.getText(sourceFile)], fixIdPrefix, ts.Diagnostics.Prefix_all_unused_declarations_with_where_possible));
                }
                return result;
            },
            fixIds: [fixIdPrefix, fixIdDelete, fixIdInfer],
            getAllCodeActions: function (context) {
                var sourceFile = context.sourceFile, program = context.program;
                var checker = program.getTypeChecker();
                var sourceFiles = program.getSourceFiles();
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                    var token = ts.getTokenAtPosition(sourceFile, diag.start);
                    switch (context.fixId) {
                        case fixIdPrefix:
                            tryPrefixDeclaration(changes, diag.code, sourceFile, token);
                            break;
                        case fixIdDelete: {
                            if (token.kind === 128 /* InferKeyword */)
                                break; // Can't delete
                            var importDecl = tryGetFullImport(token);
                            if (importDecl) {
                                changes.delete(sourceFile, importDecl);
                            }
                            else if (ts.isJSDocTemplateTag(token)) {
                                changes.delete(sourceFile, token);
                            }
                            else if (token.kind === 28 /* LessThanToken */) {
                                deleteTypeParameters(changes, sourceFile, token);
                            }
                            else if (!tryDeleteFullDestructure(token, changes, sourceFile, checker, sourceFiles, /*isFixAll*/ true) &&
                                !tryDeleteFullVariableStatement(sourceFile, token, changes)) {
                                tryDeleteDeclaration(sourceFile, token, changes, checker, sourceFiles, /*isFixAll*/ true);
                            }
                            break;
                        }
                        case fixIdInfer:
                            if (token.kind === 128 /* InferKeyword */) {
                                changeInferToUnknown(changes, sourceFile, token);
                            }
                            break;
                        default:
                            ts.Debug.fail(JSON.stringify(context.fixId));
                    }
                });
            },
        });
        function changeInferToUnknown(changes, sourceFile, token) {
            changes.replaceNode(sourceFile, token.parent, ts.createKeywordTypeNode(144 /* UnknownKeyword */));
        }
        function createDeleteFix(changes, diag) {
            return codefix.createCodeFixAction(fixName, changes, diag, fixIdDelete, ts.Diagnostics.Delete_all_unused_declarations);
        }
        function deleteTypeParameters(changes, sourceFile, token) {
            changes.delete(sourceFile, ts.Debug.assertDefined(ts.cast(token.parent, ts.isDeclarationWithTypeParameterChildren).typeParameters));
        }
        // Sometimes the diagnostic span is an entire ImportDeclaration, so we should remove the whole thing.
        function tryGetFullImport(token) {
            return token.kind === 93 /* ImportKeyword */ ? ts.tryCast(token.parent, ts.isImportDeclaration) : undefined;
        }
        function tryDeleteFullDestructure(token, changes, sourceFile, checker, sourceFiles, isFixAll) {
            if (token.kind !== 18 /* OpenBraceToken */ || !ts.isObjectBindingPattern(token.parent))
                return false;
            var decl = token.parent.parent;
            if (decl.kind === 152 /* Parameter */) {
                tryDeleteParameter(changes, sourceFile, decl, checker, sourceFiles, isFixAll);
            }
            else {
                changes.delete(sourceFile, decl);
            }
            return true;
        }
        function tryDeleteFullVariableStatement(sourceFile, token, changes) {
            var declarationList = ts.tryCast(token.parent, ts.isVariableDeclarationList);
            if (declarationList && declarationList.getChildren(sourceFile)[0] === token) {
                changes.delete(sourceFile, declarationList.parent.kind === 220 /* VariableStatement */ ? declarationList.parent : declarationList);
                return true;
            }
            return false;
        }
        function tryPrefixDeclaration(changes, errorCode, sourceFile, token) {
            // Don't offer to prefix a property.
            if (errorCode === ts.Diagnostics.Property_0_is_declared_but_its_value_is_never_read.code)
                return;
            if (token.kind === 128 /* InferKeyword */) {
                token = ts.cast(token.parent, ts.isInferTypeNode).typeParameter.name;
            }
            if (ts.isIdentifier(token) && canPrefix(token)) {
                changes.replaceNode(sourceFile, token, ts.createIdentifier("_" + token.text));
            }
        }
        function canPrefix(token) {
            switch (token.parent.kind) {
                case 152 /* Parameter */:
                case 151 /* TypeParameter */:
                    return true;
                case 238 /* VariableDeclaration */: {
                    var varDecl = token.parent;
                    switch (varDecl.parent.parent.kind) {
                        case 228 /* ForOfStatement */:
                        case 227 /* ForInStatement */:
                            return true;
                    }
                }
            }
            return false;
        }
        function tryDeleteDeclaration(sourceFile, token, changes, checker, sourceFiles, isFixAll) {
            tryDeleteDeclarationWorker(token, changes, sourceFile, checker, sourceFiles, isFixAll);
            if (ts.isIdentifier(token))
                deleteAssignments(changes, sourceFile, token, checker);
        }
        function deleteAssignments(changes, sourceFile, token, checker) {
            ts.FindAllReferences.Core.eachSymbolReferenceInFile(token, checker, sourceFile, function (ref) {
                if (ts.isPropertyAccessExpression(ref.parent) && ref.parent.name === ref)
                    ref = ref.parent;
                if (ts.isBinaryExpression(ref.parent) && ts.isExpressionStatement(ref.parent.parent) && ref.parent.left === ref) {
                    changes.delete(sourceFile, ref.parent.parent);
                }
            });
        }
        function tryDeleteDeclarationWorker(token, changes, sourceFile, checker, sourceFiles, isFixAll) {
            var parent = token.parent;
            if (ts.isParameter(parent)) {
                tryDeleteParameter(changes, sourceFile, parent, checker, sourceFiles, isFixAll);
            }
            else {
                changes.delete(sourceFile, ts.isImportClause(parent) ? token : ts.isComputedPropertyName(parent) ? parent.parent : parent);
            }
        }
        function tryDeleteParameter(changes, sourceFile, p, checker, sourceFiles, isFixAll) {
            if (mayDeleteParameter(p, checker, isFixAll)) {
                if (p.modifiers && p.modifiers.length > 0
                    && (!ts.isIdentifier(p.name) || ts.FindAllReferences.Core.isSymbolReferencedInFile(p.name, checker, sourceFile))) {
                    p.modifiers.forEach(function (modifier) {
                        changes.deleteModifier(sourceFile, modifier);
                    });
                }
                else {
                    changes.delete(sourceFile, p);
                    deleteUnusedArguments(changes, sourceFile, p, sourceFiles, checker);
                }
            }
        }
        function mayDeleteParameter(p, checker, isFixAll) {
            var parent = p.parent;
            switch (parent.kind) {
                case 157 /* MethodDeclaration */:
                    // Don't remove a parameter if this overrides something.
                    var symbol = checker.getSymbolAtLocation(parent.name);
                    if (ts.isMemberSymbolInBaseType(symbol, checker))
                        return false;
                // falls through
                case 158 /* Constructor */:
                case 240 /* FunctionDeclaration */:
                    return true;
                case 197 /* FunctionExpression */:
                case 198 /* ArrowFunction */: {
                    // Can't remove a non-last parameter in a callback. Can remove a parameter in code-fix-all if future parameters are also unused.
                    var parameters = parent.parameters;
                    var index = parameters.indexOf(p);
                    ts.Debug.assert(index !== -1);
                    return isFixAll
                        ? parameters.slice(index + 1).every(function (p) { return p.name.kind === 73 /* Identifier */ && !p.symbol.isReferenced; })
                        : index === parameters.length - 1;
                }
                case 160 /* SetAccessor */:
                    // Setter must have a parameter
                    return false;
                default:
                    return ts.Debug.failBadSyntaxKind(parent);
            }
        }
        function deleteUnusedArguments(changes, sourceFile, deletedParameter, sourceFiles, checker) {
            ts.FindAllReferences.Core.eachSignatureCall(deletedParameter.parent, sourceFiles, checker, function (call) {
                var index = deletedParameter.parent.parameters.indexOf(deletedParameter);
                if (call.arguments.length > index) { // Just in case the call didn't provide enough arguments.
                    changes.delete(sourceFile, call.arguments[index]);
                }
            });
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "fixUnreachableCode";
        var errorCodes = [ts.Diagnostics.Unreachable_code_detected.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, context.sourceFile, context.span.start, context.span.length); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Remove_unreachable_code, fixId, ts.Diagnostics.Remove_all_unreachable_code)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return doChange(changes, diag.file, diag.start, diag.length); }); },
        });
        function doChange(changes, sourceFile, start, length) {
            var token = ts.getTokenAtPosition(sourceFile, start);
            var statement = ts.findAncestor(token, ts.isStatement);
            ts.Debug.assert(statement.getStart(sourceFile) === token.getStart(sourceFile));
            var container = (ts.isBlock(statement.parent) ? statement.parent : statement).parent;
            if (!ts.isBlock(statement.parent) || statement === ts.first(statement.parent.statements)) {
                switch (container.kind) {
                    case 223 /* IfStatement */:
                        if (container.elseStatement) {
                            if (ts.isBlock(statement.parent)) {
                                break;
                            }
                            else {
                                changes.replaceNode(sourceFile, statement, ts.createBlock(ts.emptyArray));
                            }
                            return;
                        }
                    // falls through
                    case 225 /* WhileStatement */:
                    case 226 /* ForStatement */:
                        changes.delete(sourceFile, container);
                        return;
                }
            }
            if (ts.isBlock(statement.parent)) {
                var end_3 = start + length;
                var lastStatement = ts.Debug.assertDefined(lastWhere(ts.sliceAfter(statement.parent.statements, statement), function (s) { return s.pos < end_3; }));
                changes.deleteNodeRange(sourceFile, statement, lastStatement);
            }
            else {
                changes.delete(sourceFile, statement);
            }
        }
        function lastWhere(a, pred) {
            var last;
            for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
                var value = a_1[_i];
                if (!pred(value))
                    break;
                last = value;
            }
            return last;
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "fixUnusedLabel";
        var errorCodes = [ts.Diagnostics.Unused_label.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, context.sourceFile, context.span.start); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Remove_unused_label, fixId, ts.Diagnostics.Remove_all_unused_labels)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return doChange(changes, diag.file, diag.start); }); },
        });
        function doChange(changes, sourceFile, start) {
            var token = ts.getTokenAtPosition(sourceFile, start);
            var labeledStatement = ts.cast(token.parent, ts.isLabeledStatement);
            var pos = token.getStart(sourceFile);
            var statementPos = labeledStatement.statement.getStart(sourceFile);
            // If label is on a separate line, just delete the rest of that line, but not the indentation of the labeled statement.
            var end = ts.positionsAreOnSameLine(pos, statementPos, sourceFile) ? statementPos
                : ts.skipTrivia(sourceFile.text, ts.findChildOfKind(labeledStatement, 57 /* ColonToken */, sourceFile).end, /*stopAfterLineBreak*/ true);
            changes.deleteRange(sourceFile, { pos: pos, end: end });
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixIdPlain = "fixJSDocTypes_plain";
        var fixIdNullable = "fixJSDocTypes_nullable";
        var errorCodes = [ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var checker = context.program.getTypeChecker();
                var info = getInfo(sourceFile, context.span.start, checker);
                if (!info)
                    return undefined;
                var typeNode = info.typeNode, type = info.type;
                var original = typeNode.getText(sourceFile);
                var actions = [fix(type, fixIdPlain, ts.Diagnostics.Change_all_jsdoc_style_types_to_TypeScript)];
                if (typeNode.kind === 292 /* JSDocNullableType */) {
                    // for nullable types, suggest the flow-compatible `T | null | undefined`
                    // in addition to the jsdoc/closure-compatible `T | null`
                    actions.push(fix(checker.getNullableType(type, 32768 /* Undefined */), fixIdNullable, ts.Diagnostics.Change_all_jsdoc_style_types_to_TypeScript_and_add_undefined_to_nullable_types));
                }
                return actions;
                function fix(type, fixId, fixAllDescription) {
                    var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, typeNode, type, checker); });
                    return codefix.createCodeFixAction("jdocTypes", changes, [ts.Diagnostics.Change_0_to_1, original, checker.typeToString(type)], fixId, fixAllDescription);
                }
            },
            fixIds: [fixIdPlain, fixIdNullable],
            getAllCodeActions: function (context) {
                var fixId = context.fixId, program = context.program, sourceFile = context.sourceFile;
                var checker = program.getTypeChecker();
                return codefix.codeFixAll(context, errorCodes, function (changes, err) {
                    var info = getInfo(err.file, err.start, checker);
                    if (!info)
                        return;
                    var typeNode = info.typeNode, type = info.type;
                    var fixedType = typeNode.kind === 292 /* JSDocNullableType */ && fixId === fixIdNullable ? checker.getNullableType(type, 32768 /* Undefined */) : type;
                    doChange(changes, sourceFile, typeNode, fixedType, checker);
                });
            }
        });
        function doChange(changes, sourceFile, oldTypeNode, newType, checker) {
            changes.replaceNode(sourceFile, oldTypeNode, checker.typeToTypeNode(newType, /*enclosingDeclaration*/ oldTypeNode)); // TODO: GH#18217
        }
        function getInfo(sourceFile, pos, checker) {
            var decl = ts.findAncestor(ts.getTokenAtPosition(sourceFile, pos), isTypeContainer);
            var typeNode = decl && decl.type;
            return typeNode && { typeNode: typeNode, type: checker.getTypeFromTypeNode(typeNode) };
        }
        function isTypeContainer(node) {
            // NOTE: Some locations are not handled yet:
            // MappedTypeNode.typeParameters and SignatureDeclaration.typeParameters, as well as CallExpression.typeArguments
            switch (node.kind) {
                case 213 /* AsExpression */:
                case 161 /* CallSignature */:
                case 162 /* ConstructSignature */:
                case 240 /* FunctionDeclaration */:
                case 159 /* GetAccessor */:
                case 163 /* IndexSignature */:
                case 182 /* MappedType */:
                case 157 /* MethodDeclaration */:
                case 156 /* MethodSignature */:
                case 152 /* Parameter */:
                case 155 /* PropertyDeclaration */:
                case 154 /* PropertySignature */:
                case 160 /* SetAccessor */:
                case 243 /* TypeAliasDeclaration */:
                case 195 /* TypeAssertionExpression */:
                case 238 /* VariableDeclaration */:
                    return true;
                default:
                    return false;
            }
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "fixAwaitInSyncFunction";
        var errorCodes = [
            ts.Diagnostics.await_expression_is_only_allowed_within_an_async_function.code,
            ts.Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var nodes = getNodes(sourceFile, span.start);
                if (!nodes)
                    return undefined;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, nodes); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_async_modifier_to_containing_function, fixId, ts.Diagnostics.Add_all_missing_async_modifiers)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var nodes = getNodes(diag.file, diag.start);
                if (!nodes)
                    return;
                doChange(changes, context.sourceFile, nodes);
            }); },
        });
        function getReturnType(expr) {
            if (expr.type) {
                return expr.type;
            }
            if (ts.isVariableDeclaration(expr.parent) &&
                expr.parent.type &&
                ts.isFunctionTypeNode(expr.parent.type)) {
                return expr.parent.type.type;
            }
        }
        function getNodes(sourceFile, start) {
            var token = ts.getTokenAtPosition(sourceFile, start);
            var containingFunction = ts.getContainingFunction(token);
            if (!containingFunction) {
                return;
            }
            var insertBefore;
            switch (containingFunction.kind) {
                case 157 /* MethodDeclaration */:
                    insertBefore = containingFunction.name;
                    break;
                case 240 /* FunctionDeclaration */:
                case 197 /* FunctionExpression */:
                    insertBefore = ts.findChildOfKind(containingFunction, 91 /* FunctionKeyword */, sourceFile);
                    break;
                case 198 /* ArrowFunction */:
                    insertBefore = ts.findChildOfKind(containingFunction, 20 /* OpenParenToken */, sourceFile) || ts.first(containingFunction.parameters);
                    break;
                default:
                    return;
            }
            return insertBefore && {
                insertBefore: insertBefore,
                returnType: getReturnType(containingFunction)
            };
        }
        function doChange(changes, sourceFile, _a) {
            var insertBefore = _a.insertBefore, returnType = _a.returnType;
            if (returnType) {
                var entityName = ts.getEntityNameFromTypeNode(returnType);
                if (!entityName || entityName.kind !== 73 /* Identifier */ || entityName.text !== "Promise") {
                    changes.replaceNode(sourceFile, returnType, ts.createTypeReferenceNode("Promise", ts.createNodeArray([returnType])));
                }
            }
            changes.insertModifierBefore(sourceFile, 122 /* AsyncKeyword */, insertBefore);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixName = "disableJsDiagnostics";
        var fixId = "disableJsDiagnostics";
        var errorCodes = ts.mapDefined(Object.keys(ts.Diagnostics), function (key) {
            var diag = ts.Diagnostics[key];
            return diag.category === ts.DiagnosticCategory.Error ? diag.code : undefined;
        });
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, program = context.program, span = context.span, host = context.host, formatContext = context.formatContext;
                if (!ts.isInJSFile(sourceFile) || !ts.isCheckJsEnabledForFile(sourceFile, program.getCompilerOptions())) {
                    return undefined;
                }
                var fixes = [
                    // fixId unnecessary because adding `// @ts-nocheck` even once will ignore every error in the file.
                    codefix.createCodeFixActionNoFixId(fixName, [codefix.createFileTextChanges(sourceFile.fileName, [
                            ts.createTextChange(sourceFile.checkJsDirective
                                ? ts.createTextSpanFromBounds(sourceFile.checkJsDirective.pos, sourceFile.checkJsDirective.end)
                                : ts.createTextSpan(0, 0), "// @ts-nocheck" + ts.getNewLineOrDefaultFromHost(host, formatContext.options)),
                        ])], ts.Diagnostics.Disable_checking_for_this_file),
                ];
                if (ts.textChanges.isValidLocationToAddComment(sourceFile, span.start)) {
                    fixes.unshift(codefix.createCodeFixAction(fixName, ts.textChanges.ChangeTracker.with(context, function (t) { return makeChange(t, sourceFile, span.start); }), ts.Diagnostics.Ignore_this_error_message, fixId, ts.Diagnostics.Add_ts_ignore_to_all_error_messages));
                }
                return fixes;
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var seenLines = ts.createMap();
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                    if (ts.textChanges.isValidLocationToAddComment(diag.file, diag.start)) {
                        makeChange(changes, diag.file, diag.start, seenLines);
                    }
                });
            },
        });
        function makeChange(changes, sourceFile, position, seenLines) {
            var lineNumber = ts.getLineAndCharacterOfPosition(sourceFile, position).line;
            // Only need to add `// @ts-ignore` for a line once.
            if (!seenLines || ts.addToSeen(seenLines, lineNumber)) {
                changes.insertCommentBeforeLine(sourceFile, lineNumber, position, " @ts-ignore");
            }
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        /**
         * Finds members of the resolved type that are missing in the class pointed to by class decl
         * and generates source code for the missing members.
         * @param possiblyMissingSymbols The collection of symbols to filter and then get insertions for.
         * @returns Empty string iff there are no member insertions.
         */
        function createMissingMemberNodes(classDeclaration, possiblyMissingSymbols, context, preferences, out) {
            var classMembers = classDeclaration.symbol.members;
            for (var _i = 0, possiblyMissingSymbols_1 = possiblyMissingSymbols; _i < possiblyMissingSymbols_1.length; _i++) {
                var symbol = possiblyMissingSymbols_1[_i];
                if (!classMembers.has(symbol.escapedName)) {
                    addNewNodeForMemberSymbol(symbol, classDeclaration, context, preferences, out);
                }
            }
        }
        codefix.createMissingMemberNodes = createMissingMemberNodes;
        function getModuleSpecifierResolverHost(context) {
            return {
                directoryExists: context.host.directoryExists ? function (d) { return context.host.directoryExists(d); } : undefined,
                fileExists: context.host.fileExists ? function (f) { return context.host.fileExists(f); } : undefined,
                getCurrentDirectory: context.host.getCurrentDirectory ? function () { return context.host.getCurrentDirectory(); } : undefined,
                readFile: context.host.readFile ? function (f) { return context.host.readFile(f); } : undefined,
                useCaseSensitiveFileNames: context.host.useCaseSensitiveFileNames ? function () { return context.host.useCaseSensitiveFileNames(); } : undefined,
                getSourceFiles: function () { return context.program.getSourceFiles(); },
                getCommonSourceDirectory: function () { return context.program.getCommonSourceDirectory(); },
            };
        }
        function getNoopSymbolTrackerWithResolver(context) {
            return {
                trackSymbol: ts.noop,
                moduleResolverHost: getModuleSpecifierResolverHost(context),
            };
        }
        codefix.getNoopSymbolTrackerWithResolver = getNoopSymbolTrackerWithResolver;
        /**
         * @returns Empty string iff there we can't figure out a representation for `symbol` in `enclosingDeclaration`.
         */
        function addNewNodeForMemberSymbol(symbol, enclosingDeclaration, context, preferences, out) {
            var declarations = symbol.getDeclarations();
            if (!(declarations && declarations.length)) {
                return undefined;
            }
            var checker = context.program.getTypeChecker();
            var declaration = declarations[0];
            var name = ts.getSynthesizedDeepClone(ts.getNameOfDeclaration(declaration), /*includeTrivia*/ false);
            var visibilityModifier = createVisibilityModifier(ts.getModifierFlags(declaration));
            var modifiers = visibilityModifier ? ts.createNodeArray([visibilityModifier]) : undefined;
            var type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration));
            var optional = !!(symbol.flags & 16777216 /* Optional */);
            switch (declaration.kind) {
                case 159 /* GetAccessor */:
                case 160 /* SetAccessor */:
                case 154 /* PropertySignature */:
                case 155 /* PropertyDeclaration */:
                    var typeNode = checker.typeToTypeNode(type, enclosingDeclaration, /*flags*/ undefined, getNoopSymbolTrackerWithResolver(context));
                    out(ts.createProperty(
                    /*decorators*/ undefined, modifiers, name, optional ? ts.createToken(56 /* QuestionToken */) : undefined, typeNode, 
                    /*initializer*/ undefined));
                    break;
                case 156 /* MethodSignature */:
                case 157 /* MethodDeclaration */:
                    // The signature for the implementation appears as an entry in `signatures` iff
                    // there is only one signature.
                    // If there are overloads and an implementation signature, it appears as an
                    // extra declaration that isn't a signature for `type`.
                    // If there is more than one overload but no implementation signature
                    // (eg: an abstract method or interface declaration), there is a 1-1
                    // correspondence of declarations and signatures.
                    var signatures = checker.getSignaturesOfType(type, 0 /* Call */);
                    if (!ts.some(signatures)) {
                        break;
                    }
                    if (declarations.length === 1) {
                        ts.Debug.assert(signatures.length === 1);
                        var signature = signatures[0];
                        outputMethod(signature, modifiers, name, createStubbedMethodBody(preferences));
                        break;
                    }
                    for (var _i = 0, signatures_1 = signatures; _i < signatures_1.length; _i++) {
                        var signature = signatures_1[_i];
                        // Need to ensure nodes are fresh each time so they can have different positions.
                        outputMethod(signature, ts.getSynthesizedDeepClones(modifiers, /*includeTrivia*/ false), ts.getSynthesizedDeepClone(name, /*includeTrivia*/ false));
                    }
                    if (declarations.length > signatures.length) {
                        var signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1]);
                        outputMethod(signature, modifiers, name, createStubbedMethodBody(preferences));
                    }
                    else {
                        ts.Debug.assert(declarations.length === signatures.length);
                        out(createMethodImplementingSignatures(signatures, name, optional, modifiers, preferences));
                    }
                    break;
            }
            function outputMethod(signature, modifiers, name, body) {
                var method = signatureToMethodDeclaration(context, signature, enclosingDeclaration, modifiers, name, optional, body);
                if (method)
                    out(method);
            }
        }
        function signatureToMethodDeclaration(context, signature, enclosingDeclaration, modifiers, name, optional, body) {
            var program = context.program;
            var signatureDeclaration = program.getTypeChecker().signatureToSignatureDeclaration(signature, 157 /* MethodDeclaration */, enclosingDeclaration, 1 /* NoTruncation */ | 256 /* SuppressAnyReturnType */, getNoopSymbolTrackerWithResolver(context));
            if (!signatureDeclaration) {
                return undefined;
            }
            signatureDeclaration.decorators = undefined;
            signatureDeclaration.modifiers = modifiers;
            signatureDeclaration.name = name;
            signatureDeclaration.questionToken = optional ? ts.createToken(56 /* QuestionToken */) : undefined;
            signatureDeclaration.body = body;
            return signatureDeclaration;
        }
        function createMethodFromCallExpression(context, call, methodName, inJs, makeStatic, preferences, contextNode) {
            var body = !ts.isInterfaceDeclaration(contextNode);
            var typeArguments = call.typeArguments, args = call.arguments, parent = call.parent;
            var checker = context.program.getTypeChecker();
            var tracker = getNoopSymbolTrackerWithResolver(context);
            var types = ts.map(args, function (arg) {
                // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
                return checker.typeToTypeNode(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(arg)), contextNode, /*flags*/ undefined, tracker);
            });
            var names = ts.map(args, function (arg) {
                return ts.isIdentifier(arg) ? arg.text :
                    ts.isPropertyAccessExpression(arg) ? arg.name.text : undefined;
            });
            var contextualType = checker.getContextualType(call);
            var returnType = (inJs || !contextualType) ? undefined : checker.typeToTypeNode(contextualType, contextNode, /*flags*/ undefined, tracker);
            return ts.createMethod(
            /*decorators*/ undefined, 
            /*modifiers*/ makeStatic ? [ts.createToken(117 /* StaticKeyword */)] : undefined, 
            /*asteriskToken*/ ts.isYieldExpression(parent) ? ts.createToken(40 /* AsteriskToken */) : undefined, methodName, 
            /*questionToken*/ undefined, 
            /*typeParameters*/ inJs ? undefined : ts.map(typeArguments, function (_, i) {
                return ts.createTypeParameterDeclaration(84 /* T */ + typeArguments.length - 1 <= 90 /* Z */ ? String.fromCharCode(84 /* T */ + i) : "T" + i);
            }), 
            /*parameters*/ createDummyParameters(args.length, names, types, /*minArgumentCount*/ undefined, inJs), 
            /*type*/ returnType, body ? createStubbedMethodBody(preferences) : undefined);
        }
        codefix.createMethodFromCallExpression = createMethodFromCallExpression;
        function createDummyParameters(argCount, names, types, minArgumentCount, inJs) {
            var parameters = [];
            for (var i = 0; i < argCount; i++) {
                var newParameter = ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, 
                /*name*/ names && names[i] || "arg" + i, 
                /*questionToken*/ minArgumentCount !== undefined && i >= minArgumentCount ? ts.createToken(56 /* QuestionToken */) : undefined, 
                /*type*/ inJs ? undefined : types && types[i] || ts.createKeywordTypeNode(121 /* AnyKeyword */), 
                /*initializer*/ undefined);
                parameters.push(newParameter);
            }
            return parameters;
        }
        function createMethodImplementingSignatures(signatures, name, optional, modifiers, preferences) {
            /** This is *a* signature with the maximal number of arguments,
             * such that if there is a "maximal" signature without rest arguments,
             * this is one of them.
             */
            var maxArgsSignature = signatures[0];
            var minArgumentCount = signatures[0].minArgumentCount;
            var someSigHasRestParameter = false;
            for (var _i = 0, signatures_2 = signatures; _i < signatures_2.length; _i++) {
                var sig = signatures_2[_i];
                minArgumentCount = Math.min(sig.minArgumentCount, minArgumentCount);
                if (sig.hasRestParameter) {
                    someSigHasRestParameter = true;
                }
                if (sig.parameters.length >= maxArgsSignature.parameters.length && (!sig.hasRestParameter || maxArgsSignature.hasRestParameter)) {
                    maxArgsSignature = sig;
                }
            }
            var maxNonRestArgs = maxArgsSignature.parameters.length - (maxArgsSignature.hasRestParameter ? 1 : 0);
            var maxArgsParameterSymbolNames = maxArgsSignature.parameters.map(function (symbol) { return symbol.name; });
            var parameters = createDummyParameters(maxNonRestArgs, maxArgsParameterSymbolNames, /* types */ undefined, minArgumentCount, /*inJs*/ false);
            if (someSigHasRestParameter) {
                var anyArrayType = ts.createArrayTypeNode(ts.createKeywordTypeNode(121 /* AnyKeyword */));
                var restParameter = ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, ts.createToken(25 /* DotDotDotToken */), maxArgsParameterSymbolNames[maxNonRestArgs] || "rest", 
                /*questionToken*/ maxNonRestArgs >= minArgumentCount ? ts.createToken(56 /* QuestionToken */) : undefined, anyArrayType, 
                /*initializer*/ undefined);
                parameters.push(restParameter);
            }
            return createStubbedMethod(modifiers, name, optional, 
            /*typeParameters*/ undefined, parameters, 
            /*returnType*/ undefined, preferences);
        }
        function createStubbedMethod(modifiers, name, optional, typeParameters, parameters, returnType, preferences) {
            return ts.createMethod(
            /*decorators*/ undefined, modifiers, 
            /*asteriskToken*/ undefined, name, optional ? ts.createToken(56 /* QuestionToken */) : undefined, typeParameters, parameters, returnType, createStubbedMethodBody(preferences));
        }
        function createStubbedMethodBody(preferences) {
            return ts.createBlock([ts.createThrow(ts.createNew(ts.createIdentifier("Error"), 
                /*typeArguments*/ undefined, 
                // TODO Handle auto quote preference.
                [ts.createLiteral("Method not implemented.", /*isSingleQuote*/ preferences.quotePreference === "single")]))], 
            /*multiline*/ true);
        }
        function createVisibilityModifier(flags) {
            if (flags & 4 /* Public */) {
                return ts.createToken(116 /* PublicKeyword */);
            }
            else if (flags & 16 /* Protected */) {
                return ts.createToken(115 /* ProtectedKeyword */);
            }
            return undefined;
        }
        function setJsonCompilerOptionValue(changeTracker, configFile, optionName, optionValue) {
            var tsconfigObjectLiteral = ts.getTsConfigObjectLiteralExpression(configFile);
            if (!tsconfigObjectLiteral)
                return undefined;
            var compilerOptionsProperty = findJsonProperty(tsconfigObjectLiteral, "compilerOptions");
            if (compilerOptionsProperty === undefined) {
                changeTracker.insertNodeAtObjectStart(configFile, tsconfigObjectLiteral, createJsonPropertyAssignment("compilerOptions", ts.createObjectLiteral([
                    createJsonPropertyAssignment(optionName, optionValue),
                ])));
                return;
            }
            var compilerOptions = compilerOptionsProperty.initializer;
            if (!ts.isObjectLiteralExpression(compilerOptions)) {
                return;
            }
            var optionProperty = findJsonProperty(compilerOptions, optionName);
            if (optionProperty === undefined) {
                changeTracker.insertNodeAtObjectStart(configFile, compilerOptions, createJsonPropertyAssignment(optionName, optionValue));
            }
            else {
                changeTracker.replaceNode(configFile, optionProperty.initializer, optionValue);
            }
        }
        codefix.setJsonCompilerOptionValue = setJsonCompilerOptionValue;
        function createJsonPropertyAssignment(name, initializer) {
            return ts.createPropertyAssignment(ts.createStringLiteral(name), initializer);
        }
        codefix.createJsonPropertyAssignment = createJsonPropertyAssignment;
        function findJsonProperty(obj, name) {
            return ts.find(obj.properties, function (p) { return ts.isPropertyAssignment(p) && !!p.name && ts.isStringLiteral(p.name) && p.name.text === name; });
        }
        codefix.findJsonProperty = findJsonProperty;
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixName = "invalidImportSyntax";
        function getCodeFixesForImportDeclaration(context, node) {
            var sourceFile = ts.getSourceFileOfNode(node);
            var namespace = ts.getNamespaceDeclarationNode(node);
            var opts = context.program.getCompilerOptions();
            var variations = [];
            // import Bluebird from "bluebird";
            variations.push(createAction(context, sourceFile, node, ts.makeImport(namespace.name, /*namedImports*/ undefined, node.moduleSpecifier, ts.getQuotePreference(sourceFile, context.preferences))));
            if (ts.getEmitModuleKind(opts) === ts.ModuleKind.CommonJS) {
                // import Bluebird = require("bluebird");
                variations.push(createAction(context, sourceFile, node, ts.createImportEqualsDeclaration(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, namespace.name, ts.createExternalModuleReference(node.moduleSpecifier))));
            }
            return variations;
        }
        function createAction(context, sourceFile, node, replacement) {
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.replaceNode(sourceFile, node, replacement); });
            return codefix.createCodeFixActionNoFixId(fixName, changes, [ts.Diagnostics.Replace_import_with_0, changes[0].textChanges[0].newText]);
        }
        codefix.registerCodeFix({
            errorCodes: [
                ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures.code,
                ts.Diagnostics.Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature.code,
            ],
            getCodeActions: getActionsForUsageOfInvalidImport
        });
        function getActionsForUsageOfInvalidImport(context) {
            var sourceFile = context.sourceFile;
            var targetKind = ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures.code === context.errorCode ? 192 /* CallExpression */ : 193 /* NewExpression */;
            var node = ts.findAncestor(ts.getTokenAtPosition(sourceFile, context.span.start), function (a) { return a.kind === targetKind && a.getStart() === context.span.start && a.getEnd() === (context.span.start + context.span.length); });
            if (!node) {
                return [];
            }
            var expr = node.expression;
            return getImportCodeFixesForExpression(context, expr);
        }
        codefix.registerCodeFix({
            errorCodes: [
                // The following error codes cover pretty much all assignability errors that could involve an expression
                ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1.code,
                ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1.code,
                ts.Diagnostics.Type_0_is_not_assignable_to_type_1.code,
                ts.Diagnostics.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated.code,
                ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1.code,
                ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_string_index_type_2.code,
                ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2.code,
                ts.Diagnostics.Numeric_index_type_0_is_not_assignable_to_string_index_type_1.code,
                ts.Diagnostics.Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2.code,
                ts.Diagnostics.Property_0_in_type_1_is_not_assignable_to_type_2.code,
                ts.Diagnostics.Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property.code,
                ts.Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1.code,
            ],
            getCodeActions: getActionsForInvalidImportLocation
        });
        function getActionsForInvalidImportLocation(context) {
            var sourceFile = context.sourceFile;
            var node = ts.findAncestor(ts.getTokenAtPosition(sourceFile, context.span.start), function (a) { return a.getStart() === context.span.start && a.getEnd() === (context.span.start + context.span.length); });
            if (!node) {
                return [];
            }
            return getImportCodeFixesForExpression(context, node);
        }
        function getImportCodeFixesForExpression(context, expr) {
            var type = context.program.getTypeChecker().getTypeAtLocation(expr);
            if (!(type.symbol && type.symbol.originatingImport)) {
                return [];
            }
            var fixes = [];
            var relatedImport = type.symbol.originatingImport; // TODO: GH#18217
            if (!ts.isImportCall(relatedImport)) {
                ts.addRange(fixes, getCodeFixesForImportDeclaration(context, relatedImport));
            }
            if (ts.isExpression(expr) && !(ts.isNamedDeclaration(expr.parent) && expr.parent.name === expr)) {
                var sourceFile_1 = context.sourceFile;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.replaceNode(sourceFile_1, expr, ts.createPropertyAccess(expr, "default"), {}); });
                fixes.push(codefix.createCodeFixActionNoFixId(fixName, changes, ts.Diagnostics.Use_synthetic_default_member));
            }
            return fixes;
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixName = "strictClassInitialization";
        var fixIdAddDefiniteAssignmentAssertions = "addMissingPropertyDefiniteAssignmentAssertions";
        var fixIdAddUndefinedType = "addMissingPropertyUndefinedType";
        var fixIdAddInitializer = "addMissingPropertyInitializer";
        var errorCodes = [ts.Diagnostics.Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var propertyDeclaration = getPropertyDeclaration(context.sourceFile, context.span.start);
                if (!propertyDeclaration)
                    return;
                var result = [
                    getActionForAddMissingUndefinedType(context, propertyDeclaration),
                    getActionForAddMissingDefiniteAssignmentAssertion(context, propertyDeclaration)
                ];
                ts.append(result, getActionForAddMissingInitializer(context, propertyDeclaration));
                return result;
            },
            fixIds: [fixIdAddDefiniteAssignmentAssertions, fixIdAddUndefinedType, fixIdAddInitializer],
            getAllCodeActions: function (context) {
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                    var propertyDeclaration = getPropertyDeclaration(diag.file, diag.start);
                    if (!propertyDeclaration)
                        return;
                    switch (context.fixId) {
                        case fixIdAddDefiniteAssignmentAssertions:
                            addDefiniteAssignmentAssertion(changes, diag.file, propertyDeclaration);
                            break;
                        case fixIdAddUndefinedType:
                            addUndefinedType(changes, diag.file, propertyDeclaration);
                            break;
                        case fixIdAddInitializer:
                            var checker = context.program.getTypeChecker();
                            var initializer = getInitializer(checker, propertyDeclaration);
                            if (!initializer)
                                return;
                            addInitializer(changes, diag.file, propertyDeclaration, initializer);
                            break;
                        default:
                            ts.Debug.fail(JSON.stringify(context.fixId));
                    }
                });
            },
        });
        function getPropertyDeclaration(sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            return ts.isIdentifier(token) ? ts.cast(token.parent, ts.isPropertyDeclaration) : undefined;
        }
        function getActionForAddMissingDefiniteAssignmentAssertion(context, propertyDeclaration) {
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addDefiniteAssignmentAssertion(t, context.sourceFile, propertyDeclaration); });
            return codefix.createCodeFixAction(fixName, changes, [ts.Diagnostics.Add_definite_assignment_assertion_to_property_0, propertyDeclaration.getText()], fixIdAddDefiniteAssignmentAssertions, ts.Diagnostics.Add_definite_assignment_assertions_to_all_uninitialized_properties);
        }
        function addDefiniteAssignmentAssertion(changeTracker, propertyDeclarationSourceFile, propertyDeclaration) {
            var property = ts.updateProperty(propertyDeclaration, propertyDeclaration.decorators, propertyDeclaration.modifiers, propertyDeclaration.name, ts.createToken(52 /* ExclamationToken */), propertyDeclaration.type, propertyDeclaration.initializer);
            changeTracker.replaceNode(propertyDeclarationSourceFile, propertyDeclaration, property);
        }
        function getActionForAddMissingUndefinedType(context, propertyDeclaration) {
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addUndefinedType(t, context.sourceFile, propertyDeclaration); });
            return codefix.createCodeFixAction(fixName, changes, [ts.Diagnostics.Add_undefined_type_to_property_0, propertyDeclaration.name.getText()], fixIdAddUndefinedType, ts.Diagnostics.Add_undefined_type_to_all_uninitialized_properties);
        }
        function addUndefinedType(changeTracker, propertyDeclarationSourceFile, propertyDeclaration) {
            var undefinedTypeNode = ts.createKeywordTypeNode(142 /* UndefinedKeyword */);
            var type = propertyDeclaration.type; // TODO: GH#18217
            var types = ts.isUnionTypeNode(type) ? type.types.concat(undefinedTypeNode) : [type, undefinedTypeNode];
            changeTracker.replaceNode(propertyDeclarationSourceFile, type, ts.createUnionTypeNode(types));
        }
        function getActionForAddMissingInitializer(context, propertyDeclaration) {
            var checker = context.program.getTypeChecker();
            var initializer = getInitializer(checker, propertyDeclaration);
            if (!initializer)
                return undefined;
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addInitializer(t, context.sourceFile, propertyDeclaration, initializer); });
            return codefix.createCodeFixAction(fixName, changes, [ts.Diagnostics.Add_initializer_to_property_0, propertyDeclaration.name.getText()], fixIdAddInitializer, ts.Diagnostics.Add_initializers_to_all_uninitialized_properties);
        }
        function addInitializer(changeTracker, propertyDeclarationSourceFile, propertyDeclaration, initializer) {
            var property = ts.updateProperty(propertyDeclaration, propertyDeclaration.decorators, propertyDeclaration.modifiers, propertyDeclaration.name, propertyDeclaration.questionToken, propertyDeclaration.type, initializer);
            changeTracker.replaceNode(propertyDeclarationSourceFile, propertyDeclaration, property);
        }
        function getInitializer(checker, propertyDeclaration) {
            return getDefaultValueFromType(checker, checker.getTypeFromTypeNode(propertyDeclaration.type)); // TODO: GH#18217
        }
        function getDefaultValueFromType(checker, type) {
            if (type.flags & 512 /* BooleanLiteral */) {
                return (type === checker.getFalseType() || type === checker.getFalseType(/*fresh*/ true)) ? ts.createFalse() : ts.createTrue();
            }
            else if (type.isLiteral()) {
                return ts.createLiteral(type.value);
            }
            else if (type.isUnion()) {
                return ts.firstDefined(type.types, function (t) { return getDefaultValueFromType(checker, t); });
            }
            else if (type.isClass()) {
                var classDeclaration = ts.getClassLikeDeclarationOfSymbol(type.symbol);
                if (!classDeclaration || ts.hasModifier(classDeclaration, 128 /* Abstract */))
                    return undefined;
                var constructorDeclaration = ts.getFirstConstructorWithBody(classDeclaration);
                if (constructorDeclaration && constructorDeclaration.parameters.length)
                    return undefined;
                return ts.createNew(ts.createIdentifier(type.symbol.name), /*typeArguments*/ undefined, /*argumentsArray*/ undefined);
            }
            else if (checker.isArrayLikeType(type)) {
                return ts.createArrayLiteral();
            }
            return undefined;
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "requireInTs";
        var errorCodes = [ts.Diagnostics.require_call_may_be_converted_to_an_import.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, context.sourceFile, context.span.start, context.program); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Convert_require_to_import, fixId, ts.Diagnostics.Convert_all_require_to_import)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return doChange(changes, diag.file, diag.start, context.program); }); },
        });
        function doChange(changes, sourceFile, pos, program) {
            var _a = getInfo(sourceFile, pos), statement = _a.statement, name = _a.name, required = _a.required;
            changes.replaceNode(sourceFile, statement, ts.getAllowSyntheticDefaultImports(program.getCompilerOptions())
                ? ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, ts.createImportClause(name, /*namedBindings*/ undefined), required)
                : ts.createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, name, ts.createExternalModuleReference(required)));
        }
        function getInfo(sourceFile, pos) {
            var parent = ts.getTokenAtPosition(sourceFile, pos).parent;
            if (!ts.isRequireCall(parent, /*checkArgumentIsStringLiteralLike*/ true))
                throw ts.Debug.failBadSyntaxKind(parent);
            var decl = ts.cast(parent.parent, ts.isVariableDeclaration);
            return { statement: ts.cast(decl.parent.parent, ts.isVariableStatement), name: ts.cast(decl.name, ts.isIdentifier), required: parent.arguments[0] };
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "useDefaultImport";
        var errorCodes = [ts.Diagnostics.Import_may_be_converted_to_a_default_import.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, start = context.span.start;
                var info = getInfo(sourceFile, start);
                if (!info)
                    return undefined;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, info, context.preferences); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Convert_to_default_import, fixId, ts.Diagnostics.Convert_all_to_default_imports)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var info = getInfo(diag.file, diag.start);
                if (info)
                    doChange(changes, diag.file, info, context.preferences);
            }); },
        });
        function getInfo(sourceFile, pos) {
            var name = ts.getTokenAtPosition(sourceFile, pos);
            if (!ts.isIdentifier(name))
                return undefined; // bad input
            var parent = name.parent;
            if (ts.isImportEqualsDeclaration(parent) && ts.isExternalModuleReference(parent.moduleReference)) {
                return { importNode: parent, name: name, moduleSpecifier: parent.moduleReference.expression };
            }
            else if (ts.isNamespaceImport(parent)) {
                var importNode = parent.parent.parent;
                return { importNode: importNode, name: name, moduleSpecifier: importNode.moduleSpecifier };
            }
        }
        function doChange(changes, sourceFile, info, preferences) {
            changes.replaceNode(sourceFile, info.importNode, ts.makeImport(info.name, /*namedImports*/ undefined, info.moduleSpecifier, ts.getQuotePreference(sourceFile, preferences)));
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixIdAddMissingTypeof = "fixAddModuleReferTypeMissingTypeof";
        var fixId = fixIdAddMissingTypeof;
        var errorCodes = [ts.Diagnostics.Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var importType = getImportTypeNode(sourceFile, span.start);
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, importType); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_missing_typeof, fixId, ts.Diagnostics.Add_missing_typeof)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                return doChange(changes, context.sourceFile, getImportTypeNode(diag.file, diag.start));
            }); },
        });
        function getImportTypeNode(sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            ts.Debug.assert(token.kind === 93 /* ImportKeyword */);
            ts.Debug.assert(token.parent.kind === 184 /* ImportType */);
            return token.parent;
        }
        function doChange(changes, sourceFile, importType) {
            var newTypeNode = ts.updateImportTypeNode(importType, importType.argument, importType.qualifier, importType.typeArguments, /* isTypeOf */ true);
            changes.replaceNode(sourceFile, importType, newTypeNode);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixIdAddMissingTypeof = "fixConvertToMappedObjectType";
        var fixId = fixIdAddMissingTypeof;
        var errorCodes = [ts.Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var info = getInfo(sourceFile, span.start);
                if (!info)
                    return undefined;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, info); });
                var name = ts.idText(info.container.name);
                return [codefix.createCodeFixAction(fixId, changes, [ts.Diagnostics.Convert_0_to_mapped_object_type, name], fixId, [ts.Diagnostics.Convert_0_to_mapped_object_type, name])];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var info = getInfo(diag.file, diag.start);
                if (info)
                    doChange(changes, diag.file, info);
            }); }
        });
        function getInfo(sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            var indexSignature = ts.cast(token.parent.parent, ts.isIndexSignatureDeclaration);
            if (ts.isClassDeclaration(indexSignature.parent))
                return undefined;
            var container = ts.isInterfaceDeclaration(indexSignature.parent) ? indexSignature.parent : ts.cast(indexSignature.parent.parent, ts.isTypeAliasDeclaration);
            return { indexSignature: indexSignature, container: container };
        }
        function createTypeAliasFromInterface(declaration, type) {
            return ts.createTypeAliasDeclaration(declaration.decorators, declaration.modifiers, declaration.name, declaration.typeParameters, type);
        }
        function doChange(changes, sourceFile, _a) {
            var indexSignature = _a.indexSignature, container = _a.container;
            var members = ts.isInterfaceDeclaration(container) ? container.members : container.type.members;
            var otherMembers = members.filter(function (member) { return !ts.isIndexSignatureDeclaration(member); });
            var parameter = ts.first(indexSignature.parameters);
            var mappedTypeParameter = ts.createTypeParameterDeclaration(ts.cast(parameter.name, ts.isIdentifier), parameter.type);
            var mappedIntersectionType = ts.createMappedTypeNode(ts.hasReadonlyModifier(indexSignature) ? ts.createModifier(134 /* ReadonlyKeyword */) : undefined, mappedTypeParameter, indexSignature.questionToken, indexSignature.type);
            var intersectionType = ts.createIntersectionTypeNode(ts.getAllSuperTypeNodes(container).concat([
                mappedIntersectionType
            ], (otherMembers.length ? [ts.createTypeLiteralNode(otherMembers)] : ts.emptyArray)));
            changes.replaceNode(sourceFile, container, createTypeAliasFromInterface(container, intersectionType));
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var refactorName = "Convert export";
        var actionNameDefaultToNamed = "Convert default export to named export";
        var actionNameNamedToDefault = "Convert named export to default export";
        refactor.registerRefactor(refactorName, {
            getAvailableActions: function (context) {
                var info = getInfo(context);
                if (!info)
                    return ts.emptyArray;
                var description = info.wasDefault ? ts.Diagnostics.Convert_default_export_to_named_export.message : ts.Diagnostics.Convert_named_export_to_default_export.message;
                var actionName = info.wasDefault ? actionNameDefaultToNamed : actionNameNamedToDefault;
                return [{ name: refactorName, description: description, actions: [{ name: actionName, description: description }] }];
            },
            getEditsForAction: function (context, actionName) {
                ts.Debug.assert(actionName === actionNameDefaultToNamed || actionName === actionNameNamedToDefault);
                var edits = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(context.file, context.program, ts.Debug.assertDefined(getInfo(context)), t, context.cancellationToken); });
                return { edits: edits, renameFilename: undefined, renameLocation: undefined };
            },
        });
        function getInfo(context) {
            var file = context.file;
            var span = ts.getRefactorContextSpan(context);
            var token = ts.getTokenAtPosition(file, span.start);
            var exportNode = ts.getParentNodeInSpan(token, file, span);
            if (!exportNode || (!ts.isSourceFile(exportNode.parent) && !(ts.isModuleBlock(exportNode.parent) && ts.isAmbientModule(exportNode.parent.parent)))) {
                return undefined;
            }
            var exportingModuleSymbol = ts.isSourceFile(exportNode.parent) ? exportNode.parent.symbol : exportNode.parent.parent.symbol;
            var flags = ts.getModifierFlags(exportNode);
            var wasDefault = !!(flags & 512 /* Default */);
            // If source file already has a default export, don't offer refactor.
            if (!(flags & 1 /* Export */) || !wasDefault && exportingModuleSymbol.exports.has("default" /* Default */)) {
                return undefined;
            }
            switch (exportNode.kind) {
                case 240 /* FunctionDeclaration */:
                case 241 /* ClassDeclaration */:
                case 242 /* InterfaceDeclaration */:
                case 244 /* EnumDeclaration */:
                case 243 /* TypeAliasDeclaration */:
                case 245 /* ModuleDeclaration */: {
                    var node = exportNode;
                    return node.name && ts.isIdentifier(node.name) ? { exportNode: node, exportName: node.name, wasDefault: wasDefault, exportingModuleSymbol: exportingModuleSymbol } : undefined;
                }
                case 220 /* VariableStatement */: {
                    var vs = exportNode;
                    // Must be `export const x = something;`.
                    if (!(vs.declarationList.flags & 2 /* Const */) || vs.declarationList.declarations.length !== 1) {
                        return undefined;
                    }
                    var decl = ts.first(vs.declarationList.declarations);
                    if (!decl.initializer)
                        return undefined;
                    ts.Debug.assert(!wasDefault);
                    return ts.isIdentifier(decl.name) ? { exportNode: vs, exportName: decl.name, wasDefault: wasDefault, exportingModuleSymbol: exportingModuleSymbol } : undefined;
                }
                default:
                    return undefined;
            }
        }
        function doChange(exportingSourceFile, program, info, changes, cancellationToken) {
            changeExport(exportingSourceFile, info, changes, program.getTypeChecker());
            changeImports(program, info, changes, cancellationToken);
        }
        function changeExport(exportingSourceFile, _a, changes, checker) {
            var wasDefault = _a.wasDefault, exportNode = _a.exportNode, exportName = _a.exportName;
            if (wasDefault) {
                changes.delete(exportingSourceFile, ts.Debug.assertDefined(ts.findModifier(exportNode, 81 /* DefaultKeyword */)));
            }
            else {
                var exportKeyword = ts.Debug.assertDefined(ts.findModifier(exportNode, 86 /* ExportKeyword */));
                switch (exportNode.kind) {
                    case 240 /* FunctionDeclaration */:
                    case 241 /* ClassDeclaration */:
                    case 242 /* InterfaceDeclaration */:
                        changes.insertNodeAfter(exportingSourceFile, exportKeyword, ts.createToken(81 /* DefaultKeyword */));
                        break;
                    case 220 /* VariableStatement */:
                        // If 'x' isn't used in this file, `export const x = 0;` --> `export default 0;`
                        if (!ts.FindAllReferences.Core.isSymbolReferencedInFile(exportName, checker, exportingSourceFile)) {
                            // We checked in `getInfo` that an initializer exists.
                            changes.replaceNode(exportingSourceFile, exportNode, ts.createExportDefault(ts.Debug.assertDefined(ts.first(exportNode.declarationList.declarations).initializer)));
                            break;
                        }
                    // falls through
                    case 244 /* EnumDeclaration */:
                    case 243 /* TypeAliasDeclaration */:
                    case 245 /* ModuleDeclaration */:
                        // `export type T = number;` -> `type T = number; export default T;`
                        changes.deleteModifier(exportingSourceFile, exportKeyword);
                        changes.insertNodeAfter(exportingSourceFile, exportNode, ts.createExportDefault(ts.createIdentifier(exportName.text)));
                        break;
                    default:
                        ts.Debug.assertNever(exportNode);
                }
            }
        }
        function changeImports(program, _a, changes, cancellationToken) {
            var wasDefault = _a.wasDefault, exportName = _a.exportName, exportingModuleSymbol = _a.exportingModuleSymbol;
            var checker = program.getTypeChecker();
            var exportSymbol = ts.Debug.assertDefined(checker.getSymbolAtLocation(exportName));
            ts.FindAllReferences.Core.eachExportReference(program.getSourceFiles(), checker, cancellationToken, exportSymbol, exportingModuleSymbol, exportName.text, wasDefault, function (ref) {
                var importingSourceFile = ref.getSourceFile();
                if (wasDefault) {
                    changeDefaultToNamedImport(importingSourceFile, ref, changes, exportName.text);
                }
                else {
                    changeNamedToDefaultImport(importingSourceFile, ref, changes);
                }
            });
        }
        function changeDefaultToNamedImport(importingSourceFile, ref, changes, exportName) {
            var parent = ref.parent;
            switch (parent.kind) {
                case 190 /* PropertyAccessExpression */:
                    // `a.default` --> `a.foo`
                    changes.replaceNode(importingSourceFile, ref, ts.createIdentifier(exportName));
                    break;
                case 254 /* ImportSpecifier */:
                case 258 /* ExportSpecifier */: {
                    var spec = parent;
                    // `default as foo` --> `foo`, `default as bar` --> `foo as bar`
                    changes.replaceNode(importingSourceFile, spec, makeImportSpecifier(exportName, spec.name.text));
                    break;
                }
                case 251 /* ImportClause */: {
                    var clause = parent;
                    ts.Debug.assert(clause.name === ref);
                    var spec = makeImportSpecifier(exportName, ref.text);
                    var namedBindings = clause.namedBindings;
                    if (!namedBindings) {
                        // `import foo from "./a";` --> `import { foo } from "./a";`
                        changes.replaceNode(importingSourceFile, ref, ts.createNamedImports([spec]));
                    }
                    else if (namedBindings.kind === 252 /* NamespaceImport */) {
                        // `import foo, * as a from "./a";` --> `import * as a from ".a/"; import { foo } from "./a";`
                        changes.deleteRange(importingSourceFile, { pos: ref.getStart(importingSourceFile), end: namedBindings.getStart(importingSourceFile) });
                        var quotePreference = ts.isStringLiteral(clause.parent.moduleSpecifier) ? ts.quotePreferenceFromString(clause.parent.moduleSpecifier, importingSourceFile) : 1 /* Double */;
                        var newImport = ts.makeImport(/*default*/ undefined, [makeImportSpecifier(exportName, ref.text)], clause.parent.moduleSpecifier, quotePreference);
                        changes.insertNodeAfter(importingSourceFile, clause.parent, newImport);
                    }
                    else {
                        // `import foo, { bar } from "./a"` --> `import { bar, foo } from "./a";`
                        changes.delete(importingSourceFile, ref);
                        changes.insertNodeAtEndOfList(importingSourceFile, namedBindings.elements, spec);
                    }
                    break;
                }
                default:
                    ts.Debug.failBadSyntaxKind(parent);
            }
        }
        function changeNamedToDefaultImport(importingSourceFile, ref, changes) {
            var parent = ref.parent;
            switch (parent.kind) {
                case 190 /* PropertyAccessExpression */:
                    // `a.foo` --> `a.default`
                    changes.replaceNode(importingSourceFile, ref, ts.createIdentifier("default"));
                    break;
                case 254 /* ImportSpecifier */: {
                    // `import { foo } from "./a";` --> `import foo from "./a";`
                    // `import { foo as bar } from "./a";` --> `import bar from "./a";`
                    var defaultImport = ts.createIdentifier(parent.name.text);
                    if (parent.parent.elements.length === 1) {
                        changes.replaceNode(importingSourceFile, parent.parent, defaultImport);
                    }
                    else {
                        changes.delete(importingSourceFile, parent);
                        changes.insertNodeBefore(importingSourceFile, parent.parent, defaultImport);
                    }
                    break;
                }
                case 258 /* ExportSpecifier */: {
                    // `export { foo } from "./a";` --> `export { default as foo } from "./a";`
                    // `export { foo as bar } from "./a";` --> `export { default as bar } from "./a";`
                    // `export { foo as default } from "./a";` --> `export { default } from "./a";`
                    // (Because `export foo from "./a";` isn't valid syntax.)
                    changes.replaceNode(importingSourceFile, parent, makeExportSpecifier("default", parent.name.text));
                    break;
                }
                default:
                    ts.Debug.assertNever(parent);
            }
        }
        function makeImportSpecifier(propertyName, name) {
            return ts.createImportSpecifier(propertyName === name ? undefined : ts.createIdentifier(propertyName), ts.createIdentifier(name));
        }
        function makeExportSpecifier(propertyName, name) {
            return ts.createExportSpecifier(propertyName === name ? undefined : ts.createIdentifier(propertyName), ts.createIdentifier(name));
        }
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var refactorName = "Convert import";
        var actionNameNamespaceToNamed = "Convert namespace import to named imports";
        var actionNameNamedToNamespace = "Convert named imports to namespace import";
        refactor.registerRefactor(refactorName, {
            getAvailableActions: function (context) {
                var i = getImportToConvert(context);
                if (!i)
                    return ts.emptyArray;
                var description = i.kind === 252 /* NamespaceImport */ ? ts.Diagnostics.Convert_namespace_import_to_named_imports.message : ts.Diagnostics.Convert_named_imports_to_namespace_import.message;
                var actionName = i.kind === 252 /* NamespaceImport */ ? actionNameNamespaceToNamed : actionNameNamedToNamespace;
                return [{ name: refactorName, description: description, actions: [{ name: actionName, description: description }] }];
            },
            getEditsForAction: function (context, actionName) {
                ts.Debug.assert(actionName === actionNameNamespaceToNamed || actionName === actionNameNamedToNamespace);
                var edits = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(context.file, context.program, t, ts.Debug.assertDefined(getImportToConvert(context))); });
                return { edits: edits, renameFilename: undefined, renameLocation: undefined };
            }
        });
        // Can convert imports of the form `import * as m from "m";` or `import d, { x, y } from "m";`.
        function getImportToConvert(context) {
            var file = context.file;
            var span = ts.getRefactorContextSpan(context);
            var token = ts.getTokenAtPosition(file, span.start);
            var importDecl = ts.getParentNodeInSpan(token, file, span);
            if (!importDecl || !ts.isImportDeclaration(importDecl))
                return undefined;
            var importClause = importDecl.importClause;
            return importClause && importClause.namedBindings;
        }
        function doChange(sourceFile, program, changes, toConvert) {
            var checker = program.getTypeChecker();
            if (toConvert.kind === 252 /* NamespaceImport */) {
                doChangeNamespaceToNamed(sourceFile, checker, changes, toConvert, ts.getAllowSyntheticDefaultImports(program.getCompilerOptions()));
            }
            else {
                doChangeNamedToNamespace(sourceFile, checker, changes, toConvert);
            }
        }
        function doChangeNamespaceToNamed(sourceFile, checker, changes, toConvert, allowSyntheticDefaultImports) {
            var usedAsNamespaceOrDefault = false;
            var nodesToReplace = [];
            var conflictingNames = ts.createMap();
            ts.FindAllReferences.Core.eachSymbolReferenceInFile(toConvert.name, checker, sourceFile, function (id) {
                if (!ts.isPropertyAccessExpression(id.parent)) {
                    usedAsNamespaceOrDefault = true;
                }
                else {
                    var parent = ts.cast(id.parent, ts.isPropertyAccessExpression);
                    var exportName = parent.name.text;
                    if (checker.resolveName(exportName, id, 67108863 /* All */, /*excludeGlobals*/ true)) {
                        conflictingNames.set(exportName, true);
                    }
                    ts.Debug.assert(parent.expression === id);
                    nodesToReplace.push(parent);
                }
            });
            // We may need to change `mod.x` to `_x` to avoid a name conflict.
            var exportNameToImportName = ts.createMap();
            for (var _i = 0, nodesToReplace_1 = nodesToReplace; _i < nodesToReplace_1.length; _i++) {
                var propertyAccess = nodesToReplace_1[_i];
                var exportName = propertyAccess.name.text;
                var importName = exportNameToImportName.get(exportName);
                if (importName === undefined) {
                    exportNameToImportName.set(exportName, importName = conflictingNames.has(exportName) ? ts.getUniqueName(exportName, sourceFile) : exportName);
                }
                changes.replaceNode(sourceFile, propertyAccess, ts.createIdentifier(importName));
            }
            var importSpecifiers = [];
            exportNameToImportName.forEach(function (name, propertyName) {
                importSpecifiers.push(ts.createImportSpecifier(name === propertyName ? undefined : ts.createIdentifier(propertyName), ts.createIdentifier(name)));
            });
            var importDecl = toConvert.parent.parent;
            if (usedAsNamespaceOrDefault && !allowSyntheticDefaultImports) {
                // Need to leave the namespace import alone
                changes.insertNodeAfter(sourceFile, importDecl, updateImport(importDecl, /*defaultImportName*/ undefined, importSpecifiers));
            }
            else {
                changes.replaceNode(sourceFile, importDecl, updateImport(importDecl, usedAsNamespaceOrDefault ? ts.createIdentifier(toConvert.name.text) : undefined, importSpecifiers));
            }
        }
        function doChangeNamedToNamespace(sourceFile, checker, changes, toConvert) {
            var importDecl = toConvert.parent.parent;
            var moduleSpecifier = importDecl.moduleSpecifier;
            var preferredName = moduleSpecifier && ts.isStringLiteral(moduleSpecifier) ? ts.codefix.moduleSpecifierToValidIdentifier(moduleSpecifier.text, 8 /* ESNext */) : "module";
            var namespaceNameConflicts = toConvert.elements.some(function (element) {
                return ts.FindAllReferences.Core.eachSymbolReferenceInFile(element.name, checker, sourceFile, function (id) {
                    return !!checker.resolveName(preferredName, id, 67108863 /* All */, /*excludeGlobals*/ true);
                }) || false;
            });
            var namespaceImportName = namespaceNameConflicts ? ts.getUniqueName(preferredName, sourceFile) : preferredName;
            var neededNamedImports = [];
            var _loop_13 = function (element) {
                var propertyName = (element.propertyName || element.name).text;
                ts.FindAllReferences.Core.eachSymbolReferenceInFile(element.name, checker, sourceFile, function (id) {
                    var access = ts.createPropertyAccess(ts.createIdentifier(namespaceImportName), propertyName);
                    if (ts.isShorthandPropertyAssignment(id.parent)) {
                        changes.replaceNode(sourceFile, id.parent, ts.createPropertyAssignment(id.text, access));
                    }
                    else if (ts.isExportSpecifier(id.parent) && !id.parent.propertyName) {
                        if (!neededNamedImports.some(function (n) { return n.name === element.name; })) {
                            neededNamedImports.push(ts.createImportSpecifier(element.propertyName && ts.createIdentifier(element.propertyName.text), ts.createIdentifier(element.name.text)));
                        }
                    }
                    else {
                        changes.replaceNode(sourceFile, id, access);
                    }
                });
            };
            for (var _i = 0, _a = toConvert.elements; _i < _a.length; _i++) {
                var element = _a[_i];
                _loop_13(element);
            }
            changes.replaceNode(sourceFile, toConvert, ts.createNamespaceImport(ts.createIdentifier(namespaceImportName)));
            if (neededNamedImports.length) {
                changes.insertNodeAfter(sourceFile, toConvert.parent.parent, updateImport(importDecl, /*defaultImportName*/ undefined, neededNamedImports));
            }
        }
        function updateImport(old, defaultImportName, elements) {
            return ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, ts.createImportClause(defaultImportName, elements && elements.length ? ts.createNamedImports(elements) : undefined), old.moduleSpecifier);
        }
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var extractSymbol;
        (function (extractSymbol) {
            var refactorName = "Extract Symbol";
            refactor.registerRefactor(refactorName, { getAvailableActions: getAvailableActions, getEditsForAction: getEditsForAction });
            /**
             * Compute the associated code actions
             * Exported for tests.
             */
            function getAvailableActions(context) {
                var rangeToExtract = getRangeToExtract(context.file, ts.getRefactorContextSpan(context));
                var targetRange = rangeToExtract.targetRange;
                if (targetRange === undefined) {
                    return ts.emptyArray;
                }
                var extractions = getPossibleExtractions(targetRange, context);
                if (extractions === undefined) {
                    // No extractions possible
                    return ts.emptyArray;
                }
                var functionActions = [];
                var usedFunctionNames = ts.createMap();
                var constantActions = [];
                var usedConstantNames = ts.createMap();
                var i = 0;
                for (var _i = 0, extractions_1 = extractions; _i < extractions_1.length; _i++) {
                    var _a = extractions_1[_i], functionExtraction = _a.functionExtraction, constantExtraction = _a.constantExtraction;
                    // Skip these since we don't have a way to report errors yet
                    if (functionExtraction.errors.length === 0) {
                        // Don't issue refactorings with duplicated names.
                        // Scopes come back in "innermost first" order, so extractions will
                        // preferentially go into nearer scopes
                        var description = functionExtraction.description;
                        if (!usedFunctionNames.has(description)) {
                            usedFunctionNames.set(description, true);
                            functionActions.push({
                                description: description,
                                name: "function_scope_" + i
                            });
                        }
                    }
                    // Skip these since we don't have a way to report errors yet
                    if (constantExtraction.errors.length === 0) {
                        // Don't issue refactorings with duplicated names.
                        // Scopes come back in "innermost first" order, so extractions will
                        // preferentially go into nearer scopes
                        var description = constantExtraction.description;
                        if (!usedConstantNames.has(description)) {
                            usedConstantNames.set(description, true);
                            constantActions.push({
                                description: description,
                                name: "constant_scope_" + i
                            });
                        }
                    }
                    // *do* increment i anyway because we'll look for the i-th scope
                    // later when actually doing the refactoring if the user requests it
                    i++;
                }
                var infos = [];
                if (functionActions.length) {
                    infos.push({
                        name: refactorName,
                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_function),
                        actions: functionActions
                    });
                }
                if (constantActions.length) {
                    infos.push({
                        name: refactorName,
                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_constant),
                        actions: constantActions
                    });
                }
                return infos.length ? infos : ts.emptyArray;
            }
            extractSymbol.getAvailableActions = getAvailableActions;
            /* Exported for tests */
            function getEditsForAction(context, actionName) {
                var rangeToExtract = getRangeToExtract(context.file, ts.getRefactorContextSpan(context));
                var targetRange = rangeToExtract.targetRange; // TODO:GH#18217
                var parsedFunctionIndexMatch = /^function_scope_(\d+)$/.exec(actionName);
                if (parsedFunctionIndexMatch) {
                    var index = +parsedFunctionIndexMatch[1];
                    ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the function scope index");
                    return getFunctionExtractionAtIndex(targetRange, context, index);
                }
                var parsedConstantIndexMatch = /^constant_scope_(\d+)$/.exec(actionName);
                if (parsedConstantIndexMatch) {
                    var index = +parsedConstantIndexMatch[1];
                    ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the constant scope index");
                    return getConstantExtractionAtIndex(targetRange, context, index);
                }
                ts.Debug.fail("Unrecognized action name");
            }
            extractSymbol.getEditsForAction = getEditsForAction;
            // Move these into diagnostic messages if they become user-facing
            var Messages;
            (function (Messages) {
                function createMessage(message) {
                    return { message: message, code: 0, category: ts.DiagnosticCategory.Message, key: message };
                }
                Messages.cannotExtractRange = createMessage("Cannot extract range.");
                Messages.cannotExtractImport = createMessage("Cannot extract import statement.");
                Messages.cannotExtractSuper = createMessage("Cannot extract super call.");
                Messages.cannotExtractEmpty = createMessage("Cannot extract empty range.");
                Messages.expressionExpected = createMessage("expression expected.");
                Messages.uselessConstantType = createMessage("No reason to extract constant of type.");
                Messages.statementOrExpressionExpected = createMessage("Statement or expression expected.");
                Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements = createMessage("Cannot extract range containing conditional break or continue statements.");
                Messages.cannotExtractRangeContainingConditionalReturnStatement = createMessage("Cannot extract range containing conditional return statement.");
                Messages.cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange = createMessage("Cannot extract range containing labeled break or continue with target outside of the range.");
                Messages.cannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators = createMessage("Cannot extract range containing writes to references located outside of the target range in generators.");
                Messages.typeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope.");
                Messages.functionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope.");
                Messages.cannotExtractIdentifier = createMessage("Select more than a single identifier.");
                Messages.cannotExtractExportedEntity = createMessage("Cannot extract exported declaration");
                Messages.cannotWriteInExpression = createMessage("Cannot write back side-effects when extracting an expression");
                Messages.cannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor");
                Messages.cannotExtractAmbientBlock = createMessage("Cannot extract code from ambient contexts");
                Messages.cannotAccessVariablesFromNestedScopes = createMessage("Cannot access variables from nested scopes");
                Messages.cannotExtractToOtherFunctionLike = createMessage("Cannot extract method to a function-like scope that is not a function");
                Messages.cannotExtractToJSClass = createMessage("Cannot extract constant to a class scope in JS");
                Messages.cannotExtractToExpressionArrowFunction = createMessage("Cannot extract constant to an arrow function without a block");
            })(Messages = extractSymbol.Messages || (extractSymbol.Messages = {}));
            var RangeFacts;
            (function (RangeFacts) {
                RangeFacts[RangeFacts["None"] = 0] = "None";
                RangeFacts[RangeFacts["HasReturn"] = 1] = "HasReturn";
                RangeFacts[RangeFacts["IsGenerator"] = 2] = "IsGenerator";
                RangeFacts[RangeFacts["IsAsyncFunction"] = 4] = "IsAsyncFunction";
                RangeFacts[RangeFacts["UsesThis"] = 8] = "UsesThis";
                /**
                 * The range is in a function which needs the 'static' modifier in a class
                 */
                RangeFacts[RangeFacts["InStaticRegion"] = 16] = "InStaticRegion";
            })(RangeFacts || (RangeFacts = {}));
            /**
             * getRangeToExtract takes a span inside a text file and returns either an expression or an array
             * of statements representing the minimum set of nodes needed to extract the entire span. This
             * process may fail, in which case a set of errors is returned instead (these are currently
             * not shown to the user, but can be used by us diagnostically)
             */
            // exported only for tests
            function getRangeToExtract(sourceFile, span) {
                var length = span.length;
                if (length === 0) {
                    return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractEmpty)] };
                }
                // Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span.
                // This may fail (e.g. you select two statements in the root of a source file)
                var start = ts.getParentNodeInSpan(ts.getTokenAtPosition(sourceFile, span.start), sourceFile, span);
                // Do the same for the ending position
                var end = ts.getParentNodeInSpan(ts.findTokenOnLeftOfPosition(sourceFile, ts.textSpanEnd(span)), sourceFile, span);
                var declarations = [];
                // We'll modify these flags as we walk the tree to collect data
                // about what things need to be done as part of the extraction.
                var rangeFacts = RangeFacts.None;
                if (!start || !end) {
                    // cannot find either start or end node
                    return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] };
                }
                if (start.parent !== end.parent) {
                    // start and end nodes belong to different subtrees
                    return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] };
                }
                if (start !== end) {
                    // start and end should be statements and parent should be either block or a source file
                    if (!isBlockLike(start.parent)) {
                        return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] };
                    }
                    var statements = [];
                    var start2 = start; // TODO: GH#18217 Need to alias `start` to get this to compile. See https://github.com/Microsoft/TypeScript/issues/19955#issuecomment-344118248
                    for (var _i = 0, _a = start2.parent.statements; _i < _a.length; _i++) {
                        var statement = _a[_i];
                        if (statement === start || statements.length) {
                            var errors_1 = checkNode(statement);
                            if (errors_1) {
                                return { errors: errors_1 };
                            }
                            statements.push(statement);
                        }
                        if (statement === end) {
                            break;
                        }
                    }
                    if (!statements.length) {
                        // https://github.com/Microsoft/TypeScript/issues/20559
                        // Ranges like [|case 1: break;|] will fail to populate `statements` because
                        // they will never find `start` in `start.parent.statements`.
                        // Consider: We could support ranges like [|case 1:|] by refining them to just
                        // the expression.
                        return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] };
                    }
                    return { targetRange: { range: statements, facts: rangeFacts, declarations: declarations } };
                }
                if (ts.isReturnStatement(start) && !start.expression) {
                    // Makes no sense to extract an expression-less return statement.
                    return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] };
                }
                // We have a single node (start)
                var node = refineNode(start);
                var errors = checkRootNode(node) || checkNode(node);
                if (errors) {
                    return { errors: errors };
                }
                return { targetRange: { range: getStatementOrExpressionRange(node), facts: rangeFacts, declarations: declarations } }; // TODO: GH#18217
                /**
                 * Attempt to refine the extraction node (generally, by shrinking it) to produce better results.
                 * @param node The unrefined extraction node.
                 */
                function refineNode(node) {
                    if (ts.isReturnStatement(node)) {
                        if (node.expression) {
                            return node.expression;
                        }
                    }
                    else if (ts.isVariableStatement(node)) {
                        var numInitializers = 0;
                        var lastInitializer = void 0;
                        for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                            var declaration = _a[_i];
                            if (declaration.initializer) {
                                numInitializers++;
                                lastInitializer = declaration.initializer;
                            }
                        }
                        if (numInitializers === 1) {
                            return lastInitializer;
                        }
                        // No special handling if there are multiple initializers.
                    }
                    else if (ts.isVariableDeclaration(node)) {
                        if (node.initializer) {
                            return node.initializer;
                        }
                    }
                    return node;
                }
                function checkRootNode(node) {
                    if (ts.isIdentifier(ts.isExpressionStatement(node) ? node.expression : node)) {
                        return [ts.createDiagnosticForNode(node, Messages.cannotExtractIdentifier)];
                    }
                    return undefined;
                }
                function checkForStaticContext(nodeToCheck, containingClass) {
                    var current = nodeToCheck;
                    while (current !== containingClass) {
                        if (current.kind === 155 /* PropertyDeclaration */) {
                            if (ts.hasModifier(current, 32 /* Static */)) {
                                rangeFacts |= RangeFacts.InStaticRegion;
                            }
                            break;
                        }
                        else if (current.kind === 152 /* Parameter */) {
                            var ctorOrMethod = ts.getContainingFunction(current);
                            if (ctorOrMethod.kind === 158 /* Constructor */) {
                                rangeFacts |= RangeFacts.InStaticRegion;
                            }
                            break;
                        }
                        else if (current.kind === 157 /* MethodDeclaration */) {
                            if (ts.hasModifier(current, 32 /* Static */)) {
                                rangeFacts |= RangeFacts.InStaticRegion;
                            }
                        }
                        current = current.parent;
                    }
                }
                // Verifies whether we can actually extract this node or not.
                function checkNode(nodeToCheck) {
                    var PermittedJumps;
                    (function (PermittedJumps) {
                        PermittedJumps[PermittedJumps["None"] = 0] = "None";
                        PermittedJumps[PermittedJumps["Break"] = 1] = "Break";
                        PermittedJumps[PermittedJumps["Continue"] = 2] = "Continue";
                        PermittedJumps[PermittedJumps["Return"] = 4] = "Return";
                    })(PermittedJumps || (PermittedJumps = {}));
                    // We believe it's true because the node is from the (unmodified) tree.
                    ts.Debug.assert(nodeToCheck.pos <= nodeToCheck.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
                    // For understanding how skipTrivia functioned:
                    ts.Debug.assert(!ts.positionIsSynthesized(nodeToCheck.pos), "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
                    if (!ts.isStatement(nodeToCheck) && !(ts.isExpressionNode(nodeToCheck) && isExtractableExpression(nodeToCheck))) {
                        return [ts.createDiagnosticForNode(nodeToCheck, Messages.statementOrExpressionExpected)];
                    }
                    if (nodeToCheck.flags & 4194304 /* Ambient */) {
                        return [ts.createDiagnosticForNode(nodeToCheck, Messages.cannotExtractAmbientBlock)];
                    }
                    // If we're in a class, see whether we're in a static region (static property initializer, static method, class constructor parameter default)
                    var containingClass = ts.getContainingClass(nodeToCheck);
                    if (containingClass) {
                        checkForStaticContext(nodeToCheck, containingClass);
                    }
                    var errors;
                    var permittedJumps = 4 /* Return */;
                    var seenLabels;
                    visit(nodeToCheck);
                    return errors;
                    function visit(node) {
                        if (errors) {
                            // already found an error - can stop now
                            return true;
                        }
                        if (ts.isDeclaration(node)) {
                            var declaringNode = (node.kind === 238 /* VariableDeclaration */) ? node.parent.parent : node;
                            if (ts.hasModifier(declaringNode, 1 /* Export */)) {
                                // TODO: GH#18217 Silly to use `errors ||` since it's definitely not defined (see top of `visit`)
                                // Also, if we're only pushing one error, just use `let error: Diagnostic | undefined`!
                                // Also TODO: GH#19956
                                (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractExportedEntity));
                                return true;
                            }
                            declarations.push(node.symbol);
                        }
                        // Some things can't be extracted in certain situations
                        switch (node.kind) {
                            case 250 /* ImportDeclaration */:
                                (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractImport));
                                return true;
                            case 99 /* SuperKeyword */:
                                // For a super *constructor call*, we have to be extracting the entire class,
                                // but a super *method call* simply implies a 'this' reference
                                if (node.parent.kind === 192 /* CallExpression */) {
                                    // Super constructor call
                                    var containingClass_1 = ts.getContainingClass(node); // TODO:GH#18217
                                    if (containingClass_1.pos < span.start || containingClass_1.end >= (span.start + span.length)) {
                                        (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractSuper));
                                        return true;
                                    }
                                }
                                else {
                                    rangeFacts |= RangeFacts.UsesThis;
                                }
                                break;
                        }
                        if (ts.isFunctionLikeDeclaration(node) || ts.isClassLike(node)) {
                            switch (node.kind) {
                                case 240 /* FunctionDeclaration */:
                                case 241 /* ClassDeclaration */:
                                    if (ts.isSourceFile(node.parent) && node.parent.externalModuleIndicator === undefined) {
                                        // You cannot extract global declarations
                                        (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.functionWillNotBeVisibleInTheNewScope));
                                    }
                                    break;
                            }
                            // do not dive into functions or classes
                            return false;
                        }
                        var savedPermittedJumps = permittedJumps;
                        switch (node.kind) {
                            case 223 /* IfStatement */:
                                permittedJumps = 0 /* None */;
                                break;
                            case 236 /* TryStatement */:
                                // forbid all jumps inside try blocks
                                permittedJumps = 0 /* None */;
                                break;
                            case 219 /* Block */:
                                if (node.parent && node.parent.kind === 236 /* TryStatement */ && node.parent.finallyBlock === node) {
                                    // allow unconditional returns from finally blocks
                                    permittedJumps = 4 /* Return */;
                                }
                                break;
                            case 272 /* CaseClause */:
                                // allow unlabeled break inside case clauses
                                permittedJumps |= 1 /* Break */;
                                break;
                            default:
                                if (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false)) {
                                    // allow unlabeled break/continue inside loops
                                    permittedJumps |= 1 /* Break */ | 2 /* Continue */;
                                }
                                break;
                        }
                        switch (node.kind) {
                            case 179 /* ThisType */:
                            case 101 /* ThisKeyword */:
                                rangeFacts |= RangeFacts.UsesThis;
                                break;
                            case 234 /* LabeledStatement */: {
                                var label = node.label;
                                (seenLabels || (seenLabels = [])).push(label.escapedText);
                                ts.forEachChild(node, visit);
                                seenLabels.pop();
                                break;
                            }
                            case 230 /* BreakStatement */:
                            case 229 /* ContinueStatement */: {
                                var label = node.label;
                                if (label) {
                                    if (!ts.contains(seenLabels, label.escapedText)) {
                                        // attempts to jump to label that is not in range to be extracted
                                        (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange));
                                    }
                                }
                                else {
                                    if (!(permittedJumps & (node.kind === 230 /* BreakStatement */ ? 1 /* Break */ : 2 /* Continue */))) {
                                        // attempt to break or continue in a forbidden context
                                        (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements));
                                    }
                                }
                                break;
                            }
                            case 202 /* AwaitExpression */:
                                rangeFacts |= RangeFacts.IsAsyncFunction;
                                break;
                            case 208 /* YieldExpression */:
                                rangeFacts |= RangeFacts.IsGenerator;
                                break;
                            case 231 /* ReturnStatement */:
                                if (permittedJumps & 4 /* Return */) {
                                    rangeFacts |= RangeFacts.HasReturn;
                                }
                                else {
                                    (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractRangeContainingConditionalReturnStatement));
                                }
                                break;
                            default:
                                ts.forEachChild(node, visit);
                                break;
                        }
                        permittedJumps = savedPermittedJumps;
                    }
                }
            }
            extractSymbol.getRangeToExtract = getRangeToExtract;
            function getStatementOrExpressionRange(node) {
                if (ts.isStatement(node)) {
                    return [node];
                }
                else if (ts.isExpressionNode(node)) {
                    // If our selection is the expression in an ExpressionStatement, expand
                    // the selection to include the enclosing Statement (this stops us
                    // from trying to care about the return value of the extracted function
                    // and eliminates double semicolon insertion in certain scenarios)
                    return ts.isExpressionStatement(node.parent) ? [node.parent] : node;
                }
                return undefined;
            }
            function isScope(node) {
                return ts.isFunctionLikeDeclaration(node) || ts.isSourceFile(node) || ts.isModuleBlock(node) || ts.isClassLike(node);
            }
            /**
             * Computes possible places we could extract the function into. For example,
             * you may be able to extract into a class method *or* local closure *or* namespace function,
             * depending on what's in the extracted body.
             */
            function collectEnclosingScopes(range) {
                var current = isReadonlyArray(range.range) ? ts.first(range.range) : range.range;
                if (range.facts & RangeFacts.UsesThis) {
                    // if range uses this as keyword or as type inside the class then it can only be extracted to a method of the containing class
                    var containingClass = ts.getContainingClass(current);
                    if (containingClass) {
                        var containingFunction = ts.findAncestor(current, ts.isFunctionLikeDeclaration);
                        return containingFunction
                            ? [containingFunction, containingClass]
                            : [containingClass];
                    }
                }
                var scopes = [];
                while (true) {
                    current = current.parent;
                    // A function parameter's initializer is actually in the outer scope, not the function declaration
                    if (current.kind === 152 /* Parameter */) {
                        // Skip all the way to the outer scope of the function that declared this parameter
                        current = ts.findAncestor(current, function (parent) { return ts.isFunctionLikeDeclaration(parent); }).parent;
                    }
                    // We want to find the nearest parent where we can place an "equivalent" sibling to the node we're extracting out of.
                    // Walk up to the closest parent of a place where we can logically put a sibling:
                    //  * Function declaration
                    //  * Class declaration or expression
                    //  * Module/namespace or source file
                    if (isScope(current)) {
                        scopes.push(current);
                        if (current.kind === 285 /* SourceFile */) {
                            return scopes;
                        }
                    }
                }
            }
            function getFunctionExtractionAtIndex(targetRange, context, requestedChangesIndex) {
                var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, target = _b.target, usagesPerScope = _b.usagesPerScope, functionErrorsPerScope = _b.functionErrorsPerScope, exposedVariableDeclarations = _b.exposedVariableDeclarations;
                ts.Debug.assert(!functionErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?");
                context.cancellationToken.throwIfCancellationRequested(); // TODO: GH#18217
                return extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], exposedVariableDeclarations, targetRange, context);
            }
            function getConstantExtractionAtIndex(targetRange, context, requestedChangesIndex) {
                var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, target = _b.target, usagesPerScope = _b.usagesPerScope, constantErrorsPerScope = _b.constantErrorsPerScope, exposedVariableDeclarations = _b.exposedVariableDeclarations;
                ts.Debug.assert(!constantErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?");
                ts.Debug.assert(exposedVariableDeclarations.length === 0, "Extract constant accepted a range containing a variable declaration?");
                context.cancellationToken.throwIfCancellationRequested();
                var expression = ts.isExpression(target)
                    ? target
                    : target.statements[0].expression;
                return extractConstantInScope(expression, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange.facts, context);
            }
            /**
             * Given a piece of text to extract ('targetRange'), computes a list of possible extractions.
             * Each returned ExtractResultForScope corresponds to a possible target scope and is either a set of changes
             * or an error explaining why we can't extract into that scope.
             */
            function getPossibleExtractions(targetRange, context) {
                var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, functionErrorsPerScope = _b.functionErrorsPerScope, constantErrorsPerScope = _b.constantErrorsPerScope;
                // Need the inner type annotation to avoid https://github.com/Microsoft/TypeScript/issues/7547
                var extractions = scopes.map(function (scope, i) {
                    var functionDescriptionPart = getDescriptionForFunctionInScope(scope);
                    var constantDescriptionPart = getDescriptionForConstantInScope(scope);
                    var scopeDescription = ts.isFunctionLikeDeclaration(scope)
                        ? getDescriptionForFunctionLikeDeclaration(scope)
                        : ts.isClassLike(scope)
                            ? getDescriptionForClassLikeDeclaration(scope)
                            : getDescriptionForModuleLikeDeclaration(scope);
                    var functionDescription;
                    var constantDescription;
                    if (scopeDescription === 1 /* Global */) {
                        functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [functionDescriptionPart, "global"]);
                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [constantDescriptionPart, "global"]);
                    }
                    else if (scopeDescription === 0 /* Module */) {
                        functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [functionDescriptionPart, "module"]);
                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [constantDescriptionPart, "module"]);
                    }
                    else {
                        functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1), [functionDescriptionPart, scopeDescription]);
                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1), [constantDescriptionPart, scopeDescription]);
                    }
                    // Customize the phrasing for the innermost scope to increase clarity.
                    if (i === 0 && !ts.isClassLike(scope)) {
                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_enclosing_scope), [constantDescriptionPart]);
                    }
                    return {
                        functionExtraction: {
                            description: functionDescription,
                            errors: functionErrorsPerScope[i],
                        },
                        constantExtraction: {
                            description: constantDescription,
                            errors: constantErrorsPerScope[i],
                        },
                    };
                });
                return extractions;
            }
            function getPossibleExtractionsWorker(targetRange, context) {
                var sourceFile = context.file;
                var scopes = collectEnclosingScopes(targetRange);
                var enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile);
                var readsAndWrites = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker(), context.cancellationToken);
                return { scopes: scopes, readsAndWrites: readsAndWrites };
            }
            function getDescriptionForFunctionInScope(scope) {
                return ts.isFunctionLikeDeclaration(scope)
                    ? "inner function"
                    : ts.isClassLike(scope)
                        ? "method"
                        : "function";
            }
            function getDescriptionForConstantInScope(scope) {
                return ts.isClassLike(scope)
                    ? "readonly field"
                    : "constant";
            }
            function getDescriptionForFunctionLikeDeclaration(scope) {
                switch (scope.kind) {
                    case 158 /* Constructor */:
                        return "constructor";
                    case 197 /* FunctionExpression */:
                    case 240 /* FunctionDeclaration */:
                        return scope.name
                            ? "function '" + scope.name.text + "'"
                            : "anonymous function";
                    case 198 /* ArrowFunction */:
                        return "arrow function";
                    case 157 /* MethodDeclaration */:
                        return "method '" + scope.name.getText() + "'";
                    case 159 /* GetAccessor */:
                        return "'get " + scope.name.getText() + "'";
                    case 160 /* SetAccessor */:
                        return "'set " + scope.name.getText() + "'";
                    default:
                        throw ts.Debug.assertNever(scope);
                }
            }
            function getDescriptionForClassLikeDeclaration(scope) {
                return scope.kind === 241 /* ClassDeclaration */
                    ? scope.name ? "class '" + scope.name.text + "'" : "anonymous class declaration"
                    : scope.name ? "class expression '" + scope.name.text + "'" : "anonymous class expression";
            }
            function getDescriptionForModuleLikeDeclaration(scope) {
                return scope.kind === 246 /* ModuleBlock */
                    ? "namespace '" + scope.parent.name.getText() + "'"
                    : scope.externalModuleIndicator ? 0 /* Module */ : 1 /* Global */;
            }
            var SpecialScope;
            (function (SpecialScope) {
                SpecialScope[SpecialScope["Module"] = 0] = "Module";
                SpecialScope[SpecialScope["Global"] = 1] = "Global";
            })(SpecialScope || (SpecialScope = {}));
            /**
             * Result of 'extractRange' operation for a specific scope.
             * Stores either a list of changes that should be applied to extract a range or a list of errors
             */
            function extractFunctionInScope(node, scope, _a, exposedVariableDeclarations, range, context) {
                var usagesInScope = _a.usages, typeParameterUsages = _a.typeParameterUsages, substitutions = _a.substitutions;
                var checker = context.program.getTypeChecker();
                // Make a unique name for the extracted function
                var file = scope.getSourceFile();
                var functionNameText = ts.getUniqueName(ts.isClassLike(scope) ? "newMethod" : "newFunction", file);
                var isJS = ts.isInJSFile(scope);
                var functionName = ts.createIdentifier(functionNameText);
                var returnType;
                var parameters = [];
                var callArguments = [];
                var writes;
                usagesInScope.forEach(function (usage, name) {
                    var typeNode;
                    if (!isJS) {
                        var type = checker.getTypeOfSymbolAtLocation(usage.symbol, usage.node);
                        // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
                        type = checker.getBaseTypeOfLiteralType(type);
                        typeNode = checker.typeToTypeNode(type, scope, 1 /* NoTruncation */);
                    }
                    var paramDecl = ts.createParameter(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, 
                    /*dotDotDotToken*/ undefined, 
                    /*name*/ name, 
                    /*questionToken*/ undefined, typeNode);
                    parameters.push(paramDecl);
                    if (usage.usage === 2 /* Write */) {
                        (writes || (writes = [])).push(usage);
                    }
                    callArguments.push(ts.createIdentifier(name));
                });
                var typeParametersAndDeclarations = ts.arrayFrom(typeParameterUsages.values()).map(function (type) { return ({ type: type, declaration: getFirstDeclaration(type) }); });
                var sortedTypeParametersAndDeclarations = typeParametersAndDeclarations.sort(compareTypesByDeclarationOrder);
                var typeParameters = sortedTypeParametersAndDeclarations.length === 0
                    ? undefined
                    : sortedTypeParametersAndDeclarations.map(function (t) { return t.declaration; });
                // Strictly speaking, we should check whether each name actually binds to the appropriate type
                // parameter.  In cases of shadowing, they may not.
                var callTypeArguments = typeParameters !== undefined
                    ? typeParameters.map(function (decl) { return ts.createTypeReferenceNode(decl.name, /*typeArguments*/ undefined); })
                    : undefined;
                // Provide explicit return types for contextually-typed functions
                // to avoid problems when there are literal types present
                if (ts.isExpression(node) && !isJS) {
                    var contextualType = checker.getContextualType(node);
                    returnType = checker.typeToTypeNode(contextualType, scope, 1 /* NoTruncation */); // TODO: GH#18217
                }
                var _b = transformFunctionBody(node, exposedVariableDeclarations, writes, substitutions, !!(range.facts & RangeFacts.HasReturn)), body = _b.body, returnValueProperty = _b.returnValueProperty;
                ts.suppressLeadingAndTrailingTrivia(body);
                var newFunction;
                if (ts.isClassLike(scope)) {
                    // always create private method in TypeScript files
                    var modifiers = isJS ? [] : [ts.createToken(114 /* PrivateKeyword */)];
                    if (range.facts & RangeFacts.InStaticRegion) {
                        modifiers.push(ts.createToken(117 /* StaticKeyword */));
                    }
                    if (range.facts & RangeFacts.IsAsyncFunction) {
                        modifiers.push(ts.createToken(122 /* AsyncKeyword */));
                    }
                    newFunction = ts.createMethod(
                    /*decorators*/ undefined, modifiers.length ? modifiers : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(40 /* AsteriskToken */) : undefined, functionName, 
                    /*questionToken*/ undefined, typeParameters, parameters, returnType, body);
                }
                else {
                    newFunction = ts.createFunctionDeclaration(
                    /*decorators*/ undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.createToken(122 /* AsyncKeyword */)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(40 /* AsteriskToken */) : undefined, functionName, typeParameters, parameters, returnType, body);
                }
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                var minInsertionPos = (isReadonlyArray(range.range) ? ts.last(range.range) : range.range).end;
                var nodeToInsertBefore = getNodeToInsertFunctionBefore(minInsertionPos, scope);
                if (nodeToInsertBefore) {
                    changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newFunction, /*blankLineBetween*/ true);
                }
                else {
                    changeTracker.insertNodeAtEndOfScope(context.file, scope, newFunction);
                }
                var newNodes = [];
                // replace range with function call
                var called = getCalledExpression(scope, range, functionNameText);
                var call = ts.createCall(called, callTypeArguments, // Note that no attempt is made to take advantage of type argument inference
                callArguments);
                if (range.facts & RangeFacts.IsGenerator) {
                    call = ts.createYield(ts.createToken(40 /* AsteriskToken */), call);
                }
                if (range.facts & RangeFacts.IsAsyncFunction) {
                    call = ts.createAwait(call);
                }
                if (exposedVariableDeclarations.length && !writes) {
                    // No need to mix declarations and writes.
                    // How could any variables be exposed if there's a return statement?
                    ts.Debug.assert(!returnValueProperty);
                    ts.Debug.assert(!(range.facts & RangeFacts.HasReturn));
                    if (exposedVariableDeclarations.length === 1) {
                        // Declaring exactly one variable: let x = newFunction();
                        var variableDeclaration = exposedVariableDeclarations[0];
                        newNodes.push(ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.getSynthesizedDeepClone(variableDeclaration.name), /*type*/ ts.getSynthesizedDeepClone(variableDeclaration.type), /*initializer*/ call)], // TODO (acasey): test binding patterns
                        variableDeclaration.parent.flags)));
                    }
                    else {
                        // Declaring multiple variables / return properties:
                        //   let {x, y} = newFunction();
                        var bindingElements = [];
                        var typeElements = [];
                        var commonNodeFlags = exposedVariableDeclarations[0].parent.flags;
                        var sawExplicitType = false;
                        for (var _i = 0, exposedVariableDeclarations_1 = exposedVariableDeclarations; _i < exposedVariableDeclarations_1.length; _i++) {
                            var variableDeclaration = exposedVariableDeclarations_1[_i];
                            bindingElements.push(ts.createBindingElement(
                            /*dotDotDotToken*/ undefined, 
                            /*propertyName*/ undefined, 
                            /*name*/ ts.getSynthesizedDeepClone(variableDeclaration.name)));
                            // Being returned through an object literal will have widened the type.
                            var variableType = checker.typeToTypeNode(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(variableDeclaration)), scope, 1 /* NoTruncation */);
                            typeElements.push(ts.createPropertySignature(
                            /*modifiers*/ undefined, 
                            /*name*/ variableDeclaration.symbol.name, 
                            /*questionToken*/ undefined, 
                            /*type*/ variableType, 
                            /*initializer*/ undefined));
                            sawExplicitType = sawExplicitType || variableDeclaration.type !== undefined;
                            commonNodeFlags = commonNodeFlags & variableDeclaration.parent.flags;
                        }
                        var typeLiteral = sawExplicitType ? ts.createTypeLiteralNode(typeElements) : undefined;
                        if (typeLiteral) {
                            ts.setEmitFlags(typeLiteral, 1 /* SingleLine */);
                        }
                        newNodes.push(ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createObjectBindingPattern(bindingElements), 
                            /*type*/ typeLiteral, 
                            /*initializer*/ call)], commonNodeFlags)));
                    }
                }
                else if (exposedVariableDeclarations.length || writes) {
                    if (exposedVariableDeclarations.length) {
                        // CONSIDER: we're going to create one statement per variable, but we could actually preserve their original grouping.
                        for (var _c = 0, exposedVariableDeclarations_2 = exposedVariableDeclarations; _c < exposedVariableDeclarations_2.length; _c++) {
                            var variableDeclaration = exposedVariableDeclarations_2[_c];
                            var flags = variableDeclaration.parent.flags;
                            if (flags & 2 /* Const */) {
                                flags = (flags & ~2 /* Const */) | 1 /* Let */;
                            }
                            newNodes.push(ts.createVariableStatement(
                            /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(variableDeclaration.symbol.name, getTypeDeepCloneUnionUndefined(variableDeclaration.type))], flags)));
                        }
                    }
                    if (returnValueProperty) {
                        // has both writes and return, need to create variable declaration to hold return value;
                        newNodes.push(ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(returnValueProperty, getTypeDeepCloneUnionUndefined(returnType))], 1 /* Let */)));
                    }
                    var assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes);
                    if (returnValueProperty) {
                        assignments.unshift(ts.createShorthandPropertyAssignment(returnValueProperty));
                    }
                    // propagate writes back
                    if (assignments.length === 1) {
                        // We would only have introduced a return value property if there had been
                        // other assignments to make.
                        ts.Debug.assert(!returnValueProperty);
                        newNodes.push(ts.createStatement(ts.createAssignment(assignments[0].name, call)));
                        if (range.facts & RangeFacts.HasReturn) {
                            newNodes.push(ts.createReturn());
                        }
                    }
                    else {
                        // emit e.g.
                        //   { a, b, __return } = newFunction(a, b);
                        //   return __return;
                        newNodes.push(ts.createStatement(ts.createAssignment(ts.createObjectLiteral(assignments), call)));
                        if (returnValueProperty) {
                            newNodes.push(ts.createReturn(ts.createIdentifier(returnValueProperty)));
                        }
                    }
                }
                else {
                    if (range.facts & RangeFacts.HasReturn) {
                        newNodes.push(ts.createReturn(call));
                    }
                    else if (isReadonlyArray(range.range)) {
                        newNodes.push(ts.createStatement(call));
                    }
                    else {
                        newNodes.push(call);
                    }
                }
                if (isReadonlyArray(range.range)) {
                    changeTracker.replaceNodeRangeWithNodes(context.file, ts.first(range.range), ts.last(range.range), newNodes);
                }
                else {
                    changeTracker.replaceNodeWithNodes(context.file, range.range, newNodes);
                }
                var edits = changeTracker.getChanges();
                var renameRange = isReadonlyArray(range.range) ? ts.first(range.range) : range.range;
                var renameFilename = renameRange.getSourceFile().fileName;
                var renameLocation = ts.getRenameLocation(edits, renameFilename, functionNameText, /*isDeclaredBeforeUse*/ false);
                return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits };
                function getTypeDeepCloneUnionUndefined(typeNode) {
                    if (typeNode === undefined) {
                        return undefined;
                    }
                    var clone = ts.getSynthesizedDeepClone(typeNode);
                    var withoutParens = clone;
                    while (ts.isParenthesizedTypeNode(withoutParens)) {
                        withoutParens = withoutParens.type;
                    }
                    return ts.isUnionTypeNode(withoutParens) && ts.find(withoutParens.types, function (t) { return t.kind === 142 /* UndefinedKeyword */; })
                        ? clone
                        : ts.createUnionTypeNode([clone, ts.createKeywordTypeNode(142 /* UndefinedKeyword */)]);
                }
            }
            /**
             * Result of 'extractRange' operation for a specific scope.
             * Stores either a list of changes that should be applied to extract a range or a list of errors
             */
            function extractConstantInScope(node, scope, _a, rangeFacts, context) {
                var substitutions = _a.substitutions;
                var checker = context.program.getTypeChecker();
                // Make a unique name for the extracted variable
                var file = scope.getSourceFile();
                var localNameText = ts.getUniqueName(ts.isClassLike(scope) ? "newProperty" : "newLocal", file);
                var isJS = ts.isInJSFile(scope);
                var variableType = isJS || !checker.isContextSensitive(node)
                    ? undefined
                    : checker.typeToTypeNode(checker.getContextualType(node), scope, 1 /* NoTruncation */); // TODO: GH#18217
                var initializer = transformConstantInitializer(node, substitutions);
                ts.suppressLeadingAndTrailingTrivia(initializer);
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                if (ts.isClassLike(scope)) {
                    ts.Debug.assert(!isJS); // See CannotExtractToJSClass
                    var modifiers = [];
                    modifiers.push(ts.createToken(114 /* PrivateKeyword */));
                    if (rangeFacts & RangeFacts.InStaticRegion) {
                        modifiers.push(ts.createToken(117 /* StaticKeyword */));
                    }
                    modifiers.push(ts.createToken(134 /* ReadonlyKeyword */));
                    var newVariable = ts.createProperty(
                    /*decorators*/ undefined, modifiers, localNameText, 
                    /*questionToken*/ undefined, variableType, initializer);
                    var localReference = ts.createPropertyAccess(rangeFacts & RangeFacts.InStaticRegion
                        ? ts.createIdentifier(scope.name.getText()) // TODO: GH#18217
                        : ts.createThis(), ts.createIdentifier(localNameText));
                    // Declare
                    var maxInsertionPos = node.pos;
                    var nodeToInsertBefore = getNodeToInsertPropertyBefore(maxInsertionPos, scope);
                    changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariable, /*blankLineBetween*/ true);
                    // Consume
                    changeTracker.replaceNode(context.file, node, localReference);
                }
                else {
                    var newVariableDeclaration = ts.createVariableDeclaration(localNameText, variableType, initializer);
                    // If the node is part of an initializer in a list of variable declarations, insert a new
                    // variable declaration into the list (in case it depends on earlier ones).
                    // CONSIDER: If the declaration list isn't const, we might want to split it into multiple
                    // lists so that the newly extracted one can be const.
                    var oldVariableDeclaration = getContainingVariableDeclarationIfInList(node, scope);
                    if (oldVariableDeclaration) {
                        // Declare
                        // CONSIDER: could detect that each is on a separate line (See `extractConstant_VariableList_MultipleLines` in `extractConstants.ts`)
                        changeTracker.insertNodeBefore(context.file, oldVariableDeclaration, newVariableDeclaration);
                        // Consume
                        var localReference = ts.createIdentifier(localNameText);
                        changeTracker.replaceNode(context.file, node, localReference);
                    }
                    else if (node.parent.kind === 222 /* ExpressionStatement */ && scope === ts.findAncestor(node, isScope)) {
                        // If the parent is an expression statement and the target scope is the immediately enclosing one,
                        // replace the statement with the declaration.
                        var newVariableStatement = ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList([newVariableDeclaration], 2 /* Const */));
                        changeTracker.replaceNode(context.file, node.parent, newVariableStatement);
                    }
                    else {
                        var newVariableStatement = ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList([newVariableDeclaration], 2 /* Const */));
                        // Declare
                        var nodeToInsertBefore = getNodeToInsertConstantBefore(node, scope);
                        if (nodeToInsertBefore.pos === 0) {
                            changeTracker.insertNodeAtTopOfFile(context.file, newVariableStatement, /*blankLineBetween*/ false);
                        }
                        else {
                            changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariableStatement, /*blankLineBetween*/ false);
                        }
                        // Consume
                        if (node.parent.kind === 222 /* ExpressionStatement */) {
                            // If the parent is an expression statement, delete it.
                            changeTracker.delete(context.file, node.parent);
                        }
                        else {
                            var localReference = ts.createIdentifier(localNameText);
                            changeTracker.replaceNode(context.file, node, localReference);
                        }
                    }
                }
                var edits = changeTracker.getChanges();
                var renameFilename = node.getSourceFile().fileName;
                var renameLocation = ts.getRenameLocation(edits, renameFilename, localNameText, /*isDeclaredBeforeUse*/ true);
                return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits };
            }
            function getContainingVariableDeclarationIfInList(node, scope) {
                var prevNode;
                while (node !== undefined && node !== scope) {
                    if (ts.isVariableDeclaration(node) &&
                        node.initializer === prevNode &&
                        ts.isVariableDeclarationList(node.parent) &&
                        node.parent.declarations.length > 1) {
                        return node;
                    }
                    prevNode = node;
                    node = node.parent;
                }
            }
            function getFirstDeclaration(type) {
                var firstDeclaration;
                var symbol = type.symbol;
                if (symbol && symbol.declarations) {
                    for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                        var declaration = _a[_i];
                        if (firstDeclaration === undefined || declaration.pos < firstDeclaration.pos) {
                            firstDeclaration = declaration;
                        }
                    }
                }
                return firstDeclaration;
            }
            function compareTypesByDeclarationOrder(_a, _b) {
                var type1 = _a.type, declaration1 = _a.declaration;
                var type2 = _b.type, declaration2 = _b.declaration;
                return ts.compareProperties(declaration1, declaration2, "pos", ts.compareValues)
                    || ts.compareStringsCaseSensitive(type1.symbol ? type1.symbol.getName() : "", type2.symbol ? type2.symbol.getName() : "")
                    || ts.compareValues(type1.id, type2.id);
            }
            function getCalledExpression(scope, range, functionNameText) {
                var functionReference = ts.createIdentifier(functionNameText);
                if (ts.isClassLike(scope)) {
                    var lhs = range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.text) : ts.createThis(); // TODO: GH#18217
                    return ts.createPropertyAccess(lhs, functionReference);
                }
                else {
                    return functionReference;
                }
            }
            function transformFunctionBody(body, exposedVariableDeclarations, writes, substitutions, hasReturn) {
                var hasWritesOrVariableDeclarations = writes !== undefined || exposedVariableDeclarations.length > 0;
                if (ts.isBlock(body) && !hasWritesOrVariableDeclarations && substitutions.size === 0) {
                    // already block, no declarations or writes to propagate back, no substitutions - can use node as is
                    return { body: ts.createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined };
                }
                var returnValueProperty;
                var ignoreReturns = false;
                var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]);
                // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions
                if (hasWritesOrVariableDeclarations || substitutions.size) {
                    var rewrittenStatements = ts.visitNodes(statements, visitor).slice();
                    if (hasWritesOrVariableDeclarations && !hasReturn && ts.isStatement(body)) {
                        // add return at the end to propagate writes back in case if control flow falls out of the function body
                        // it is ok to know that range has at least one return since it we only allow unconditional returns
                        var assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes);
                        if (assignments.length === 1) {
                            rewrittenStatements.push(ts.createReturn(assignments[0].name));
                        }
                        else {
                            rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments)));
                        }
                    }
                    return { body: ts.createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty: returnValueProperty };
                }
                else {
                    return { body: ts.createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined };
                }
                function visitor(node) {
                    if (!ignoreReturns && node.kind === 231 /* ReturnStatement */ && hasWritesOrVariableDeclarations) {
                        var assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes);
                        if (node.expression) {
                            if (!returnValueProperty) {
                                returnValueProperty = "__return";
                            }
                            assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor)));
                        }
                        if (assignments.length === 1) {
                            return ts.createReturn(assignments[0].name);
                        }
                        else {
                            return ts.createReturn(ts.createObjectLiteral(assignments));
                        }
                    }
                    else {
                        var oldIgnoreReturns = ignoreReturns;
                        ignoreReturns = ignoreReturns || ts.isFunctionLikeDeclaration(node) || ts.isClassLike(node);
                        var substitution = substitutions.get(ts.getNodeId(node).toString());
                        var result = substitution ? ts.getSynthesizedDeepClone(substitution) : ts.visitEachChild(node, visitor, ts.nullTransformationContext);
                        ignoreReturns = oldIgnoreReturns;
                        return result;
                    }
                }
            }
            function transformConstantInitializer(initializer, substitutions) {
                return substitutions.size
                    ? visitor(initializer)
                    : initializer;
                function visitor(node) {
                    var substitution = substitutions.get(ts.getNodeId(node).toString());
                    return substitution ? ts.getSynthesizedDeepClone(substitution) : ts.visitEachChild(node, visitor, ts.nullTransformationContext);
                }
            }
            function getStatementsOrClassElements(scope) {
                if (ts.isFunctionLikeDeclaration(scope)) {
                    var body = scope.body; // TODO: GH#18217
                    if (ts.isBlock(body)) {
                        return body.statements;
                    }
                }
                else if (ts.isModuleBlock(scope) || ts.isSourceFile(scope)) {
                    return scope.statements;
                }
                else if (ts.isClassLike(scope)) {
                    return scope.members;
                }
                else {
                    ts.assertType(scope);
                }
                return ts.emptyArray;
            }
            /**
             * If `scope` contains a function after `minPos`, then return the first such function.
             * Otherwise, return `undefined`.
             */
            function getNodeToInsertFunctionBefore(minPos, scope) {
                return ts.find(getStatementsOrClassElements(scope), function (child) {
                    return child.pos >= minPos && ts.isFunctionLikeDeclaration(child) && !ts.isConstructorDeclaration(child);
                });
            }
            function getNodeToInsertPropertyBefore(maxPos, scope) {
                var members = scope.members;
                ts.Debug.assert(members.length > 0); // There must be at least one child, since we extracted from one.
                var prevMember;
                var allProperties = true;
                for (var _i = 0, members_2 = members; _i < members_2.length; _i++) {
                    var member = members_2[_i];
                    if (member.pos > maxPos) {
                        return prevMember || members[0];
                    }
                    if (allProperties && !ts.isPropertyDeclaration(member)) {
                        // If it is non-vacuously true that all preceding members are properties,
                        // insert before the current member (i.e. at the end of the list of properties).
                        if (prevMember !== undefined) {
                            return member;
                        }
                        allProperties = false;
                    }
                    prevMember = member;
                }
                if (prevMember === undefined)
                    return ts.Debug.fail(); // If the loop didn't return, then it did set prevMember.
                return prevMember;
            }
            function getNodeToInsertConstantBefore(node, scope) {
                ts.Debug.assert(!ts.isClassLike(scope));
                var prevScope;
                for (var curr = node; curr !== scope; curr = curr.parent) {
                    if (isScope(curr)) {
                        prevScope = curr;
                    }
                }
                for (var curr = (prevScope || node).parent;; curr = curr.parent) {
                    if (isBlockLike(curr)) {
                        var prevStatement = void 0;
                        for (var _i = 0, _a = curr.statements; _i < _a.length; _i++) {
                            var statement = _a[_i];
                            if (statement.pos > node.pos) {
                                break;
                            }
                            prevStatement = statement;
                        }
                        if (!prevStatement && ts.isCaseClause(curr)) {
                            // We must have been in the expression of the case clause.
                            ts.Debug.assert(ts.isSwitchStatement(curr.parent.parent));
                            return curr.parent.parent;
                        }
                        // There must be at least one statement since we started in one.
                        return ts.Debug.assertDefined(prevStatement);
                    }
                    ts.Debug.assert(curr !== scope, "Didn't encounter a block-like before encountering scope");
                }
            }
            function getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes) {
                var variableAssignments = ts.map(exposedVariableDeclarations, function (v) { return ts.createShorthandPropertyAssignment(v.symbol.name); });
                var writeAssignments = ts.map(writes, function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); });
                // TODO: GH#18217 `variableAssignments` not possibly undefined!
                return variableAssignments === undefined
                    ? writeAssignments
                    : writeAssignments === undefined
                        ? variableAssignments
                        : variableAssignments.concat(writeAssignments);
            }
            function isReadonlyArray(v) {
                return ts.isArray(v);
            }
            /**
             * Produces a range that spans the entirety of nodes, given a selection
             * that might start/end in the middle of nodes.
             *
             * For example, when the user makes a selection like this
             *                     v---v
             *   var someThing = foo + bar;
             *  this returns     ^-------^
             */
            function getEnclosingTextRange(targetRange, sourceFile) {
                return isReadonlyArray(targetRange.range)
                    ? { pos: ts.first(targetRange.range).getStart(sourceFile), end: ts.last(targetRange.range).getEnd() }
                    : targetRange.range;
            }
            var Usage;
            (function (Usage) {
                // value should be passed to extracted method
                Usage[Usage["Read"] = 1] = "Read";
                // value should be passed to extracted method and propagated back
                Usage[Usage["Write"] = 2] = "Write";
            })(Usage || (Usage = {}));
            function collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, checker, cancellationToken) {
                var allTypeParameterUsages = ts.createMap(); // Key is type ID
                var usagesPerScope = [];
                var substitutionsPerScope = [];
                var functionErrorsPerScope = [];
                var constantErrorsPerScope = [];
                var visibleDeclarationsInExtractedRange = [];
                var exposedVariableSymbolSet = ts.createMap(); // Key is symbol ID
                var exposedVariableDeclarations = [];
                var firstExposedNonVariableDeclaration;
                var expression = !isReadonlyArray(targetRange.range)
                    ? targetRange.range
                    : targetRange.range.length === 1 && ts.isExpressionStatement(targetRange.range[0])
                        ? targetRange.range[0].expression
                        : undefined;
                var expressionDiagnostic;
                if (expression === undefined) {
                    var statements = targetRange.range;
                    var start = ts.first(statements).getStart();
                    var end = ts.last(statements).end;
                    expressionDiagnostic = ts.createFileDiagnostic(sourceFile, start, end - start, Messages.expressionExpected);
                }
                else if (checker.getTypeAtLocation(expression).flags & (16384 /* Void */ | 131072 /* Never */)) {
                    expressionDiagnostic = ts.createDiagnosticForNode(expression, Messages.uselessConstantType);
                }
                // initialize results
                for (var _i = 0, scopes_1 = scopes; _i < scopes_1.length; _i++) {
                    var scope = scopes_1[_i];
                    usagesPerScope.push({ usages: ts.createMap(), typeParameterUsages: ts.createMap(), substitutions: ts.createMap() });
                    substitutionsPerScope.push(ts.createMap());
                    functionErrorsPerScope.push(ts.isFunctionLikeDeclaration(scope) && scope.kind !== 240 /* FunctionDeclaration */
                        ? [ts.createDiagnosticForNode(scope, Messages.cannotExtractToOtherFunctionLike)]
                        : []);
                    var constantErrors = [];
                    if (expressionDiagnostic) {
                        constantErrors.push(expressionDiagnostic);
                    }
                    if (ts.isClassLike(scope) && ts.isInJSFile(scope)) {
                        constantErrors.push(ts.createDiagnosticForNode(scope, Messages.cannotExtractToJSClass));
                    }
                    if (ts.isArrowFunction(scope) && !ts.isBlock(scope.body)) {
                        // TODO (https://github.com/Microsoft/TypeScript/issues/18924): allow this
                        constantErrors.push(ts.createDiagnosticForNode(scope, Messages.cannotExtractToExpressionArrowFunction));
                    }
                    constantErrorsPerScope.push(constantErrors);
                }
                var seenUsages = ts.createMap();
                var target = isReadonlyArray(targetRange.range) ? ts.createBlock(targetRange.range) : targetRange.range;
                var unmodifiedNode = isReadonlyArray(targetRange.range) ? ts.first(targetRange.range) : targetRange.range;
                var inGenericContext = isInGenericContext(unmodifiedNode);
                collectUsages(target);
                // Unfortunately, this code takes advantage of the knowledge that the generated method
                // will use the contextual type of an expression as the return type of the extracted
                // method (and will therefore "use" all the types involved).
                if (inGenericContext && !isReadonlyArray(targetRange.range)) {
                    var contextualType = checker.getContextualType(targetRange.range); // TODO: GH#18217
                    recordTypeParameterUsages(contextualType);
                }
                if (allTypeParameterUsages.size > 0) {
                    var seenTypeParameterUsages = ts.createMap(); // Key is type ID
                    var i_1 = 0;
                    for (var curr = unmodifiedNode; curr !== undefined && i_1 < scopes.length; curr = curr.parent) {
                        if (curr === scopes[i_1]) {
                            // Copy current contents of seenTypeParameterUsages into scope.
                            seenTypeParameterUsages.forEach(function (typeParameter, id) {
                                usagesPerScope[i_1].typeParameterUsages.set(id, typeParameter);
                            });
                            i_1++;
                        }
                        // Note that we add the current node's type parameters *after* updating the corresponding scope.
                        if (ts.isDeclarationWithTypeParameters(curr)) {
                            for (var _a = 0, _b = ts.getEffectiveTypeParameterDeclarations(curr); _a < _b.length; _a++) {
                                var typeParameterDecl = _b[_a];
                                var typeParameter = checker.getTypeAtLocation(typeParameterDecl);
                                if (allTypeParameterUsages.has(typeParameter.id.toString())) {
                                    seenTypeParameterUsages.set(typeParameter.id.toString(), typeParameter);
                                }
                            }
                        }
                    }
                    // If we didn't get through all the scopes, then there were some that weren't in our
                    // parent chain (impossible at time of writing).  A conservative solution would be to
                    // copy allTypeParameterUsages into all remaining scopes.
                    ts.Debug.assert(i_1 === scopes.length);
                }
                // If there are any declarations in the extracted block that are used in the same enclosing
                // lexical scope, we can't move the extraction "up" as those declarations will become unreachable
                if (visibleDeclarationsInExtractedRange.length) {
                    var containingLexicalScopeOfExtraction = ts.isBlockScope(scopes[0], scopes[0].parent)
                        ? scopes[0]
                        : ts.getEnclosingBlockScopeContainer(scopes[0]);
                    ts.forEachChild(containingLexicalScopeOfExtraction, checkForUsedDeclarations);
                }
                var _loop_14 = function (i) {
                    var scopeUsages = usagesPerScope[i];
                    // Special case: in the innermost scope, all usages are available.
                    // (The computed value reflects the value at the top-level of the scope, but the
                    // local will actually be declared at the same level as the extracted expression).
                    if (i > 0 && (scopeUsages.usages.size > 0 || scopeUsages.typeParameterUsages.size > 0)) {
                        var errorNode = isReadonlyArray(targetRange.range) ? targetRange.range[0] : targetRange.range;
                        constantErrorsPerScope[i].push(ts.createDiagnosticForNode(errorNode, Messages.cannotAccessVariablesFromNestedScopes));
                    }
                    var hasWrite = false;
                    var readonlyClassPropertyWrite;
                    usagesPerScope[i].usages.forEach(function (value) {
                        if (value.usage === 2 /* Write */) {
                            hasWrite = true;
                            if (value.symbol.flags & 106500 /* ClassMember */ &&
                                value.symbol.valueDeclaration &&
                                ts.hasModifier(value.symbol.valueDeclaration, 64 /* Readonly */)) {
                                readonlyClassPropertyWrite = value.symbol.valueDeclaration;
                            }
                        }
                    });
                    // If an expression was extracted, then there shouldn't have been any variable declarations.
                    ts.Debug.assert(isReadonlyArray(targetRange.range) || exposedVariableDeclarations.length === 0);
                    if (hasWrite && !isReadonlyArray(targetRange.range)) {
                        var diag = ts.createDiagnosticForNode(targetRange.range, Messages.cannotWriteInExpression);
                        functionErrorsPerScope[i].push(diag);
                        constantErrorsPerScope[i].push(diag);
                    }
                    else if (readonlyClassPropertyWrite && i > 0) {
                        var diag = ts.createDiagnosticForNode(readonlyClassPropertyWrite, Messages.cannotExtractReadonlyPropertyInitializerOutsideConstructor);
                        functionErrorsPerScope[i].push(diag);
                        constantErrorsPerScope[i].push(diag);
                    }
                    else if (firstExposedNonVariableDeclaration) {
                        var diag = ts.createDiagnosticForNode(firstExposedNonVariableDeclaration, Messages.cannotExtractExportedEntity);
                        functionErrorsPerScope[i].push(diag);
                        constantErrorsPerScope[i].push(diag);
                    }
                };
                for (var i = 0; i < scopes.length; i++) {
                    _loop_14(i);
                }
                return { target: target, usagesPerScope: usagesPerScope, functionErrorsPerScope: functionErrorsPerScope, constantErrorsPerScope: constantErrorsPerScope, exposedVariableDeclarations: exposedVariableDeclarations };
                function isInGenericContext(node) {
                    return !!ts.findAncestor(node, function (n) { return ts.isDeclarationWithTypeParameters(n) && ts.getEffectiveTypeParameterDeclarations(n).length !== 0; });
                }
                function recordTypeParameterUsages(type) {
                    // PERF: This is potentially very expensive.  `type` could be a library type with
                    // a lot of properties, each of which the walker will visit.  Unfortunately, the
                    // solution isn't as trivial as filtering to user types because of (e.g.) Array.
                    var symbolWalker = checker.getSymbolWalker(function () { return (cancellationToken.throwIfCancellationRequested(), true); });
                    var visitedTypes = symbolWalker.walkType(type).visitedTypes;
                    for (var _i = 0, visitedTypes_1 = visitedTypes; _i < visitedTypes_1.length; _i++) {
                        var visitedType = visitedTypes_1[_i];
                        if (visitedType.isTypeParameter()) {
                            allTypeParameterUsages.set(visitedType.id.toString(), visitedType);
                        }
                    }
                }
                function collectUsages(node, valueUsage) {
                    if (valueUsage === void 0) { valueUsage = 1 /* Read */; }
                    if (inGenericContext) {
                        var type = checker.getTypeAtLocation(node);
                        recordTypeParameterUsages(type);
                    }
                    if (ts.isDeclaration(node) && node.symbol) {
                        visibleDeclarationsInExtractedRange.push(node);
                    }
                    if (ts.isAssignmentExpression(node)) {
                        // use 'write' as default usage for values
                        collectUsages(node.left, 2 /* Write */);
                        collectUsages(node.right);
                    }
                    else if (ts.isUnaryExpressionWithWrite(node)) {
                        collectUsages(node.operand, 2 /* Write */);
                    }
                    else if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) {
                        // use 'write' as default usage for values
                        ts.forEachChild(node, collectUsages);
                    }
                    else if (ts.isIdentifier(node)) {
                        if (!node.parent) {
                            return;
                        }
                        if (ts.isQualifiedName(node.parent) && node !== node.parent.left) {
                            return;
                        }
                        if (ts.isPropertyAccessExpression(node.parent) && node !== node.parent.expression) {
                            return;
                        }
                        recordUsage(node, valueUsage, /*isTypeNode*/ ts.isPartOfTypeNode(node));
                    }
                    else {
                        ts.forEachChild(node, collectUsages);
                    }
                }
                function recordUsage(n, usage, isTypeNode) {
                    var symbolId = recordUsagebySymbol(n, usage, isTypeNode);
                    if (symbolId) {
                        for (var i = 0; i < scopes.length; i++) {
                            // push substitution from map<symbolId, subst> to map<nodeId, subst> to simplify rewriting
                            var substitution = substitutionsPerScope[i].get(symbolId);
                            if (substitution) {
                                usagesPerScope[i].substitutions.set(ts.getNodeId(n).toString(), substitution);
                            }
                        }
                    }
                }
                function recordUsagebySymbol(identifier, usage, isTypeName) {
                    var symbol = getSymbolReferencedByIdentifier(identifier);
                    if (!symbol) {
                        // cannot find symbol - do nothing
                        return undefined;
                    }
                    var symbolId = ts.getSymbolId(symbol).toString();
                    var lastUsage = seenUsages.get(symbolId);
                    // there are two kinds of value usages
                    // - reads - if range contains a read from the value located outside of the range then value should be passed as a parameter
                    // - writes - if range contains a write to a value located outside the range the value should be passed as a parameter and
                    //   returned as a return value
                    // 'write' case is a superset of 'read' so if we already have processed 'write' of some symbol there is not need to handle 'read'
                    // since all information is already recorded
                    if (lastUsage && lastUsage >= usage) {
                        return symbolId;
                    }
                    seenUsages.set(symbolId, usage);
                    if (lastUsage) {
                        // if we get here this means that we are trying to handle 'write' and 'read' was already processed
                        // walk scopes and update existing records.
                        for (var _i = 0, usagesPerScope_1 = usagesPerScope; _i < usagesPerScope_1.length; _i++) {
                            var perScope = usagesPerScope_1[_i];
                            var prevEntry = perScope.usages.get(identifier.text);
                            if (prevEntry) {
                                perScope.usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier });
                            }
                        }
                        return symbolId;
                    }
                    // find first declaration in this file
                    var decls = symbol.getDeclarations();
                    var declInFile = decls && ts.find(decls, function (d) { return d.getSourceFile() === sourceFile; });
                    if (!declInFile) {
                        return undefined;
                    }
                    if (ts.rangeContainsStartEnd(enclosingTextRange, declInFile.getStart(), declInFile.end)) {
                        // declaration is located in range to be extracted - do nothing
                        return undefined;
                    }
                    if (targetRange.facts & RangeFacts.IsGenerator && usage === 2 /* Write */) {
                        // this is write to a reference located outside of the target scope and range is extracted into generator
                        // currently this is unsupported scenario
                        var diag = ts.createDiagnosticForNode(identifier, Messages.cannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators);
                        for (var _a = 0, functionErrorsPerScope_1 = functionErrorsPerScope; _a < functionErrorsPerScope_1.length; _a++) {
                            var errors = functionErrorsPerScope_1[_a];
                            errors.push(diag);
                        }
                        for (var _b = 0, constantErrorsPerScope_1 = constantErrorsPerScope; _b < constantErrorsPerScope_1.length; _b++) {
                            var errors = constantErrorsPerScope_1[_b];
                            errors.push(diag);
                        }
                    }
                    for (var i = 0; i < scopes.length; i++) {
                        var scope = scopes[i];
                        var resolvedSymbol = checker.resolveName(symbol.name, scope, symbol.flags, /*excludeGlobals*/ false);
                        if (resolvedSymbol === symbol) {
                            continue;
                        }
                        if (!substitutionsPerScope[i].has(symbolId)) {
                            var substitution = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.exportSymbol || symbol, scope, isTypeName);
                            if (substitution) {
                                substitutionsPerScope[i].set(symbolId, substitution);
                            }
                            else if (isTypeName) {
                                // If the symbol is a type parameter that won't be in scope, we'll pass it as a type argument
                                // so there's no problem.
                                if (!(symbol.flags & 262144 /* TypeParameter */)) {
                                    var diag = ts.createDiagnosticForNode(identifier, Messages.typeWillNotBeVisibleInTheNewScope);
                                    functionErrorsPerScope[i].push(diag);
                                    constantErrorsPerScope[i].push(diag);
                                }
                            }
                            else {
                                usagesPerScope[i].usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier });
                            }
                        }
                    }
                    return symbolId;
                }
                function checkForUsedDeclarations(node) {
                    // If this node is entirely within the original extraction range, we don't need to do anything.
                    if (node === targetRange.range || (isReadonlyArray(targetRange.range) && targetRange.range.indexOf(node) >= 0)) {
                        return;
                    }
                    // Otherwise check and recurse.
                    var sym = ts.isIdentifier(node)
                        ? getSymbolReferencedByIdentifier(node)
                        : checker.getSymbolAtLocation(node);
                    if (sym) {
                        var decl = ts.find(visibleDeclarationsInExtractedRange, function (d) { return d.symbol === sym; });
                        if (decl) {
                            if (ts.isVariableDeclaration(decl)) {
                                var idString = decl.symbol.id.toString();
                                if (!exposedVariableSymbolSet.has(idString)) {
                                    exposedVariableDeclarations.push(decl);
                                    exposedVariableSymbolSet.set(idString, true);
                                }
                            }
                            else {
                                // CONSIDER: this includes binding elements, which we could
                                // expose in the same way as variables.
                                firstExposedNonVariableDeclaration = firstExposedNonVariableDeclaration || decl;
                            }
                        }
                    }
                    ts.forEachChild(node, checkForUsedDeclarations);
                }
                /**
                 * Return the symbol referenced by an identifier (even if it declares a different symbol).
                 */
                function getSymbolReferencedByIdentifier(identifier) {
                    // If the identifier is both a property name and its value, we're only interested in its value
                    // (since the name is a declaration and will be included in the extracted range).
                    return identifier.parent && ts.isShorthandPropertyAssignment(identifier.parent) && identifier.parent.name === identifier
                        ? checker.getShorthandAssignmentValueSymbol(identifier.parent)
                        : checker.getSymbolAtLocation(identifier);
                }
                function tryReplaceWithQualifiedNameOrPropertyAccess(symbol, scopeDecl, isTypeNode) {
                    if (!symbol) {
                        return undefined;
                    }
                    var decls = symbol.getDeclarations();
                    if (decls && decls.some(function (d) { return d.parent === scopeDecl; })) {
                        return ts.createIdentifier(symbol.name);
                    }
                    var prefix = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.parent, scopeDecl, isTypeNode);
                    if (prefix === undefined) {
                        return undefined;
                    }
                    return isTypeNode
                        ? ts.createQualifiedName(prefix, ts.createIdentifier(symbol.name))
                        : ts.createPropertyAccess(prefix, symbol.name);
                }
            }
            /**
             * Computes whether or not a node represents an expression in a position where it could
             * be extracted.
             * The isExpression() in utilities.ts returns some false positives we need to handle,
             * such as `import x from 'y'` -- the 'y' is a StringLiteral but is *not* an expression
             * in the sense of something that you could extract on
             */
            function isExtractableExpression(node) {
                var parent = node.parent;
                switch (parent.kind) {
                    case 279 /* EnumMember */:
                        return false;
                }
                switch (node.kind) {
                    case 10 /* StringLiteral */:
                        return parent.kind !== 250 /* ImportDeclaration */ &&
                            parent.kind !== 254 /* ImportSpecifier */;
                    case 209 /* SpreadElement */:
                    case 185 /* ObjectBindingPattern */:
                    case 187 /* BindingElement */:
                        return false;
                    case 73 /* Identifier */:
                        return parent.kind !== 187 /* BindingElement */ &&
                            parent.kind !== 254 /* ImportSpecifier */ &&
                            parent.kind !== 258 /* ExportSpecifier */;
                }
                return true;
            }
            function isBlockLike(node) {
                switch (node.kind) {
                    case 219 /* Block */:
                    case 285 /* SourceFile */:
                    case 246 /* ModuleBlock */:
                    case 272 /* CaseClause */:
                        return true;
                    default:
                        return false;
                }
            }
        })(extractSymbol = refactor.extractSymbol || (refactor.extractSymbol = {}));
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var refactorName = "Extract type";
        var extractToTypeAlias = "Extract to type alias";
        var extractToTypeDef = "Extract to typedef";
        refactor.registerRefactor(refactorName, {
            getAvailableActions: function (context) {
                var info = getRangeToExtract(context);
                if (!info)
                    return ts.emptyArray;
                return [{
                        name: refactorName,
                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_type),
                        actions: [info.isJS ? {
                                name: extractToTypeDef, description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_typedef)
                            } : {
                                name: extractToTypeAlias, description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_type_alias)
                            }]
                    }];
            },
            getEditsForAction: function (context, actionName) {
                ts.Debug.assert(actionName === extractToTypeAlias || actionName === extractToTypeDef);
                var file = context.file;
                var info = ts.Debug.assertDefined(getRangeToExtract(context));
                ts.Debug.assert(actionName === extractToTypeAlias && !info.isJS || actionName === extractToTypeDef && info.isJS);
                var name = ts.getUniqueName("NewType", file);
                var edits = ts.textChanges.ChangeTracker.with(context, function (changes) { return info.isJS ?
                    doTypedefChange(changes, file, name, info.firstStatement, info.selection, info.typeParameters) :
                    doTypeAliasChange(changes, file, name, info.firstStatement, info.selection, info.typeParameters); });
                var renameFilename = file.fileName;
                var renameLocation = ts.getRenameLocation(edits, renameFilename, name, /*preferLastLocation*/ false);
                return { edits: edits, renameFilename: renameFilename, renameLocation: renameLocation };
            }
        });
        function getRangeToExtract(context) {
            var file = context.file, startPosition = context.startPosition;
            var isJS = ts.isSourceFileJS(file);
            var current = ts.getTokenAtPosition(file, startPosition);
            var range = ts.createTextRangeFromSpan(ts.getRefactorContextSpan(context));
            var selection = ts.findAncestor(current, (function (node) { return node.parent && rangeContainsSkipTrivia(range, node, file) && !rangeContainsSkipTrivia(range, node.parent, file); }));
            if (!selection || !ts.isTypeNode(selection))
                return undefined;
            var checker = context.program.getTypeChecker();
            var firstStatement = ts.Debug.assertDefined(isJS ? ts.findAncestor(selection, isStatementAndHasJSDoc) : ts.findAncestor(selection, ts.isStatement));
            var typeParameters = collectTypeParameters(checker, selection, firstStatement, file);
            if (!typeParameters)
                return undefined;
            return { isJS: isJS, selection: selection, firstStatement: firstStatement, typeParameters: typeParameters };
        }
        function isStatementAndHasJSDoc(n) {
            return ts.isStatement(n) && ts.hasJSDocNodes(n);
        }
        function rangeContainsSkipTrivia(r1, node, file) {
            return ts.rangeContainsStartEnd(r1, ts.skipTrivia(file.text, node.pos), node.end);
        }
        function collectTypeParameters(checker, selection, statement, file) {
            var result = [];
            return visitor(selection) ? undefined : result;
            function visitor(node) {
                if (ts.isTypeReferenceNode(node)) {
                    if (ts.isIdentifier(node.typeName)) {
                        var symbol = checker.resolveName(node.typeName.text, node.typeName, 262144 /* TypeParameter */, /* excludeGlobals */ true);
                        if (symbol) {
                            var declaration = ts.cast(ts.first(symbol.declarations), ts.isTypeParameterDeclaration);
                            if (rangeContainsSkipTrivia(statement, declaration, file) && !rangeContainsSkipTrivia(selection, declaration, file)) {
                                result.push(declaration);
                            }
                        }
                    }
                }
                else if (ts.isInferTypeNode(node)) {
                    var conditionalTypeNode = ts.findAncestor(node, function (n) { return ts.isConditionalTypeNode(n) && rangeContainsSkipTrivia(n.extendsType, node, file); });
                    if (!conditionalTypeNode || !rangeContainsSkipTrivia(selection, conditionalTypeNode, file)) {
                        return true;
                    }
                }
                else if ((ts.isTypePredicateNode(node) || ts.isThisTypeNode(node))) {
                    var functionLikeNode = ts.findAncestor(node.parent, ts.isFunctionLike);
                    if (functionLikeNode && functionLikeNode.type && rangeContainsSkipTrivia(functionLikeNode.type, node, file) && !rangeContainsSkipTrivia(selection, functionLikeNode, file)) {
                        return true;
                    }
                }
                else if (ts.isTypeQueryNode(node)) {
                    if (ts.isIdentifier(node.exprName)) {
                        var symbol = checker.resolveName(node.exprName.text, node.exprName, 67220415 /* Value */, /* excludeGlobals */ false);
                        if (symbol && rangeContainsSkipTrivia(statement, symbol.valueDeclaration, file) && !rangeContainsSkipTrivia(selection, symbol.valueDeclaration, file)) {
                            return true;
                        }
                    }
                    else {
                        if (ts.isThisIdentifier(node.exprName.left) && !rangeContainsSkipTrivia(selection, node.parent, file)) {
                            return true;
                        }
                    }
                }
                return ts.forEachChild(node, visitor);
            }
        }
        function doTypeAliasChange(changes, file, name, firstStatement, selection, typeParameters) {
            var newTypeNode = ts.createTypeAliasDeclaration(
            /* decorators */ undefined, 
            /* modifiers */ undefined, name, typeParameters.map(function (id) { return ts.updateTypeParameterDeclaration(id, id.name, id.constraint, /* defaultType */ undefined); }), selection);
            changes.insertNodeBefore(file, firstStatement, newTypeNode, /* blankLineBetween */ true);
            changes.replaceNode(file, selection, ts.createTypeReferenceNode(name, typeParameters.map(function (id) { return ts.createTypeReferenceNode(id.name, /* typeArguments */ undefined); })));
        }
        function doTypedefChange(changes, file, name, firstStatement, selection, typeParameters) {
            var node = ts.createNode(310 /* JSDocTypedefTag */);
            node.tagName = ts.createIdentifier("typedef"); // TODO: jsdoc factory https://github.com/Microsoft/TypeScript/pull/29539
            node.fullName = ts.createIdentifier(name);
            node.name = node.fullName;
            node.typeExpression = ts.createJSDocTypeExpression(selection);
            var templates = [];
            ts.forEach(typeParameters, function (typeParameter) {
                var constraint = ts.getEffectiveConstraintOfTypeParameter(typeParameter);
                var template = ts.createNode(309 /* JSDocTemplateTag */);
                template.tagName = ts.createIdentifier("template");
                template.constraint = constraint && ts.cast(constraint, ts.isJSDocTypeExpression);
                var parameter = ts.createNode(151 /* TypeParameter */);
                parameter.name = typeParameter.name;
                template.typeParameters = ts.createNodeArray([parameter]);
                templates.push(template);
            });
            changes.insertNodeBefore(file, firstStatement, ts.createJSDocComment(/* comment */ undefined, ts.createNodeArray(ts.concatenate(templates, [node]))), /* blankLineBetween */ true);
            changes.replaceNode(file, selection, ts.createTypeReferenceNode(name, typeParameters.map(function (id) { return ts.createTypeReferenceNode(id.name, /* typeArguments */ undefined); })));
        }
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var generateGetAccessorAndSetAccessor;
        (function (generateGetAccessorAndSetAccessor) {
            var actionName = "Generate 'get' and 'set' accessors";
            var actionDescription = ts.Diagnostics.Generate_get_and_set_accessors.message;
            refactor.registerRefactor(actionName, { getEditsForAction: getEditsForAction, getAvailableActions: getAvailableActions });
            function getAvailableActions(context) {
                if (!getConvertibleFieldAtPosition(context))
                    return ts.emptyArray;
                return [{
                        name: actionName,
                        description: actionDescription,
                        actions: [
                            {
                                name: actionName,
                                description: actionDescription
                            }
                        ]
                    }];
            }
            function getEditsForAction(context, _actionName) {
                var file = context.file;
                var fieldInfo = getConvertibleFieldAtPosition(context);
                if (!fieldInfo)
                    return undefined;
                var isJS = ts.isSourceFileJS(file);
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                var isStatic = fieldInfo.isStatic, isReadonly = fieldInfo.isReadonly, fieldName = fieldInfo.fieldName, accessorName = fieldInfo.accessorName, originalName = fieldInfo.originalName, type = fieldInfo.type, container = fieldInfo.container, declaration = fieldInfo.declaration, renameAccessor = fieldInfo.renameAccessor;
                ts.suppressLeadingAndTrailingTrivia(fieldName);
                ts.suppressLeadingAndTrailingTrivia(declaration);
                ts.suppressLeadingAndTrailingTrivia(container);
                var isInClassLike = ts.isClassLike(container);
                // avoid Readonly modifier because it will convert to get accessor
                var modifierFlags = ts.getModifierFlags(declaration) & ~64 /* Readonly */;
                var accessorModifiers = isInClassLike
                    ? !modifierFlags || modifierFlags & 8 /* Private */
                        ? getModifiers(isJS, isStatic, 116 /* PublicKeyword */)
                        : ts.createNodeArray(ts.createModifiersFromModifierFlags(modifierFlags))
                    : undefined;
                var fieldModifiers = isInClassLike ? getModifiers(isJS, isStatic, 114 /* PrivateKeyword */) : undefined;
                updateFieldDeclaration(changeTracker, file, declaration, fieldName, fieldModifiers);
                var getAccessor = generateGetAccessor(fieldName, accessorName, type, accessorModifiers, isStatic, container);
                ts.suppressLeadingAndTrailingTrivia(getAccessor);
                insertAccessor(changeTracker, file, getAccessor, declaration, container);
                if (isReadonly) {
                    // readonly modifier only existed in classLikeDeclaration
                    var constructor = ts.getFirstConstructorWithBody(container);
                    if (constructor) {
                        updateReadonlyPropertyInitializerStatementConstructor(changeTracker, file, constructor, fieldName.text, originalName);
                    }
                }
                else {
                    var setAccessor = generateSetAccessor(fieldName, accessorName, type, accessorModifiers, isStatic, container);
                    ts.suppressLeadingAndTrailingTrivia(setAccessor);
                    insertAccessor(changeTracker, file, setAccessor, declaration, container);
                }
                var edits = changeTracker.getChanges();
                var renameFilename = file.fileName;
                var nameNeedRename = renameAccessor ? accessorName : fieldName;
                var renameLocationOffset = ts.isIdentifier(nameNeedRename) ? 0 : -1;
                var renameLocation = renameLocationOffset + ts.getRenameLocation(edits, renameFilename, nameNeedRename.text, /*preferLastLocation*/ ts.isParameter(declaration));
                return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits };
            }
            function isConvertibleName(name) {
                return ts.isIdentifier(name) || ts.isStringLiteral(name);
            }
            function isAcceptedDeclaration(node) {
                return ts.isParameterPropertyDeclaration(node) || ts.isPropertyDeclaration(node) || ts.isPropertyAssignment(node);
            }
            function createPropertyName(name, originalName) {
                return ts.isIdentifier(originalName) ? ts.createIdentifier(name) : ts.createLiteral(name);
            }
            function createAccessorAccessExpression(fieldName, isStatic, container) {
                var leftHead = isStatic ? container.name : ts.createThis(); // TODO: GH#18217
                return ts.isIdentifier(fieldName) ? ts.createPropertyAccess(leftHead, fieldName) : ts.createElementAccess(leftHead, ts.createLiteral(fieldName));
            }
            function getModifiers(isJS, isStatic, accessModifier) {
                var modifiers = ts.append(!isJS ? [ts.createToken(accessModifier)] : undefined, isStatic ? ts.createToken(117 /* StaticKeyword */) : undefined);
                return modifiers && ts.createNodeArray(modifiers);
            }
            function startsWithUnderscore(name) {
                return name.charCodeAt(0) === 95 /* _ */;
            }
            function getConvertibleFieldAtPosition(context) {
                var file = context.file, startPosition = context.startPosition, endPosition = context.endPosition;
                var node = ts.getTokenAtPosition(file, startPosition);
                var declaration = ts.findAncestor(node.parent, isAcceptedDeclaration);
                // make sure declaration have AccessibilityModifier or Static Modifier or Readonly Modifier
                var meaning = 28 /* AccessibilityModifier */ | 32 /* Static */ | 64 /* Readonly */;
                if (!declaration || !ts.nodeOverlapsWithStartEnd(declaration.name, file, startPosition, endPosition) // TODO: GH#18217
                    || !isConvertibleName(declaration.name) || (ts.getModifierFlags(declaration) | meaning) !== meaning)
                    return undefined;
                var name = declaration.name.text;
                var startWithUnderscore = startsWithUnderscore(name);
                var fieldName = createPropertyName(startWithUnderscore ? name : ts.getUniqueName("_" + name, file), declaration.name);
                var accessorName = createPropertyName(startWithUnderscore ? ts.getUniqueName(name.substring(1), file) : name, declaration.name);
                return {
                    isStatic: ts.hasStaticModifier(declaration),
                    isReadonly: ts.hasReadonlyModifier(declaration),
                    type: ts.getTypeAnnotationNode(declaration),
                    container: declaration.kind === 152 /* Parameter */ ? declaration.parent.parent : declaration.parent,
                    originalName: declaration.name.text,
                    declaration: declaration,
                    fieldName: fieldName,
                    accessorName: accessorName,
                    renameAccessor: startWithUnderscore
                };
            }
            function generateGetAccessor(fieldName, accessorName, type, modifiers, isStatic, container) {
                return ts.createGetAccessor(
                /*decorators*/ undefined, modifiers, accessorName, 
                /*parameters*/ undefined, // TODO: GH#18217
                type, ts.createBlock([
                    ts.createReturn(createAccessorAccessExpression(fieldName, isStatic, container))
                ], /*multiLine*/ true));
            }
            function generateSetAccessor(fieldName, accessorName, type, modifiers, isStatic, container) {
                return ts.createSetAccessor(
                /*decorators*/ undefined, modifiers, accessorName, [ts.createParameter(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, 
                    /*dotDotDotToken*/ undefined, ts.createIdentifier("value"), 
                    /*questionToken*/ undefined, type)], ts.createBlock([
                    ts.createStatement(ts.createAssignment(createAccessorAccessExpression(fieldName, isStatic, container), ts.createIdentifier("value")))
                ], /*multiLine*/ true));
            }
            function updatePropertyDeclaration(changeTracker, file, declaration, fieldName, modifiers) {
                var property = ts.updateProperty(declaration, declaration.decorators, modifiers, fieldName, declaration.questionToken || declaration.exclamationToken, declaration.type, declaration.initializer);
                changeTracker.replaceNode(file, declaration, property);
            }
            function updatePropertyAssignmentDeclaration(changeTracker, file, declaration, fieldName) {
                var assignment = ts.updatePropertyAssignment(declaration, fieldName, declaration.initializer);
                changeTracker.replacePropertyAssignment(file, declaration, assignment);
            }
            function updateFieldDeclaration(changeTracker, file, declaration, fieldName, modifiers) {
                if (ts.isPropertyDeclaration(declaration)) {
                    updatePropertyDeclaration(changeTracker, file, declaration, fieldName, modifiers);
                }
                else if (ts.isPropertyAssignment(declaration)) {
                    updatePropertyAssignmentDeclaration(changeTracker, file, declaration, fieldName);
                }
                else {
                    changeTracker.replaceNode(file, declaration, ts.updateParameter(declaration, declaration.decorators, modifiers, declaration.dotDotDotToken, ts.cast(fieldName, ts.isIdentifier), declaration.questionToken, declaration.type, declaration.initializer));
                }
            }
            function insertAccessor(changeTracker, file, accessor, declaration, container) {
                ts.isParameterPropertyDeclaration(declaration)
                    ? changeTracker.insertNodeAtClassStart(file, container, accessor)
                    : ts.isPropertyAssignment(declaration)
                        ? changeTracker.insertNodeAfterComma(file, declaration, accessor)
                        : changeTracker.insertNodeAfter(file, declaration, accessor);
            }
            function updateReadonlyPropertyInitializerStatementConstructor(changeTracker, file, constructor, fieldName, originalName) {
                if (!constructor.body)
                    return;
                constructor.body.forEachChild(function recur(node) {
                    if (ts.isElementAccessExpression(node) &&
                        node.expression.kind === 101 /* ThisKeyword */ &&
                        ts.isStringLiteral(node.argumentExpression) &&
                        node.argumentExpression.text === originalName &&
                        ts.isWriteAccess(node)) {
                        changeTracker.replaceNode(file, node.argumentExpression, ts.createStringLiteral(fieldName));
                    }
                    if (ts.isPropertyAccessExpression(node) && node.expression.kind === 101 /* ThisKeyword */ && node.name.text === originalName && ts.isWriteAccess(node)) {
                        changeTracker.replaceNode(file, node.name, ts.createIdentifier(fieldName));
                    }
                    if (!ts.isFunctionLike(node) && !ts.isClassLike(node)) {
                        node.forEachChild(recur);
                    }
                });
            }
        })(generateGetAccessorAndSetAccessor = refactor.generateGetAccessorAndSetAccessor || (refactor.generateGetAccessorAndSetAccessor = {}));
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var refactorName = "Move to a new file";
        refactor.registerRefactor(refactorName, {
            getAvailableActions: function (context) {
                if (!context.preferences.allowTextChangesInNewFiles || getStatementsToMove(context) === undefined)
                    return ts.emptyArray;
                var description = ts.getLocaleSpecificMessage(ts.Diagnostics.Move_to_a_new_file);
                return [{ name: refactorName, description: description, actions: [{ name: refactorName, description: description }] }];
            },
            getEditsForAction: function (context, actionName) {
                ts.Debug.assert(actionName === refactorName);
                var statements = ts.Debug.assertDefined(getStatementsToMove(context));
                var edits = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(context.file, context.program, statements, t, context.host, context.preferences); });
                return { edits: edits, renameFilename: undefined, renameLocation: undefined };
            }
        });
        function getRangeToMove(context) {
            var file = context.file;
            var range = ts.createTextRangeFromSpan(ts.getRefactorContextSpan(context));
            var statements = file.statements;
            var startNodeIndex = ts.findIndex(statements, function (s) { return s.end > range.pos; });
            if (startNodeIndex === -1)
                return undefined;
            var startStatement = statements[startNodeIndex];
            if (ts.isNamedDeclaration(startStatement) && startStatement.name && ts.rangeContainsRange(startStatement.name, range)) {
                return { toMove: [statements[startNodeIndex]], afterLast: statements[startNodeIndex + 1] };
            }
            // Can't only partially include the start node or be partially into the next node
            if (range.pos > startStatement.getStart(file))
                return undefined;
            var afterEndNodeIndex = ts.findIndex(statements, function (s) { return s.end > range.end; }, startNodeIndex);
            // Can't be partially into the next node
            if (afterEndNodeIndex !== -1 && (afterEndNodeIndex === 0 || statements[afterEndNodeIndex].getStart(file) < range.end))
                return undefined;
            return {
                toMove: statements.slice(startNodeIndex, afterEndNodeIndex === -1 ? statements.length : afterEndNodeIndex),
                afterLast: afterEndNodeIndex === -1 ? undefined : statements[afterEndNodeIndex],
            };
        }
        function doChange(oldFile, program, toMove, changes, host, preferences) {
            var checker = program.getTypeChecker();
            var usage = getUsageInfo(oldFile, toMove.all, checker);
            var currentDirectory = ts.getDirectoryPath(oldFile.fileName);
            var extension = ts.extensionFromPath(oldFile.fileName);
            var newModuleName = makeUniqueModuleName(getNewModuleName(usage.movedSymbols), extension, currentDirectory, host);
            var newFileNameWithExtension = newModuleName + extension;
            // If previous file was global, this is easy.
            changes.createNewFile(oldFile, ts.combinePaths(currentDirectory, newFileNameWithExtension), getNewStatementsAndRemoveFromOldFile(oldFile, usage, changes, toMove, program, newModuleName, preferences));
            addNewFileToTsconfig(program, changes, oldFile.fileName, newFileNameWithExtension, ts.hostGetCanonicalFileName(host));
        }
        // Filters imports out of the range of statements to move. Imports will be copied to the new file anyway, and may still be needed in the old file.
        function getStatementsToMove(context) {
            var rangeToMove = getRangeToMove(context);
            if (rangeToMove === undefined)
                return undefined;
            var all = [];
            var ranges = [];
            var toMove = rangeToMove.toMove, afterLast = rangeToMove.afterLast;
            ts.getRangesWhere(toMove, function (s) { return !isPureImport(s); }, function (start, afterEndIndex) {
                for (var i = start; i < afterEndIndex; i++)
                    all.push(toMove[i]);
                ranges.push({ first: toMove[start], afterLast: afterLast });
            });
            return all.length === 0 ? undefined : { all: all, ranges: ranges };
        }
        function isPureImport(node) {
            switch (node.kind) {
                case 250 /* ImportDeclaration */:
                    return true;
                case 249 /* ImportEqualsDeclaration */:
                    return !ts.hasModifier(node, 1 /* Export */);
                case 220 /* VariableStatement */:
                    return node.declarationList.declarations.every(function (d) { return !!d.initializer && ts.isRequireCall(d.initializer, /*checkArgumentIsStringLiteralLike*/ true); });
                default:
                    return false;
            }
        }
        function addNewFileToTsconfig(program, changes, oldFileName, newFileNameWithExtension, getCanonicalFileName) {
            var cfg = program.getCompilerOptions().configFile;
            if (!cfg)
                return;
            var newFileAbsolutePath = ts.normalizePath(ts.combinePaths(oldFileName, "..", newFileNameWithExtension));
            var newFilePath = ts.getRelativePathFromFile(cfg.fileName, newFileAbsolutePath, getCanonicalFileName);
            var cfgObject = cfg.statements[0] && ts.tryCast(cfg.statements[0].expression, ts.isObjectLiteralExpression);
            var filesProp = cfgObject && ts.find(cfgObject.properties, function (prop) {
                return ts.isPropertyAssignment(prop) && ts.isStringLiteral(prop.name) && prop.name.text === "files";
            });
            if (filesProp && ts.isArrayLiteralExpression(filesProp.initializer)) {
                changes.insertNodeInListAfter(cfg, ts.last(filesProp.initializer.elements), ts.createLiteral(newFilePath), filesProp.initializer.elements);
            }
        }
        function getNewStatementsAndRemoveFromOldFile(oldFile, usage, changes, toMove, program, newModuleName, preferences) {
            var checker = program.getTypeChecker();
            if (!oldFile.externalModuleIndicator && !oldFile.commonJsModuleIndicator) {
                deleteMovedStatements(oldFile, toMove.ranges, changes);
                return toMove.all;
            }
            var useEs6ModuleSyntax = !!oldFile.externalModuleIndicator;
            var quotePreference = ts.getQuotePreference(oldFile, preferences);
            var importsFromNewFile = createOldFileImportsFromNewFile(usage.oldFileImportsFromNewFile, newModuleName, useEs6ModuleSyntax, quotePreference);
            if (importsFromNewFile) {
                ts.insertImport(changes, oldFile, importsFromNewFile);
            }
            deleteUnusedOldImports(oldFile, toMove.all, changes, usage.unusedImportsFromOldFile, checker);
            deleteMovedStatements(oldFile, toMove.ranges, changes);
            updateImportsInOtherFiles(changes, program, oldFile, usage.movedSymbols, newModuleName);
            return getNewFileImportsAndAddExportInOldFile(oldFile, usage.oldImportsNeededByNewFile, usage.newFileImportsFromOldFile, changes, checker, useEs6ModuleSyntax, quotePreference).concat(addExports(oldFile, toMove.all, usage.oldFileImportsFromNewFile, useEs6ModuleSyntax));
        }
        function deleteMovedStatements(sourceFile, moved, changes) {
            for (var _i = 0, moved_1 = moved; _i < moved_1.length; _i++) {
                var _a = moved_1[_i], first_1 = _a.first, afterLast = _a.afterLast;
                changes.deleteNodeRangeExcludingEnd(sourceFile, first_1, afterLast);
            }
        }
        function deleteUnusedOldImports(oldFile, toMove, changes, toDelete, checker) {
            for (var _i = 0, _a = oldFile.statements; _i < _a.length; _i++) {
                var statement = _a[_i];
                if (ts.contains(toMove, statement))
                    continue;
                forEachImportInStatement(statement, function (i) { return deleteUnusedImports(oldFile, i, changes, function (name) { return toDelete.has(checker.getSymbolAtLocation(name)); }); });
            }
        }
        function updateImportsInOtherFiles(changes, program, oldFile, movedSymbols, newModuleName) {
            var checker = program.getTypeChecker();
            var _loop_15 = function (sourceFile) {
                if (sourceFile === oldFile)
                    return "continue";
                var _loop_16 = function (statement) {
                    forEachImportInStatement(statement, function (importNode) {
                        if (checker.getSymbolAtLocation(moduleSpecifierFromImport(importNode)) !== oldFile.symbol)
                            return;
                        var shouldMove = function (name) {
                            var symbol = ts.isBindingElement(name.parent)
                                ? ts.getPropertySymbolFromBindingElement(checker, name.parent)
                                : ts.skipAlias(checker.getSymbolAtLocation(name), checker); // TODO: GH#18217
                            return !!symbol && movedSymbols.has(symbol);
                        };
                        deleteUnusedImports(sourceFile, importNode, changes, shouldMove); // These will be changed to imports from the new file
                        var newModuleSpecifier = ts.combinePaths(ts.getDirectoryPath(moduleSpecifierFromImport(importNode).text), newModuleName);
                        var newImportDeclaration = filterImport(importNode, ts.createLiteral(newModuleSpecifier), shouldMove);
                        if (newImportDeclaration)
                            changes.insertNodeAfter(sourceFile, statement, newImportDeclaration);
                        var ns = getNamespaceLikeImport(importNode);
                        if (ns)
                            updateNamespaceLikeImport(changes, sourceFile, checker, movedSymbols, newModuleName, newModuleSpecifier, ns, importNode);
                    });
                };
                for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
                    var statement = _a[_i];
                    _loop_16(statement);
                }
            };
            for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
                var sourceFile = _a[_i];
                _loop_15(sourceFile);
            }
        }
        function getNamespaceLikeImport(node) {
            switch (node.kind) {
                case 250 /* ImportDeclaration */:
                    return node.importClause && node.importClause.namedBindings && node.importClause.namedBindings.kind === 252 /* NamespaceImport */ ?
                        node.importClause.namedBindings.name : undefined;
                case 249 /* ImportEqualsDeclaration */:
                    return node.name;
                case 238 /* VariableDeclaration */:
                    return ts.tryCast(node.name, ts.isIdentifier);
                default:
                    return ts.Debug.assertNever(node);
            }
        }
        function updateNamespaceLikeImport(changes, sourceFile, checker, movedSymbols, newModuleName, newModuleSpecifier, oldImportId, oldImportNode) {
            var preferredNewNamespaceName = ts.codefix.moduleSpecifierToValidIdentifier(newModuleName, 8 /* ESNext */);
            var needUniqueName = false;
            var toChange = [];
            ts.FindAllReferences.Core.eachSymbolReferenceInFile(oldImportId, checker, sourceFile, function (ref) {
                if (!ts.isPropertyAccessExpression(ref.parent))
                    return;
                needUniqueName = needUniqueName || !!checker.resolveName(preferredNewNamespaceName, ref, 67108863 /* All */, /*excludeGlobals*/ true);
                if (movedSymbols.has(checker.getSymbolAtLocation(ref.parent.name))) {
                    toChange.push(ref);
                }
            });
            if (toChange.length) {
                var newNamespaceName = needUniqueName ? ts.getUniqueName(preferredNewNamespaceName, sourceFile) : preferredNewNamespaceName;
                for (var _i = 0, toChange_1 = toChange; _i < toChange_1.length; _i++) {
                    var ref = toChange_1[_i];
                    changes.replaceNode(sourceFile, ref, ts.createIdentifier(newNamespaceName));
                }
                changes.insertNodeAfter(sourceFile, oldImportNode, updateNamespaceLikeImportNode(oldImportNode, newModuleName, newModuleSpecifier));
            }
        }
        function updateNamespaceLikeImportNode(node, newNamespaceName, newModuleSpecifier) {
            var newNamespaceId = ts.createIdentifier(newNamespaceName);
            var newModuleString = ts.createLiteral(newModuleSpecifier);
            switch (node.kind) {
                case 250 /* ImportDeclaration */:
                    return ts.createImportDeclaration(
                    /*decorators*/ undefined, /*modifiers*/ undefined, ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(newNamespaceId)), newModuleString);
                case 249 /* ImportEqualsDeclaration */:
                    return ts.createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newNamespaceId, ts.createExternalModuleReference(newModuleString));
                case 238 /* VariableDeclaration */:
                    return ts.createVariableDeclaration(newNamespaceId, /*type*/ undefined, createRequireCall(newModuleString));
                default:
                    return ts.Debug.assertNever(node);
            }
        }
        function moduleSpecifierFromImport(i) {
            return (i.kind === 250 /* ImportDeclaration */ ? i.moduleSpecifier
                : i.kind === 249 /* ImportEqualsDeclaration */ ? i.moduleReference.expression
                    : i.initializer.arguments[0]);
        }
        function forEachImportInStatement(statement, cb) {
            if (ts.isImportDeclaration(statement)) {
                if (ts.isStringLiteral(statement.moduleSpecifier))
                    cb(statement);
            }
            else if (ts.isImportEqualsDeclaration(statement)) {
                if (ts.isExternalModuleReference(statement.moduleReference) && ts.isStringLiteralLike(statement.moduleReference.expression)) {
                    cb(statement);
                }
            }
            else if (ts.isVariableStatement(statement)) {
                for (var _i = 0, _a = statement.declarationList.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    if (decl.initializer && ts.isRequireCall(decl.initializer, /*checkArgumentIsStringLiteralLike*/ true)) {
                        cb(decl);
                    }
                }
            }
        }
        function createOldFileImportsFromNewFile(newFileNeedExport, newFileNameWithExtension, useEs6Imports, quotePreference) {
            var defaultImport;
            var imports = [];
            newFileNeedExport.forEach(function (symbol) {
                if (symbol.escapedName === "default" /* Default */) {
                    defaultImport = ts.createIdentifier(ts.symbolNameNoDefault(symbol)); // TODO: GH#18217
                }
                else {
                    imports.push(symbol.name);
                }
            });
            return makeImportOrRequire(defaultImport, imports, newFileNameWithExtension, useEs6Imports, quotePreference);
        }
        function makeImportOrRequire(defaultImport, imports, path, useEs6Imports, quotePreference) {
            path = ts.ensurePathIsNonModuleName(path);
            if (useEs6Imports) {
                var specifiers = imports.map(function (i) { return ts.createImportSpecifier(/*propertyName*/ undefined, ts.createIdentifier(i)); });
                return ts.makeImportIfNecessary(defaultImport, specifiers, path, quotePreference);
            }
            else {
                ts.Debug.assert(!defaultImport); // If there's a default export, it should have been an es6 module.
                var bindingElements = imports.map(function (i) { return ts.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, i); });
                return bindingElements.length
                    ? makeVariableStatement(ts.createObjectBindingPattern(bindingElements), /*type*/ undefined, createRequireCall(ts.createLiteral(path)))
                    : undefined;
            }
        }
        function makeVariableStatement(name, type, initializer, flags) {
            if (flags === void 0) { flags = 2 /* Const */; }
            return ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(name, type, initializer)], flags));
        }
        function createRequireCall(moduleSpecifier) {
            return ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, [moduleSpecifier]);
        }
        function addExports(sourceFile, toMove, needExport, useEs6Exports) {
            return ts.flatMap(toMove, function (statement) {
                if (isTopLevelDeclarationStatement(statement) &&
                    !isExported(sourceFile, statement, useEs6Exports) &&
                    forEachTopLevelDeclaration(statement, function (d) { return needExport.has(ts.Debug.assertDefined(d.symbol)); })) {
                    var exports = addExport(statement, useEs6Exports);
                    if (exports)
                        return exports;
                }
                return statement;
            });
        }
        function deleteUnusedImports(sourceFile, importDecl, changes, isUnused) {
            switch (importDecl.kind) {
                case 250 /* ImportDeclaration */:
                    deleteUnusedImportsInDeclaration(sourceFile, importDecl, changes, isUnused);
                    break;
                case 249 /* ImportEqualsDeclaration */:
                    if (isUnused(importDecl.name)) {
                        changes.delete(sourceFile, importDecl);
                    }
                    break;
                case 238 /* VariableDeclaration */:
                    deleteUnusedImportsInVariableDeclaration(sourceFile, importDecl, changes, isUnused);
                    break;
                default:
                    ts.Debug.assertNever(importDecl);
            }
        }
        function deleteUnusedImportsInDeclaration(sourceFile, importDecl, changes, isUnused) {
            if (!importDecl.importClause)
                return;
            var _a = importDecl.importClause, name = _a.name, namedBindings = _a.namedBindings;
            var defaultUnused = !name || isUnused(name);
            var namedBindingsUnused = !namedBindings ||
                (namedBindings.kind === 252 /* NamespaceImport */ ? isUnused(namedBindings.name) : namedBindings.elements.length !== 0 && namedBindings.elements.every(function (e) { return isUnused(e.name); }));
            if (defaultUnused && namedBindingsUnused) {
                changes.delete(sourceFile, importDecl);
            }
            else {
                if (name && defaultUnused) {
                    changes.delete(sourceFile, name);
                }
                if (namedBindings) {
                    if (namedBindingsUnused) {
                        changes.delete(sourceFile, namedBindings);
                    }
                    else if (namedBindings.kind === 253 /* NamedImports */) {
                        for (var _i = 0, _b = namedBindings.elements; _i < _b.length; _i++) {
                            var element = _b[_i];
                            if (isUnused(element.name))
                                changes.delete(sourceFile, element);
                        }
                    }
                }
            }
        }
        function deleteUnusedImportsInVariableDeclaration(sourceFile, varDecl, changes, isUnused) {
            var name = varDecl.name;
            switch (name.kind) {
                case 73 /* Identifier */:
                    if (isUnused(name)) {
                        changes.delete(sourceFile, name);
                    }
                    break;
                case 186 /* ArrayBindingPattern */:
                    break;
                case 185 /* ObjectBindingPattern */:
                    if (name.elements.every(function (e) { return ts.isIdentifier(e.name) && isUnused(e.name); })) {
                        changes.delete(sourceFile, ts.isVariableDeclarationList(varDecl.parent) && varDecl.parent.declarations.length === 1 ? varDecl.parent.parent : varDecl);
                    }
                    else {
                        for (var _i = 0, _a = name.elements; _i < _a.length; _i++) {
                            var element = _a[_i];
                            if (ts.isIdentifier(element.name) && isUnused(element.name)) {
                                changes.delete(sourceFile, element.name);
                            }
                        }
                    }
                    break;
            }
        }
        function getNewFileImportsAndAddExportInOldFile(oldFile, importsToCopy, newFileImportsFromOldFile, changes, checker, useEs6ModuleSyntax, quotePreference) {
            var copiedOldImports = [];
            for (var _i = 0, _a = oldFile.statements; _i < _a.length; _i++) {
                var oldStatement = _a[_i];
                forEachImportInStatement(oldStatement, function (i) {
                    ts.append(copiedOldImports, filterImport(i, moduleSpecifierFromImport(i), function (name) { return importsToCopy.has(checker.getSymbolAtLocation(name)); }));
                });
            }
            // Also, import things used from the old file, and insert 'export' modifiers as necessary in the old file.
            var oldFileDefault;
            var oldFileNamedImports = [];
            var markSeenTop = ts.nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`.
            newFileImportsFromOldFile.forEach(function (symbol) {
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    if (!isTopLevelDeclaration(decl))
                        continue;
                    var name = nameOfTopLevelDeclaration(decl);
                    if (!name)
                        continue;
                    var top = getTopLevelDeclarationStatement(decl);
                    if (markSeenTop(top)) {
                        addExportToChanges(oldFile, top, changes, useEs6ModuleSyntax);
                    }
                    if (ts.hasModifier(decl, 512 /* Default */)) {
                        oldFileDefault = name;
                    }
                    else {
                        oldFileNamedImports.push(name.text);
                    }
                }
            });
            ts.append(copiedOldImports, makeImportOrRequire(oldFileDefault, oldFileNamedImports, ts.removeFileExtension(ts.getBaseFileName(oldFile.fileName)), useEs6ModuleSyntax, quotePreference));
            return copiedOldImports;
        }
        function makeUniqueModuleName(moduleName, extension, inDirectory, host) {
            var newModuleName = moduleName;
            for (var i = 1;; i++) {
                var name = ts.combinePaths(inDirectory, newModuleName + extension);
                if (!host.fileExists(name))
                    return newModuleName; // TODO: GH#18217
                newModuleName = moduleName + "." + i;
            }
        }
        function getNewModuleName(movedSymbols) {
            return movedSymbols.forEachEntry(ts.symbolNameNoDefault) || "newFile";
        }
        function getUsageInfo(oldFile, toMove, checker) {
            var movedSymbols = new SymbolSet();
            var oldImportsNeededByNewFile = new SymbolSet();
            var newFileImportsFromOldFile = new SymbolSet();
            var containsJsx = ts.find(toMove, function (statement) { return !!(statement.transformFlags & 2 /* ContainsJsx */); });
            var jsxNamespaceSymbol = getJsxNamespaceSymbol(containsJsx);
            if (jsxNamespaceSymbol) { // Might not exist (e.g. in non-compiling code)
                oldImportsNeededByNewFile.add(jsxNamespaceSymbol);
            }
            for (var _i = 0, toMove_1 = toMove; _i < toMove_1.length; _i++) {
                var statement = toMove_1[_i];
                forEachTopLevelDeclaration(statement, function (decl) {
                    movedSymbols.add(ts.Debug.assertDefined(ts.isExpressionStatement(decl) ? checker.getSymbolAtLocation(decl.expression.left) : decl.symbol));
                });
            }
            for (var _a = 0, toMove_2 = toMove; _a < toMove_2.length; _a++) {
                var statement = toMove_2[_a];
                forEachReference(statement, checker, function (symbol) {
                    if (!symbol.declarations)
                        return;
                    for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                        var decl = _a[_i];
                        if (isInImport(decl)) {
                            oldImportsNeededByNewFile.add(symbol);
                        }
                        else if (isTopLevelDeclaration(decl) && sourceFileOfTopLevelDeclaration(decl) === oldFile && !movedSymbols.has(symbol)) {
                            newFileImportsFromOldFile.add(symbol);
                        }
                    }
                });
            }
            var unusedImportsFromOldFile = oldImportsNeededByNewFile.clone();
            var oldFileImportsFromNewFile = new SymbolSet();
            for (var _b = 0, _c = oldFile.statements; _b < _c.length; _b++) {
                var statement = _c[_b];
                if (ts.contains(toMove, statement))
                    continue;
                // jsxNamespaceSymbol will only be set iff it is in oldImportsNeededByNewFile.
                if (jsxNamespaceSymbol && !!(statement.transformFlags & 2 /* ContainsJsx */)) {
                    unusedImportsFromOldFile.delete(jsxNamespaceSymbol);
                }
                forEachReference(statement, checker, function (symbol) {
                    if (movedSymbols.has(symbol))
                        oldFileImportsFromNewFile.add(symbol);
                    unusedImportsFromOldFile.delete(symbol);
                });
            }
            return { movedSymbols: movedSymbols, newFileImportsFromOldFile: newFileImportsFromOldFile, oldFileImportsFromNewFile: oldFileImportsFromNewFile, oldImportsNeededByNewFile: oldImportsNeededByNewFile, unusedImportsFromOldFile: unusedImportsFromOldFile };
            function getJsxNamespaceSymbol(containsJsx) {
                if (containsJsx === undefined) {
                    return undefined;
                }
                var jsxNamespace = checker.getJsxNamespace(containsJsx);
                // Strictly speaking, this could resolve to a symbol other than the JSX namespace.
                // This will produce erroneous output (probably, an incorrectly copied import) but
                // is expected to be very rare and easily reversible.
                var jsxNamespaceSymbol = checker.resolveName(jsxNamespace, containsJsx, 1920 /* Namespace */, /*excludeGlobals*/ true);
                return !!jsxNamespaceSymbol && ts.some(jsxNamespaceSymbol.declarations, isInImport)
                    ? jsxNamespaceSymbol
                    : undefined;
            }
        }
        // Below should all be utilities
        function isInImport(decl) {
            switch (decl.kind) {
                case 249 /* ImportEqualsDeclaration */:
                case 254 /* ImportSpecifier */:
                case 251 /* ImportClause */:
                    return true;
                case 238 /* VariableDeclaration */:
                    return isVariableDeclarationInImport(decl);
                case 187 /* BindingElement */:
                    return ts.isVariableDeclaration(decl.parent.parent) && isVariableDeclarationInImport(decl.parent.parent);
                default:
                    return false;
            }
        }
        function isVariableDeclarationInImport(decl) {
            return ts.isSourceFile(decl.parent.parent.parent) &&
                !!decl.initializer && ts.isRequireCall(decl.initializer, /*checkArgumentIsStringLiteralLike*/ true);
        }
        function filterImport(i, moduleSpecifier, keep) {
            switch (i.kind) {
                case 250 /* ImportDeclaration */: {
                    var clause = i.importClause;
                    if (!clause)
                        return undefined;
                    var defaultImport = clause.name && keep(clause.name) ? clause.name : undefined;
                    var namedBindings = clause.namedBindings && filterNamedBindings(clause.namedBindings, keep);
                    return defaultImport || namedBindings
                        ? ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, ts.createImportClause(defaultImport, namedBindings), moduleSpecifier)
                        : undefined;
                }
                case 249 /* ImportEqualsDeclaration */:
                    return keep(i.name) ? i : undefined;
                case 238 /* VariableDeclaration */: {
                    var name = filterBindingName(i.name, keep);
                    return name ? makeVariableStatement(name, i.type, createRequireCall(moduleSpecifier), i.parent.flags) : undefined;
                }
                default:
                    return ts.Debug.assertNever(i);
            }
        }
        function filterNamedBindings(namedBindings, keep) {
            if (namedBindings.kind === 252 /* NamespaceImport */) {
                return keep(namedBindings.name) ? namedBindings : undefined;
            }
            else {
                var newElements = namedBindings.elements.filter(function (e) { return keep(e.name); });
                return newElements.length ? ts.createNamedImports(newElements) : undefined;
            }
        }
        function filterBindingName(name, keep) {
            switch (name.kind) {
                case 73 /* Identifier */:
                    return keep(name) ? name : undefined;
                case 186 /* ArrayBindingPattern */:
                    return name;
                case 185 /* ObjectBindingPattern */: {
                    // We can't handle nested destructurings or property names well here, so just copy them all.
                    var newElements = name.elements.filter(function (prop) { return prop.propertyName || !ts.isIdentifier(prop.name) || keep(prop.name); });
                    return newElements.length ? ts.createObjectBindingPattern(newElements) : undefined;
                }
            }
        }
        function forEachReference(node, checker, onReference) {
            node.forEachChild(function cb(node) {
                if (ts.isIdentifier(node) && !ts.isDeclarationName(node)) {
                    var sym = checker.getSymbolAtLocation(node);
                    if (sym)
                        onReference(sym);
                }
                else {
                    node.forEachChild(cb);
                }
            });
        }
        var SymbolSet = /** @class */ (function () {
            function SymbolSet() {
                this.map = ts.createMap();
            }
            SymbolSet.prototype.add = function (symbol) {
                this.map.set(String(ts.getSymbolId(symbol)), symbol);
            };
            SymbolSet.prototype.has = function (symbol) {
                return this.map.has(String(ts.getSymbolId(symbol)));
            };
            SymbolSet.prototype.delete = function (symbol) {
                this.map.delete(String(ts.getSymbolId(symbol)));
            };
            SymbolSet.prototype.forEach = function (cb) {
                this.map.forEach(cb);
            };
            SymbolSet.prototype.forEachEntry = function (cb) {
                return ts.forEachEntry(this.map, cb);
            };
            SymbolSet.prototype.clone = function () {
                var clone = new SymbolSet();
                ts.copyEntries(this.map, clone.map);
                return clone;
            };
            return SymbolSet;
        }());
        function isTopLevelDeclaration(node) {
            return isNonVariableTopLevelDeclaration(node) && ts.isSourceFile(node.parent) || ts.isVariableDeclaration(node) && ts.isSourceFile(node.parent.parent.parent);
        }
        function sourceFileOfTopLevelDeclaration(node) {
            return ts.isVariableDeclaration(node) ? node.parent.parent.parent : node.parent;
        }
        function isTopLevelDeclarationStatement(node) {
            ts.Debug.assert(ts.isSourceFile(node.parent));
            return isNonVariableTopLevelDeclaration(node) || ts.isVariableStatement(node);
        }
        function isNonVariableTopLevelDeclaration(node) {
            switch (node.kind) {
                case 240 /* FunctionDeclaration */:
                case 241 /* ClassDeclaration */:
                case 245 /* ModuleDeclaration */:
                case 244 /* EnumDeclaration */:
                case 243 /* TypeAliasDeclaration */:
                case 242 /* InterfaceDeclaration */:
                case 249 /* ImportEqualsDeclaration */:
                    return true;
                default:
                    return false;
            }
        }
        function forEachTopLevelDeclaration(statement, cb) {
            switch (statement.kind) {
                case 240 /* FunctionDeclaration */:
                case 241 /* ClassDeclaration */:
                case 245 /* ModuleDeclaration */:
                case 244 /* EnumDeclaration */:
                case 243 /* TypeAliasDeclaration */:
                case 242 /* InterfaceDeclaration */:
                case 249 /* ImportEqualsDeclaration */:
                    return cb(statement);
                case 220 /* VariableStatement */:
                    return ts.firstDefined(statement.declarationList.declarations, function (decl) { return forEachTopLevelDeclarationInBindingName(decl.name, cb); });
                case 222 /* ExpressionStatement */: {
                    var expression = statement.expression;
                    return ts.isBinaryExpression(expression) && ts.getAssignmentDeclarationKind(expression) === 1 /* ExportsProperty */
                        ? cb(statement)
                        : undefined;
                }
            }
        }
        function forEachTopLevelDeclarationInBindingName(name, cb) {
            switch (name.kind) {
                case 73 /* Identifier */:
                    return cb(ts.cast(name.parent, function (x) { return ts.isVariableDeclaration(x) || ts.isBindingElement(x); }));
                case 186 /* ArrayBindingPattern */:
                case 185 /* ObjectBindingPattern */:
                    return ts.firstDefined(name.elements, function (em) { return ts.isOmittedExpression(em) ? undefined : forEachTopLevelDeclarationInBindingName(em.name, cb); });
                default:
                    return ts.Debug.assertNever(name);
            }
        }
        function nameOfTopLevelDeclaration(d) {
            return ts.isExpressionStatement(d) ? d.expression.left.name : ts.tryCast(d.name, ts.isIdentifier);
        }
        function getTopLevelDeclarationStatement(d) {
            switch (d.kind) {
                case 238 /* VariableDeclaration */:
                    return d.parent.parent;
                case 187 /* BindingElement */:
                    return getTopLevelDeclarationStatement(ts.cast(d.parent.parent, function (p) { return ts.isVariableDeclaration(p) || ts.isBindingElement(p); }));
                default:
                    return d;
            }
        }
        function addExportToChanges(sourceFile, decl, changes, useEs6Exports) {
            if (isExported(sourceFile, decl, useEs6Exports))
                return;
            if (useEs6Exports) {
                if (!ts.isExpressionStatement(decl))
                    changes.insertExportModifier(sourceFile, decl);
            }
            else {
                var names = getNamesToExportInCommonJS(decl);
                if (names.length !== 0)
                    changes.insertNodesAfter(sourceFile, decl, names.map(createExportAssignment));
            }
        }
        function isExported(sourceFile, decl, useEs6Exports) {
            if (useEs6Exports) {
                return !ts.isExpressionStatement(decl) && ts.hasModifier(decl, 1 /* Export */);
            }
            else {
                return getNamesToExportInCommonJS(decl).some(function (name) { return sourceFile.symbol.exports.has(ts.escapeLeadingUnderscores(name)); });
            }
        }
        function addExport(decl, useEs6Exports) {
            return useEs6Exports ? [addEs6Export(decl)] : addCommonjsExport(decl);
        }
        function addEs6Export(d) {
            var modifiers = ts.concatenate([ts.createModifier(86 /* ExportKeyword */)], d.modifiers);
            switch (d.kind) {
                case 240 /* FunctionDeclaration */:
                    return ts.updateFunctionDeclaration(d, d.decorators, modifiers, d.asteriskToken, d.name, d.typeParameters, d.parameters, d.type, d.body);
                case 241 /* ClassDeclaration */:
                    return ts.updateClassDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members);
                case 220 /* VariableStatement */:
                    return ts.updateVariableStatement(d, modifiers, d.declarationList);
                case 245 /* ModuleDeclaration */:
                    return ts.updateModuleDeclaration(d, d.decorators, modifiers, d.name, d.body);
                case 244 /* EnumDeclaration */:
                    return ts.updateEnumDeclaration(d, d.decorators, modifiers, d.name, d.members);
                case 243 /* TypeAliasDeclaration */:
                    return ts.updateTypeAliasDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.type);
                case 242 /* InterfaceDeclaration */:
                    return ts.updateInterfaceDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members);
                case 249 /* ImportEqualsDeclaration */:
                    return ts.updateImportEqualsDeclaration(d, d.decorators, modifiers, d.name, d.moduleReference);
                case 222 /* ExpressionStatement */:
                    return ts.Debug.fail(); // Shouldn't try to add 'export' keyword to `exports.x = ...`
                default:
                    return ts.Debug.assertNever(d);
            }
        }
        function addCommonjsExport(decl) {
            return [decl].concat(getNamesToExportInCommonJS(decl).map(createExportAssignment));
        }
        function getNamesToExportInCommonJS(decl) {
            switch (decl.kind) {
                case 240 /* FunctionDeclaration */:
                case 241 /* ClassDeclaration */:
                    return [decl.name.text]; // TODO: GH#18217
                case 220 /* VariableStatement */:
                    return ts.mapDefined(decl.declarationList.declarations, function (d) { return ts.isIdentifier(d.name) ? d.name.text : undefined; });
                case 245 /* ModuleDeclaration */:
                case 244 /* EnumDeclaration */:
                case 243 /* TypeAliasDeclaration */:
                case 242 /* InterfaceDeclaration */:
                case 249 /* ImportEqualsDeclaration */:
                    return ts.emptyArray;
                case 222 /* ExpressionStatement */:
                    return ts.Debug.fail(); // Shouldn't try to add 'export' keyword to `exports.x = ...`
                default:
                    return ts.Debug.assertNever(decl);
            }
        }
        /** Creates `exports.x = x;` */
        function createExportAssignment(name) {
            return ts.createExpressionStatement(ts.createBinary(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.createIdentifier(name)), 60 /* EqualsToken */, ts.createIdentifier(name)));
        }
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var addOrRemoveBracesToArrowFunction;
        (function (addOrRemoveBracesToArrowFunction) {
            var refactorName = "Add or remove braces in an arrow function";
            var refactorDescription = ts.Diagnostics.Add_or_remove_braces_in_an_arrow_function.message;
            var addBracesActionName = "Add braces to arrow function";
            var removeBracesActionName = "Remove braces from arrow function";
            var addBracesActionDescription = ts.Diagnostics.Add_braces_to_arrow_function.message;
            var removeBracesActionDescription = ts.Diagnostics.Remove_braces_from_arrow_function.message;
            refactor.registerRefactor(refactorName, { getEditsForAction: getEditsForAction, getAvailableActions: getAvailableActions });
            function getAvailableActions(context) {
                var file = context.file, startPosition = context.startPosition;
                var info = getConvertibleArrowFunctionAtPosition(file, startPosition);
                if (!info)
                    return ts.emptyArray;
                return [{
                        name: refactorName,
                        description: refactorDescription,
                        actions: [
                            info.addBraces ?
                                {
                                    name: addBracesActionName,
                                    description: addBracesActionDescription
                                } : {
                                name: removeBracesActionName,
                                description: removeBracesActionDescription
                            }
                        ]
                    }];
            }
            function getEditsForAction(context, actionName) {
                var file = context.file, startPosition = context.startPosition;
                var info = getConvertibleArrowFunctionAtPosition(file, startPosition);
                if (!info)
                    return undefined;
                var expression = info.expression, returnStatement = info.returnStatement, func = info.func;
                var body;
                if (actionName === addBracesActionName) {
                    var returnStatement_1 = ts.createReturn(expression);
                    body = ts.createBlock([returnStatement_1], /* multiLine */ true);
                    ts.suppressLeadingAndTrailingTrivia(body);
                    ts.copyLeadingComments(expression, returnStatement_1, file, 3 /* MultiLineCommentTrivia */, /* hasTrailingNewLine */ true);
                }
                else if (actionName === removeBracesActionName && returnStatement) {
                    var actualExpression = expression || ts.createVoidZero();
                    body = needsParentheses(actualExpression) ? ts.createParen(actualExpression) : actualExpression;
                    ts.suppressLeadingAndTrailingTrivia(body);
                    ts.copyLeadingComments(returnStatement, body, file, 3 /* MultiLineCommentTrivia */, /* hasTrailingNewLine */ false);
                }
                else {
                    ts.Debug.fail("invalid action");
                }
                var edits = ts.textChanges.ChangeTracker.with(context, function (t) { return t.replaceNode(file, func.body, body); });
                return { renameFilename: undefined, renameLocation: undefined, edits: edits };
            }
            function needsParentheses(expression) {
                return ts.isBinaryExpression(expression) && expression.operatorToken.kind === 27 /* CommaToken */ || ts.isObjectLiteralExpression(expression);
            }
            function getConvertibleArrowFunctionAtPosition(file, startPosition) {
                var node = ts.getTokenAtPosition(file, startPosition);
                var func = ts.getContainingFunction(node);
                if (!func || !ts.isArrowFunction(func) || (!ts.rangeContainsRange(func, node) || ts.rangeContainsRange(func.body, node)))
                    return undefined;
                if (ts.isExpression(func.body)) {
                    return {
                        func: func,
                        addBraces: true,
                        expression: func.body
                    };
                }
                else if (func.body.statements.length === 1) {
                    var firstStatement = ts.first(func.body.statements);
                    if (ts.isReturnStatement(firstStatement)) {
                        return {
                            func: func,
                            addBraces: false,
                            expression: firstStatement.expression,
                            returnStatement: firstStatement
                        };
                    }
                }
                return undefined;
            }
        })(addOrRemoveBracesToArrowFunction = refactor.addOrRemoveBracesToArrowFunction || (refactor.addOrRemoveBracesToArrowFunction = {}));
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var convertParamsToDestructuredObject;
        (function (convertParamsToDestructuredObject) {
            var refactorName = "Convert parameters to destructured object";
            var minimumParameterLength = 2;
            refactor.registerRefactor(refactorName, { getEditsForAction: getEditsForAction, getAvailableActions: getAvailableActions });
            function getAvailableActions(context) {
                var file = context.file, startPosition = context.startPosition;
                var isJSFile = ts.isSourceFileJS(file);
                if (isJSFile)
                    return ts.emptyArray; // TODO: GH#30113
                var functionDeclaration = getFunctionDeclarationAtPosition(file, startPosition, context.program.getTypeChecker());
                if (!functionDeclaration)
                    return ts.emptyArray;
                var description = ts.getLocaleSpecificMessage(ts.Diagnostics.Convert_parameters_to_destructured_object);
                return [{
                        name: refactorName,
                        description: description,
                        actions: [{
                                name: refactorName,
                                description: description
                            }]
                    }];
            }
            function getEditsForAction(context, actionName) {
                ts.Debug.assert(actionName === refactorName);
                var file = context.file, startPosition = context.startPosition, program = context.program, cancellationToken = context.cancellationToken, host = context.host;
                var functionDeclaration = getFunctionDeclarationAtPosition(file, startPosition, program.getTypeChecker());
                if (!functionDeclaration || !cancellationToken)
                    return undefined;
                var groupedReferences = getGroupedReferences(functionDeclaration, program, cancellationToken);
                if (groupedReferences.valid) {
                    var edits = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(file, program, host, t, functionDeclaration, groupedReferences); });
                    return { renameFilename: undefined, renameLocation: undefined, edits: edits };
                }
                return { edits: [] }; // TODO: GH#30113
            }
            function doChange(sourceFile, program, host, changes, functionDeclaration, groupedReferences) {
                var newParamDeclaration = ts.map(createNewParameters(functionDeclaration, program, host), function (param) { return ts.getSynthesizedDeepClone(param); });
                changes.replaceNodeRangeWithNodes(sourceFile, ts.first(functionDeclaration.parameters), ts.last(functionDeclaration.parameters), newParamDeclaration, { joiner: ", ",
                    // indentation is set to 0 because otherwise the object parameter will be indented if there is a `this` parameter
                    indentation: 0,
                    leadingTriviaOption: ts.textChanges.LeadingTriviaOption.IncludeAll,
                    trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Include
                });
                var functionCalls = ts.sortAndDeduplicate(groupedReferences.functionCalls, /*comparer*/ function (a, b) { return ts.compareValues(a.pos, b.pos); });
                for (var _i = 0, functionCalls_1 = functionCalls; _i < functionCalls_1.length; _i++) {
                    var call = functionCalls_1[_i];
                    if (call.arguments && call.arguments.length) {
                        var newArgument = ts.getSynthesizedDeepClone(createNewArgument(functionDeclaration, call.arguments), /*includeTrivia*/ true);
                        changes.replaceNodeRange(ts.getSourceFileOfNode(call), ts.first(call.arguments), ts.last(call.arguments), newArgument, { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.IncludeAll, trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Include });
                    }
                }
            }
            function getGroupedReferences(functionDeclaration, program, cancellationToken) {
                var functionNames = getFunctionNames(functionDeclaration);
                var classNames = ts.isConstructorDeclaration(functionDeclaration) ? getClassNames(functionDeclaration) : [];
                var names = ts.deduplicate(functionNames.concat(classNames), ts.equateValues);
                var checker = program.getTypeChecker();
                var references = ts.flatMap(names, /*mapfn*/ function (/*mapfn*/ name) { return ts.FindAllReferences.getReferenceEntriesForNode(-1, name, program, program.getSourceFiles(), cancellationToken); });
                var groupedReferences = groupReferences(references);
                if (!ts.every(groupedReferences.declarations, /*callback*/ function (/*callback*/ decl) { return ts.contains(names, decl); })) {
                    groupedReferences.valid = false;
                }
                return groupedReferences;
                function groupReferences(referenceEntries) {
                    var classReferences = { accessExpressions: [], typeUsages: [] };
                    var groupedReferences = { functionCalls: [], declarations: [], classReferences: classReferences, valid: true };
                    var functionSymbols = ts.map(functionNames, getSymbolTargetAtLocation);
                    var classSymbols = ts.map(classNames, getSymbolTargetAtLocation);
                    var isConstructor = ts.isConstructorDeclaration(functionDeclaration);
                    for (var _i = 0, referenceEntries_1 = referenceEntries; _i < referenceEntries_1.length; _i++) {
                        var entry = referenceEntries_1[_i];
                        if (entry.kind !== 1 /* Node */) {
                            groupedReferences.valid = false;
                            continue;
                        }
                        /* We compare symbols because in some cases find all references wil return a reference that may or may not be to the refactored function.
                        Example from the refactorConvertParamsToDestructuredObject_methodCallUnion.ts test:
                            class A { foo(a: number, b: number) { return a + b; } }
                            class B { foo(c: number, d: number) { return c + d; } }
                            declare const ab: A | B;
                            ab.foo(1, 2);
                        Find all references will return `ab.foo(1, 2)` as a reference to A's `foo` but we could be calling B's `foo`.
                        When looking for constructor calls, however, the symbol on the constructor call reference is going to be the corresponding class symbol.
                        So we need to add a special case for this because when calling a constructor of a class through one of its subclasses,
                        the symbols are going to be different.
                        */
                        if (ts.contains(functionSymbols, getSymbolTargetAtLocation(entry.node)) || ts.isNewExpressionTarget(entry.node)) {
                            var importOrExportReference = entryToImportOrExport(entry);
                            if (importOrExportReference) {
                                continue;
                            }
                            var decl = entryToDeclaration(entry);
                            if (decl) {
                                groupedReferences.declarations.push(decl);
                                continue;
                            }
                            var call = entryToFunctionCall(entry);
                            if (call) {
                                groupedReferences.functionCalls.push(call);
                                continue;
                            }
                        }
                        // if the refactored function is a constructor, we must also check if the references to its class are valid
                        if (isConstructor && ts.contains(classSymbols, getSymbolTargetAtLocation(entry.node))) {
                            var importOrExportReference = entryToImportOrExport(entry);
                            if (importOrExportReference) {
                                continue;
                            }
                            var decl = entryToDeclaration(entry);
                            if (decl) {
                                groupedReferences.declarations.push(decl);
                                continue;
                            }
                            var accessExpression = entryToAccessExpression(entry);
                            if (accessExpression) {
                                classReferences.accessExpressions.push(accessExpression);
                                continue;
                            }
                            // Only class declarations are allowed to be used as a type (in a heritage clause),
                            // otherwise `findAllReferences` might not be able to track constructor calls.
                            if (ts.isClassDeclaration(functionDeclaration.parent)) {
                                var type = entryToType(entry);
                                if (type) {
                                    classReferences.typeUsages.push(type);
                                    continue;
                                }
                            }
                        }
                        groupedReferences.valid = false;
                    }
                    return groupedReferences;
                }
                function getSymbolTargetAtLocation(node) {
                    var symbol = checker.getSymbolAtLocation(node);
                    return symbol && ts.getSymbolTarget(symbol, checker);
                }
            }
            function entryToImportOrExport(entry) {
                var node = entry.node;
                if (ts.isImportSpecifier(node.parent)
                    || ts.isImportClause(node.parent)
                    || ts.isImportEqualsDeclaration(node.parent)
                    || ts.isNamespaceImport(node.parent)) {
                    return node;
                }
                if (ts.isExportSpecifier(node.parent) || ts.isExportAssignment(node.parent)) {
                    return node;
                }
                return undefined;
            }
            function entryToDeclaration(entry) {
                if (ts.isDeclaration(entry.node.parent)) {
                    return entry.node;
                }
                return undefined;
            }
            function entryToFunctionCall(entry) {
                if (entry.node.parent) {
                    var functionReference = entry.node;
                    var parent = functionReference.parent;
                    switch (parent.kind) {
                        // foo(...) or super(...) or new Foo(...)
                        case 192 /* CallExpression */:
                        case 193 /* NewExpression */:
                            var callOrNewExpression = ts.tryCast(parent, ts.isCallOrNewExpression);
                            if (callOrNewExpression && callOrNewExpression.expression === functionReference) {
                                return callOrNewExpression;
                            }
                            break;
                        // x.foo(...)
                        case 190 /* PropertyAccessExpression */:
                            var propertyAccessExpression = ts.tryCast(parent, ts.isPropertyAccessExpression);
                            if (propertyAccessExpression && propertyAccessExpression.parent && propertyAccessExpression.name === functionReference) {
                                var callOrNewExpression_1 = ts.tryCast(propertyAccessExpression.parent, ts.isCallOrNewExpression);
                                if (callOrNewExpression_1 && callOrNewExpression_1.expression === propertyAccessExpression) {
                                    return callOrNewExpression_1;
                                }
                            }
                            break;
                        // x["foo"](...)
                        case 191 /* ElementAccessExpression */:
                            var elementAccessExpression = ts.tryCast(parent, ts.isElementAccessExpression);
                            if (elementAccessExpression && elementAccessExpression.parent && elementAccessExpression.argumentExpression === functionReference) {
                                var callOrNewExpression_2 = ts.tryCast(elementAccessExpression.parent, ts.isCallOrNewExpression);
                                if (callOrNewExpression_2 && callOrNewExpression_2.expression === elementAccessExpression) {
                                    return callOrNewExpression_2;
                                }
                            }
                            break;
                    }
                }
                return undefined;
            }
            function entryToAccessExpression(entry) {
                if (entry.node.parent) {
                    var reference = entry.node;
                    var parent = reference.parent;
                    switch (parent.kind) {
                        // `C.foo`
                        case 190 /* PropertyAccessExpression */:
                            var propertyAccessExpression = ts.tryCast(parent, ts.isPropertyAccessExpression);
                            if (propertyAccessExpression && propertyAccessExpression.expression === reference) {
                                return propertyAccessExpression;
                            }
                            break;
                        // `C["foo"]`
                        case 191 /* ElementAccessExpression */:
                            var elementAccessExpression = ts.tryCast(parent, ts.isElementAccessExpression);
                            if (elementAccessExpression && elementAccessExpression.expression === reference) {
                                return elementAccessExpression;
                            }
                            break;
                    }
                }
                return undefined;
            }
            function entryToType(entry) {
                var reference = entry.node;
                if (ts.getMeaningFromLocation(reference) === 2 /* Type */ || ts.isExpressionWithTypeArgumentsInClassExtendsClause(reference.parent)) {
                    return reference;
                }
                return undefined;
            }
            function getFunctionDeclarationAtPosition(file, startPosition, checker) {
                var node = ts.getTouchingToken(file, startPosition);
                var functionDeclaration = ts.getContainingFunctionDeclaration(node);
                // don't offer refactor on top-level JSDoc
                if (isTopLevelJSDoc(node))
                    return undefined;
                if (functionDeclaration
                    && isValidFunctionDeclaration(functionDeclaration, checker)
                    && ts.rangeContainsRange(functionDeclaration, node)
                    && !(functionDeclaration.body && ts.rangeContainsRange(functionDeclaration.body, node)))
                    return functionDeclaration;
                return undefined;
            }
            function isTopLevelJSDoc(node) {
                var containingJSDoc = ts.findAncestor(node, ts.isJSDocNode);
                if (containingJSDoc) {
                    var containingNonJSDoc = ts.findAncestor(containingJSDoc, function (n) { return !ts.isJSDocNode(n); });
                    return !!containingNonJSDoc && ts.isFunctionLikeDeclaration(containingNonJSDoc);
                }
                return false;
            }
            function isValidFunctionDeclaration(functionDeclaration, checker) {
                if (!isValidParameterNodeArray(functionDeclaration.parameters, checker))
                    return false;
                switch (functionDeclaration.kind) {
                    case 240 /* FunctionDeclaration */:
                        return hasNameOrDefault(functionDeclaration) && isSingleImplementation(functionDeclaration, checker);
                    case 157 /* MethodDeclaration */:
                        return isSingleImplementation(functionDeclaration, checker);
                    case 158 /* Constructor */:
                        if (ts.isClassDeclaration(functionDeclaration.parent)) {
                            return hasNameOrDefault(functionDeclaration.parent) && isSingleImplementation(functionDeclaration, checker);
                        }
                        else {
                            return isValidVariableDeclaration(functionDeclaration.parent.parent)
                                && isSingleImplementation(functionDeclaration, checker);
                        }
                    case 197 /* FunctionExpression */:
                    case 198 /* ArrowFunction */:
                        return isValidVariableDeclaration(functionDeclaration.parent);
                }
                return false;
            }
            function isSingleImplementation(functionDeclaration, checker) {
                return !!functionDeclaration.body && !checker.isImplementationOfOverload(functionDeclaration);
            }
            function hasNameOrDefault(functionOrClassDeclaration) {
                if (!functionOrClassDeclaration.name) {
                    var defaultKeyword = ts.findModifier(functionOrClassDeclaration, 81 /* DefaultKeyword */);
                    return !!defaultKeyword;
                }
                return true;
            }
            function isValidParameterNodeArray(parameters, checker) {
                return getRefactorableParametersLength(parameters) >= minimumParameterLength
                    && ts.every(parameters, /*callback*/ function (/*callback*/ paramDecl) { return isValidParameterDeclaration(paramDecl, checker); });
            }
            function isValidParameterDeclaration(parameterDeclaration, checker) {
                if (ts.isRestParameter(parameterDeclaration)) {
                    var type = checker.getTypeAtLocation(parameterDeclaration);
                    if (!checker.isArrayType(type) && !checker.isTupleType(type))
                        return false;
                }
                return !parameterDeclaration.modifiers && !parameterDeclaration.decorators && ts.isIdentifier(parameterDeclaration.name);
            }
            function isValidVariableDeclaration(node) {
                return ts.isVariableDeclaration(node) && ts.isVarConst(node) && ts.isIdentifier(node.name) && !node.type; // TODO: GH#30113
            }
            function hasThisParameter(parameters) {
                return parameters.length > 0 && ts.isThis(parameters[0].name);
            }
            function getRefactorableParametersLength(parameters) {
                if (hasThisParameter(parameters)) {
                    return parameters.length - 1;
                }
                return parameters.length;
            }
            function getRefactorableParameters(parameters) {
                if (hasThisParameter(parameters)) {
                    parameters = ts.createNodeArray(parameters.slice(1), parameters.hasTrailingComma);
                }
                return parameters;
            }
            function createPropertyOrShorthandAssignment(name, initializer) {
                if (ts.isIdentifier(initializer) && ts.getTextOfIdentifierOrLiteral(initializer) === name) {
                    return ts.createShorthandPropertyAssignment(name);
                }
                return ts.createPropertyAssignment(name, initializer);
            }
            function createNewArgument(functionDeclaration, functionArguments) {
                var parameters = getRefactorableParameters(functionDeclaration.parameters);
                var hasRestParameter = ts.isRestParameter(ts.last(parameters));
                var nonRestArguments = hasRestParameter ? functionArguments.slice(0, parameters.length - 1) : functionArguments;
                var properties = ts.map(nonRestArguments, function (arg, i) {
                    var parameterName = getParameterName(parameters[i]);
                    var property = createPropertyOrShorthandAssignment(parameterName, arg);
                    ts.suppressLeadingAndTrailingTrivia(property.name);
                    if (ts.isPropertyAssignment(property))
                        ts.suppressLeadingAndTrailingTrivia(property.initializer);
                    copyComments(arg, property);
                    return property;
                });
                if (hasRestParameter && functionArguments.length >= parameters.length) {
                    var restArguments = functionArguments.slice(parameters.length - 1);
                    var restProperty = ts.createPropertyAssignment(getParameterName(ts.last(parameters)), ts.createArrayLiteral(restArguments));
                    properties.push(restProperty);
                }
                var objectLiteral = ts.createObjectLiteral(properties, /*multiLine*/ false);
                return objectLiteral;
            }
            function createNewParameters(functionDeclaration, program, host) {
                var checker = program.getTypeChecker();
                var refactorableParameters = getRefactorableParameters(functionDeclaration.parameters);
                var bindingElements = ts.map(refactorableParameters, createBindingElementFromParameterDeclaration);
                var objectParameterName = ts.createObjectBindingPattern(bindingElements);
                var objectParameterType = createParameterTypeNode(refactorableParameters);
                var objectInitializer;
                // If every parameter in the original function was optional, add an empty object initializer to the new object parameter
                if (ts.every(refactorableParameters, isOptionalParameter)) {
                    objectInitializer = ts.createObjectLiteral();
                }
                var objectParameter = ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, objectParameterName, 
                /*questionToken*/ undefined, objectParameterType, objectInitializer);
                if (hasThisParameter(functionDeclaration.parameters)) {
                    var thisParameter = functionDeclaration.parameters[0];
                    var newThisParameter = ts.createParameter(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, 
                    /*dotDotDotToken*/ undefined, thisParameter.name, 
                    /*questionToken*/ undefined, thisParameter.type);
                    ts.suppressLeadingAndTrailingTrivia(newThisParameter.name);
                    copyComments(thisParameter.name, newThisParameter.name);
                    if (thisParameter.type) {
                        ts.suppressLeadingAndTrailingTrivia(newThisParameter.type);
                        copyComments(thisParameter.type, newThisParameter.type);
                    }
                    return ts.createNodeArray([newThisParameter, objectParameter]);
                }
                return ts.createNodeArray([objectParameter]);
                function createBindingElementFromParameterDeclaration(parameterDeclaration) {
                    var element = ts.createBindingElement(
                    /*dotDotDotToken*/ undefined, 
                    /*propertyName*/ undefined, getParameterName(parameterDeclaration), ts.isRestParameter(parameterDeclaration) && isOptionalParameter(parameterDeclaration) ? ts.createArrayLiteral() : parameterDeclaration.initializer);
                    ts.suppressLeadingAndTrailingTrivia(element);
                    if (parameterDeclaration.initializer && element.initializer) {
                        copyComments(parameterDeclaration.initializer, element.initializer);
                    }
                    return element;
                }
                function createParameterTypeNode(parameters) {
                    var members = ts.map(parameters, createPropertySignatureFromParameterDeclaration);
                    var typeNode = ts.addEmitFlags(ts.createTypeLiteralNode(members), 1 /* SingleLine */);
                    return typeNode;
                }
                function createPropertySignatureFromParameterDeclaration(parameterDeclaration) {
                    var parameterType = parameterDeclaration.type;
                    if (!parameterType && (parameterDeclaration.initializer || ts.isRestParameter(parameterDeclaration))) {
                        parameterType = getTypeNode(parameterDeclaration);
                    }
                    var propertySignature = ts.createPropertySignature(
                    /*modifiers*/ undefined, getParameterName(parameterDeclaration), isOptionalParameter(parameterDeclaration) ? ts.createToken(56 /* QuestionToken */) : parameterDeclaration.questionToken, parameterType, 
                    /*initializer*/ undefined);
                    ts.suppressLeadingAndTrailingTrivia(propertySignature);
                    copyComments(parameterDeclaration.name, propertySignature.name);
                    if (parameterDeclaration.type && propertySignature.type) {
                        copyComments(parameterDeclaration.type, propertySignature.type);
                    }
                    return propertySignature;
                }
                function getTypeNode(node) {
                    var type = checker.getTypeAtLocation(node);
                    return ts.getTypeNodeIfAccessible(type, node, program, host);
                }
                function isOptionalParameter(parameterDeclaration) {
                    if (ts.isRestParameter(parameterDeclaration)) {
                        var type = checker.getTypeAtLocation(parameterDeclaration);
                        return !checker.isTupleType(type);
                    }
                    return checker.isOptionalParameter(parameterDeclaration);
                }
            }
            function copyComments(sourceNode, targetNode) {
                var sourceFile = sourceNode.getSourceFile();
                var text = sourceFile.text;
                if (hasLeadingLineBreak(sourceNode, text)) {
                    ts.copyLeadingComments(sourceNode, targetNode, sourceFile);
                }
                else {
                    ts.copyTrailingAsLeadingComments(sourceNode, targetNode, sourceFile);
                }
                ts.copyTrailingComments(sourceNode, targetNode, sourceFile);
            }
            function hasLeadingLineBreak(node, text) {
                var start = node.getFullStart();
                var end = node.getStart();
                for (var i = start; i < end; i++) {
                    if (text.charCodeAt(i) === 10 /* lineFeed */)
                        return true;
                }
                return false;
            }
            function getParameterName(paramDeclaration) {
                return ts.getTextOfIdentifierOrLiteral(paramDeclaration.name);
            }
            function getClassNames(constructorDeclaration) {
                switch (constructorDeclaration.parent.kind) {
                    case 241 /* ClassDeclaration */:
                        var classDeclaration = constructorDeclaration.parent;
                        if (classDeclaration.name)
                            return [classDeclaration.name];
                        // If the class declaration doesn't have a name, it should have a default modifier.
                        // We validated this in `isValidFunctionDeclaration` through `hasNameOrDefault`
                        var defaultModifier = ts.Debug.assertDefined(ts.findModifier(classDeclaration, 81 /* DefaultKeyword */), "Nameless class declaration should be a default export");
                        return [defaultModifier];
                    case 210 /* ClassExpression */:
                        var classExpression = constructorDeclaration.parent;
                        var variableDeclaration = constructorDeclaration.parent.parent;
                        var className = classExpression.name;
                        if (className)
                            return [className, variableDeclaration.name];
                        return [variableDeclaration.name];
                }
            }
            function getFunctionNames(functionDeclaration) {
                switch (functionDeclaration.kind) {
                    case 240 /* FunctionDeclaration */:
                        if (functionDeclaration.name)
                            return [functionDeclaration.name];
                        // If the function declaration doesn't have a name, it should have a default modifier.
                        // We validated this in `isValidFunctionDeclaration` through `hasNameOrDefault`
                        var defaultModifier = ts.Debug.assertDefined(ts.findModifier(functionDeclaration, 81 /* DefaultKeyword */), "Nameless function declaration should be a default export");
                        return [defaultModifier];
                    case 157 /* MethodDeclaration */:
                        return [functionDeclaration.name];
                    case 158 /* Constructor */:
                        var ctrKeyword = ts.Debug.assertDefined(ts.findChildOfKind(functionDeclaration, 125 /* ConstructorKeyword */, functionDeclaration.getSourceFile()), "Constructor declaration should have constructor keyword");
                        if (functionDeclaration.parent.kind === 210 /* ClassExpression */) {
                            var variableDeclaration = functionDeclaration.parent.parent;
                            return [variableDeclaration.name, ctrKeyword];
                        }
                        return [ctrKeyword];
                    case 198 /* ArrowFunction */:
                        return [functionDeclaration.parent.name];
                    case 197 /* FunctionExpression */:
                        if (functionDeclaration.name)
                            return [functionDeclaration.name, functionDeclaration.parent.name];
                        return [functionDeclaration.parent.name];
                    default:
                        return ts.Debug.assertNever(functionDeclaration);
                }
            }
        })(convertParamsToDestructuredObject = refactor.convertParamsToDestructuredObject || (refactor.convertParamsToDestructuredObject = {}));
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    /** The version of the language service API */
    ts.servicesVersion = "0.8";
    function createNode(kind, pos, end, parent) {
        var node = ts.isNodeKind(kind) ? new NodeObject(kind, pos, end) :
            kind === 73 /* Identifier */ ? new IdentifierObject(73 /* Identifier */, pos, end) :
                new TokenObject(kind, pos, end);
        node.parent = parent;
        node.flags = parent.flags & 12679168 /* ContextFlags */;
        return node;
    }
    var NodeObject = /** @class */ (function () {
        function NodeObject(kind, pos, end) {
            this.pos = pos;
            this.end = end;
            this.flags = 0 /* None */;
            this.modifierFlagsCache = 0 /* None */;
            this.transformFlags = 0 /* None */;
            this.parent = undefined;
            this.kind = kind;
        }
        NodeObject.prototype.assertHasRealPosition = function (message) {
            // tslint:disable-next-line:debug-assert
            ts.Debug.assert(!ts.positionIsSynthesized(this.pos) && !ts.positionIsSynthesized(this.end), message || "Node must have a real position for this operation");
        };
        NodeObject.prototype.getSourceFile = function () {
            return ts.getSourceFileOfNode(this);
        };
        NodeObject.prototype.getStart = function (sourceFile, includeJsDocComment) {
            this.assertHasRealPosition();
            return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment);
        };
        NodeObject.prototype.getFullStart = function () {
            this.assertHasRealPosition();
            return this.pos;
        };
        NodeObject.prototype.getEnd = function () {
            this.assertHasRealPosition();
            return this.end;
        };
        NodeObject.prototype.getWidth = function (sourceFile) {
            this.assertHasRealPosition();
            return this.getEnd() - this.getStart(sourceFile);
        };
        NodeObject.prototype.getFullWidth = function () {
            this.assertHasRealPosition();
            return this.end - this.pos;
        };
        NodeObject.prototype.getLeadingTriviaWidth = function (sourceFile) {
            this.assertHasRealPosition();
            return this.getStart(sourceFile) - this.pos;
        };
        NodeObject.prototype.getFullText = function (sourceFile) {
            this.assertHasRealPosition();
            return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end);
        };
        NodeObject.prototype.getText = function (sourceFile) {
            this.assertHasRealPosition();
            if (!sourceFile) {
                sourceFile = this.getSourceFile();
            }
            return sourceFile.text.substring(this.getStart(sourceFile), this.getEnd());
        };
        NodeObject.prototype.getChildCount = function (sourceFile) {
            return this.getChildren(sourceFile).length;
        };
        NodeObject.prototype.getChildAt = function (index, sourceFile) {
            return this.getChildren(sourceFile)[index];
        };
        NodeObject.prototype.getChildren = function (sourceFile) {
            this.assertHasRealPosition("Node without a real position cannot be scanned and thus has no token nodes - use forEachChild and collect the result if that's fine");
            return this._children || (this._children = createChildren(this, sourceFile));
        };
        NodeObject.prototype.getFirstToken = function (sourceFile) {
            this.assertHasRealPosition();
            var children = this.getChildren(sourceFile);
            if (!children.length) {
                return undefined;
            }
            var child = ts.find(children, function (kid) { return kid.kind < 289 /* FirstJSDocNode */ || kid.kind > 311 /* LastJSDocNode */; });
            return child.kind < 149 /* FirstNode */ ?
                child :
                child.getFirstToken(sourceFile);
        };
        NodeObject.prototype.getLastToken = function (sourceFile) {
            this.assertHasRealPosition();
            var children = this.getChildren(sourceFile);
            var child = ts.lastOrUndefined(children);
            if (!child) {
                return undefined;
            }
            return child.kind < 149 /* FirstNode */ ? child : child.getLastToken(sourceFile);
        };
        NodeObject.prototype.forEachChild = function (cbNode, cbNodeArray) {
            return ts.forEachChild(this, cbNode, cbNodeArray);
        };
        return NodeObject;
    }());
    function createChildren(node, sourceFile) {
        if (!ts.isNodeKind(node.kind)) {
            return ts.emptyArray;
        }
        var children = [];
        if (ts.isJSDocCommentContainingNode(node)) {
            /** Don't add trivia for "tokens" since this is in a comment. */
            node.forEachChild(function (child) { children.push(child); });
            return children;
        }
        ts.scanner.setText((sourceFile || node.getSourceFile()).text);
        var pos = node.pos;
        var processNode = function (child) {
            addSyntheticNodes(children, pos, child.pos, node);
            children.push(child);
            pos = child.end;
        };
        var processNodes = function (nodes) {
            addSyntheticNodes(children, pos, nodes.pos, node);
            children.push(createSyntaxList(nodes, node));
            pos = nodes.end;
        };
        // jsDocComments need to be the first children
        ts.forEach(node.jsDoc, processNode);
        // For syntactic classifications, all trivia are classified together, including jsdoc comments.
        // For that to work, the jsdoc comments should still be the leading trivia of the first child.
        // Restoring the scanner position ensures that.
        pos = node.pos;
        node.forEachChild(processNode, processNodes);
        addSyntheticNodes(children, pos, node.end, node);
        ts.scanner.setText(undefined);
        return children;
    }
    function addSyntheticNodes(nodes, pos, end, parent) {
        ts.scanner.setTextPos(pos);
        while (pos < end) {
            var token = ts.scanner.scan();
            var textPos = ts.scanner.getTextPos();
            if (textPos <= end) {
                if (token === 73 /* Identifier */) {
                    ts.Debug.fail("Did not expect " + ts.Debug.formatSyntaxKind(parent.kind) + " to have an Identifier in its trivia");
                }
                nodes.push(createNode(token, pos, textPos, parent));
            }
            pos = textPos;
            if (token === 1 /* EndOfFileToken */) {
                break;
            }
        }
    }
    function createSyntaxList(nodes, parent) {
        var list = createNode(312 /* SyntaxList */, nodes.pos, nodes.end, parent);
        list._children = [];
        var pos = nodes.pos;
        for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
            var node = nodes_1[_i];
            addSyntheticNodes(list._children, pos, node.pos, parent);
            list._children.push(node);
            pos = node.end;
        }
        addSyntheticNodes(list._children, pos, nodes.end, parent);
        return list;
    }
    var TokenOrIdentifierObject = /** @class */ (function () {
        function TokenOrIdentifierObject(pos, end) {
            // Set properties in same order as NodeObject
            this.pos = pos;
            this.end = end;
            this.flags = 0 /* None */;
            this.modifierFlagsCache = 0 /* None */;
            this.transformFlags = 0 /* None */;
            this.parent = undefined;
        }
        TokenOrIdentifierObject.prototype.getSourceFile = function () {
            return ts.getSourceFileOfNode(this);
        };
        TokenOrIdentifierObject.prototype.getStart = function (sourceFile, includeJsDocComment) {
            return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment);
        };
        TokenOrIdentifierObject.prototype.getFullStart = function () {
            return this.pos;
        };
        TokenOrIdentifierObject.prototype.getEnd = function () {
            return this.end;
        };
        TokenOrIdentifierObject.prototype.getWidth = function (sourceFile) {
            return this.getEnd() - this.getStart(sourceFile);
        };
        TokenOrIdentifierObject.prototype.getFullWidth = function () {
            return this.end - this.pos;
        };
        TokenOrIdentifierObject.prototype.getLeadingTriviaWidth = function (sourceFile) {
            return this.getStart(sourceFile) - this.pos;
        };
        TokenOrIdentifierObject.prototype.getFullText = function (sourceFile) {
            return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end);
        };
        TokenOrIdentifierObject.prototype.getText = function (sourceFile) {
            if (!sourceFile) {
                sourceFile = this.getSourceFile();
            }
            return sourceFile.text.substring(this.getStart(sourceFile), this.getEnd());
        };
        TokenOrIdentifierObject.prototype.getChildCount = function () {
            return 0;
        };
        TokenOrIdentifierObject.prototype.getChildAt = function () {
            return undefined; // TODO: GH#18217
        };
        TokenOrIdentifierObject.prototype.getChildren = function () {
            return this.kind === 1 /* EndOfFileToken */ ? this.jsDoc || ts.emptyArray : ts.emptyArray;
        };
        TokenOrIdentifierObject.prototype.getFirstToken = function () {
            return undefined;
        };
        TokenOrIdentifierObject.prototype.getLastToken = function () {
            return undefined;
        };
        TokenOrIdentifierObject.prototype.forEachChild = function () {
            return undefined;
        };
        return TokenOrIdentifierObject;
    }());
    var SymbolObject = /** @class */ (function () {
        function SymbolObject(flags, name) {
            this.flags = flags;
            this.escapedName = name;
        }
        SymbolObject.prototype.getFlags = function () {
            return this.flags;
        };
        Object.defineProperty(SymbolObject.prototype, "name", {
            get: function () {
                return ts.symbolName(this);
            },
            enumerable: true,
            configurable: true
        });
        SymbolObject.prototype.getEscapedName = function () {
            return this.escapedName;
        };
        SymbolObject.prototype.getName = function () {
            return this.name;
        };
        SymbolObject.prototype.getDeclarations = function () {
            return this.declarations;
        };
        SymbolObject.prototype.getDocumentationComment = function (checker) {
            if (!this.documentationComment) {
                this.documentationComment = ts.emptyArray; // Set temporarily to avoid an infinite loop finding inherited docs
                this.documentationComment = getDocumentationComment(this.declarations, checker);
            }
            return this.documentationComment;
        };
        SymbolObject.prototype.getJsDocTags = function () {
            if (this.tags === undefined) {
                this.tags = ts.JsDoc.getJsDocTagsFromDeclarations(this.declarations);
            }
            return this.tags;
        };
        return SymbolObject;
    }());
    var TokenObject = /** @class */ (function (_super) {
        __extends(TokenObject, _super);
        function TokenObject(kind, pos, end) {
            var _this = _super.call(this, pos, end) || this;
            _this.kind = kind;
            return _this;
        }
        return TokenObject;
    }(TokenOrIdentifierObject));
    var IdentifierObject = /** @class */ (function (_super) {
        __extends(IdentifierObject, _super);
        function IdentifierObject(_kind, pos, end) {
            return _super.call(this, pos, end) || this;
        }
        Object.defineProperty(IdentifierObject.prototype, "text", {
            get: function () {
                return ts.idText(this);
            },
            enumerable: true,
            configurable: true
        });
        return IdentifierObject;
    }(TokenOrIdentifierObject));
    IdentifierObject.prototype.kind = 73 /* Identifier */;
    var TypeObject = /** @class */ (function () {
        function TypeObject(checker, flags) {
            this.checker = checker;
            this.flags = flags;
        }
        TypeObject.prototype.getFlags = function () {
            return this.flags;
        };
        TypeObject.prototype.getSymbol = function () {
            return this.symbol;
        };
        TypeObject.prototype.getProperties = function () {
            return this.checker.getPropertiesOfType(this);
        };
        TypeObject.prototype.getProperty = function (propertyName) {
            return this.checker.getPropertyOfType(this, propertyName);
        };
        TypeObject.prototype.getApparentProperties = function () {
            return this.checker.getAugmentedPropertiesOfType(this);
        };
        TypeObject.prototype.getCallSignatures = function () {
            return this.checker.getSignaturesOfType(this, 0 /* Call */);
        };
        TypeObject.prototype.getConstructSignatures = function () {
            return this.checker.getSignaturesOfType(this, 1 /* Construct */);
        };
        TypeObject.prototype.getStringIndexType = function () {
            return this.checker.getIndexTypeOfType(this, 0 /* String */);
        };
        TypeObject.prototype.getNumberIndexType = function () {
            return this.checker.getIndexTypeOfType(this, 1 /* Number */);
        };
        TypeObject.prototype.getBaseTypes = function () {
            return this.isClassOrInterface() ? this.checker.getBaseTypes(this) : undefined;
        };
        TypeObject.prototype.getNonNullableType = function () {
            return this.checker.getNonNullableType(this);
        };
        TypeObject.prototype.getConstraint = function () {
            return this.checker.getBaseConstraintOfType(this);
        };
        TypeObject.prototype.getDefault = function () {
            return this.checker.getDefaultFromTypeParameter(this);
        };
        TypeObject.prototype.isUnion = function () {
            return !!(this.flags & 1048576 /* Union */);
        };
        TypeObject.prototype.isIntersection = function () {
            return !!(this.flags & 2097152 /* Intersection */);
        };
        TypeObject.prototype.isUnionOrIntersection = function () {
            return !!(this.flags & 3145728 /* UnionOrIntersection */);
        };
        TypeObject.prototype.isLiteral = function () {
            return !!(this.flags & 384 /* StringOrNumberLiteral */);
        };
        TypeObject.prototype.isStringLiteral = function () {
            return !!(this.flags & 128 /* StringLiteral */);
        };
        TypeObject.prototype.isNumberLiteral = function () {
            return !!(this.flags & 256 /* NumberLiteral */);
        };
        TypeObject.prototype.isTypeParameter = function () {
            return !!(this.flags & 262144 /* TypeParameter */);
        };
        TypeObject.prototype.isClassOrInterface = function () {
            return !!(ts.getObjectFlags(this) & 3 /* ClassOrInterface */);
        };
        TypeObject.prototype.isClass = function () {
            return !!(ts.getObjectFlags(this) & 1 /* Class */);
        };
        return TypeObject;
    }());
    var SignatureObject = /** @class */ (function () {
        function SignatureObject(checker) {
            this.checker = checker;
        }
        SignatureObject.prototype.getDeclaration = function () {
            return this.declaration;
        };
        SignatureObject.prototype.getTypeParameters = function () {
            return this.typeParameters;
        };
        SignatureObject.prototype.getParameters = function () {
            return this.parameters;
        };
        SignatureObject.prototype.getReturnType = function () {
            return this.checker.getReturnTypeOfSignature(this);
        };
        SignatureObject.prototype.getDocumentationComment = function () {
            return this.documentationComment || (this.documentationComment = getDocumentationComment(ts.singleElementArray(this.declaration), this.checker));
        };
        SignatureObject.prototype.getJsDocTags = function () {
            if (this.jsDocTags === undefined) {
                this.jsDocTags = this.declaration ? ts.JsDoc.getJsDocTagsFromDeclarations([this.declaration]) : [];
            }
            return this.jsDocTags;
        };
        return SignatureObject;
    }());
    /**
     * Returns whether or not the given node has a JSDoc "inheritDoc" tag on it.
     * @param node the Node in question.
     * @returns `true` if `node` has a JSDoc "inheritDoc" tag on it, otherwise `false`.
     */
    function hasJSDocInheritDocTag(node) {
        return ts.getJSDocTags(node).some(function (tag) { return tag.tagName.text === "inheritDoc"; });
    }
    function getDocumentationComment(declarations, checker) {
        if (!declarations)
            return ts.emptyArray;
        var doc = ts.JsDoc.getJsDocCommentsFromDeclarations(declarations);
        if (doc.length === 0 || declarations.some(hasJSDocInheritDocTag)) {
            for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) {
                var declaration = declarations_4[_i];
                var inheritedDocs = findInheritedJSDocComments(declaration, declaration.symbol.name, checker); // TODO: GH#18217
                // TODO: GH#16312 Return a ReadonlyArray, avoid copying inheritedDocs
                if (inheritedDocs)
                    doc = doc.length === 0 ? inheritedDocs.slice() : inheritedDocs.concat(ts.lineBreakPart(), doc);
            }
        }
        return doc;
    }
    /**
     * Attempts to find JSDoc comments for possibly-inherited properties.  Checks superclasses then traverses
     * implemented interfaces until a symbol is found with the same name and with documentation.
     * @param declaration The possibly-inherited declaration to find comments for.
     * @param propertyName The name of the possibly-inherited property.
     * @param typeChecker A TypeChecker, used to find inherited properties.
     * @returns A filled array of documentation comments if any were found, otherwise an empty array.
     */
    function findInheritedJSDocComments(declaration, propertyName, typeChecker) {
        return ts.firstDefined(declaration.parent ? ts.getAllSuperTypeNodes(declaration.parent) : ts.emptyArray, function (superTypeNode) {
            var superType = typeChecker.getTypeAtLocation(superTypeNode);
            var baseProperty = superType && typeChecker.getPropertyOfType(superType, propertyName);
            var inheritedDocs = baseProperty && baseProperty.getDocumentationComment(typeChecker);
            return inheritedDocs && inheritedDocs.length ? inheritedDocs : undefined;
        });
    }
    var SourceFileObject = /** @class */ (function (_super) {
        __extends(SourceFileObject, _super);
        function SourceFileObject(kind, pos, end) {
            return _super.call(this, kind, pos, end) || this;
        }
        SourceFileObject.prototype.update = function (newText, textChangeRange) {
            return ts.updateSourceFile(this, newText, textChangeRange);
        };
        SourceFileObject.prototype.getLineAndCharacterOfPosition = function (position) {
            return ts.getLineAndCharacterOfPosition(this, position);
        };
        SourceFileObject.prototype.getLineStarts = function () {
            return ts.getLineStarts(this);
        };
        SourceFileObject.prototype.getPositionOfLineAndCharacter = function (line, character, allowEdits) {
            return ts.computePositionOfLineAndCharacter(ts.getLineStarts(this), line, character, this.text, allowEdits);
        };
        SourceFileObject.prototype.getLineEndOfPosition = function (pos) {
            var line = this.getLineAndCharacterOfPosition(pos).line;
            var lineStarts = this.getLineStarts();
            var lastCharPos;
            if (line + 1 >= lineStarts.length) {
                lastCharPos = this.getEnd();
            }
            if (!lastCharPos) {
                lastCharPos = lineStarts[line + 1] - 1;
            }
            var fullText = this.getFullText();
            // if the new line is "\r\n", we should return the last non-new-line-character position
            return fullText[lastCharPos] === "\n" && fullText[lastCharPos - 1] === "\r" ? lastCharPos - 1 : lastCharPos;
        };
        SourceFileObject.prototype.getNamedDeclarations = function () {
            if (!this.namedDeclarations) {
                this.namedDeclarations = this.computeNamedDeclarations();
            }
            return this.namedDeclarations;
        };
        SourceFileObject.prototype.computeNamedDeclarations = function () {
            var result = ts.createMultiMap();
            this.forEachChild(visit);
            return result;
            function addDeclaration(declaration) {
                var name = getDeclarationName(declaration);
                if (name) {
                    result.add(name, declaration);
                }
            }
            function getDeclarations(name) {
                var declarations = result.get(name);
                if (!declarations) {
                    result.set(name, declarations = []);
                }
                return declarations;
            }
            function getDeclarationName(declaration) {
                var name = ts.getNonAssignedNameOfDeclaration(declaration);
                return name && (ts.isComputedPropertyName(name) && ts.isPropertyAccessExpression(name.expression) ? name.expression.name.text
                    : ts.isPropertyName(name) ? ts.getNameFromPropertyName(name) : undefined);
            }
            function visit(node) {
                switch (node.kind) {
                    case 240 /* FunctionDeclaration */:
                    case 197 /* FunctionExpression */:
                    case 157 /* MethodDeclaration */:
                    case 156 /* MethodSignature */:
                        var functionDeclaration = node;
                        var declarationName = getDeclarationName(functionDeclaration);
                        if (declarationName) {
                            var declarations = getDeclarations(declarationName);
                            var lastDeclaration = ts.lastOrUndefined(declarations);
                            // Check whether this declaration belongs to an "overload group".
                            if (lastDeclaration && functionDeclaration.parent === lastDeclaration.parent && functionDeclaration.symbol === lastDeclaration.symbol) {
                                // Overwrite the last declaration if it was an overload
                                // and this one is an implementation.
                                if (functionDeclaration.body && !lastDeclaration.body) {
                                    declarations[declarations.length - 1] = functionDeclaration;
                                }
                            }
                            else {
                                declarations.push(functionDeclaration);
                            }
                        }
                        ts.forEachChild(node, visit);
                        break;
                    case 241 /* ClassDeclaration */:
                    case 210 /* ClassExpression */:
                    case 242 /* InterfaceDeclaration */:
                    case 243 /* TypeAliasDeclaration */:
                    case 244 /* EnumDeclaration */:
                    case 245 /* ModuleDeclaration */:
                    case 249 /* ImportEqualsDeclaration */:
                    case 258 /* ExportSpecifier */:
                    case 254 /* ImportSpecifier */:
                    case 251 /* ImportClause */:
                    case 252 /* NamespaceImport */:
                    case 159 /* GetAccessor */:
                    case 160 /* SetAccessor */:
                    case 169 /* TypeLiteral */:
                        addDeclaration(node);
                        ts.forEachChild(node, visit);
                        break;
                    case 152 /* Parameter */:
                        // Only consider parameter properties
                        if (!ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) {
                            break;
                        }
                    // falls through
                    case 238 /* VariableDeclaration */:
                    case 187 /* BindingElement */: {
                        var decl = node;
                        if (ts.isBindingPattern(decl.name)) {
                            ts.forEachChild(decl.name, visit);
                            break;
                        }
                        if (decl.initializer) {
                            visit(decl.initializer);
                        }
                    }
                    // falls through
                    case 279 /* EnumMember */:
                    case 155 /* PropertyDeclaration */:
                    case 154 /* PropertySignature */:
                        addDeclaration(node);
                        break;
                    case 256 /* ExportDeclaration */:
                        // Handle named exports case e.g.:
                        //    export {a, b as B} from "mod";
                        if (node.exportClause) {
                            ts.forEach(node.exportClause.elements, visit);
                        }
                        break;
                    case 250 /* ImportDeclaration */:
                        var importClause = node.importClause;
                        if (importClause) {
                            // Handle default import case e.g.:
                            //    import d from "mod";
                            if (importClause.name) {
                                addDeclaration(importClause.name);
                            }
                            // Handle named bindings in imports e.g.:
                            //    import * as NS from "mod";
                            //    import {a, b as B} from "mod";
                            if (importClause.namedBindings) {
                                if (importClause.namedBindings.kind === 252 /* NamespaceImport */) {
                                    addDeclaration(importClause.namedBindings);
                                }
                                else {
                                    ts.forEach(importClause.namedBindings.elements, visit);
                                }
                            }
                        }
                        break;
                    case 205 /* BinaryExpression */:
                        if (ts.getAssignmentDeclarationKind(node) !== 0 /* None */) {
                            addDeclaration(node);
                        }
                    // falls through
                    default:
                        ts.forEachChild(node, visit);
                }
            }
        };
        return SourceFileObject;
    }(NodeObject));
    var SourceMapSourceObject = /** @class */ (function () {
        function SourceMapSourceObject(fileName, text, skipTrivia) {
            this.fileName = fileName;
            this.text = text;
            this.skipTrivia = skipTrivia;
        }
        SourceMapSourceObject.prototype.getLineAndCharacterOfPosition = function (pos) {
            return ts.getLineAndCharacterOfPosition(this, pos);
        };
        return SourceMapSourceObject;
    }());
    function getServicesObjectAllocator() {
        return {
            getNodeConstructor: function () { return NodeObject; },
            getTokenConstructor: function () { return TokenObject; },
            getIdentifierConstructor: function () { return IdentifierObject; },
            getSourceFileConstructor: function () { return SourceFileObject; },
            getSymbolConstructor: function () { return SymbolObject; },
            getTypeConstructor: function () { return TypeObject; },
            getSignatureConstructor: function () { return SignatureObject; },
            getSourceMapSourceConstructor: function () { return SourceMapSourceObject; },
        };
    }
    function toEditorSettings(optionsAsMap) {
        var allPropertiesAreCamelCased = true;
        for (var key in optionsAsMap) {
            if (ts.hasProperty(optionsAsMap, key) && !isCamelCase(key)) {
                allPropertiesAreCamelCased = false;
                break;
            }
        }
        if (allPropertiesAreCamelCased) {
            return optionsAsMap;
        }
        var settings = {};
        for (var key in optionsAsMap) {
            if (ts.hasProperty(optionsAsMap, key)) {
                var newKey = isCamelCase(key) ? key : key.charAt(0).toLowerCase() + key.substr(1);
                settings[newKey] = optionsAsMap[key];
            }
        }
        return settings;
    }
    ts.toEditorSettings = toEditorSettings;
    function isCamelCase(s) {
        return !s.length || s.charAt(0) === s.charAt(0).toLowerCase();
    }
    function displayPartsToString(displayParts) {
        if (displayParts) {
            return ts.map(displayParts, function (displayPart) { return displayPart.text; }).join("");
        }
        return "";
    }
    ts.displayPartsToString = displayPartsToString;
    function getDefaultCompilerOptions() {
        // Always default to "ScriptTarget.ES5" for the language service
        return {
            target: 1 /* ES5 */,
            jsx: 1 /* Preserve */
        };
    }
    ts.getDefaultCompilerOptions = getDefaultCompilerOptions;
    function getSupportedCodeFixes() {
        return ts.codefix.getSupportedErrorCodes();
    }
    ts.getSupportedCodeFixes = getSupportedCodeFixes;
    // Cache host information about script Should be refreshed
    // at each language service public entry point, since we don't know when
    // the set of scripts handled by the host changes.
    var HostCache = /** @class */ (function () {
        function HostCache(host, getCanonicalFileName) {
            this.host = host;
            // script id => script index
            this.currentDirectory = host.getCurrentDirectory();
            this.fileNameToEntry = ts.createMap();
            // Initialize the list with the root file names
            var rootFileNames = host.getScriptFileNames();
            for (var _i = 0, rootFileNames_1 = rootFileNames; _i < rootFileNames_1.length; _i++) {
                var fileName = rootFileNames_1[_i];
                this.createEntry(fileName, ts.toPath(fileName, this.currentDirectory, getCanonicalFileName));
            }
            // store the compilation settings
            this._compilationSettings = host.getCompilationSettings() || getDefaultCompilerOptions();
        }
        HostCache.prototype.compilationSettings = function () {
            return this._compilationSettings;
        };
        HostCache.prototype.getProjectReferences = function () {
            return this.host.getProjectReferences && this.host.getProjectReferences();
        };
        HostCache.prototype.createEntry = function (fileName, path) {
            var entry;
            var scriptSnapshot = this.host.getScriptSnapshot(fileName);
            if (scriptSnapshot) {
                entry = {
                    hostFileName: fileName,
                    version: this.host.getScriptVersion(fileName),
                    scriptSnapshot: scriptSnapshot,
                    scriptKind: ts.getScriptKind(fileName, this.host)
                };
            }
            else {
                entry = fileName;
            }
            this.fileNameToEntry.set(path, entry);
            return entry;
        };
        HostCache.prototype.getEntryByPath = function (path) {
            return this.fileNameToEntry.get(path);
        };
        HostCache.prototype.getHostFileInformation = function (path) {
            var entry = this.fileNameToEntry.get(path);
            return !ts.isString(entry) ? entry : undefined;
        };
        HostCache.prototype.getOrCreateEntryByPath = function (fileName, path) {
            var info = this.getEntryByPath(path) || this.createEntry(fileName, path);
            return ts.isString(info) ? undefined : info; // TODO: GH#18217
        };
        HostCache.prototype.getRootFileNames = function () {
            var names = [];
            this.fileNameToEntry.forEach(function (entry) {
                if (ts.isString(entry)) {
                    names.push(entry);
                }
                else {
                    if (entry.scriptKind !== 6 /* JSON */) {
                        names.push(entry.hostFileName);
                    }
                }
            });
            return names;
        };
        HostCache.prototype.getVersion = function (path) {
            var file = this.getHostFileInformation(path);
            return (file && file.version); // TODO: GH#18217
        };
        HostCache.prototype.getScriptSnapshot = function (path) {
            var file = this.getHostFileInformation(path);
            return (file && file.scriptSnapshot); // TODO: GH#18217
        };
        return HostCache;
    }());
    var SyntaxTreeCache = /** @class */ (function () {
        function SyntaxTreeCache(host) {
            this.host = host;
        }
        SyntaxTreeCache.prototype.getCurrentSourceFile = function (fileName) {
            var scriptSnapshot = this.host.getScriptSnapshot(fileName);
            if (!scriptSnapshot) {
                // The host does not know about this file.
                throw new Error("Could not find file: '" + fileName + "'.");
            }
            var scriptKind = ts.getScriptKind(fileName, this.host);
            var version = this.host.getScriptVersion(fileName);
            var sourceFile;
            if (this.currentFileName !== fileName) {
                // This is a new file, just parse it
                sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, 8 /* Latest */, version, /*setNodeParents*/ true, scriptKind);
            }
            else if (this.currentFileVersion !== version) {
                // This is the same file, just a newer version. Incrementally parse the file.
                var editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot);
                sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, editRange);
            }
            if (sourceFile) {
                // All done, ensure state is up to date
                this.currentFileVersion = version;
                this.currentFileName = fileName;
                this.currentFileScriptSnapshot = scriptSnapshot;
                this.currentSourceFile = sourceFile;
            }
            return this.currentSourceFile;
        };
        return SyntaxTreeCache;
    }());
    function setSourceFileFields(sourceFile, scriptSnapshot, version) {
        sourceFile.version = version;
        sourceFile.scriptSnapshot = scriptSnapshot;
    }
    function createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, setNodeParents, scriptKind) {
        var sourceFile = ts.createSourceFile(fileName, ts.getSnapshotText(scriptSnapshot), scriptTarget, setNodeParents, scriptKind);
        setSourceFileFields(sourceFile, scriptSnapshot, version);
        return sourceFile;
    }
    ts.createLanguageServiceSourceFile = createLanguageServiceSourceFile;
    ts.disableIncrementalParsing = false;
    function updateLanguageServiceSourceFile(sourceFile, scriptSnapshot, version, textChangeRange, aggressiveChecks) {
        // If we were given a text change range, and our version or open-ness changed, then
        // incrementally parse this file.
        if (textChangeRange) {
            if (version !== sourceFile.version) {
                // Once incremental parsing is ready, then just call into this function.
                if (!ts.disableIncrementalParsing) {
                    var newText = void 0;
                    // grab the fragment from the beginning of the original text to the beginning of the span
                    var prefix = textChangeRange.span.start !== 0
                        ? sourceFile.text.substr(0, textChangeRange.span.start)
                        : "";
                    // grab the fragment from the end of the span till the end of the original text
                    var suffix = ts.textSpanEnd(textChangeRange.span) !== sourceFile.text.length
                        ? sourceFile.text.substr(ts.textSpanEnd(textChangeRange.span))
                        : "";
                    if (textChangeRange.newLength === 0) {
                        // edit was a deletion - just combine prefix and suffix
                        newText = prefix && suffix ? prefix + suffix : prefix || suffix;
                    }
                    else {
                        // it was actual edit, fetch the fragment of new text that correspond to new span
                        var changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength);
                        // combine prefix, changed text and suffix
                        newText = prefix && suffix
                            ? prefix + changedText + suffix
                            : prefix
                                ? (prefix + changedText)
                                : (changedText + suffix);
                    }
                    var newSourceFile = ts.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks);
                    setSourceFileFields(newSourceFile, scriptSnapshot, version);
                    // after incremental parsing nameTable might not be up-to-date
                    // drop it so it can be lazily recreated later
                    newSourceFile.nameTable = undefined;
                    // dispose all resources held by old script snapshot
                    if (sourceFile !== newSourceFile && sourceFile.scriptSnapshot) {
                        if (sourceFile.scriptSnapshot.dispose) {
                            sourceFile.scriptSnapshot.dispose();
                        }
                        sourceFile.scriptSnapshot = undefined;
                    }
                    return newSourceFile;
                }
            }
        }
        // Otherwise, just create a new source file.
        return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents*/ true, sourceFile.scriptKind);
    }
    ts.updateLanguageServiceSourceFile = updateLanguageServiceSourceFile;
    var CancellationTokenObject = /** @class */ (function () {
        function CancellationTokenObject(cancellationToken) {
            this.cancellationToken = cancellationToken;
        }
        CancellationTokenObject.prototype.isCancellationRequested = function () {
            return !!this.cancellationToken && this.cancellationToken.isCancellationRequested();
        };
        CancellationTokenObject.prototype.throwIfCancellationRequested = function () {
            if (this.isCancellationRequested()) {
                throw new ts.OperationCanceledException();
            }
        };
        return CancellationTokenObject;
    }());
    /* @internal */
    /** A cancellation that throttles calls to the host */
    var ThrottledCancellationToken = /** @class */ (function () {
        function ThrottledCancellationToken(hostCancellationToken, throttleWaitMilliseconds) {
            if (throttleWaitMilliseconds === void 0) { throttleWaitMilliseconds = 20; }
            this.hostCancellationToken = hostCancellationToken;
            this.throttleWaitMilliseconds = throttleWaitMilliseconds;
            // Store when we last tried to cancel.  Checking cancellation can be expensive (as we have
            // to marshall over to the host layer).  So we only bother actually checking once enough
            // time has passed.
            this.lastCancellationCheckTime = 0;
        }
        ThrottledCancellationToken.prototype.isCancellationRequested = function () {
            var time = ts.timestamp();
            var duration = Math.abs(time - this.lastCancellationCheckTime);
            if (duration >= this.throttleWaitMilliseconds) {
                // Check no more than once every throttle wait milliseconds
                this.lastCancellationCheckTime = time;
                return this.hostCancellationToken.isCancellationRequested();
            }
            return false;
        };
        ThrottledCancellationToken.prototype.throwIfCancellationRequested = function () {
            if (this.isCancellationRequested()) {
                throw new ts.OperationCanceledException();
            }
        };
        return ThrottledCancellationToken;
    }());
    ts.ThrottledCancellationToken = ThrottledCancellationToken;
    function createLanguageService(host, documentRegistry, syntaxOnly) {
        var _a;
        if (documentRegistry === void 0) { documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory()); }
        if (syntaxOnly === void 0) { syntaxOnly = false; }
        var syntaxTreeCache = new SyntaxTreeCache(host);
        var program;
        var lastProjectVersion;
        var lastTypesRootVersion = 0;
        var cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken());
        var currentDirectory = host.getCurrentDirectory();
        // Check if the localized messages json is set, otherwise query the host for it
        if (!ts.localizedDiagnosticMessages && host.getLocalizedDiagnosticMessages) {
            ts.localizedDiagnosticMessages = host.getLocalizedDiagnosticMessages();
        }
        function log(message) {
            if (host.log) {
                host.log(message);
            }
        }
        var useCaseSensitiveFileNames = ts.hostUsesCaseSensitiveFileNames(host);
        var getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        var sourceMapper = ts.getSourceMapper({
            useCaseSensitiveFileNames: function () { return useCaseSensitiveFileNames; },
            getCurrentDirectory: function () { return currentDirectory; },
            getProgram: getProgram,
            fileExists: host.fileExists && (function (f) { return host.fileExists(f); }),
            readFile: host.readFile && (function (f, encoding) { return host.readFile(f, encoding); }),
            getDocumentPositionMapper: host.getDocumentPositionMapper && (function (generatedFileName, sourceFileName) { return host.getDocumentPositionMapper(generatedFileName, sourceFileName); }),
            getSourceFileLike: host.getSourceFileLike && (function (f) { return host.getSourceFileLike(f); }),
            log: log
        });
        function getValidSourceFile(fileName) {
            var sourceFile = program.getSourceFile(fileName);
            if (!sourceFile) {
                throw new Error("Could not find sourceFile: '" + fileName + "' in " + (program && JSON.stringify(program.getSourceFiles().map(function (f) { return f.fileName; }))) + ".");
            }
            return sourceFile;
        }
        function synchronizeHostData() {
            ts.Debug.assert(!syntaxOnly);
            // perform fast check if host supports it
            if (host.getProjectVersion) {
                var hostProjectVersion = host.getProjectVersion();
                if (hostProjectVersion) {
                    if (lastProjectVersion === hostProjectVersion && !host.hasChangedAutomaticTypeDirectiveNames) {
                        return;
                    }
                    lastProjectVersion = hostProjectVersion;
                }
            }
            var typeRootsVersion = host.getTypeRootsVersion ? host.getTypeRootsVersion() : 0;
            if (lastTypesRootVersion !== typeRootsVersion) {
                log("TypeRoots version has changed; provide new program");
                program = undefined; // TODO: GH#18217
                lastTypesRootVersion = typeRootsVersion;
            }
            // Get a fresh cache of the host information
            var hostCache = new HostCache(host, getCanonicalFileName);
            var rootFileNames = hostCache.getRootFileNames();
            var hasInvalidatedResolution = host.hasInvalidatedResolution || ts.returnFalse;
            var projectReferences = hostCache.getProjectReferences();
            // If the program is already up-to-date, we can reuse it
            if (ts.isProgramUptoDate(program, rootFileNames, hostCache.compilationSettings(), function (path) { return hostCache.getVersion(path); }, fileExists, hasInvalidatedResolution, !!host.hasChangedAutomaticTypeDirectiveNames, projectReferences)) {
                return;
            }
            // IMPORTANT - It is critical from this moment onward that we do not check
            // cancellation tokens.  We are about to mutate source files from a previous program
            // instance.  If we cancel midway through, we may end up in an inconsistent state where
            // the program points to old source files that have been invalidated because of
            // incremental parsing.
            var newSettings = hostCache.compilationSettings();
            // Now create a new compiler
            var compilerHost = {
                getSourceFile: getOrCreateSourceFile,
                getSourceFileByPath: getOrCreateSourceFileByPath,
                getCancellationToken: function () { return cancellationToken; },
                getCanonicalFileName: getCanonicalFileName,
                useCaseSensitiveFileNames: function () { return useCaseSensitiveFileNames; },
                getNewLine: function () { return ts.getNewLineCharacter(newSettings, function () { return ts.getNewLineOrDefaultFromHost(host); }); },
                getDefaultLibFileName: function (options) { return host.getDefaultLibFileName(options); },
                writeFile: ts.noop,
                getCurrentDirectory: function () { return currentDirectory; },
                fileExists: fileExists,
                readFile: readFile,
                realpath: host.realpath && (function (path) { return host.realpath(path); }),
                directoryExists: function (directoryName) {
                    return ts.directoryProbablyExists(directoryName, host);
                },
                getDirectories: function (path) {
                    return host.getDirectories ? host.getDirectories(path) : [];
                },
                readDirectory: function (path, extensions, exclude, include, depth) {
                    ts.Debug.assertDefined(host.readDirectory, "'LanguageServiceHost.readDirectory' must be implemented to correctly process 'projectReferences'");
                    return host.readDirectory(path, extensions, exclude, include, depth);
                },
                onReleaseOldSourceFile: onReleaseOldSourceFile,
                hasInvalidatedResolution: hasInvalidatedResolution,
                hasChangedAutomaticTypeDirectiveNames: host.hasChangedAutomaticTypeDirectiveNames
            };
            if (host.trace) {
                compilerHost.trace = function (message) { return host.trace(message); };
            }
            if (host.resolveModuleNames) {
                compilerHost.resolveModuleNames = function (moduleNames, containingFile, reusedNames, redirectedReference) { return host.resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference); };
            }
            if (host.resolveTypeReferenceDirectives) {
                compilerHost.resolveTypeReferenceDirectives = function (typeReferenceDirectiveNames, containingFile, redirectedReference) {
                    return host.resolveTypeReferenceDirectives(typeReferenceDirectiveNames, containingFile, redirectedReference);
                };
            }
            var documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings);
            var options = {
                rootNames: rootFileNames,
                options: newSettings,
                host: compilerHost,
                oldProgram: program,
                projectReferences: projectReferences
            };
            program = ts.createProgram(options);
            // hostCache is captured in the closure for 'getOrCreateSourceFile' but it should not be used past this point.
            // It needs to be cleared to allow all collected snapshots to be released
            hostCache = undefined;
            // We reset this cache on structure invalidation so we don't hold on to outdated files for long; however we can't use the `compilerHost` above,
            // Because it only functions until `hostCache` is cleared, while we'll potentially need the functionality to lazily read sourcemap files during
            // the course of whatever called `synchronizeHostData`
            sourceMapper.clearCache();
            // Make sure all the nodes in the program are both bound, and have their parent
            // pointers set property.
            program.getTypeChecker();
            return;
            function fileExists(fileName) {
                var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
                var entry = hostCache && hostCache.getEntryByPath(path);
                return entry ?
                    !ts.isString(entry) :
                    (!!host.fileExists && host.fileExists(fileName));
            }
            function readFile(fileName) {
                // stub missing host functionality
                var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
                var entry = hostCache && hostCache.getEntryByPath(path);
                if (entry) {
                    return ts.isString(entry) ? undefined : ts.getSnapshotText(entry.scriptSnapshot);
                }
                return host.readFile && host.readFile(fileName);
            }
            // Release any files we have acquired in the old program but are
            // not part of the new program.
            function onReleaseOldSourceFile(oldSourceFile, oldOptions) {
                var oldSettingsKey = documentRegistry.getKeyForCompilationSettings(oldOptions);
                documentRegistry.releaseDocumentWithKey(oldSourceFile.resolvedPath, oldSettingsKey);
            }
            function getOrCreateSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile) {
                return getOrCreateSourceFileByPath(fileName, ts.toPath(fileName, currentDirectory, getCanonicalFileName), languageVersion, onError, shouldCreateNewSourceFile);
            }
            function getOrCreateSourceFileByPath(fileName, path, _languageVersion, _onError, shouldCreateNewSourceFile) {
                ts.Debug.assert(hostCache !== undefined, "getOrCreateSourceFileByPath called after typical CompilerHost lifetime, check the callstack something with a reference to an old host.");
                // The program is asking for this file, check first if the host can locate it.
                // If the host can not locate the file, then it does not exist. return undefined
                // to the program to allow reporting of errors for missing files.
                var hostFileInformation = hostCache && hostCache.getOrCreateEntryByPath(fileName, path);
                if (!hostFileInformation) {
                    return undefined;
                }
                // Check if the language version has changed since we last created a program; if they are the same,
                // it is safe to reuse the sourceFiles; if not, then the shape of the AST can change, and the oldSourceFile
                // can not be reused. we have to dump all syntax trees and create new ones.
                if (!shouldCreateNewSourceFile) {
                    // Check if the old program had this file already
                    var oldSourceFile = program && program.getSourceFileByPath(path);
                    if (oldSourceFile) {
                        // We already had a source file for this file name.  Go to the registry to
                        // ensure that we get the right up to date version of it.  We need this to
                        // address the following race-condition.  Specifically, say we have the following:
                        //
                        //      LS1
                        //          \
                        //           DocumentRegistry
                        //          /
                        //      LS2
                        //
                        // Each LS has a reference to file 'foo.ts' at version 1.  LS2 then updates
                        // it's version of 'foo.ts' to version 2.  This will cause LS2 and the
                        // DocumentRegistry to have version 2 of the document.  HOwever, LS1 will
                        // have version 1.  And *importantly* this source file will be *corrupt*.
                        // The act of creating version 2 of the file irrevocably damages the version
                        // 1 file.
                        //
                        // So, later when we call into LS1, we need to make sure that it doesn't use
                        // it's source file any more, and instead defers to DocumentRegistry to get
                        // either version 1, version 2 (or some other version) depending on what the
                        // host says should be used.
                        // We do not support the scenario where a host can modify a registered
                        // file's script kind, i.e. in one project some file is treated as ".ts"
                        // and in another as ".js"
                        ts.Debug.assertEqual(hostFileInformation.scriptKind, oldSourceFile.scriptKind, "Registered script kind should match new script kind.", path);
                        return documentRegistry.updateDocumentWithKey(fileName, path, newSettings, documentRegistryBucketKey, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind);
                    }
                    // We didn't already have the file.  Fall through and acquire it from the registry.
                }
                // Could not find this file in the old program, create a new SourceFile for it.
                return documentRegistry.acquireDocumentWithKey(fileName, path, newSettings, documentRegistryBucketKey, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind);
            }
        }
        // TODO: GH#18217 frequently asserted as defined
        function getProgram() {
            if (syntaxOnly) {
                ts.Debug.assert(program === undefined);
                return undefined;
            }
            synchronizeHostData();
            return program;
        }
        function cleanupSemanticCache() {
            program = undefined; // TODO: GH#18217
        }
        function dispose() {
            if (program) {
                ts.forEach(program.getSourceFiles(), function (f) {
                    return documentRegistry.releaseDocument(f.fileName, program.getCompilerOptions());
                });
                program = undefined; // TODO: GH#18217
            }
            host = undefined;
        }
        /// Diagnostics
        function getSyntacticDiagnostics(fileName) {
            synchronizeHostData();
            return program.getSyntacticDiagnostics(getValidSourceFile(fileName), cancellationToken).slice();
        }
        /**
         * getSemanticDiagnostics return array of Diagnostics. If '-d' is not enabled, only report semantic errors
         * If '-d' enabled, report both semantic and emitter errors
         */
        function getSemanticDiagnostics(fileName) {
            synchronizeHostData();
            var targetSourceFile = getValidSourceFile(fileName);
            // Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file.
            // Therefore only get diagnostics for given file.
            var semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken);
            if (!ts.getEmitDeclarations(program.getCompilerOptions())) {
                return semanticDiagnostics.slice();
            }
            // If '-d' is enabled, check for emitter error. One example of emitter error is export class implements non-export interface
            var declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken);
            return semanticDiagnostics.concat(declarationDiagnostics);
        }
        function getSuggestionDiagnostics(fileName) {
            synchronizeHostData();
            return ts.computeSuggestionDiagnostics(getValidSourceFile(fileName), program, cancellationToken);
        }
        function getCompilerOptionsDiagnostics() {
            synchronizeHostData();
            return program.getOptionsDiagnostics(cancellationToken).concat(program.getGlobalDiagnostics(cancellationToken));
        }
        function getCompletionsAtPosition(fileName, position, options) {
            if (options === void 0) { options = ts.emptyOptions; }
            // Convert from deprecated options names to new names
            var fullPreferences = __assign({}, ts.identity(options), { includeCompletionsForModuleExports: options.includeCompletionsForModuleExports || options.includeExternalModuleExports, includeCompletionsWithInsertText: options.includeCompletionsWithInsertText || options.includeInsertTextCompletions });
            synchronizeHostData();
            return ts.Completions.getCompletionsAtPosition(host, program, log, getValidSourceFile(fileName), position, fullPreferences, options.triggerCharacter);
        }
        function getCompletionEntryDetails(fileName, position, name, formattingOptions, source, preferences) {
            if (preferences === void 0) { preferences = ts.emptyOptions; }
            synchronizeHostData();
            return ts.Completions.getCompletionEntryDetails(program, log, getValidSourceFile(fileName), position, { name: name, source: source }, host, (formattingOptions && ts.formatting.getFormatContext(formattingOptions)), // TODO: GH#18217
            preferences, cancellationToken);
        }
        function getCompletionEntrySymbol(fileName, position, name, source) {
            synchronizeHostData();
            return ts.Completions.getCompletionEntrySymbol(program, log, getValidSourceFile(fileName), position, { name: name, source: source });
        }
        function getQuickInfoAtPosition(fileName, position) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var node = ts.getTouchingPropertyName(sourceFile, position);
            if (node === sourceFile) {
                // Avoid giving quickInfo for the sourceFile as a whole.
                return undefined;
            }
            var typeChecker = program.getTypeChecker();
            var nodeForQuickInfo = getNodeForQuickInfo(node);
            var symbol = getSymbolAtLocationForQuickInfo(nodeForQuickInfo, typeChecker);
            if (!symbol || typeChecker.isUnknownSymbol(symbol)) {
                var type_2 = shouldGetType(sourceFile, nodeForQuickInfo, position) ? typeChecker.getTypeAtLocation(nodeForQuickInfo) : undefined;
                return type_2 && {
                    kind: "" /* unknown */,
                    kindModifiers: "" /* none */,
                    textSpan: ts.createTextSpanFromNode(nodeForQuickInfo, sourceFile),
                    displayParts: typeChecker.runWithCancellationToken(cancellationToken, function (typeChecker) { return ts.typeToDisplayParts(typeChecker, type_2, ts.getContainerNode(nodeForQuickInfo)); }),
                    documentation: type_2.symbol ? type_2.symbol.getDocumentationComment(typeChecker) : undefined,
                    tags: type_2.symbol ? type_2.symbol.getJsDocTags() : undefined
                };
            }
            var _a = typeChecker.runWithCancellationToken(cancellationToken, function (typeChecker) {
                return ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, ts.getContainerNode(nodeForQuickInfo), nodeForQuickInfo);
            }), symbolKind = _a.symbolKind, displayParts = _a.displayParts, documentation = _a.documentation, tags = _a.tags;
            return {
                kind: symbolKind,
                kindModifiers: ts.SymbolDisplay.getSymbolModifiers(symbol),
                textSpan: ts.createTextSpanFromNode(nodeForQuickInfo, sourceFile),
                displayParts: displayParts,
                documentation: documentation,
                tags: tags,
            };
        }
        function getNodeForQuickInfo(node) {
            if (ts.isNewExpression(node.parent) && node.pos === node.parent.pos) {
                return node.parent.expression;
            }
            return node;
        }
        function shouldGetType(sourceFile, node, position) {
            switch (node.kind) {
                case 73 /* Identifier */:
                    return !ts.isLabelName(node) && !ts.isTagName(node);
                case 190 /* PropertyAccessExpression */:
                case 149 /* QualifiedName */:
                    // Don't return quickInfo if inside the comment in `a/**/.b`
                    return !ts.isInComment(sourceFile, position);
                case 101 /* ThisKeyword */:
                case 179 /* ThisType */:
                case 99 /* SuperKeyword */:
                    return true;
                default:
                    return false;
            }
        }
        /// Goto definition
        function getDefinitionAtPosition(fileName, position) {
            synchronizeHostData();
            return ts.GoToDefinition.getDefinitionAtPosition(program, getValidSourceFile(fileName), position);
        }
        function getDefinitionAndBoundSpan(fileName, position) {
            synchronizeHostData();
            return ts.GoToDefinition.getDefinitionAndBoundSpan(program, getValidSourceFile(fileName), position);
        }
        function getTypeDefinitionAtPosition(fileName, position) {
            synchronizeHostData();
            return ts.GoToDefinition.getTypeDefinitionAtPosition(program.getTypeChecker(), getValidSourceFile(fileName), position);
        }
        /// Goto implementation
        function getImplementationAtPosition(fileName, position) {
            synchronizeHostData();
            return ts.FindAllReferences.getImplementationsAtPosition(program, cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position);
        }
        /// References and Occurrences
        function getOccurrencesAtPosition(fileName, position) {
            return ts.flatMap(getDocumentHighlights(fileName, position, [fileName]), function (entry) { return entry.highlightSpans.map(function (highlightSpan) { return ({
                fileName: entry.fileName,
                textSpan: highlightSpan.textSpan,
                isWriteAccess: highlightSpan.kind === "writtenReference" /* writtenReference */,
                isDefinition: false,
                isInString: highlightSpan.isInString,
            }); }); });
        }
        function getDocumentHighlights(fileName, position, filesToSearch) {
            var normalizedFileName = ts.normalizePath(fileName);
            ts.Debug.assert(filesToSearch.some(function (f) { return ts.normalizePath(f) === normalizedFileName; }));
            synchronizeHostData();
            var sourceFilesToSearch = filesToSearch.map(getValidSourceFile);
            var sourceFile = getValidSourceFile(fileName);
            return ts.DocumentHighlights.getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch);
        }
        function findRenameLocations(fileName, position, findInStrings, findInComments, providePrefixAndSuffixTextForRename) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var node = ts.getTouchingPropertyName(sourceFile, position);
            if (ts.isIdentifier(node) && (ts.isJsxOpeningElement(node.parent) || ts.isJsxClosingElement(node.parent)) && ts.isIntrinsicJsxName(node.escapedText)) {
                var _a = node.parent.parent, openingElement = _a.openingElement, closingElement = _a.closingElement;
                return [openingElement, closingElement].map(function (node) {
                    return ({ fileName: sourceFile.fileName, textSpan: ts.createTextSpanFromNode(node.tagName, sourceFile) });
                });
            }
            else {
                return getReferencesWorker(node, position, { findInStrings: findInStrings, findInComments: findInComments, providePrefixAndSuffixTextForRename: providePrefixAndSuffixTextForRename, isForRename: true }, function (entry, originalNode, checker) { return ts.FindAllReferences.toRenameLocation(entry, originalNode, checker, providePrefixAndSuffixTextForRename || false); });
            }
        }
        function getReferencesAtPosition(fileName, position) {
            synchronizeHostData();
            return getReferencesWorker(ts.getTouchingPropertyName(getValidSourceFile(fileName), position), position, {}, ts.FindAllReferences.toReferenceEntry);
        }
        function getReferencesWorker(node, position, options, cb) {
            synchronizeHostData();
            // Exclude default library when renaming as commonly user don't want to change that file.
            var sourceFiles = options && options.isForRename
                ? program.getSourceFiles().filter(function (sourceFile) { return !program.isSourceFileDefaultLibrary(sourceFile); })
                : program.getSourceFiles();
            return ts.FindAllReferences.findReferenceOrRenameEntries(program, cancellationToken, sourceFiles, node, position, options, cb);
        }
        function findReferences(fileName, position) {
            synchronizeHostData();
            return ts.FindAllReferences.findReferencedSymbols(program, cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position);
        }
        function getNavigateToItems(searchValue, maxResultCount, fileName, excludeDtsFiles) {
            if (excludeDtsFiles === void 0) { excludeDtsFiles = false; }
            synchronizeHostData();
            var sourceFiles = fileName ? [getValidSourceFile(fileName)] : program.getSourceFiles();
            return ts.NavigateTo.getNavigateToItems(sourceFiles, program.getTypeChecker(), cancellationToken, searchValue, maxResultCount, excludeDtsFiles);
        }
        function getEmitOutput(fileName, emitOnlyDtsFiles) {
            if (emitOnlyDtsFiles === void 0) { emitOnlyDtsFiles = false; }
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var customTransformers = host.getCustomTransformers && host.getCustomTransformers();
            return ts.getFileEmitOutput(program, sourceFile, emitOnlyDtsFiles, cancellationToken, customTransformers);
        }
        // Signature help
        /**
         * This is a semantic operation.
         */
        function getSignatureHelpItems(fileName, position, _a) {
            var triggerReason = (_a === void 0 ? ts.emptyOptions : _a).triggerReason;
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            return ts.SignatureHelp.getSignatureHelpItems(program, sourceFile, position, triggerReason, cancellationToken);
        }
        /// Syntactic features
        function getNonBoundSourceFile(fileName) {
            return syntaxTreeCache.getCurrentSourceFile(fileName);
        }
        function getNameOrDottedNameSpan(fileName, startPos, _endPos) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            // Get node at the location
            var node = ts.getTouchingPropertyName(sourceFile, startPos);
            if (node === sourceFile) {
                return undefined;
            }
            switch (node.kind) {
                case 190 /* PropertyAccessExpression */:
                case 149 /* QualifiedName */:
                case 10 /* StringLiteral */:
                case 88 /* FalseKeyword */:
                case 103 /* TrueKeyword */:
                case 97 /* NullKeyword */:
                case 99 /* SuperKeyword */:
                case 101 /* ThisKeyword */:
                case 179 /* ThisType */:
                case 73 /* Identifier */:
                    break;
                // Cant create the text span
                default:
                    return undefined;
            }
            var nodeForStartPos = node;
            while (true) {
                if (ts.isRightSideOfPropertyAccess(nodeForStartPos) || ts.isRightSideOfQualifiedName(nodeForStartPos)) {
                    // If on the span is in right side of the the property or qualified name, return the span from the qualified name pos to end of this node
                    nodeForStartPos = nodeForStartPos.parent;
                }
                else if (ts.isNameOfModuleDeclaration(nodeForStartPos)) {
                    // If this is name of a module declarations, check if this is right side of dotted module name
                    // If parent of the module declaration which is parent of this node is module declaration and its body is the module declaration that this node is name of
                    // Then this name is name from dotted module
                    if (nodeForStartPos.parent.parent.kind === 245 /* ModuleDeclaration */ &&
                        nodeForStartPos.parent.parent.body === nodeForStartPos.parent) {
                        // Use parent module declarations name for start pos
                        nodeForStartPos = nodeForStartPos.parent.parent.name;
                    }
                    else {
                        // We have to use this name for start pos
                        break;
                    }
                }
                else {
                    // Is not a member expression so we have found the node for start pos
                    break;
                }
            }
            return ts.createTextSpanFromBounds(nodeForStartPos.getStart(), node.getEnd());
        }
        function getBreakpointStatementAtPosition(fileName, position) {
            // doesn't use compiler - no need to synchronize with host
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            return ts.BreakpointResolver.spanInSourceFileAtLocation(sourceFile, position);
        }
        function getNavigationBarItems(fileName) {
            return ts.NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken);
        }
        function getNavigationTree(fileName) {
            return ts.NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken);
        }
        function isTsOrTsxFile(fileName) {
            var kind = ts.getScriptKind(fileName, host);
            return kind === 3 /* TS */ || kind === 4 /* TSX */;
        }
        function getSemanticClassifications(fileName, span) {
            if (!isTsOrTsxFile(fileName)) {
                // do not run semantic classification on non-ts-or-tsx files
                return [];
            }
            synchronizeHostData();
            return ts.getSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span);
        }
        function getEncodedSemanticClassifications(fileName, span) {
            if (!isTsOrTsxFile(fileName)) {
                // do not run semantic classification on non-ts-or-tsx files
                return { spans: [], endOfLineState: 0 /* None */ };
            }
            synchronizeHostData();
            return ts.getEncodedSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span);
        }
        function getSyntacticClassifications(fileName, span) {
            // doesn't use compiler - no need to synchronize with host
            return ts.getSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span);
        }
        function getEncodedSyntacticClassifications(fileName, span) {
            // doesn't use compiler - no need to synchronize with host
            return ts.getEncodedSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span);
        }
        function getOutliningSpans(fileName) {
            // doesn't use compiler - no need to synchronize with host
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            return ts.OutliningElementsCollector.collectElements(sourceFile, cancellationToken);
        }
        var braceMatching = ts.createMapFromTemplate((_a = {},
            _a[18 /* OpenBraceToken */] = 19 /* CloseBraceToken */,
            _a[20 /* OpenParenToken */] = 21 /* CloseParenToken */,
            _a[22 /* OpenBracketToken */] = 23 /* CloseBracketToken */,
            _a[30 /* GreaterThanToken */] = 28 /* LessThanToken */,
            _a));
        braceMatching.forEach(function (value, key) { return braceMatching.set(value.toString(), Number(key)); });
        function getBraceMatchingAtPosition(fileName, position) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            var token = ts.getTouchingToken(sourceFile, position);
            var matchKind = token.getStart(sourceFile) === position ? braceMatching.get(token.kind.toString()) : undefined;
            var match = matchKind && ts.findChildOfKind(token.parent, matchKind, sourceFile);
            // We want to order the braces when we return the result.
            return match ? [ts.createTextSpanFromNode(token, sourceFile), ts.createTextSpanFromNode(match, sourceFile)].sort(function (a, b) { return a.start - b.start; }) : ts.emptyArray;
        }
        function getIndentationAtPosition(fileName, position, editorOptions) {
            var start = ts.timestamp();
            var settings = toEditorSettings(editorOptions);
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            log("getIndentationAtPosition: getCurrentSourceFile: " + (ts.timestamp() - start));
            start = ts.timestamp();
            var result = ts.formatting.SmartIndenter.getIndentation(position, sourceFile, settings);
            log("getIndentationAtPosition: computeIndentation  : " + (ts.timestamp() - start));
            return result;
        }
        function getFormattingEditsForRange(fileName, start, end, options) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            return ts.formatting.formatSelection(start, end, sourceFile, ts.formatting.getFormatContext(toEditorSettings(options)));
        }
        function getFormattingEditsForDocument(fileName, options) {
            return ts.formatting.formatDocument(syntaxTreeCache.getCurrentSourceFile(fileName), ts.formatting.getFormatContext(toEditorSettings(options)));
        }
        function getFormattingEditsAfterKeystroke(fileName, position, key, options) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            var formatContext = ts.formatting.getFormatContext(toEditorSettings(options));
            if (!ts.isInComment(sourceFile, position)) {
                switch (key) {
                    case "{":
                        return ts.formatting.formatOnOpeningCurly(position, sourceFile, formatContext);
                    case "}":
                        return ts.formatting.formatOnClosingCurly(position, sourceFile, formatContext);
                    case ";":
                        return ts.formatting.formatOnSemicolon(position, sourceFile, formatContext);
                    case "\n":
                        return ts.formatting.formatOnEnter(position, sourceFile, formatContext);
                }
            }
            return [];
        }
        function getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions, preferences) {
            if (preferences === void 0) { preferences = ts.emptyOptions; }
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var span = ts.createTextSpanFromBounds(start, end);
            var formatContext = ts.formatting.getFormatContext(formatOptions);
            return ts.flatMap(ts.deduplicate(errorCodes, ts.equateValues, ts.compareValues), function (errorCode) {
                cancellationToken.throwIfCancellationRequested();
                return ts.codefix.getFixes({ errorCode: errorCode, sourceFile: sourceFile, span: span, program: program, host: host, cancellationToken: cancellationToken, formatContext: formatContext, preferences: preferences });
            });
        }
        function getCombinedCodeFix(scope, fixId, formatOptions, preferences) {
            if (preferences === void 0) { preferences = ts.emptyOptions; }
            synchronizeHostData();
            ts.Debug.assert(scope.type === "file");
            var sourceFile = getValidSourceFile(scope.fileName);
            var formatContext = ts.formatting.getFormatContext(formatOptions);
            return ts.codefix.getAllFixes({ fixId: fixId, sourceFile: sourceFile, program: program, host: host, cancellationToken: cancellationToken, formatContext: formatContext, preferences: preferences });
        }
        function organizeImports(scope, formatOptions, preferences) {
            if (preferences === void 0) { preferences = ts.emptyOptions; }
            synchronizeHostData();
            ts.Debug.assert(scope.type === "file");
            var sourceFile = getValidSourceFile(scope.fileName);
            var formatContext = ts.formatting.getFormatContext(formatOptions);
            return ts.OrganizeImports.organizeImports(sourceFile, formatContext, host, program, preferences);
        }
        function getEditsForFileRename(oldFilePath, newFilePath, formatOptions, preferences) {
            if (preferences === void 0) { preferences = ts.emptyOptions; }
            return ts.getEditsForFileRename(getProgram(), oldFilePath, newFilePath, host, ts.formatting.getFormatContext(formatOptions), preferences, sourceMapper);
        }
        function applyCodeActionCommand(fileName, actionOrFormatSettingsOrUndefined) {
            var action = typeof fileName === "string" ? actionOrFormatSettingsOrUndefined : fileName;
            return ts.isArray(action) ? Promise.all(action.map(function (a) { return applySingleCodeActionCommand(a); })) : applySingleCodeActionCommand(action);
        }
        function applySingleCodeActionCommand(action) {
            var getPath = function (path) { return ts.toPath(path, currentDirectory, getCanonicalFileName); };
            ts.Debug.assertEqual(action.type, "install package");
            return host.installPackage
                ? host.installPackage({ fileName: getPath(action.file), packageName: action.packageName })
                : Promise.reject("Host does not implement `installPackage`");
        }
        function getDocCommentTemplateAtPosition(fileName, position) {
            return ts.JsDoc.getDocCommentTemplateAtPosition(ts.getNewLineOrDefaultFromHost(host), syntaxTreeCache.getCurrentSourceFile(fileName), position);
        }
        function isValidBraceCompletionAtPosition(fileName, position, openingBrace) {
            // '<' is currently not supported, figuring out if we're in a Generic Type vs. a comparison is too
            // expensive to do during typing scenarios
            // i.e. whether we're dealing with:
            //      var x = new foo<| ( with class foo<T>{} )
            // or
            //      var y = 3 <|
            if (openingBrace === 60 /* lessThan */) {
                return false;
            }
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            // Check if in a context where we don't want to perform any insertion
            if (ts.isInString(sourceFile, position)) {
                return false;
            }
            if (ts.isInsideJsxElementOrAttribute(sourceFile, position)) {
                return openingBrace === 123 /* openBrace */;
            }
            if (ts.isInTemplateString(sourceFile, position)) {
                return false;
            }
            switch (openingBrace) {
                case 39 /* singleQuote */:
                case 34 /* doubleQuote */:
                case 96 /* backtick */:
                    return !ts.isInComment(sourceFile, position);
            }
            return true;
        }
        function getJsxClosingTagAtPosition(fileName, position) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            var token = ts.findPrecedingToken(position, sourceFile);
            if (!token)
                return undefined;
            var element = token.kind === 30 /* GreaterThanToken */ && ts.isJsxOpeningElement(token.parent) ? token.parent.parent
                : ts.isJsxText(token) ? token.parent : undefined;
            if (element && isUnclosedTag(element)) {
                return { newText: "</" + element.openingElement.tagName.getText(sourceFile) + ">" };
            }
        }
        function isUnclosedTag(_a) {
            var openingElement = _a.openingElement, closingElement = _a.closingElement, parent = _a.parent;
            return !ts.tagNamesAreEquivalent(openingElement.tagName, closingElement.tagName) ||
                ts.isJsxElement(parent) && ts.tagNamesAreEquivalent(openingElement.tagName, parent.openingElement.tagName) && isUnclosedTag(parent);
        }
        function getSpanOfEnclosingComment(fileName, position, onlyMultiLine) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            var range = ts.formatting.getRangeOfEnclosingComment(sourceFile, position);
            return range && (!onlyMultiLine || range.kind === 3 /* MultiLineCommentTrivia */) ? ts.createTextSpanFromRange(range) : undefined;
        }
        function getTodoComments(fileName, descriptors) {
            // Note: while getting todo comments seems like a syntactic operation, we actually
            // treat it as a semantic operation here.  This is because we expect our host to call
            // this on every single file.  If we treat this syntactically, then that will cause
            // us to populate and throw away the tree in our syntax tree cache for each file.  By
            // treating this as a semantic operation, we can access any tree without throwing
            // anything away.
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            cancellationToken.throwIfCancellationRequested();
            var fileContents = sourceFile.text;
            var result = [];
            // Exclude node_modules files as we don't want to show the todos of external libraries.
            if (descriptors.length > 0 && !isNodeModulesFile(sourceFile.fileName)) {
                var regExp = getTodoCommentsRegExp();
                var matchArray = void 0;
                while (matchArray = regExp.exec(fileContents)) {
                    cancellationToken.throwIfCancellationRequested();
                    // If we got a match, here is what the match array will look like.  Say the source text is:
                    //
                    //      "    // hack   1"
                    //
                    // The result array with the regexp:    will be:
                    //
                    //      ["// hack   1", "// ", "hack   1", undefined, "hack"]
                    //
                    // Here are the relevant capture groups:
                    //  0) The full match for the entire regexp.
                    //  1) The preamble to the message portion.
                    //  2) The message portion.
                    //  3...N) The descriptor that was matched - by index.  'undefined' for each
                    //         descriptor that didn't match.  an actual value if it did match.
                    //
                    //  i.e. 'undefined' in position 3 above means TODO(jason) didn't match.
                    //       "hack"      in position 4 means HACK did match.
                    var firstDescriptorCaptureIndex = 3;
                    ts.Debug.assert(matchArray.length === descriptors.length + firstDescriptorCaptureIndex);
                    var preamble = matchArray[1];
                    var matchPosition = matchArray.index + preamble.length;
                    // OK, we have found a match in the file.  This is only an acceptable match if
                    // it is contained within a comment.
                    if (!ts.isInComment(sourceFile, matchPosition)) {
                        continue;
                    }
                    var descriptor = void 0;
                    for (var i = 0; i < descriptors.length; i++) {
                        if (matchArray[i + firstDescriptorCaptureIndex]) {
                            descriptor = descriptors[i];
                        }
                    }
                    if (descriptor === undefined)
                        return ts.Debug.fail();
                    // We don't want to match something like 'TODOBY', so we make sure a non
                    // letter/digit follows the match.
                    if (isLetterOrDigit(fileContents.charCodeAt(matchPosition + descriptor.text.length))) {
                        continue;
                    }
                    var message = matchArray[2];
                    result.push({ descriptor: descriptor, message: message, position: matchPosition });
                }
            }
            return result;
            function escapeRegExp(str) {
                return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
            }
            function getTodoCommentsRegExp() {
                // NOTE: `?:` means 'non-capture group'.  It allows us to have groups without having to
                // filter them out later in the final result array.
                // TODO comments can appear in one of the following forms:
                //
                //  1)      // TODO     or  /////////// TODO
                //
                //  2)      /* TODO     or  /********** TODO
                //
                //  3)      /*
                //           *   TODO
                //           */
                //
                // The following three regexps are used to match the start of the text up to the TODO
                // comment portion.
                var singleLineCommentStart = /(?:\/\/+\s*)/.source;
                var multiLineCommentStart = /(?:\/\*+\s*)/.source;
                var anyNumberOfSpacesAndAsterisksAtStartOfLine = /(?:^(?:\s|\*)*)/.source;
                // Match any of the above three TODO comment start regexps.
                // Note that the outermost group *is* a capture group.  We want to capture the preamble
                // so that we can determine the starting position of the TODO comment match.
                var preamble = "(" + anyNumberOfSpacesAndAsterisksAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")";
                // Takes the descriptors and forms a regexp that matches them as if they were literals.
                // For example, if the descriptors are "TODO(jason)" and "HACK", then this will be:
                //
                //      (?:(TODO\(jason\))|(HACK))
                //
                // Note that the outermost group is *not* a capture group, but the innermost groups
                // *are* capture groups.  By capturing the inner literals we can determine after
                // matching which descriptor we are dealing with.
                var literals = "(?:" + ts.map(descriptors, function (d) { return "(" + escapeRegExp(d.text) + ")"; }).join("|") + ")";
                // After matching a descriptor literal, the following regexp matches the rest of the
                // text up to the end of the line (or */).
                var endOfLineOrEndOfComment = /(?:$|\*\/)/.source;
                var messageRemainder = /(?:.*?)/.source;
                // This is the portion of the match we'll return as part of the TODO comment result. We
                // match the literal portion up to the end of the line or end of comment.
                var messagePortion = "(" + literals + messageRemainder + ")";
                var regExpString = preamble + messagePortion + endOfLineOrEndOfComment;
                // The final regexp will look like this:
                // /((?:\/\/+\s*)|(?:\/\*+\s*)|(?:^(?:\s|\*)*))((?:(TODO\(jason\))|(HACK))(?:.*?))(?:$|\*\/)/gim
                // The flags of the regexp are important here.
                //  'g' is so that we are doing a global search and can find matches several times
                //  in the input.
                //
                //  'i' is for case insensitivity (We do this to match C# TODO comment code).
                //
                //  'm' is so we can find matches in a multi-line input.
                return new RegExp(regExpString, "gim");
            }
            function isLetterOrDigit(char) {
                return (char >= 97 /* a */ && char <= 122 /* z */) ||
                    (char >= 65 /* A */ && char <= 90 /* Z */) ||
                    (char >= 48 /* _0 */ && char <= 57 /* _9 */);
            }
            function isNodeModulesFile(path) {
                return ts.stringContains(path, "/node_modules/");
            }
        }
        function getRenameInfo(fileName, position, options) {
            synchronizeHostData();
            return ts.Rename.getRenameInfo(program, getValidSourceFile(fileName), position, options);
        }
        function getRefactorContext(file, positionOrRange, preferences, formatOptions) {
            var _a = typeof positionOrRange === "number" ? [positionOrRange, undefined] : [positionOrRange.pos, positionOrRange.end], startPosition = _a[0], endPosition = _a[1];
            return {
                file: file,
                startPosition: startPosition,
                endPosition: endPosition,
                program: getProgram(),
                host: host,
                formatContext: ts.formatting.getFormatContext(formatOptions),
                cancellationToken: cancellationToken,
                preferences: preferences,
            };
        }
        function getSmartSelectionRange(fileName, position) {
            return ts.SmartSelectionRange.getSmartSelectionRange(position, syntaxTreeCache.getCurrentSourceFile(fileName));
        }
        function getApplicableRefactors(fileName, positionOrRange, preferences) {
            if (preferences === void 0) { preferences = ts.emptyOptions; }
            synchronizeHostData();
            var file = getValidSourceFile(fileName);
            return ts.refactor.getApplicableRefactors(getRefactorContext(file, positionOrRange, preferences));
        }
        function getEditsForRefactor(fileName, formatOptions, positionOrRange, refactorName, actionName, preferences) {
            if (preferences === void 0) { preferences = ts.emptyOptions; }
            synchronizeHostData();
            var file = getValidSourceFile(fileName);
            return ts.refactor.getEditsForRefactor(getRefactorContext(file, positionOrRange, preferences, formatOptions), refactorName, actionName);
        }
        return {
            dispose: dispose,
            cleanupSemanticCache: cleanupSemanticCache,
            getSyntacticDiagnostics: getSyntacticDiagnostics,
            getSemanticDiagnostics: getSemanticDiagnostics,
            getSuggestionDiagnostics: getSuggestionDiagnostics,
            getCompilerOptionsDiagnostics: getCompilerOptionsDiagnostics,
            getSyntacticClassifications: getSyntacticClassifications,
            getSemanticClassifications: getSemanticClassifications,
            getEncodedSyntacticClassifications: getEncodedSyntacticClassifications,
            getEncodedSemanticClassifications: getEncodedSemanticClassifications,
            getCompletionsAtPosition: getCompletionsAtPosition,
            getCompletionEntryDetails: getCompletionEntryDetails,
            getCompletionEntrySymbol: getCompletionEntrySymbol,
            getSignatureHelpItems: getSignatureHelpItems,
            getQuickInfoAtPosition: getQuickInfoAtPosition,
            getDefinitionAtPosition: getDefinitionAtPosition,
            getDefinitionAndBoundSpan: getDefinitionAndBoundSpan,
            getImplementationAtPosition: getImplementationAtPosition,
            getTypeDefinitionAtPosition: getTypeDefinitionAtPosition,
            getReferencesAtPosition: getReferencesAtPosition,
            findReferences: findReferences,
            getOccurrencesAtPosition: getOccurrencesAtPosition,
            getDocumentHighlights: getDocumentHighlights,
            getNameOrDottedNameSpan: getNameOrDottedNameSpan,
            getBreakpointStatementAtPosition: getBreakpointStatementAtPosition,
            getNavigateToItems: getNavigateToItems,
            getRenameInfo: getRenameInfo,
            getSmartSelectionRange: getSmartSelectionRange,
            findRenameLocations: findRenameLocations,
            getNavigationBarItems: getNavigationBarItems,
            getNavigationTree: getNavigationTree,
            getOutliningSpans: getOutliningSpans,
            getTodoComments: getTodoComments,
            getBraceMatchingAtPosition: getBraceMatchingAtPosition,
            getIndentationAtPosition: getIndentationAtPosition,
            getFormattingEditsForRange: getFormattingEditsForRange,
            getFormattingEditsForDocument: getFormattingEditsForDocument,
            getFormattingEditsAfterKeystroke: getFormattingEditsAfterKeystroke,
            getDocCommentTemplateAtPosition: getDocCommentTemplateAtPosition,
            isValidBraceCompletionAtPosition: isValidBraceCompletionAtPosition,
            getJsxClosingTagAtPosition: getJsxClosingTagAtPosition,
            getSpanOfEnclosingComment: getSpanOfEnclosingComment,
            getCodeFixesAtPosition: getCodeFixesAtPosition,
            getCombinedCodeFix: getCombinedCodeFix,
            applyCodeActionCommand: applyCodeActionCommand,
            organizeImports: organizeImports,
            getEditsForFileRename: getEditsForFileRename,
            getEmitOutput: getEmitOutput,
            getNonBoundSourceFile: getNonBoundSourceFile,
            getProgram: getProgram,
            getApplicableRefactors: getApplicableRefactors,
            getEditsForRefactor: getEditsForRefactor,
            toLineColumnOffset: sourceMapper.toLineColumnOffset,
            getSourceMapper: function () { return sourceMapper; },
        };
    }
    ts.createLanguageService = createLanguageService;
    /* @internal */
    /** Names in the name table are escaped, so an identifier `__foo` will have a name table entry `___foo`. */
    function getNameTable(sourceFile) {
        if (!sourceFile.nameTable) {
            initializeNameTable(sourceFile);
        }
        return sourceFile.nameTable; // TODO: GH#18217
    }
    ts.getNameTable = getNameTable;
    function initializeNameTable(sourceFile) {
        var nameTable = sourceFile.nameTable = ts.createUnderscoreEscapedMap();
        sourceFile.forEachChild(function walk(node) {
            if (ts.isIdentifier(node) && !ts.isTagName(node) && node.escapedText || ts.isStringOrNumericLiteralLike(node) && literalIsName(node)) {
                var text = ts.getEscapedTextOfIdentifierOrLiteral(node);
                nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1);
            }
            ts.forEachChild(node, walk);
            if (ts.hasJSDocNodes(node)) {
                for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                    var jsDoc = _a[_i];
                    ts.forEachChild(jsDoc, walk);
                }
            }
        });
    }
    /**
     * We want to store any numbers/strings if they were a name that could be
     * related to a declaration.  So, if we have 'import x = require("something")'
     * then we want 'something' to be in the name table.  Similarly, if we have
     * "a['propname']" then we want to store "propname" in the name table.
     */
    function literalIsName(node) {
        return ts.isDeclarationName(node) ||
            node.parent.kind === 260 /* ExternalModuleReference */ ||
            isArgumentOfElementAccessExpression(node) ||
            ts.isLiteralComputedPropertyDeclarationName(node);
    }
    /**
     * Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
     */
    /* @internal */
    function getContainingObjectLiteralElement(node) {
        var element = getContainingObjectLiteralElementWorker(node);
        return element && (ts.isObjectLiteralExpression(element.parent) || ts.isJsxAttributes(element.parent)) ? element : undefined;
    }
    ts.getContainingObjectLiteralElement = getContainingObjectLiteralElement;
    function getContainingObjectLiteralElementWorker(node) {
        switch (node.kind) {
            case 10 /* StringLiteral */:
            case 8 /* NumericLiteral */:
                if (node.parent.kind === 150 /* ComputedPropertyName */) {
                    return ts.isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;
                }
            // falls through
            case 73 /* Identifier */:
                return ts.isObjectLiteralElement(node.parent) &&
                    (node.parent.parent.kind === 189 /* ObjectLiteralExpression */ || node.parent.parent.kind === 269 /* JsxAttributes */) &&
                    node.parent.name === node ? node.parent : undefined;
        }
        return undefined;
    }
    function getSymbolAtLocationForQuickInfo(node, checker) {
        var object = getContainingObjectLiteralElement(node);
        if (object) {
            var contextualType = checker.getContextualType(object.parent);
            var properties = contextualType && getPropertySymbolsFromContextualType(object, checker, contextualType, /*unionSymbolOk*/ false);
            if (properties && properties.length === 1) {
                return ts.first(properties);
            }
        }
        return checker.getSymbolAtLocation(node);
    }
    /** Gets all symbols for one property. Does not get symbols for every property. */
    /* @internal */
    function getPropertySymbolsFromContextualType(node, checker, contextualType, unionSymbolOk) {
        var name = ts.getNameFromPropertyName(node.name);
        if (!name)
            return ts.emptyArray;
        if (!contextualType.isUnion()) {
            var symbol = contextualType.getProperty(name);
            return symbol ? [symbol] : ts.emptyArray;
        }
        var discriminatedPropertySymbols = ts.mapDefined(contextualType.types, function (t) { return ts.isObjectLiteralExpression(node.parent) && checker.isTypeInvalidDueToUnionDiscriminant(t, node.parent) ? undefined : t.getProperty(name); });
        if (unionSymbolOk && (discriminatedPropertySymbols.length === 0 || discriminatedPropertySymbols.length === contextualType.types.length)) {
            var symbol = contextualType.getProperty(name);
            if (symbol)
                return [symbol];
        }
        if (discriminatedPropertySymbols.length === 0) {
            // Bad discriminant -- do again without discriminating
            return ts.mapDefined(contextualType.types, function (t) { return t.getProperty(name); });
        }
        return discriminatedPropertySymbols;
    }
    ts.getPropertySymbolsFromContextualType = getPropertySymbolsFromContextualType;
    function isArgumentOfElementAccessExpression(node) {
        return node &&
            node.parent &&
            node.parent.kind === 191 /* ElementAccessExpression */ &&
            node.parent.argumentExpression === node;
    }
    /**
     * Get the path of the default library files (lib.d.ts) as distributed with the typescript
     * node package.
     * The functionality is not supported if the ts module is consumed outside of a node module.
     */
    function getDefaultLibFilePath(options) {
        // Check __dirname is defined and that we are on a node.js system.
        if (typeof __dirname !== "undefined") {
            return __dirname + ts.directorySeparator + ts.getDefaultLibFileName(options);
        }
        throw new Error("getDefaultLibFilePath is only supported when consumed as a node module. ");
    }
    ts.getDefaultLibFilePath = getDefaultLibFilePath;
    ts.objectAllocator = getServicesObjectAllocator();
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var BreakpointResolver;
    (function (BreakpointResolver) {
        /**
         * Get the breakpoint span in given sourceFile
         */
        function spanInSourceFileAtLocation(sourceFile, position) {
            // Cannot set breakpoint in dts file
            if (sourceFile.isDeclarationFile) {
                return undefined;
            }
            var tokenAtLocation = ts.getTokenAtPosition(sourceFile, position);
            var lineOfPosition = sourceFile.getLineAndCharacterOfPosition(position).line;
            if (sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getStart(sourceFile)).line > lineOfPosition) {
                // Get previous token if the token is returned starts on new line
                // eg: let x =10; |--- cursor is here
                //     let y = 10;
                // token at position will return let keyword on second line as the token but we would like to use
                // token on same line if trailing trivia (comments or white spaces on same line) part of the last token on that line
                var preceding = ts.findPrecedingToken(tokenAtLocation.pos, sourceFile);
                // It's a blank line
                if (!preceding || sourceFile.getLineAndCharacterOfPosition(preceding.getEnd()).line !== lineOfPosition) {
                    return undefined;
                }
                tokenAtLocation = preceding;
            }
            // Cannot set breakpoint in ambient declarations
            if (tokenAtLocation.flags & 4194304 /* Ambient */) {
                return undefined;
            }
            // Get the span in the node based on its syntax
            return spanInNode(tokenAtLocation);
            function textSpan(startNode, endNode) {
                var start = startNode.decorators ?
                    ts.skipTrivia(sourceFile.text, startNode.decorators.end) :
                    startNode.getStart(sourceFile);
                return ts.createTextSpanFromBounds(start, (endNode || startNode).getEnd());
            }
            function textSpanEndingAtNextToken(startNode, previousTokenToFindNextEndToken) {
                return textSpan(startNode, ts.findNextToken(previousTokenToFindNextEndToken, previousTokenToFindNextEndToken.parent, sourceFile));
            }
            function spanInNodeIfStartsOnSameLine(node, otherwiseOnNode) {
                if (node && lineOfPosition === sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line) {
                    return spanInNode(node);
                }
                return spanInNode(otherwiseOnNode);
            }
            function spanInNodeArray(nodeArray) {
                return ts.createTextSpanFromBounds(ts.skipTrivia(sourceFile.text, nodeArray.pos), nodeArray.end);
            }
            function spanInPreviousNode(node) {
                return spanInNode(ts.findPrecedingToken(node.pos, sourceFile));
            }
            function spanInNextNode(node) {
                return spanInNode(ts.findNextToken(node, node.parent, sourceFile));
            }
            function spanInNode(node) {
                if (node) {
                    var parent = node.parent;
                    switch (node.kind) {
                        case 220 /* VariableStatement */:
                            // Span on first variable declaration
                            return spanInVariableDeclaration(node.declarationList.declarations[0]);
                        case 238 /* VariableDeclaration */:
                        case 155 /* PropertyDeclaration */:
                        case 154 /* PropertySignature */:
                            return spanInVariableDeclaration(node);
                        case 152 /* Parameter */:
                            return spanInParameterDeclaration(node);
                        case 240 /* FunctionDeclaration */:
                        case 157 /* MethodDeclaration */:
                        case 156 /* MethodSignature */:
                        case 159 /* GetAccessor */:
                        case 160 /* SetAccessor */:
                        case 158 /* Constructor */:
                        case 197 /* FunctionExpression */:
                        case 198 /* ArrowFunction */:
                            return spanInFunctionDeclaration(node);
                        case 219 /* Block */:
                            if (ts.isFunctionBlock(node)) {
                                return spanInFunctionBlock(node);
                            }
                        // falls through
                        case 246 /* ModuleBlock */:
                            return spanInBlock(node);
                        case 275 /* CatchClause */:
                            return spanInBlock(node.block);
                        case 222 /* ExpressionStatement */:
                            // span on the expression
                            return textSpan(node.expression);
                        case 231 /* ReturnStatement */:
                            // span on return keyword and expression if present
                            return textSpan(node.getChildAt(0), node.expression);
                        case 225 /* WhileStatement */:
                            // Span on while(...)
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 224 /* DoStatement */:
                            // span in statement of the do statement
                            return spanInNode(node.statement);
                        case 237 /* DebuggerStatement */:
                            // span on debugger keyword
                            return textSpan(node.getChildAt(0));
                        case 223 /* IfStatement */:
                            // set on if(..) span
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 234 /* LabeledStatement */:
                            // span in statement
                            return spanInNode(node.statement);
                        case 230 /* BreakStatement */:
                        case 229 /* ContinueStatement */:
                            // On break or continue keyword and label if present
                            return textSpan(node.getChildAt(0), node.label);
                        case 226 /* ForStatement */:
                            return spanInForStatement(node);
                        case 227 /* ForInStatement */:
                            // span of for (a in ...)
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 228 /* ForOfStatement */:
                            // span in initializer
                            return spanInInitializerOfForLike(node);
                        case 233 /* SwitchStatement */:
                            // span on switch(...)
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 272 /* CaseClause */:
                        case 273 /* DefaultClause */:
                            // span in first statement of the clause
                            return spanInNode(node.statements[0]);
                        case 236 /* TryStatement */:
                            // span in try block
                            return spanInBlock(node.tryBlock);
                        case 235 /* ThrowStatement */:
                            // span in throw ...
                            return textSpan(node, node.expression);
                        case 255 /* ExportAssignment */:
                            // span on export = id
                            return textSpan(node, node.expression);
                        case 249 /* ImportEqualsDeclaration */:
                            // import statement without including semicolon
                            return textSpan(node, node.moduleReference);
                        case 250 /* ImportDeclaration */:
                            // import statement without including semicolon
                            return textSpan(node, node.moduleSpecifier);
                        case 256 /* ExportDeclaration */:
                            // import statement without including semicolon
                            return textSpan(node, node.moduleSpecifier);
                        case 245 /* ModuleDeclaration */:
                            // span on complete module if it is instantiated
                            if (ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
                                return undefined;
                            }
                        // falls through
                        case 241 /* ClassDeclaration */:
                        case 244 /* EnumDeclaration */:
                        case 279 /* EnumMember */:
                        case 187 /* BindingElement */:
                            // span on complete node
                            return textSpan(node);
                        case 232 /* WithStatement */:
                            // span in statement
                            return spanInNode(node.statement);
                        case 153 /* Decorator */:
                            return spanInNodeArray(parent.decorators);
                        case 185 /* ObjectBindingPattern */:
                        case 186 /* ArrayBindingPattern */:
                            return spanInBindingPattern(node);
                        // No breakpoint in interface, type alias
                        case 242 /* InterfaceDeclaration */:
                        case 243 /* TypeAliasDeclaration */:
                            return undefined;
                        // Tokens:
                        case 26 /* SemicolonToken */:
                        case 1 /* EndOfFileToken */:
                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile));
                        case 27 /* CommaToken */:
                            return spanInPreviousNode(node);
                        case 18 /* OpenBraceToken */:
                            return spanInOpenBraceToken(node);
                        case 19 /* CloseBraceToken */:
                            return spanInCloseBraceToken(node);
                        case 23 /* CloseBracketToken */:
                            return spanInCloseBracketToken(node);
                        case 20 /* OpenParenToken */:
                            return spanInOpenParenToken(node);
                        case 21 /* CloseParenToken */:
                            return spanInCloseParenToken(node);
                        case 57 /* ColonToken */:
                            return spanInColonToken(node);
                        case 30 /* GreaterThanToken */:
                        case 28 /* LessThanToken */:
                            return spanInGreaterThanOrLessThanToken(node);
                        // Keywords:
                        case 108 /* WhileKeyword */:
                            return spanInWhileKeyword(node);
                        case 84 /* ElseKeyword */:
                        case 76 /* CatchKeyword */:
                        case 89 /* FinallyKeyword */:
                            return spanInNextNode(node);
                        case 148 /* OfKeyword */:
                            return spanInOfKeyword(node);
                        default:
                            // Destructuring pattern in destructuring assignment
                            // [a, b, c] of
                            // [a, b, c] = expression
                            if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node)) {
                                return spanInArrayLiteralOrObjectLiteralDestructuringPattern(node);
                            }
                            // Set breakpoint on identifier element of destructuring pattern
                            // `a` or `...c` or `d: x` from
                            // `[a, b, ...c]` or `{ a, b }` or `{ d: x }` from destructuring pattern
                            if ((node.kind === 73 /* Identifier */ ||
                                node.kind === 209 /* SpreadElement */ ||
                                node.kind === 276 /* PropertyAssignment */ ||
                                node.kind === 277 /* ShorthandPropertyAssignment */) &&
                                ts.isArrayLiteralOrObjectLiteralDestructuringPattern(parent)) {
                                return textSpan(node);
                            }
                            if (node.kind === 205 /* BinaryExpression */) {
                                var _a = node, left = _a.left, operatorToken = _a.operatorToken;
                                // Set breakpoint in destructuring pattern if its destructuring assignment
                                // [a, b, c] or {a, b, c} of
                                // [a, b, c] = expression or
                                // {a, b, c} = expression
                                if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(left)) {
                                    return spanInArrayLiteralOrObjectLiteralDestructuringPattern(left);
                                }
                                if (operatorToken.kind === 60 /* EqualsToken */ && ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
                                    // Set breakpoint on assignment expression element of destructuring pattern
                                    // a = expression of
                                    // [a = expression, b, c] = someExpression or
                                    // { a = expression, b, c } = someExpression
                                    return textSpan(node);
                                }
                                if (operatorToken.kind === 27 /* CommaToken */) {
                                    return spanInNode(left);
                                }
                            }
                            if (ts.isExpressionNode(node)) {
                                switch (parent.kind) {
                                    case 224 /* DoStatement */:
                                        // Set span as if on while keyword
                                        return spanInPreviousNode(node);
                                    case 153 /* Decorator */:
                                        // Set breakpoint on the decorator emit
                                        return spanInNode(node.parent);
                                    case 226 /* ForStatement */:
                                    case 228 /* ForOfStatement */:
                                        return textSpan(node);
                                    case 205 /* BinaryExpression */:
                                        if (node.parent.operatorToken.kind === 27 /* CommaToken */) {
                                            // If this is a comma expression, the breakpoint is possible in this expression
                                            return textSpan(node);
                                        }
                                        break;
                                    case 198 /* ArrowFunction */:
                                        if (node.parent.body === node) {
                                            // If this is body of arrow function, it is allowed to have the breakpoint
                                            return textSpan(node);
                                        }
                                        break;
                                }
                            }
                            switch (node.parent.kind) {
                                case 276 /* PropertyAssignment */:
                                    // If this is name of property assignment, set breakpoint in the initializer
                                    if (node.parent.name === node &&
                                        !ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent.parent)) {
                                        return spanInNode(node.parent.initializer);
                                    }
                                    break;
                                case 195 /* TypeAssertionExpression */:
                                    // Breakpoint in type assertion goes to its operand
                                    if (node.parent.type === node) {
                                        return spanInNextNode(node.parent.type);
                                    }
                                    break;
                                case 238 /* VariableDeclaration */:
                                case 152 /* Parameter */: {
                                    // initializer of variable/parameter declaration go to previous node
                                    var _b = node.parent, initializer = _b.initializer, type = _b.type;
                                    if (initializer === node || type === node || ts.isAssignmentOperator(node.kind)) {
                                        return spanInPreviousNode(node);
                                    }
                                    break;
                                }
                                case 205 /* BinaryExpression */: {
                                    var left = node.parent.left;
                                    if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(left) && node !== left) {
                                        // If initializer of destructuring assignment move to previous token
                                        return spanInPreviousNode(node);
                                    }
                                    break;
                                }
                                default:
                                    // return type of function go to previous token
                                    if (ts.isFunctionLike(node.parent) && node.parent.type === node) {
                                        return spanInPreviousNode(node);
                                    }
                            }
                            // Default go to parent to set the breakpoint
                            return spanInNode(node.parent);
                    }
                }
                function textSpanFromVariableDeclaration(variableDeclaration) {
                    if (ts.isVariableDeclarationList(variableDeclaration.parent) && variableDeclaration.parent.declarations[0] === variableDeclaration) {
                        // First declaration - include let keyword
                        return textSpan(ts.findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent), variableDeclaration);
                    }
                    else {
                        // Span only on this declaration
                        return textSpan(variableDeclaration);
                    }
                }
                function spanInVariableDeclaration(variableDeclaration) {
                    // If declaration of for in statement, just set the span in parent
                    if (variableDeclaration.parent.parent.kind === 227 /* ForInStatement */) {
                        return spanInNode(variableDeclaration.parent.parent);
                    }
                    var parent = variableDeclaration.parent;
                    // If this is a destructuring pattern, set breakpoint in binding pattern
                    if (ts.isBindingPattern(variableDeclaration.name)) {
                        return spanInBindingPattern(variableDeclaration.name);
                    }
                    // Breakpoint is possible in variableDeclaration only if there is initialization
                    // or its declaration from 'for of'
                    if (variableDeclaration.initializer ||
                        ts.hasModifier(variableDeclaration, 1 /* Export */) ||
                        parent.parent.kind === 228 /* ForOfStatement */) {
                        return textSpanFromVariableDeclaration(variableDeclaration);
                    }
                    if (ts.isVariableDeclarationList(variableDeclaration.parent) &&
                        variableDeclaration.parent.declarations[0] !== variableDeclaration) {
                        // If we cannot set breakpoint on this declaration, set it on previous one
                        // Because the variable declaration may be binding pattern and
                        // we would like to set breakpoint in last binding element if that's the case,
                        // use preceding token instead
                        return spanInNode(ts.findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent));
                    }
                }
                function canHaveSpanInParameterDeclaration(parameter) {
                    // Breakpoint is possible on parameter only if it has initializer, is a rest parameter, or has public or private modifier
                    return !!parameter.initializer || parameter.dotDotDotToken !== undefined ||
                        ts.hasModifier(parameter, 4 /* Public */ | 8 /* Private */);
                }
                function spanInParameterDeclaration(parameter) {
                    if (ts.isBindingPattern(parameter.name)) {
                        // Set breakpoint in binding pattern
                        return spanInBindingPattern(parameter.name);
                    }
                    else if (canHaveSpanInParameterDeclaration(parameter)) {
                        return textSpan(parameter);
                    }
                    else {
                        var functionDeclaration = parameter.parent;
                        var indexOfParameter = functionDeclaration.parameters.indexOf(parameter);
                        ts.Debug.assert(indexOfParameter !== -1);
                        if (indexOfParameter !== 0) {
                            // Not a first parameter, go to previous parameter
                            return spanInParameterDeclaration(functionDeclaration.parameters[indexOfParameter - 1]);
                        }
                        else {
                            // Set breakpoint in the function declaration body
                            return spanInNode(functionDeclaration.body);
                        }
                    }
                }
                function canFunctionHaveSpanInWholeDeclaration(functionDeclaration) {
                    return ts.hasModifier(functionDeclaration, 1 /* Export */) ||
                        (functionDeclaration.parent.kind === 241 /* ClassDeclaration */ && functionDeclaration.kind !== 158 /* Constructor */);
                }
                function spanInFunctionDeclaration(functionDeclaration) {
                    // No breakpoints in the function signature
                    if (!functionDeclaration.body) {
                        return undefined;
                    }
                    if (canFunctionHaveSpanInWholeDeclaration(functionDeclaration)) {
                        // Set the span on whole function declaration
                        return textSpan(functionDeclaration);
                    }
                    // Set span in function body
                    return spanInNode(functionDeclaration.body);
                }
                function spanInFunctionBlock(block) {
                    var nodeForSpanInBlock = block.statements.length ? block.statements[0] : block.getLastToken();
                    if (canFunctionHaveSpanInWholeDeclaration(block.parent)) {
                        return spanInNodeIfStartsOnSameLine(block.parent, nodeForSpanInBlock);
                    }
                    return spanInNode(nodeForSpanInBlock);
                }
                function spanInBlock(block) {
                    switch (block.parent.kind) {
                        case 245 /* ModuleDeclaration */:
                            if (ts.getModuleInstanceState(block.parent) !== 1 /* Instantiated */) {
                                return undefined;
                            }
                        // falls through
                        // Set on parent if on same line otherwise on first statement
                        case 225 /* WhileStatement */:
                        case 223 /* IfStatement */:
                        case 227 /* ForInStatement */:
                            return spanInNodeIfStartsOnSameLine(block.parent, block.statements[0]);
                        // Set span on previous token if it starts on same line otherwise on the first statement of the block
                        case 226 /* ForStatement */:
                        case 228 /* ForOfStatement */:
                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(block.pos, sourceFile, block.parent), block.statements[0]);
                    }
                    // Default action is to set on first statement
                    return spanInNode(block.statements[0]);
                }
                function spanInInitializerOfForLike(forLikeStatement) {
                    if (forLikeStatement.initializer.kind === 239 /* VariableDeclarationList */) {
                        // Declaration list - set breakpoint in first declaration
                        var variableDeclarationList = forLikeStatement.initializer;
                        if (variableDeclarationList.declarations.length > 0) {
                            return spanInNode(variableDeclarationList.declarations[0]);
                        }
                    }
                    else {
                        // Expression - set breakpoint in it
                        return spanInNode(forLikeStatement.initializer);
                    }
                }
                function spanInForStatement(forStatement) {
                    if (forStatement.initializer) {
                        return spanInInitializerOfForLike(forStatement);
                    }
                    if (forStatement.condition) {
                        return textSpan(forStatement.condition);
                    }
                    if (forStatement.incrementor) {
                        return textSpan(forStatement.incrementor);
                    }
                }
                function spanInBindingPattern(bindingPattern) {
                    // Set breakpoint in first binding element
                    var firstBindingElement = ts.forEach(bindingPattern.elements, function (element) { return element.kind !== 211 /* OmittedExpression */ ? element : undefined; });
                    if (firstBindingElement) {
                        return spanInNode(firstBindingElement);
                    }
                    // Empty binding pattern of binding element, set breakpoint on binding element
                    if (bindingPattern.parent.kind === 187 /* BindingElement */) {
                        return textSpan(bindingPattern.parent);
                    }
                    // Variable declaration is used as the span
                    return textSpanFromVariableDeclaration(bindingPattern.parent);
                }
                function spanInArrayLiteralOrObjectLiteralDestructuringPattern(node) {
                    ts.Debug.assert(node.kind !== 186 /* ArrayBindingPattern */ && node.kind !== 185 /* ObjectBindingPattern */);
                    var elements = node.kind === 188 /* ArrayLiteralExpression */ ? node.elements : node.properties;
                    var firstBindingElement = ts.forEach(elements, function (element) { return element.kind !== 211 /* OmittedExpression */ ? element : undefined; });
                    if (firstBindingElement) {
                        return spanInNode(firstBindingElement);
                    }
                    // Could be ArrayLiteral from destructuring assignment or
                    // just nested element in another destructuring assignment
                    // set breakpoint on assignment when parent is destructuring assignment
                    // Otherwise set breakpoint for this element
                    return textSpan(node.parent.kind === 205 /* BinaryExpression */ ? node.parent : node);
                }
                // Tokens:
                function spanInOpenBraceToken(node) {
                    switch (node.parent.kind) {
                        case 244 /* EnumDeclaration */:
                            var enumDeclaration = node.parent;
                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile, node.parent), enumDeclaration.members.length ? enumDeclaration.members[0] : enumDeclaration.getLastToken(sourceFile));
                        case 241 /* ClassDeclaration */:
                            var classDeclaration = node.parent;
                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile, node.parent), classDeclaration.members.length ? classDeclaration.members[0] : classDeclaration.getLastToken(sourceFile));
                        case 247 /* CaseBlock */:
                            return spanInNodeIfStartsOnSameLine(node.parent.parent, node.parent.clauses[0]);
                    }
                    // Default to parent node
                    return spanInNode(node.parent);
                }
                function spanInCloseBraceToken(node) {
                    switch (node.parent.kind) {
                        case 246 /* ModuleBlock */:
                            // If this is not an instantiated module block, no bp span
                            if (ts.getModuleInstanceState(node.parent.parent) !== 1 /* Instantiated */) {
                                return undefined;
                            }
                        // falls through
                        case 244 /* EnumDeclaration */:
                        case 241 /* ClassDeclaration */:
                            // Span on close brace token
                            return textSpan(node);
                        case 219 /* Block */:
                            if (ts.isFunctionBlock(node.parent)) {
                                // Span on close brace token
                                return textSpan(node);
                            }
                        // falls through
                        case 275 /* CatchClause */:
                            return spanInNode(ts.lastOrUndefined(node.parent.statements));
                        case 247 /* CaseBlock */:
                            // breakpoint in last statement of the last clause
                            var caseBlock = node.parent;
                            var lastClause = ts.lastOrUndefined(caseBlock.clauses);
                            if (lastClause) {
                                return spanInNode(ts.lastOrUndefined(lastClause.statements));
                            }
                            return undefined;
                        case 185 /* ObjectBindingPattern */:
                            // Breakpoint in last binding element or binding pattern if it contains no elements
                            var bindingPattern = node.parent;
                            return spanInNode(ts.lastOrUndefined(bindingPattern.elements) || bindingPattern);
                        // Default to parent node
                        default:
                            if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
                                // Breakpoint in last binding element or binding pattern if it contains no elements
                                var objectLiteral = node.parent;
                                return textSpan(ts.lastOrUndefined(objectLiteral.properties) || objectLiteral);
                            }
                            return spanInNode(node.parent);
                    }
                }
                function spanInCloseBracketToken(node) {
                    switch (node.parent.kind) {
                        case 186 /* ArrayBindingPattern */:
                            // Breakpoint in last binding element or binding pattern if it contains no elements
                            var bindingPattern = node.parent;
                            return textSpan(ts.lastOrUndefined(bindingPattern.elements) || bindingPattern);
                        default:
                            if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
                                // Breakpoint in last binding element or binding pattern if it contains no elements
                                var arrayLiteral = node.parent;
                                return textSpan(ts.lastOrUndefined(arrayLiteral.elements) || arrayLiteral);
                            }
                            // Default to parent node
                            return spanInNode(node.parent);
                    }
                }
                function spanInOpenParenToken(node) {
                    if (node.parent.kind === 224 /* DoStatement */ || // Go to while keyword and do action instead
                        node.parent.kind === 192 /* CallExpression */ ||
                        node.parent.kind === 193 /* NewExpression */) {
                        return spanInPreviousNode(node);
                    }
                    if (node.parent.kind === 196 /* ParenthesizedExpression */) {
                        return spanInNextNode(node);
                    }
                    // Default to parent node
                    return spanInNode(node.parent);
                }
                function spanInCloseParenToken(node) {
                    // Is this close paren token of parameter list, set span in previous token
                    switch (node.parent.kind) {
                        case 197 /* FunctionExpression */:
                        case 240 /* FunctionDeclaration */:
                        case 198 /* ArrowFunction */:
                        case 157 /* MethodDeclaration */:
                        case 156 /* MethodSignature */:
                        case 159 /* GetAccessor */:
                        case 160 /* SetAccessor */:
                        case 158 /* Constructor */:
                        case 225 /* WhileStatement */:
                        case 224 /* DoStatement */:
                        case 226 /* ForStatement */:
                        case 228 /* ForOfStatement */:
                        case 192 /* CallExpression */:
                        case 193 /* NewExpression */:
                        case 196 /* ParenthesizedExpression */:
                            return spanInPreviousNode(node);
                        // Default to parent node
                        default:
                            return spanInNode(node.parent);
                    }
                }
                function spanInColonToken(node) {
                    // Is this : specifying return annotation of the function declaration
                    if (ts.isFunctionLike(node.parent) ||
                        node.parent.kind === 276 /* PropertyAssignment */ ||
                        node.parent.kind === 152 /* Parameter */) {
                        return spanInPreviousNode(node);
                    }
                    return spanInNode(node.parent);
                }
                function spanInGreaterThanOrLessThanToken(node) {
                    if (node.parent.kind === 195 /* TypeAssertionExpression */) {
                        return spanInNextNode(node);
                    }
                    return spanInNode(node.parent);
                }
                function spanInWhileKeyword(node) {
                    if (node.parent.kind === 224 /* DoStatement */) {
                        // Set span on while expression
                        return textSpanEndingAtNextToken(node, node.parent.expression);
                    }
                    // Default to parent node
                    return spanInNode(node.parent);
                }
                function spanInOfKeyword(node) {
                    if (node.parent.kind === 228 /* ForOfStatement */) {
                        // Set using next token
                        return spanInNextNode(node);
                    }
                    // Default to parent node
                    return spanInNode(node.parent);
                }
            }
        }
        BreakpointResolver.spanInSourceFileAtLocation = spanInSourceFileAtLocation;
    })(BreakpointResolver = ts.BreakpointResolver || (ts.BreakpointResolver = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    /**
     * Transform one or more nodes using the supplied transformers.
     * @param source A single `Node` or an array of `Node` objects.
     * @param transformers An array of `TransformerFactory` callbacks used to process the transformation.
     * @param compilerOptions Optional compiler options.
     */
    function transform(source, transformers, compilerOptions) {
        var diagnostics = [];
        compilerOptions = ts.fixupCompilerOptions(compilerOptions, diagnostics); // TODO: GH#18217
        var nodes = ts.isArray(source) ? source : [source];
        var result = ts.transformNodes(/*resolver*/ undefined, /*emitHost*/ undefined, compilerOptions, nodes, transformers, /*allowDtsFiles*/ true);
        result.diagnostics = ts.concatenate(result.diagnostics, diagnostics);
        return result;
    }
    ts.transform = transform;
})(ts || (ts = {}));
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/* @internal */
var debugObjectHost = (function () { return this; })();
// We need to use 'null' to interface with the managed side.
/* tslint:disable:no-null-keyword */
/* tslint:disable:no-in-operator */
/* @internal */
var ts;
(function (ts) {
    function logInternalError(logger, err) {
        if (logger) {
            logger.log("*INTERNAL ERROR* - Exception in typescript services: " + err.message);
        }
    }
    var ScriptSnapshotShimAdapter = /** @class */ (function () {
        function ScriptSnapshotShimAdapter(scriptSnapshotShim) {
            this.scriptSnapshotShim = scriptSnapshotShim;
        }
        ScriptSnapshotShimAdapter.prototype.getText = function (start, end) {
            return this.scriptSnapshotShim.getText(start, end);
        };
        ScriptSnapshotShimAdapter.prototype.getLength = function () {
            return this.scriptSnapshotShim.getLength();
        };
        ScriptSnapshotShimAdapter.prototype.getChangeRange = function (oldSnapshot) {
            var oldSnapshotShim = oldSnapshot;
            var encoded = this.scriptSnapshotShim.getChangeRange(oldSnapshotShim.scriptSnapshotShim);
            if (encoded === null) {
                return null; // TODO: GH#18217
            }
            var decoded = JSON.parse(encoded); // TODO: GH#18217
            return ts.createTextChangeRange(ts.createTextSpan(decoded.span.start, decoded.span.length), decoded.newLength);
        };
        ScriptSnapshotShimAdapter.prototype.dispose = function () {
            // if scriptSnapshotShim is a COM object then property check becomes method call with no arguments
            // 'in' does not have this effect
            if ("dispose" in this.scriptSnapshotShim) {
                this.scriptSnapshotShim.dispose(); // TODO: GH#18217 Can we just use `if (this.scriptSnapshotShim.dispose)`?
            }
        };
        return ScriptSnapshotShimAdapter;
    }());
    var LanguageServiceShimHostAdapter = /** @class */ (function () {
        function LanguageServiceShimHostAdapter(shimHost) {
            var _this = this;
            this.shimHost = shimHost;
            this.loggingEnabled = false;
            this.tracingEnabled = false;
            // if shimHost is a COM object then property check will become method call with no arguments.
            // 'in' does not have this effect.
            if ("getModuleResolutionsForFile" in this.shimHost) {
                this.resolveModuleNames = function (moduleNames, containingFile) {
                    var resolutionsInFile = JSON.parse(_this.shimHost.getModuleResolutionsForFile(containingFile)); // TODO: GH#18217
                    return ts.map(moduleNames, function (name) {
                        var result = ts.getProperty(resolutionsInFile, name);
                        return result ? { resolvedFileName: result, extension: ts.extensionFromPath(result), isExternalLibraryImport: false } : undefined;
                    });
                };
            }
            if ("directoryExists" in this.shimHost) {
                this.directoryExists = function (directoryName) { return _this.shimHost.directoryExists(directoryName); };
            }
            if ("getTypeReferenceDirectiveResolutionsForFile" in this.shimHost) {
                this.resolveTypeReferenceDirectives = function (typeDirectiveNames, containingFile) {
                    var typeDirectivesForFile = JSON.parse(_this.shimHost.getTypeReferenceDirectiveResolutionsForFile(containingFile)); // TODO: GH#18217
                    return ts.map(typeDirectiveNames, function (name) { return ts.getProperty(typeDirectivesForFile, name); });
                };
            }
        }
        LanguageServiceShimHostAdapter.prototype.log = function (s) {
            if (this.loggingEnabled) {
                this.shimHost.log(s);
            }
        };
        LanguageServiceShimHostAdapter.prototype.trace = function (s) {
            if (this.tracingEnabled) {
                this.shimHost.trace(s);
            }
        };
        LanguageServiceShimHostAdapter.prototype.error = function (s) {
            this.shimHost.error(s);
        };
        LanguageServiceShimHostAdapter.prototype.getProjectVersion = function () {
            if (!this.shimHost.getProjectVersion) {
                // shimmed host does not support getProjectVersion
                return undefined; // TODO: GH#18217
            }
            return this.shimHost.getProjectVersion();
        };
        LanguageServiceShimHostAdapter.prototype.getTypeRootsVersion = function () {
            if (!this.shimHost.getTypeRootsVersion) {
                return 0;
            }
            return this.shimHost.getTypeRootsVersion();
        };
        LanguageServiceShimHostAdapter.prototype.useCaseSensitiveFileNames = function () {
            return this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false;
        };
        LanguageServiceShimHostAdapter.prototype.getCompilationSettings = function () {
            var settingsJson = this.shimHost.getCompilationSettings();
            if (settingsJson === null || settingsJson === "") {
                throw Error("LanguageServiceShimHostAdapter.getCompilationSettings: empty compilationSettings");
            }
            var compilerOptions = JSON.parse(settingsJson);
            // permit language service to handle all files (filtering should be performed on the host side)
            compilerOptions.allowNonTsExtensions = true;
            return compilerOptions;
        };
        LanguageServiceShimHostAdapter.prototype.getScriptFileNames = function () {
            var encoded = this.shimHost.getScriptFileNames();
            return JSON.parse(encoded);
        };
        LanguageServiceShimHostAdapter.prototype.getScriptSnapshot = function (fileName) {
            var scriptSnapshot = this.shimHost.getScriptSnapshot(fileName);
            return scriptSnapshot && new ScriptSnapshotShimAdapter(scriptSnapshot);
        };
        LanguageServiceShimHostAdapter.prototype.getScriptKind = function (fileName) {
            if ("getScriptKind" in this.shimHost) {
                return this.shimHost.getScriptKind(fileName); // TODO: GH#18217
            }
            else {
                return 0 /* Unknown */;
            }
        };
        LanguageServiceShimHostAdapter.prototype.getScriptVersion = function (fileName) {
            return this.shimHost.getScriptVersion(fileName);
        };
        LanguageServiceShimHostAdapter.prototype.getLocalizedDiagnosticMessages = function () {
            var diagnosticMessagesJson = this.shimHost.getLocalizedDiagnosticMessages();
            if (diagnosticMessagesJson === null || diagnosticMessagesJson === "") {
                return null;
            }
            try {
                return JSON.parse(diagnosticMessagesJson);
            }
            catch (e) {
                this.log(e.description || "diagnosticMessages.generated.json has invalid JSON format");
                return null;
            }
        };
        LanguageServiceShimHostAdapter.prototype.getCancellationToken = function () {
            var hostCancellationToken = this.shimHost.getCancellationToken();
            return new ts.ThrottledCancellationToken(hostCancellationToken);
        };
        LanguageServiceShimHostAdapter.prototype.getCurrentDirectory = function () {
            return this.shimHost.getCurrentDirectory();
        };
        LanguageServiceShimHostAdapter.prototype.getDirectories = function (path) {
            return JSON.parse(this.shimHost.getDirectories(path));
        };
        LanguageServiceShimHostAdapter.prototype.getDefaultLibFileName = function (options) {
            return this.shimHost.getDefaultLibFileName(JSON.stringify(options));
        };
        LanguageServiceShimHostAdapter.prototype.readDirectory = function (path, extensions, exclude, include, depth) {
            var pattern = ts.getFileMatcherPatterns(path, exclude, include, this.shimHost.useCaseSensitiveFileNames(), this.shimHost.getCurrentDirectory()); // TODO: GH#18217
            return JSON.parse(this.shimHost.readDirectory(path, JSON.stringify(extensions), JSON.stringify(pattern.basePaths), pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern, depth));
        };
        LanguageServiceShimHostAdapter.prototype.readFile = function (path, encoding) {
            return this.shimHost.readFile(path, encoding);
        };
        LanguageServiceShimHostAdapter.prototype.fileExists = function (path) {
            return this.shimHost.fileExists(path);
        };
        return LanguageServiceShimHostAdapter;
    }());
    ts.LanguageServiceShimHostAdapter = LanguageServiceShimHostAdapter;
    var CoreServicesShimHostAdapter = /** @class */ (function () {
        function CoreServicesShimHostAdapter(shimHost) {
            var _this = this;
            this.shimHost = shimHost;
            this.useCaseSensitiveFileNames = this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false;
            if ("directoryExists" in this.shimHost) {
                this.directoryExists = function (directoryName) { return _this.shimHost.directoryExists(directoryName); };
            }
            else {
                this.directoryExists = undefined; // TODO: GH#18217
            }
            if ("realpath" in this.shimHost) {
                this.realpath = function (path) { return _this.shimHost.realpath(path); }; // TODO: GH#18217
            }
            else {
                this.realpath = undefined; // TODO: GH#18217
            }
        }
        CoreServicesShimHostAdapter.prototype.readDirectory = function (rootDir, extensions, exclude, include, depth) {
            var pattern = ts.getFileMatcherPatterns(rootDir, exclude, include, this.shimHost.useCaseSensitiveFileNames(), this.shimHost.getCurrentDirectory()); // TODO: GH#18217
            return JSON.parse(this.shimHost.readDirectory(rootDir, JSON.stringify(extensions), JSON.stringify(pattern.basePaths), pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern, depth));
        };
        CoreServicesShimHostAdapter.prototype.fileExists = function (fileName) {
            return this.shimHost.fileExists(fileName);
        };
        CoreServicesShimHostAdapter.prototype.readFile = function (fileName) {
            return this.shimHost.readFile(fileName);
        };
        CoreServicesShimHostAdapter.prototype.getDirectories = function (path) {
            return JSON.parse(this.shimHost.getDirectories(path));
        };
        return CoreServicesShimHostAdapter;
    }());
    ts.CoreServicesShimHostAdapter = CoreServicesShimHostAdapter;
    function simpleForwardCall(logger, actionDescription, action, logPerformance) {
        var start;
        if (logPerformance) {
            logger.log(actionDescription);
            start = ts.timestamp();
        }
        var result = action();
        if (logPerformance) {
            var end = ts.timestamp();
            logger.log(actionDescription + " completed in " + (end - start) + " msec");
            if (ts.isString(result)) {
                var str = result;
                if (str.length > 128) {
                    str = str.substring(0, 128) + "...";
                }
                logger.log("  result.length=" + str.length + ", result='" + JSON.stringify(str) + "'");
            }
        }
        return result;
    }
    function forwardJSONCall(logger, actionDescription, action, logPerformance) {
        return forwardCall(logger, actionDescription, /*returnJson*/ true, action, logPerformance);
    }
    function forwardCall(logger, actionDescription, returnJson, action, logPerformance) {
        try {
            var result = simpleForwardCall(logger, actionDescription, action, logPerformance);
            return returnJson ? JSON.stringify({ result: result }) : result;
        }
        catch (err) {
            if (err instanceof ts.OperationCanceledException) {
                return JSON.stringify({ canceled: true });
            }
            logInternalError(logger, err);
            err.description = actionDescription;
            return JSON.stringify({ error: err });
        }
    }
    var ShimBase = /** @class */ (function () {
        function ShimBase(factory) {
            this.factory = factory;
            factory.registerShim(this);
        }
        ShimBase.prototype.dispose = function (_dummy) {
            this.factory.unregisterShim(this);
        };
        return ShimBase;
    }());
    function realizeDiagnostics(diagnostics, newLine) {
        return diagnostics.map(function (d) { return realizeDiagnostic(d, newLine); });
    }
    ts.realizeDiagnostics = realizeDiagnostics;
    function realizeDiagnostic(diagnostic, newLine) {
        return {
            message: ts.flattenDiagnosticMessageText(diagnostic.messageText, newLine),
            start: diagnostic.start,
            length: diagnostic.length,
            category: ts.diagnosticCategoryName(diagnostic),
            code: diagnostic.code,
            reportsUnnecessary: diagnostic.reportsUnnecessary,
        };
    }
    var LanguageServiceShimObject = /** @class */ (function (_super) {
        __extends(LanguageServiceShimObject, _super);
        function LanguageServiceShimObject(factory, host, languageService) {
            var _this = _super.call(this, factory) || this;
            _this.host = host;
            _this.languageService = languageService;
            _this.logPerformance = false;
            _this.logger = _this.host;
            return _this;
        }
        LanguageServiceShimObject.prototype.forwardJSONCall = function (actionDescription, action) {
            return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance);
        };
        /// DISPOSE
        /**
         * Ensure (almost) deterministic release of internal Javascript resources when
         * some external native objects holds onto us (e.g. Com/Interop).
         */
        LanguageServiceShimObject.prototype.dispose = function (dummy) {
            this.logger.log("dispose()");
            this.languageService.dispose();
            this.languageService = null;
            // force a GC
            if (debugObjectHost && debugObjectHost.CollectGarbage) {
                debugObjectHost.CollectGarbage();
                this.logger.log("CollectGarbage()");
            }
            this.logger = null;
            _super.prototype.dispose.call(this, dummy);
        };
        /// REFRESH
        /**
         * Update the list of scripts known to the compiler
         */
        LanguageServiceShimObject.prototype.refresh = function (throwOnError) {
            this.forwardJSONCall("refresh(" + throwOnError + ")", function () { return null; });
        };
        LanguageServiceShimObject.prototype.cleanupSemanticCache = function () {
            var _this = this;
            this.forwardJSONCall("cleanupSemanticCache()", function () {
                _this.languageService.cleanupSemanticCache();
                return null;
            });
        };
        LanguageServiceShimObject.prototype.realizeDiagnostics = function (diagnostics) {
            var newLine = ts.getNewLineOrDefaultFromHost(this.host);
            return realizeDiagnostics(diagnostics, newLine);
        };
        LanguageServiceShimObject.prototype.getSyntacticClassifications = function (fileName, start, length) {
            var _this = this;
            return this.forwardJSONCall("getSyntacticClassifications('" + fileName + "', " + start + ", " + length + ")", function () { return _this.languageService.getSyntacticClassifications(fileName, ts.createTextSpan(start, length)); });
        };
        LanguageServiceShimObject.prototype.getSemanticClassifications = function (fileName, start, length) {
            var _this = this;
            return this.forwardJSONCall("getSemanticClassifications('" + fileName + "', " + start + ", " + length + ")", function () { return _this.languageService.getSemanticClassifications(fileName, ts.createTextSpan(start, length)); });
        };
        LanguageServiceShimObject.prototype.getEncodedSyntacticClassifications = function (fileName, start, length) {
            var _this = this;
            return this.forwardJSONCall("getEncodedSyntacticClassifications('" + fileName + "', " + start + ", " + length + ")", 
            // directly serialize the spans out to a string.  This is much faster to decode
            // on the managed side versus a full JSON array.
            function () { return convertClassifications(_this.languageService.getEncodedSyntacticClassifications(fileName, ts.createTextSpan(start, length))); });
        };
        LanguageServiceShimObject.prototype.getEncodedSemanticClassifications = function (fileName, start, length) {
            var _this = this;
            return this.forwardJSONCall("getEncodedSemanticClassifications('" + fileName + "', " + start + ", " + length + ")", 
            // directly serialize the spans out to a string.  This is much faster to decode
            // on the managed side versus a full JSON array.
            function () { return convertClassifications(_this.languageService.getEncodedSemanticClassifications(fileName, ts.createTextSpan(start, length))); });
        };
        LanguageServiceShimObject.prototype.getSyntacticDiagnostics = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getSyntacticDiagnostics('" + fileName + "')", function () {
                var diagnostics = _this.languageService.getSyntacticDiagnostics(fileName);
                return _this.realizeDiagnostics(diagnostics);
            });
        };
        LanguageServiceShimObject.prototype.getSemanticDiagnostics = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getSemanticDiagnostics('" + fileName + "')", function () {
                var diagnostics = _this.languageService.getSemanticDiagnostics(fileName);
                return _this.realizeDiagnostics(diagnostics);
            });
        };
        LanguageServiceShimObject.prototype.getSuggestionDiagnostics = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getSuggestionDiagnostics('" + fileName + "')", function () { return _this.realizeDiagnostics(_this.languageService.getSuggestionDiagnostics(fileName)); });
        };
        LanguageServiceShimObject.prototype.getCompilerOptionsDiagnostics = function () {
            var _this = this;
            return this.forwardJSONCall("getCompilerOptionsDiagnostics()", function () {
                var diagnostics = _this.languageService.getCompilerOptionsDiagnostics();
                return _this.realizeDiagnostics(diagnostics);
            });
        };
        /// QUICKINFO
        /**
         * Computes a string representation of the type at the requested position
         * in the active file.
         */
        LanguageServiceShimObject.prototype.getQuickInfoAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getQuickInfoAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getQuickInfoAtPosition(fileName, position); });
        };
        /// NAMEORDOTTEDNAMESPAN
        /**
         * Computes span information of the name or dotted name at the requested position
         * in the active file.
         */
        LanguageServiceShimObject.prototype.getNameOrDottedNameSpan = function (fileName, startPos, endPos) {
            var _this = this;
            return this.forwardJSONCall("getNameOrDottedNameSpan('" + fileName + "', " + startPos + ", " + endPos + ")", function () { return _this.languageService.getNameOrDottedNameSpan(fileName, startPos, endPos); });
        };
        /**
         * STATEMENTSPAN
         * Computes span information of statement at the requested position in the active file.
         */
        LanguageServiceShimObject.prototype.getBreakpointStatementAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getBreakpointStatementAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getBreakpointStatementAtPosition(fileName, position); });
        };
        /// SIGNATUREHELP
        LanguageServiceShimObject.prototype.getSignatureHelpItems = function (fileName, position, options) {
            var _this = this;
            return this.forwardJSONCall("getSignatureHelpItems('" + fileName + "', " + position + ")", function () { return _this.languageService.getSignatureHelpItems(fileName, position, options); });
        };
        /// GOTO DEFINITION
        /**
         * Computes the definition location and file for the symbol
         * at the requested position.
         */
        LanguageServiceShimObject.prototype.getDefinitionAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getDefinitionAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getDefinitionAtPosition(fileName, position); });
        };
        /**
         * Computes the definition location and file for the symbol
         * at the requested position.
         */
        LanguageServiceShimObject.prototype.getDefinitionAndBoundSpan = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getDefinitionAndBoundSpan('" + fileName + "', " + position + ")", function () { return _this.languageService.getDefinitionAndBoundSpan(fileName, position); });
        };
        /// GOTO Type
        /**
         * Computes the definition location of the type of the symbol
         * at the requested position.
         */
        LanguageServiceShimObject.prototype.getTypeDefinitionAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getTypeDefinitionAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getTypeDefinitionAtPosition(fileName, position); });
        };
        /// GOTO Implementation
        /**
         * Computes the implementation location of the symbol
         * at the requested position.
         */
        LanguageServiceShimObject.prototype.getImplementationAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getImplementationAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getImplementationAtPosition(fileName, position); });
        };
        LanguageServiceShimObject.prototype.getRenameInfo = function (fileName, position, options) {
            var _this = this;
            return this.forwardJSONCall("getRenameInfo('" + fileName + "', " + position + ")", function () { return _this.languageService.getRenameInfo(fileName, position, options); });
        };
        LanguageServiceShimObject.prototype.getSmartSelectionRange = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getSmartSelectionRange('" + fileName + "', " + position + ")", function () { return _this.languageService.getSmartSelectionRange(fileName, position); });
        };
        LanguageServiceShimObject.prototype.findRenameLocations = function (fileName, position, findInStrings, findInComments, providePrefixAndSuffixTextForRename) {
            var _this = this;
            return this.forwardJSONCall("findRenameLocations('" + fileName + "', " + position + ", " + findInStrings + ", " + findInComments + ", " + providePrefixAndSuffixTextForRename + ")", function () { return _this.languageService.findRenameLocations(fileName, position, findInStrings, findInComments, providePrefixAndSuffixTextForRename); });
        };
        /// GET BRACE MATCHING
        LanguageServiceShimObject.prototype.getBraceMatchingAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getBraceMatchingAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getBraceMatchingAtPosition(fileName, position); });
        };
        LanguageServiceShimObject.prototype.isValidBraceCompletionAtPosition = function (fileName, position, openingBrace) {
            var _this = this;
            return this.forwardJSONCall("isValidBraceCompletionAtPosition('" + fileName + "', " + position + ", " + openingBrace + ")", function () { return _this.languageService.isValidBraceCompletionAtPosition(fileName, position, openingBrace); });
        };
        LanguageServiceShimObject.prototype.getSpanOfEnclosingComment = function (fileName, position, onlyMultiLine) {
            var _this = this;
            return this.forwardJSONCall("getSpanOfEnclosingComment('" + fileName + "', " + position + ")", function () { return _this.languageService.getSpanOfEnclosingComment(fileName, position, onlyMultiLine); });
        };
        /// GET SMART INDENT
        LanguageServiceShimObject.prototype.getIndentationAtPosition = function (fileName, position, options /*Services.EditorOptions*/) {
            var _this = this;
            return this.forwardJSONCall("getIndentationAtPosition('" + fileName + "', " + position + ")", function () {
                var localOptions = JSON.parse(options);
                return _this.languageService.getIndentationAtPosition(fileName, position, localOptions);
            });
        };
        /// GET REFERENCES
        LanguageServiceShimObject.prototype.getReferencesAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getReferencesAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getReferencesAtPosition(fileName, position); });
        };
        LanguageServiceShimObject.prototype.findReferences = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("findReferences('" + fileName + "', " + position + ")", function () { return _this.languageService.findReferences(fileName, position); });
        };
        LanguageServiceShimObject.prototype.getOccurrencesAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getOccurrencesAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getOccurrencesAtPosition(fileName, position); });
        };
        LanguageServiceShimObject.prototype.getDocumentHighlights = function (fileName, position, filesToSearch) {
            var _this = this;
            return this.forwardJSONCall("getDocumentHighlights('" + fileName + "', " + position + ")", function () {
                var results = _this.languageService.getDocumentHighlights(fileName, position, JSON.parse(filesToSearch));
                // workaround for VS document highlighting issue - keep only items from the initial file
                var normalizedName = ts.normalizeSlashes(fileName).toLowerCase();
                return ts.filter(results, function (r) { return ts.normalizeSlashes(r.fileName).toLowerCase() === normalizedName; });
            });
        };
        /// COMPLETION LISTS
        /**
         * Get a string based representation of the completions
         * to provide at the given source position and providing a member completion
         * list if requested.
         */
        LanguageServiceShimObject.prototype.getCompletionsAtPosition = function (fileName, position, preferences) {
            var _this = this;
            return this.forwardJSONCall("getCompletionsAtPosition('" + fileName + "', " + position + ", " + preferences + ")", function () { return _this.languageService.getCompletionsAtPosition(fileName, position, preferences); });
        };
        /** Get a string based representation of a completion list entry details */
        LanguageServiceShimObject.prototype.getCompletionEntryDetails = function (fileName, position, entryName, formatOptions, source, preferences) {
            var _this = this;
            return this.forwardJSONCall("getCompletionEntryDetails('" + fileName + "', " + position + ", '" + entryName + "')", function () {
                var localOptions = formatOptions === undefined ? undefined : JSON.parse(formatOptions);
                return _this.languageService.getCompletionEntryDetails(fileName, position, entryName, localOptions, source, preferences);
            });
        };
        LanguageServiceShimObject.prototype.getFormattingEditsForRange = function (fileName, start, end, options /*Services.FormatCodeOptions*/) {
            var _this = this;
            return this.forwardJSONCall("getFormattingEditsForRange('" + fileName + "', " + start + ", " + end + ")", function () {
                var localOptions = JSON.parse(options);
                return _this.languageService.getFormattingEditsForRange(fileName, start, end, localOptions);
            });
        };
        LanguageServiceShimObject.prototype.getFormattingEditsForDocument = function (fileName, options /*Services.FormatCodeOptions*/) {
            var _this = this;
            return this.forwardJSONCall("getFormattingEditsForDocument('" + fileName + "')", function () {
                var localOptions = JSON.parse(options);
                return _this.languageService.getFormattingEditsForDocument(fileName, localOptions);
            });
        };
        LanguageServiceShimObject.prototype.getFormattingEditsAfterKeystroke = function (fileName, position, key, options /*Services.FormatCodeOptions*/) {
            var _this = this;
            return this.forwardJSONCall("getFormattingEditsAfterKeystroke('" + fileName + "', " + position + ", '" + key + "')", function () {
                var localOptions = JSON.parse(options);
                return _this.languageService.getFormattingEditsAfterKeystroke(fileName, position, key, localOptions);
            });
        };
        LanguageServiceShimObject.prototype.getDocCommentTemplateAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getDocCommentTemplateAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getDocCommentTemplateAtPosition(fileName, position); });
        };
        /// NAVIGATE TO
        /** Return a list of symbols that are interesting to navigate to */
        LanguageServiceShimObject.prototype.getNavigateToItems = function (searchValue, maxResultCount, fileName) {
            var _this = this;
            return this.forwardJSONCall("getNavigateToItems('" + searchValue + "', " + maxResultCount + ", " + fileName + ")", function () { return _this.languageService.getNavigateToItems(searchValue, maxResultCount, fileName); });
        };
        LanguageServiceShimObject.prototype.getNavigationBarItems = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getNavigationBarItems('" + fileName + "')", function () { return _this.languageService.getNavigationBarItems(fileName); });
        };
        LanguageServiceShimObject.prototype.getNavigationTree = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getNavigationTree('" + fileName + "')", function () { return _this.languageService.getNavigationTree(fileName); });
        };
        LanguageServiceShimObject.prototype.getOutliningSpans = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getOutliningSpans('" + fileName + "')", function () { return _this.languageService.getOutliningSpans(fileName); });
        };
        LanguageServiceShimObject.prototype.getTodoComments = function (fileName, descriptors) {
            var _this = this;
            return this.forwardJSONCall("getTodoComments('" + fileName + "')", function () { return _this.languageService.getTodoComments(fileName, JSON.parse(descriptors)); });
        };
        /// Emit
        LanguageServiceShimObject.prototype.getEmitOutput = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getEmitOutput('" + fileName + "')", function () { return _this.languageService.getEmitOutput(fileName); });
        };
        LanguageServiceShimObject.prototype.getEmitOutputObject = function (fileName) {
            var _this = this;
            return forwardCall(this.logger, "getEmitOutput('" + fileName + "')", 
            /*returnJson*/ false, function () { return _this.languageService.getEmitOutput(fileName); }, this.logPerformance);
        };
        return LanguageServiceShimObject;
    }(ShimBase));
    function convertClassifications(classifications) {
        return { spans: classifications.spans.join(","), endOfLineState: classifications.endOfLineState };
    }
    var ClassifierShimObject = /** @class */ (function (_super) {
        __extends(ClassifierShimObject, _super);
        function ClassifierShimObject(factory, logger) {
            var _this = _super.call(this, factory) || this;
            _this.logger = logger;
            _this.logPerformance = false;
            _this.classifier = ts.createClassifier();
            return _this;
        }
        ClassifierShimObject.prototype.getEncodedLexicalClassifications = function (text, lexState, syntacticClassifierAbsent) {
            var _this = this;
            if (syntacticClassifierAbsent === void 0) { syntacticClassifierAbsent = false; }
            return forwardJSONCall(this.logger, "getEncodedLexicalClassifications", function () { return convertClassifications(_this.classifier.getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent)); }, this.logPerformance);
        };
        /// COLORIZATION
        ClassifierShimObject.prototype.getClassificationsForLine = function (text, lexState, classifyKeywordsInGenerics) {
            if (classifyKeywordsInGenerics === void 0) { classifyKeywordsInGenerics = false; }
            var classification = this.classifier.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics);
            var result = "";
            for (var _i = 0, _a = classification.entries; _i < _a.length; _i++) {
                var item = _a[_i];
                result += item.length + "\n";
                result += item.classification + "\n";
            }
            result += classification.finalLexState;
            return result;
        };
        return ClassifierShimObject;
    }(ShimBase));
    var CoreServicesShimObject = /** @class */ (function (_super) {
        __extends(CoreServicesShimObject, _super);
        function CoreServicesShimObject(factory, logger, host) {
            var _this = _super.call(this, factory) || this;
            _this.logger = logger;
            _this.host = host;
            _this.logPerformance = false;
            return _this;
        }
        CoreServicesShimObject.prototype.forwardJSONCall = function (actionDescription, action) {
            return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance);
        };
        CoreServicesShimObject.prototype.resolveModuleName = function (fileName, moduleName, compilerOptionsJson) {
            var _this = this;
            return this.forwardJSONCall("resolveModuleName('" + fileName + "')", function () {
                var compilerOptions = JSON.parse(compilerOptionsJson);
                var result = ts.resolveModuleName(moduleName, ts.normalizeSlashes(fileName), compilerOptions, _this.host);
                var resolvedFileName = result.resolvedModule ? result.resolvedModule.resolvedFileName : undefined;
                if (result.resolvedModule && result.resolvedModule.extension !== ".ts" /* Ts */ && result.resolvedModule.extension !== ".tsx" /* Tsx */ && result.resolvedModule.extension !== ".d.ts" /* Dts */) {
                    resolvedFileName = undefined;
                }
                return {
                    resolvedFileName: resolvedFileName,
                    failedLookupLocations: result.failedLookupLocations
                };
            });
        };
        CoreServicesShimObject.prototype.resolveTypeReferenceDirective = function (fileName, typeReferenceDirective, compilerOptionsJson) {
            var _this = this;
            return this.forwardJSONCall("resolveTypeReferenceDirective(" + fileName + ")", function () {
                var compilerOptions = JSON.parse(compilerOptionsJson);
                var result = ts.resolveTypeReferenceDirective(typeReferenceDirective, ts.normalizeSlashes(fileName), compilerOptions, _this.host);
                return {
                    resolvedFileName: result.resolvedTypeReferenceDirective ? result.resolvedTypeReferenceDirective.resolvedFileName : undefined,
                    primary: result.resolvedTypeReferenceDirective ? result.resolvedTypeReferenceDirective.primary : true,
                    failedLookupLocations: result.failedLookupLocations
                };
            });
        };
        CoreServicesShimObject.prototype.getPreProcessedFileInfo = function (fileName, sourceTextSnapshot) {
            var _this = this;
            return this.forwardJSONCall("getPreProcessedFileInfo('" + fileName + "')", function () {
                // for now treat files as JavaScript
                var result = ts.preProcessFile(ts.getSnapshotText(sourceTextSnapshot), /* readImportFiles */ true, /* detectJavaScriptImports */ true);
                return {
                    referencedFiles: _this.convertFileReferences(result.referencedFiles),
                    importedFiles: _this.convertFileReferences(result.importedFiles),
                    ambientExternalModules: result.ambientExternalModules,
                    isLibFile: result.isLibFile,
                    typeReferenceDirectives: _this.convertFileReferences(result.typeReferenceDirectives),
                    libReferenceDirectives: _this.convertFileReferences(result.libReferenceDirectives)
                };
            });
        };
        CoreServicesShimObject.prototype.getAutomaticTypeDirectiveNames = function (compilerOptionsJson) {
            var _this = this;
            return this.forwardJSONCall("getAutomaticTypeDirectiveNames('" + compilerOptionsJson + "')", function () {
                var compilerOptions = JSON.parse(compilerOptionsJson);
                return ts.getAutomaticTypeDirectiveNames(compilerOptions, _this.host);
            });
        };
        CoreServicesShimObject.prototype.convertFileReferences = function (refs) {
            if (!refs) {
                return undefined;
            }
            var result = [];
            for (var _i = 0, refs_1 = refs; _i < refs_1.length; _i++) {
                var ref = refs_1[_i];
                result.push({
                    path: ts.normalizeSlashes(ref.fileName),
                    position: ref.pos,
                    length: ref.end - ref.pos
                });
            }
            return result;
        };
        CoreServicesShimObject.prototype.getTSConfigFileInfo = function (fileName, sourceTextSnapshot) {
            var _this = this;
            return this.forwardJSONCall("getTSConfigFileInfo('" + fileName + "')", function () {
                var result = ts.parseJsonText(fileName, ts.getSnapshotText(sourceTextSnapshot));
                var normalizedFileName = ts.normalizeSlashes(fileName);
                var configFile = ts.parseJsonSourceFileConfigFileContent(result, _this.host, ts.getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName);
                return {
                    options: configFile.options,
                    typeAcquisition: configFile.typeAcquisition,
                    files: configFile.fileNames,
                    raw: configFile.raw,
                    errors: realizeDiagnostics(result.parseDiagnostics.concat(configFile.errors), "\r\n")
                };
            });
        };
        CoreServicesShimObject.prototype.getDefaultCompilationSettings = function () {
            return this.forwardJSONCall("getDefaultCompilationSettings()", function () { return ts.getDefaultCompilerOptions(); });
        };
        CoreServicesShimObject.prototype.discoverTypings = function (discoverTypingsJson) {
            var _this = this;
            var getCanonicalFileName = ts.createGetCanonicalFileName(/*useCaseSensitivefileNames:*/ false);
            return this.forwardJSONCall("discoverTypings()", function () {
                var info = JSON.parse(discoverTypingsJson);
                if (_this.safeList === undefined) {
                    _this.safeList = ts.JsTyping.loadSafeList(_this.host, ts.toPath(info.safeListPath, info.safeListPath, getCanonicalFileName));
                }
                return ts.JsTyping.discoverTypings(_this.host, function (msg) { return _this.logger.log(msg); }, info.fileNames, ts.toPath(info.projectRootPath, info.projectRootPath, getCanonicalFileName), _this.safeList, info.packageNameToTypingLocation, info.typeAcquisition, info.unresolvedImports, info.typesRegistry);
            });
        };
        return CoreServicesShimObject;
    }(ShimBase));
    var TypeScriptServicesFactory = /** @class */ (function () {
        function TypeScriptServicesFactory() {
            this._shims = [];
        }
        /*
         * Returns script API version.
         */
        TypeScriptServicesFactory.prototype.getServicesVersion = function () {
            return ts.servicesVersion;
        };
        TypeScriptServicesFactory.prototype.createLanguageServiceShim = function (host) {
            try {
                if (this.documentRegistry === undefined) {
                    this.documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory());
                }
                var hostAdapter = new LanguageServiceShimHostAdapter(host);
                var languageService = ts.createLanguageService(hostAdapter, this.documentRegistry, /*syntaxOnly*/ false);
                return new LanguageServiceShimObject(this, host, languageService);
            }
            catch (err) {
                logInternalError(host, err);
                throw err;
            }
        };
        TypeScriptServicesFactory.prototype.createClassifierShim = function (logger) {
            try {
                return new ClassifierShimObject(this, logger);
            }
            catch (err) {
                logInternalError(logger, err);
                throw err;
            }
        };
        TypeScriptServicesFactory.prototype.createCoreServicesShim = function (host) {
            try {
                var adapter = new CoreServicesShimHostAdapter(host);
                return new CoreServicesShimObject(this, host, adapter);
            }
            catch (err) {
                logInternalError(host, err);
                throw err;
            }
        };
        TypeScriptServicesFactory.prototype.close = function () {
            // Forget all the registered shims
            ts.clear(this._shims);
            this.documentRegistry = undefined;
        };
        TypeScriptServicesFactory.prototype.registerShim = function (shim) {
            this._shims.push(shim);
        };
        TypeScriptServicesFactory.prototype.unregisterShim = function (shim) {
            for (var i = 0; i < this._shims.length; i++) {
                if (this._shims[i] === shim) {
                    delete this._shims[i];
                    return;
                }
            }
            throw new Error("Invalid operation");
        };
        return TypeScriptServicesFactory;
    }());
    ts.TypeScriptServicesFactory = TypeScriptServicesFactory;
    if (typeof module !== "undefined" && module.exports) {
        module.exports = ts;
    }
})(ts || (ts = {}));
/* tslint:enable:no-in-operator */
/* tslint:enable:no-null */
/// TODO: this is used by VS, clean this up on both sides of the interface
/* @internal */
var TypeScript;
(function (TypeScript) {
    var Services;
    (function (Services) {
        Services.TypeScriptServicesFactory = ts.TypeScriptServicesFactory;
    })(Services = TypeScript.Services || (TypeScript.Services = {}));
})(TypeScript || (TypeScript = {}));
// 'toolsVersion' gets consumed by the managed side, so it's not unused.
// TODO: it should be moved into a namespace though.
/* @internal */
var toolsVersion = ts.versionMajorMinor;

//# sourceMappingURL=typescriptServices.js.map
