/*! *****************************************************************************
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 __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
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 = {}));
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;
/* @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 server;
    (function (server) {
        var LogLevel;
        (function (LogLevel) {
            LogLevel[LogLevel["terse"] = 0] = "terse";
            LogLevel[LogLevel["normal"] = 1] = "normal";
            LogLevel[LogLevel["requestTime"] = 2] = "requestTime";
            LogLevel[LogLevel["verbose"] = 3] = "verbose";
        })(LogLevel = server.LogLevel || (server.LogLevel = {}));
        server.emptyArray = createSortedArray();
        // TODO: Use a const enum (https://github.com/Microsoft/TypeScript/issues/16804)
        var Msg;
        (function (Msg) {
            Msg["Err"] = "Err";
            Msg["Info"] = "Info";
            Msg["Perf"] = "Perf";
        })(Msg = server.Msg || (server.Msg = {}));
        function createInstallTypingsRequest(project, typeAcquisition, unresolvedImports, cachePath) {
            return {
                projectName: project.getProjectName(),
                fileNames: project.getFileNames(/*excludeFilesFromExternalLibraries*/ true, /*excludeConfigFiles*/ true).concat(project.getExcludedFiles()),
                compilerOptions: project.getCompilationSettings(),
                typeAcquisition: typeAcquisition,
                unresolvedImports: unresolvedImports,
                projectRootPath: project.getCurrentDirectory(),
                cachePath: cachePath,
                kind: "discover"
            };
        }
        server.createInstallTypingsRequest = createInstallTypingsRequest;
        var Errors;
        (function (Errors) {
            function ThrowNoProject() {
                throw new Error("No Project.");
            }
            Errors.ThrowNoProject = ThrowNoProject;
            function ThrowProjectLanguageServiceDisabled() {
                throw new Error("The project's language service is disabled.");
            }
            Errors.ThrowProjectLanguageServiceDisabled = ThrowProjectLanguageServiceDisabled;
            function ThrowProjectDoesNotContainDocument(fileName, project) {
                throw new Error("Project '" + project.getProjectName() + "' does not contain document '" + fileName + "'");
            }
            Errors.ThrowProjectDoesNotContainDocument = ThrowProjectDoesNotContainDocument;
        })(Errors = server.Errors || (server.Errors = {}));
        function toNormalizedPath(fileName) {
            return ts.normalizePath(fileName);
        }
        server.toNormalizedPath = toNormalizedPath;
        function normalizedPathToPath(normalizedPath, currentDirectory, getCanonicalFileName) {
            var f = ts.isRootedDiskPath(normalizedPath) ? normalizedPath : ts.getNormalizedAbsolutePath(normalizedPath, currentDirectory);
            return getCanonicalFileName(f);
        }
        server.normalizedPathToPath = normalizedPathToPath;
        function asNormalizedPath(fileName) {
            return fileName;
        }
        server.asNormalizedPath = asNormalizedPath;
        function createNormalizedPathMap() {
            var map = ts.createMap();
            return {
                get: function (path) {
                    return map.get(path);
                },
                set: function (path, value) {
                    map.set(path, value);
                },
                contains: function (path) {
                    return map.has(path);
                },
                remove: function (path) {
                    map.delete(path);
                }
            };
        }
        server.createNormalizedPathMap = createNormalizedPathMap;
        function isInferredProjectName(name) {
            // POSIX defines /dev/null as a device - there should be no file with this prefix
            return /dev\/null\/inferredProject\d+\*/.test(name);
        }
        server.isInferredProjectName = isInferredProjectName;
        function makeInferredProjectName(counter) {
            return "/dev/null/inferredProject" + counter + "*";
        }
        server.makeInferredProjectName = makeInferredProjectName;
        function createSortedArray() {
            return []; // TODO: GH#19873
        }
        server.createSortedArray = createSortedArray;
    })(server = ts.server || (ts.server = {}));
})(ts || (ts = {}));
/* @internal */
(function (ts) {
    var server;
    (function (server) {
        var ThrottledOperations = /** @class */ (function () {
            function ThrottledOperations(host, logger) {
                this.host = host;
                this.pendingTimeouts = ts.createMap();
                this.logger = logger.hasLevel(server.LogLevel.verbose) ? logger : undefined;
            }
            /**
             * Wait `number` milliseconds and then invoke `cb`.  If, while waiting, schedule
             * is called again with the same `operationId`, cancel this operation in favor
             * of the new one.  (Note that the amount of time the canceled operation had been
             * waiting does not affect the amount of time that the new operation waits.)
             */
            ThrottledOperations.prototype.schedule = function (operationId, delay, cb) {
                var pendingTimeout = this.pendingTimeouts.get(operationId);
                if (pendingTimeout) {
                    // another operation was already scheduled for this id - cancel it
                    this.host.clearTimeout(pendingTimeout);
                }
                // schedule new operation, pass arguments
                this.pendingTimeouts.set(operationId, this.host.setTimeout(ThrottledOperations.run, delay, this, operationId, cb));
                if (this.logger) {
                    this.logger.info("Scheduled: " + operationId + (pendingTimeout ? ", Cancelled earlier one" : ""));
                }
            };
            ThrottledOperations.run = function (self, operationId, cb) {
                self.pendingTimeouts.delete(operationId);
                if (self.logger) {
                    self.logger.info("Running: " + operationId);
                }
                cb();
            };
            return ThrottledOperations;
        }());
        server.ThrottledOperations = ThrottledOperations;
        var GcTimer = /** @class */ (function () {
            function GcTimer(host, delay, logger) {
                this.host = host;
                this.delay = delay;
                this.logger = logger;
            }
            GcTimer.prototype.scheduleCollect = function () {
                if (!this.host.gc || this.timerId !== undefined) {
                    // no global.gc or collection was already scheduled - skip this request
                    return;
                }
                this.timerId = this.host.setTimeout(GcTimer.run, this.delay, this);
            };
            GcTimer.run = function (self) {
                self.timerId = undefined;
                var log = self.logger.hasLevel(server.LogLevel.requestTime);
                var before = log && self.host.getMemoryUsage(); // TODO: GH#18217
                self.host.gc(); // TODO: GH#18217
                if (log) {
                    var after = self.host.getMemoryUsage(); // TODO: GH#18217
                    self.logger.perftrc("GC::before " + before + ", after " + after);
                }
            };
            return GcTimer;
        }());
        server.GcTimer = GcTimer;
        function getBaseConfigFileName(configFilePath) {
            var base = ts.getBaseFileName(configFilePath);
            return base === "tsconfig.json" || base === "jsconfig.json" ? base : undefined;
        }
        server.getBaseConfigFileName = getBaseConfigFileName;
        function removeSorted(array, remove, compare) {
            if (!array || array.length === 0) {
                return;
            }
            if (array[0] === remove) {
                array.splice(0, 1);
                return;
            }
            var removeIndex = ts.binarySearch(array, remove, ts.identity, compare);
            if (removeIndex >= 0) {
                array.splice(removeIndex, 1);
            }
        }
        server.removeSorted = removeSorted;
        var indentStr = "\n    ";
        function indent(str) {
            return indentStr + str.replace(/\n/g, indentStr);
        }
        server.indent = indent;
        /** Put stringified JSON on the next line, indented. */
        function stringifyIndented(json) {
            return indentStr + JSON.stringify(json);
        }
        server.stringifyIndented = stringifyIndented;
    })(server = ts.server || (ts.server = {}));
})(ts || (ts = {}));
/* @internal */
(function (ts) {
    // Additional tsserver specific watch information
    var WatchType;
    (function (WatchType) {
        WatchType["ClosedScriptInfo"] = "Closed Script info";
        WatchType["ConfigFileForInferredRoot"] = "Config file for the inferred project root";
        WatchType["NodeModulesForClosedScriptInfo"] = "node_modules for closed script infos in them";
        WatchType["MissingSourceMapFile"] = "Missing source map file";
    })(WatchType = ts.WatchType || (ts.WatchType = {}));
})(ts || (ts = {}));
// tslint:disable no-unnecessary-qualifier
/**
 * Declaration module describing the TypeScript Server protocol
 */
var ts;
(function (ts) {
    var server;
    (function (server) {
        var protocol;
        (function (protocol) {
            // NOTE: If updating this, be sure to also update `allCommandNames` in `harness/unittests/session.ts`.
            var CommandTypes;
            (function (CommandTypes) {
                CommandTypes["JsxClosingTag"] = "jsxClosingTag";
                CommandTypes["Brace"] = "brace";
                /* @internal */
                CommandTypes["BraceFull"] = "brace-full";
                CommandTypes["BraceCompletion"] = "braceCompletion";
                CommandTypes["GetSpanOfEnclosingComment"] = "getSpanOfEnclosingComment";
                CommandTypes["Change"] = "change";
                CommandTypes["Close"] = "close";
                /** @deprecated Prefer CompletionInfo -- see comment on CompletionsResponse */
                CommandTypes["Completions"] = "completions";
                CommandTypes["CompletionInfo"] = "completionInfo";
                /* @internal */
                CommandTypes["CompletionsFull"] = "completions-full";
                CommandTypes["CompletionDetails"] = "completionEntryDetails";
                /* @internal */
                CommandTypes["CompletionDetailsFull"] = "completionEntryDetails-full";
                CommandTypes["CompileOnSaveAffectedFileList"] = "compileOnSaveAffectedFileList";
                CommandTypes["CompileOnSaveEmitFile"] = "compileOnSaveEmitFile";
                CommandTypes["Configure"] = "configure";
                CommandTypes["Definition"] = "definition";
                /* @internal */
                CommandTypes["DefinitionFull"] = "definition-full";
                CommandTypes["DefinitionAndBoundSpan"] = "definitionAndBoundSpan";
                /* @internal */
                CommandTypes["DefinitionAndBoundSpanFull"] = "definitionAndBoundSpan-full";
                CommandTypes["Implementation"] = "implementation";
                /* @internal */
                CommandTypes["ImplementationFull"] = "implementation-full";
                /* @internal */
                CommandTypes["EmitOutput"] = "emit-output";
                CommandTypes["Exit"] = "exit";
                CommandTypes["Format"] = "format";
                CommandTypes["Formatonkey"] = "formatonkey";
                /* @internal */
                CommandTypes["FormatFull"] = "format-full";
                /* @internal */
                CommandTypes["FormatonkeyFull"] = "formatonkey-full";
                /* @internal */
                CommandTypes["FormatRangeFull"] = "formatRange-full";
                CommandTypes["Geterr"] = "geterr";
                CommandTypes["GeterrForProject"] = "geterrForProject";
                CommandTypes["SemanticDiagnosticsSync"] = "semanticDiagnosticsSync";
                CommandTypes["SyntacticDiagnosticsSync"] = "syntacticDiagnosticsSync";
                CommandTypes["SuggestionDiagnosticsSync"] = "suggestionDiagnosticsSync";
                CommandTypes["NavBar"] = "navbar";
                /* @internal */
                CommandTypes["NavBarFull"] = "navbar-full";
                CommandTypes["Navto"] = "navto";
                /* @internal */
                CommandTypes["NavtoFull"] = "navto-full";
                CommandTypes["NavTree"] = "navtree";
                CommandTypes["NavTreeFull"] = "navtree-full";
                /** @deprecated */
                CommandTypes["Occurrences"] = "occurrences";
                CommandTypes["DocumentHighlights"] = "documentHighlights";
                /* @internal */
                CommandTypes["DocumentHighlightsFull"] = "documentHighlights-full";
                CommandTypes["Open"] = "open";
                CommandTypes["Quickinfo"] = "quickinfo";
                /* @internal */
                CommandTypes["QuickinfoFull"] = "quickinfo-full";
                CommandTypes["References"] = "references";
                /* @internal */
                CommandTypes["ReferencesFull"] = "references-full";
                CommandTypes["Reload"] = "reload";
                CommandTypes["Rename"] = "rename";
                /* @internal */
                CommandTypes["RenameInfoFull"] = "rename-full";
                /* @internal */
                CommandTypes["RenameLocationsFull"] = "renameLocations-full";
                CommandTypes["Saveto"] = "saveto";
                CommandTypes["SignatureHelp"] = "signatureHelp";
                /* @internal */
                CommandTypes["SignatureHelpFull"] = "signatureHelp-full";
                CommandTypes["Status"] = "status";
                CommandTypes["TypeDefinition"] = "typeDefinition";
                CommandTypes["ProjectInfo"] = "projectInfo";
                CommandTypes["ReloadProjects"] = "reloadProjects";
                CommandTypes["Unknown"] = "unknown";
                CommandTypes["OpenExternalProject"] = "openExternalProject";
                CommandTypes["OpenExternalProjects"] = "openExternalProjects";
                CommandTypes["CloseExternalProject"] = "closeExternalProject";
                /* @internal */
                CommandTypes["SynchronizeProjectList"] = "synchronizeProjectList";
                /* @internal */
                CommandTypes["ApplyChangedToOpenFiles"] = "applyChangedToOpenFiles";
                CommandTypes["UpdateOpen"] = "updateOpen";
                /* @internal */
                CommandTypes["EncodedSemanticClassificationsFull"] = "encodedSemanticClassifications-full";
                /* @internal */
                CommandTypes["Cleanup"] = "cleanup";
                CommandTypes["GetOutliningSpans"] = "getOutliningSpans";
                /* @internal */
                CommandTypes["GetOutliningSpansFull"] = "outliningSpans";
                CommandTypes["TodoComments"] = "todoComments";
                CommandTypes["Indentation"] = "indentation";
                CommandTypes["DocCommentTemplate"] = "docCommentTemplate";
                /* @internal */
                CommandTypes["CompilerOptionsDiagnosticsFull"] = "compilerOptionsDiagnostics-full";
                /* @internal */
                CommandTypes["NameOrDottedNameSpan"] = "nameOrDottedNameSpan";
                /* @internal */
                CommandTypes["BreakpointStatement"] = "breakpointStatement";
                CommandTypes["CompilerOptionsForInferredProjects"] = "compilerOptionsForInferredProjects";
                CommandTypes["GetCodeFixes"] = "getCodeFixes";
                /* @internal */
                CommandTypes["GetCodeFixesFull"] = "getCodeFixes-full";
                CommandTypes["GetCombinedCodeFix"] = "getCombinedCodeFix";
                /* @internal */
                CommandTypes["GetCombinedCodeFixFull"] = "getCombinedCodeFix-full";
                CommandTypes["ApplyCodeActionCommand"] = "applyCodeActionCommand";
                CommandTypes["GetSupportedCodeFixes"] = "getSupportedCodeFixes";
                CommandTypes["GetApplicableRefactors"] = "getApplicableRefactors";
                CommandTypes["GetEditsForRefactor"] = "getEditsForRefactor";
                /* @internal */
                CommandTypes["GetEditsForRefactorFull"] = "getEditsForRefactor-full";
                CommandTypes["OrganizeImports"] = "organizeImports";
                /* @internal */
                CommandTypes["OrganizeImportsFull"] = "organizeImports-full";
                CommandTypes["GetEditsForFileRename"] = "getEditsForFileRename";
                /* @internal */
                CommandTypes["GetEditsForFileRenameFull"] = "getEditsForFileRename-full";
                CommandTypes["ConfigurePlugin"] = "configurePlugin";
                CommandTypes["SelectionRange"] = "selectionRange";
                /* @internal */
                CommandTypes["SelectionRangeFull"] = "selectionRange-full";
                // NOTE: If updating this, be sure to also update `allCommandNames` in `harness/unittests/session.ts`.
            })(CommandTypes = protocol.CommandTypes || (protocol.CommandTypes = {}));
            var IndentStyle;
            (function (IndentStyle) {
                IndentStyle["None"] = "None";
                IndentStyle["Block"] = "Block";
                IndentStyle["Smart"] = "Smart";
            })(IndentStyle = protocol.IndentStyle || (protocol.IndentStyle = {}));
            var JsxEmit;
            (function (JsxEmit) {
                JsxEmit["None"] = "None";
                JsxEmit["Preserve"] = "Preserve";
                JsxEmit["ReactNative"] = "ReactNative";
                JsxEmit["React"] = "React";
            })(JsxEmit = protocol.JsxEmit || (protocol.JsxEmit = {}));
            var ModuleKind;
            (function (ModuleKind) {
                ModuleKind["None"] = "None";
                ModuleKind["CommonJS"] = "CommonJS";
                ModuleKind["AMD"] = "AMD";
                ModuleKind["UMD"] = "UMD";
                ModuleKind["System"] = "System";
                ModuleKind["ES6"] = "ES6";
                ModuleKind["ES2015"] = "ES2015";
                ModuleKind["ESNext"] = "ESNext";
            })(ModuleKind = protocol.ModuleKind || (protocol.ModuleKind = {}));
            var ModuleResolutionKind;
            (function (ModuleResolutionKind) {
                ModuleResolutionKind["Classic"] = "Classic";
                ModuleResolutionKind["Node"] = "Node";
            })(ModuleResolutionKind = protocol.ModuleResolutionKind || (protocol.ModuleResolutionKind = {}));
            var NewLineKind;
            (function (NewLineKind) {
                NewLineKind["Crlf"] = "Crlf";
                NewLineKind["Lf"] = "Lf";
            })(NewLineKind = protocol.NewLineKind || (protocol.NewLineKind = {}));
            var ScriptTarget;
            (function (ScriptTarget) {
                ScriptTarget["ES3"] = "ES3";
                ScriptTarget["ES5"] = "ES5";
                ScriptTarget["ES6"] = "ES6";
                ScriptTarget["ES2015"] = "ES2015";
                ScriptTarget["ES2016"] = "ES2016";
                ScriptTarget["ES2017"] = "ES2017";
                ScriptTarget["ES2018"] = "ES2018";
                ScriptTarget["ES2019"] = "ES2019";
                ScriptTarget["ES2020"] = "ES2020";
                ScriptTarget["ESNext"] = "ESNext";
            })(ScriptTarget = protocol.ScriptTarget || (protocol.ScriptTarget = {}));
        })(protocol = server.protocol || (server.protocol = {}));
    })(server = ts.server || (ts.server = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    var server;
    (function (server) {
        /* @internal */
        var TextStorage = /** @class */ (function () {
            function TextStorage(host, fileName, initialVersion, info) {
                this.host = host;
                this.fileName = fileName;
                this.info = info;
                /**
                 * True if the text is for the file thats open in the editor
                 */
                this.isOpen = false;
                /**
                 * True if the text present is the text from the file on the disk
                 */
                this.ownFileText = false;
                /**
                 * True when reloading contents of file from the disk is pending
                 */
                this.pendingReloadFromDisk = false;
                this.version = initialVersion || { svc: 0, text: 0 };
            }
            TextStorage.prototype.getVersion = function () {
                return this.svc
                    ? "SVC-" + this.version.svc + "-" + this.svc.getSnapshotVersion()
                    : "Text-" + this.version.text;
            };
            TextStorage.prototype.hasScriptVersionCache_TestOnly = function () {
                return this.svc !== undefined;
            };
            TextStorage.prototype.useScriptVersionCache_TestOnly = function () {
                this.switchToScriptVersionCache();
            };
            TextStorage.prototype.resetSourceMapInfo = function () {
                this.info.sourceFileLike = undefined;
                this.info.closeSourceMapFileWatcher();
                this.info.sourceMapFilePath = undefined;
                this.info.declarationInfoPath = undefined;
                this.info.sourceInfos = undefined;
                this.info.documentPositionMapper = undefined;
            };
            /** Public for testing */
            TextStorage.prototype.useText = function (newText) {
                this.svc = undefined;
                this.text = newText;
                this.lineMap = undefined;
                this.fileSize = undefined;
                this.resetSourceMapInfo();
                this.version.text++;
            };
            TextStorage.prototype.edit = function (start, end, newText) {
                this.switchToScriptVersionCache().edit(start, end - start, newText);
                this.ownFileText = false;
                this.text = undefined;
                this.lineMap = undefined;
                this.fileSize = undefined;
                this.resetSourceMapInfo();
            };
            /**
             * Set the contents as newText
             * returns true if text changed
             */
            TextStorage.prototype.reload = function (newText) {
                ts.Debug.assert(newText !== undefined);
                // Reload always has fresh content
                this.pendingReloadFromDisk = false;
                // If text changed set the text
                // This also ensures that if we had switched to version cache,
                // we are switching back to text.
                // The change to version cache will happen when needed
                // Thus avoiding the computation if there are no changes
                if (this.text !== newText) {
                    this.useText(newText);
                    // We cant guarantee new text is own file text
                    this.ownFileText = false;
                    return true;
                }
                return false;
            };
            /**
             * Reads the contents from tempFile(if supplied) or own file and sets it as contents
             * returns true if text changed
             */
            TextStorage.prototype.reloadWithFileText = function (tempFileName) {
                var _a = this.getFileTextAndSize(tempFileName), newText = _a.text, fileSize = _a.fileSize;
                var reloaded = this.reload(newText);
                this.fileSize = fileSize; // NB: after reload since reload clears it
                this.ownFileText = !tempFileName || tempFileName === this.fileName;
                return reloaded;
            };
            /**
             * Reloads the contents from the file if there is no pending reload from disk or the contents of file are same as file text
             * returns true if text changed
             */
            TextStorage.prototype.reloadFromDisk = function () {
                if (!this.pendingReloadFromDisk && !this.ownFileText) {
                    return this.reloadWithFileText();
                }
                return false;
            };
            TextStorage.prototype.delayReloadFromFileIntoText = function () {
                this.pendingReloadFromDisk = true;
            };
            /**
             * For telemetry purposes, we would like to be able to report the size of the file.
             * However, we do not want telemetry to require extra file I/O so we report a size
             * that may be stale (e.g. may not reflect change made on disk since the last reload).
             * NB: Will read from disk if the file contents have never been loaded because
             * telemetry falsely indicating size 0 would be counter-productive.
             */
            TextStorage.prototype.getTelemetryFileSize = function () {
                return !!this.fileSize
                    ? this.fileSize
                    : !!this.text // Check text before svc because its length is cheaper
                        ? this.text.length // Could be wrong if this.pendingReloadFromDisk
                        : !!this.svc
                            ? this.svc.getSnapshot().getLength() // Could be wrong if this.pendingReloadFromDisk
                            : this.getSnapshot().getLength(); // Should be strictly correct
            };
            TextStorage.prototype.getSnapshot = function () {
                return this.useScriptVersionCacheIfValidOrOpen()
                    ? this.svc.getSnapshot()
                    : ts.ScriptSnapshot.fromString(this.getOrLoadText());
            };
            TextStorage.prototype.getAbsolutePositionAndLineText = function (line) {
                return this.switchToScriptVersionCache().getAbsolutePositionAndLineText(line);
            };
            /**
             *  @param line 0 based index
             */
            TextStorage.prototype.lineToTextSpan = function (line) {
                if (!this.useScriptVersionCacheIfValidOrOpen()) {
                    var lineMap = this.getLineMap();
                    var start = lineMap[line]; // -1 since line is 1-based
                    var end = line + 1 < lineMap.length ? lineMap[line + 1] : this.text.length;
                    return ts.createTextSpanFromBounds(start, end);
                }
                return this.svc.lineToTextSpan(line);
            };
            /**
             * @param line 1 based index
             * @param offset 1 based index
             */
            TextStorage.prototype.lineOffsetToPosition = function (line, offset, allowEdits) {
                if (!this.useScriptVersionCacheIfValidOrOpen()) {
                    return ts.computePositionOfLineAndCharacter(this.getLineMap(), line - 1, offset - 1, this.text, allowEdits);
                }
                // TODO: assert this offset is actually on the line
                return this.svc.lineOffsetToPosition(line, offset);
            };
            TextStorage.prototype.positionToLineOffset = function (position) {
                if (!this.useScriptVersionCacheIfValidOrOpen()) {
                    var _a = ts.computeLineAndCharacterOfPosition(this.getLineMap(), position), line = _a.line, character = _a.character;
                    return { line: line + 1, offset: character + 1 };
                }
                return this.svc.positionToLineOffset(position);
            };
            TextStorage.prototype.getFileTextAndSize = function (tempFileName) {
                var _this = this;
                var text;
                var fileName = tempFileName || this.fileName;
                var getText = function () { return text === undefined ? (text = _this.host.readFile(fileName) || "") : text; };
                // Only non typescript files have size limitation
                if (!ts.hasTSFileExtension(this.fileName)) {
                    var fileSize = this.host.getFileSize ? this.host.getFileSize(fileName) : getText().length;
                    if (fileSize > server.maxFileSize) {
                        ts.Debug.assert(!!this.info.containingProjects.length);
                        var service = this.info.containingProjects[0].projectService;
                        service.logger.info("Skipped loading contents of large file " + fileName + " for info " + this.info.fileName + ": fileSize: " + fileSize);
                        this.info.containingProjects[0].projectService.sendLargeFileReferencedEvent(fileName, fileSize);
                        return { text: "", fileSize: fileSize };
                    }
                }
                return { text: getText() };
            };
            TextStorage.prototype.switchToScriptVersionCache = function () {
                if (!this.svc || this.pendingReloadFromDisk) {
                    this.svc = server.ScriptVersionCache.fromString(this.getOrLoadText());
                    this.version.svc++;
                }
                return this.svc;
            };
            TextStorage.prototype.useScriptVersionCacheIfValidOrOpen = function () {
                // If this is open script, use the cache
                if (this.isOpen) {
                    return this.switchToScriptVersionCache();
                }
                // If there is pending reload from the disk then, reload the text
                if (this.pendingReloadFromDisk) {
                    this.reloadWithFileText();
                }
                // At this point if svc is present its valid
                return this.svc;
            };
            TextStorage.prototype.getOrLoadText = function () {
                if (this.text === undefined || this.pendingReloadFromDisk) {
                    ts.Debug.assert(!this.svc || this.pendingReloadFromDisk, "ScriptVersionCache should not be set when reloading from disk");
                    this.reloadWithFileText();
                }
                return this.text;
            };
            TextStorage.prototype.getLineMap = function () {
                ts.Debug.assert(!this.svc, "ScriptVersionCache should not be set");
                return this.lineMap || (this.lineMap = ts.computeLineStarts(this.getOrLoadText()));
            };
            TextStorage.prototype.getLineInfo = function () {
                var _this = this;
                if (this.svc) {
                    return {
                        getLineCount: function () { return _this.svc.getLineCount(); },
                        getLineText: function (line) { return _this.svc.getAbsolutePositionAndLineText(line + 1).lineText; }
                    };
                }
                var lineMap = this.getLineMap();
                return ts.getLineInfo(this.text, lineMap);
            };
            return TextStorage;
        }());
        server.TextStorage = TextStorage;
        /*@internal*/
        function isDynamicFileName(fileName) {
            return fileName[0] === "^" || ts.getBaseFileName(fileName)[0] === "^";
        }
        server.isDynamicFileName = isDynamicFileName;
        var ScriptInfo = /** @class */ (function () {
            function ScriptInfo(host, fileName, scriptKind, hasMixedContent, path, initialVersion) {
                this.host = host;
                this.fileName = fileName;
                this.scriptKind = scriptKind;
                this.hasMixedContent = hasMixedContent;
                this.path = path;
                /**
                 * All projects that include this file
                 */
                this.containingProjects = [];
                this.isDynamic = isDynamicFileName(fileName);
                this.textStorage = new TextStorage(host, fileName, initialVersion, this);
                if (hasMixedContent || this.isDynamic) {
                    this.textStorage.reload("");
                    this.realpath = this.path;
                }
                this.scriptKind = scriptKind
                    ? scriptKind
                    : ts.getScriptKindFromFileName(fileName);
            }
            /*@internal*/
            ScriptInfo.prototype.getVersion = function () {
                return this.textStorage.version;
            };
            /*@internal*/
            ScriptInfo.prototype.getTelemetryFileSize = function () {
                return this.textStorage.getTelemetryFileSize();
            };
            /*@internal*/
            ScriptInfo.prototype.isDynamicOrHasMixedContent = function () {
                return this.hasMixedContent || this.isDynamic;
            };
            ScriptInfo.prototype.isScriptOpen = function () {
                return this.textStorage.isOpen;
            };
            ScriptInfo.prototype.open = function (newText) {
                this.textStorage.isOpen = true;
                if (newText !== undefined &&
                    this.textStorage.reload(newText)) {
                    // reload new contents only if the existing contents changed
                    this.markContainingProjectsAsDirty();
                }
            };
            ScriptInfo.prototype.close = function (fileExists) {
                if (fileExists === void 0) { fileExists = true; }
                this.textStorage.isOpen = false;
                if (this.isDynamicOrHasMixedContent() || !fileExists) {
                    if (this.textStorage.reload("")) {
                        this.markContainingProjectsAsDirty();
                    }
                }
                else if (this.textStorage.reloadFromDisk()) {
                    this.markContainingProjectsAsDirty();
                }
            };
            ScriptInfo.prototype.getSnapshot = function () {
                return this.textStorage.getSnapshot();
            };
            ScriptInfo.prototype.ensureRealPath = function () {
                if (this.realpath === undefined) {
                    // Default is just the path
                    this.realpath = this.path;
                    if (this.host.realpath) {
                        ts.Debug.assert(!!this.containingProjects.length);
                        var project = this.containingProjects[0];
                        var realpath = this.host.realpath(this.path);
                        if (realpath) {
                            this.realpath = project.toPath(realpath);
                            // If it is different from this.path, add to the map
                            if (this.realpath !== this.path) {
                                project.projectService.realpathToScriptInfos.add(this.realpath, this); // TODO: GH#18217
                            }
                        }
                    }
                }
            };
            /*@internal*/
            ScriptInfo.prototype.getRealpathIfDifferent = function () {
                return this.realpath && this.realpath !== this.path ? this.realpath : undefined;
            };
            ScriptInfo.prototype.getFormatCodeSettings = function () { return this.formatSettings; };
            ScriptInfo.prototype.getPreferences = function () { return this.preferences; };
            ScriptInfo.prototype.attachToProject = function (project) {
                var isNew = !this.isAttached(project);
                if (isNew) {
                    this.containingProjects.push(project);
                    project.onFileAddedOrRemoved();
                    if (!project.getCompilerOptions().preserveSymlinks) {
                        this.ensureRealPath();
                    }
                }
                return isNew;
            };
            ScriptInfo.prototype.isAttached = function (project) {
                // unrolled for common cases
                switch (this.containingProjects.length) {
                    case 0: return false;
                    case 1: return this.containingProjects[0] === project;
                    case 2: return this.containingProjects[0] === project || this.containingProjects[1] === project;
                    default: return ts.contains(this.containingProjects, project);
                }
            };
            ScriptInfo.prototype.detachFromProject = function (project) {
                // unrolled for common cases
                switch (this.containingProjects.length) {
                    case 0:
                        return;
                    case 1:
                        if (this.containingProjects[0] === project) {
                            project.onFileAddedOrRemoved();
                            this.containingProjects.pop();
                        }
                        break;
                    case 2:
                        if (this.containingProjects[0] === project) {
                            project.onFileAddedOrRemoved();
                            this.containingProjects[0] = this.containingProjects.pop();
                        }
                        else if (this.containingProjects[1] === project) {
                            project.onFileAddedOrRemoved();
                            this.containingProjects.pop();
                        }
                        break;
                    default:
                        if (ts.unorderedRemoveItem(this.containingProjects, project)) {
                            project.onFileAddedOrRemoved();
                        }
                        break;
                }
            };
            ScriptInfo.prototype.detachAllProjects = function () {
                for (var _i = 0, _a = this.containingProjects; _i < _a.length; _i++) {
                    var p = _a[_i];
                    if (p.projectKind === server.ProjectKind.Configured) {
                        p.getCachedDirectoryStructureHost().addOrDeleteFile(this.fileName, this.path, ts.FileWatcherEventKind.Deleted);
                    }
                    var isInfoRoot = p.isRoot(this);
                    // detach is unnecessary since we'll clean the list of containing projects anyways
                    p.removeFile(this, /*fileExists*/ false, /*detachFromProjects*/ false);
                    // If the info was for the external or configured project's root,
                    // add missing file as the root
                    if (isInfoRoot && p.projectKind !== server.ProjectKind.Inferred) {
                        p.addMissingFileRoot(this.fileName);
                    }
                }
                ts.clear(this.containingProjects);
            };
            ScriptInfo.prototype.getDefaultProject = function () {
                switch (this.containingProjects.length) {
                    case 0:
                        return server.Errors.ThrowNoProject();
                    case 1:
                        return this.containingProjects[0];
                    default:
                        // if this file belongs to multiple projects, the first configured project should be
                        // the default project; if no configured projects, the first external project should
                        // be the default project; otherwise the first inferred project should be the default.
                        var firstExternalProject = void 0;
                        for (var _i = 0, _a = this.containingProjects; _i < _a.length; _i++) {
                            var project = _a[_i];
                            if (project.projectKind === server.ProjectKind.Configured) {
                                return project;
                            }
                            else if (project.projectKind === server.ProjectKind.External && !firstExternalProject) {
                                firstExternalProject = project;
                            }
                        }
                        return firstExternalProject || this.containingProjects[0];
                }
            };
            ScriptInfo.prototype.registerFileUpdate = function () {
                for (var _i = 0, _a = this.containingProjects; _i < _a.length; _i++) {
                    var p = _a[_i];
                    p.registerFileUpdate(this.path);
                }
            };
            ScriptInfo.prototype.setOptions = function (formatSettings, preferences) {
                if (formatSettings) {
                    if (!this.formatSettings) {
                        this.formatSettings = ts.getDefaultFormatCodeSettings(this.host.newLine);
                        ts.assign(this.formatSettings, formatSettings);
                    }
                    else {
                        this.formatSettings = __assign({}, this.formatSettings, formatSettings);
                    }
                }
                if (preferences) {
                    if (!this.preferences) {
                        this.preferences = ts.emptyOptions;
                    }
                    this.preferences = __assign({}, this.preferences, preferences);
                }
            };
            ScriptInfo.prototype.getLatestVersion = function () {
                return this.textStorage.getVersion();
            };
            ScriptInfo.prototype.saveTo = function (fileName) {
                this.host.writeFile(fileName, ts.getSnapshotText(this.textStorage.getSnapshot()));
            };
            /*@internal*/
            ScriptInfo.prototype.delayReloadNonMixedContentFile = function () {
                ts.Debug.assert(!this.isDynamicOrHasMixedContent());
                this.textStorage.delayReloadFromFileIntoText();
                this.markContainingProjectsAsDirty();
            };
            ScriptInfo.prototype.reloadFromFile = function (tempFileName) {
                if (this.isDynamicOrHasMixedContent()) {
                    this.textStorage.reload("");
                    this.markContainingProjectsAsDirty();
                    return true;
                }
                else {
                    if (this.textStorage.reloadWithFileText(tempFileName)) {
                        this.markContainingProjectsAsDirty();
                        return true;
                    }
                }
                return false;
            };
            /*@internal*/
            ScriptInfo.prototype.getAbsolutePositionAndLineText = function (line) {
                return this.textStorage.getAbsolutePositionAndLineText(line);
            };
            ScriptInfo.prototype.editContent = function (start, end, newText) {
                this.textStorage.edit(start, end, newText);
                this.markContainingProjectsAsDirty();
            };
            ScriptInfo.prototype.markContainingProjectsAsDirty = function () {
                for (var _i = 0, _a = this.containingProjects; _i < _a.length; _i++) {
                    var p = _a[_i];
                    p.markAsDirty();
                }
            };
            ScriptInfo.prototype.isOrphan = function () {
                return !ts.forEach(this.containingProjects, function (p) { return !p.isOrphan(); });
            };
            /**
             *  @param line 1 based index
             */
            ScriptInfo.prototype.lineToTextSpan = function (line) {
                return this.textStorage.lineToTextSpan(line);
            };
            ScriptInfo.prototype.lineOffsetToPosition = function (line, offset, allowEdits) {
                return this.textStorage.lineOffsetToPosition(line, offset, allowEdits);
            };
            ScriptInfo.prototype.positionToLineOffset = function (position) {
                return this.textStorage.positionToLineOffset(position);
            };
            ScriptInfo.prototype.isJavaScript = function () {
                return this.scriptKind === 1 /* JS */ || this.scriptKind === 2 /* JSX */;
            };
            /*@internal*/
            ScriptInfo.prototype.getLineInfo = function () {
                return this.textStorage.getLineInfo();
            };
            /*@internal*/
            ScriptInfo.prototype.closeSourceMapFileWatcher = function () {
                if (this.sourceMapFilePath && !ts.isString(this.sourceMapFilePath)) {
                    ts.closeFileWatcherOf(this.sourceMapFilePath);
                    this.sourceMapFilePath = undefined;
                }
            };
            return ScriptInfo;
        }());
        server.ScriptInfo = ScriptInfo;
    })(server = ts.server || (ts.server = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    var server;
    (function (server) {
        server.nullTypingsInstaller = {
            isKnownTypesPackageName: ts.returnFalse,
            // Should never be called because we never provide a types registry.
            installPackage: ts.notImplemented,
            enqueueInstallTypingsRequest: ts.noop,
            attach: ts.noop,
            onProjectClosed: ts.noop,
            globalTypingsCacheLocation: undefined // TODO: GH#18217
        };
        function setIsEqualTo(arr1, arr2) {
            if (arr1 === arr2) {
                return true;
            }
            if ((arr1 || server.emptyArray).length === 0 && (arr2 || server.emptyArray).length === 0) {
                return true;
            }
            var set = ts.createMap();
            var unique = 0;
            for (var _i = 0, _a = arr1; _i < _a.length; _i++) {
                var v = _a[_i];
                if (set.get(v) !== true) {
                    set.set(v, true);
                    unique++;
                }
            }
            for (var _b = 0, _c = arr2; _b < _c.length; _b++) {
                var v = _c[_b];
                var isSet = set.get(v);
                if (isSet === undefined) {
                    return false;
                }
                if (isSet === true) {
                    set.set(v, false);
                    unique--;
                }
            }
            return unique === 0;
        }
        function typeAcquisitionChanged(opt1, opt2) {
            return opt1.enable !== opt2.enable ||
                !setIsEqualTo(opt1.include, opt2.include) ||
                !setIsEqualTo(opt1.exclude, opt2.exclude);
        }
        function compilerOptionsChanged(opt1, opt2) {
            // TODO: add more relevant properties
            return opt1.allowJs !== opt2.allowJs;
        }
        function unresolvedImportsChanged(imports1, imports2) {
            if (imports1 === imports2) {
                return false;
            }
            return !ts.arrayIsEqualTo(imports1, imports2);
        }
        /*@internal*/
        var TypingsCache = /** @class */ (function () {
            function TypingsCache(installer) {
                this.installer = installer;
                this.perProjectCache = ts.createMap();
            }
            TypingsCache.prototype.isKnownTypesPackageName = function (name) {
                return this.installer.isKnownTypesPackageName(name);
            };
            TypingsCache.prototype.installPackage = function (options) {
                return this.installer.installPackage(options);
            };
            TypingsCache.prototype.enqueueInstallTypingsForProject = function (project, unresolvedImports, forceRefresh) {
                var typeAcquisition = project.getTypeAcquisition();
                if (!typeAcquisition || !typeAcquisition.enable) {
                    return;
                }
                var entry = this.perProjectCache.get(project.getProjectName());
                if (forceRefresh ||
                    !entry ||
                    typeAcquisitionChanged(typeAcquisition, entry.typeAcquisition) ||
                    compilerOptionsChanged(project.getCompilationSettings(), entry.compilerOptions) ||
                    unresolvedImportsChanged(unresolvedImports, entry.unresolvedImports)) {
                    // Note: entry is now poisoned since it does not really contain typings for a given combination of compiler options\typings options.
                    // instead it acts as a placeholder to prevent issuing multiple requests
                    this.perProjectCache.set(project.getProjectName(), {
                        compilerOptions: project.getCompilationSettings(),
                        typeAcquisition: typeAcquisition,
                        typings: entry ? entry.typings : server.emptyArray,
                        unresolvedImports: unresolvedImports,
                        poisoned: true
                    });
                    // something has been changed, issue a request to update typings
                    this.installer.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
                }
            };
            TypingsCache.prototype.updateTypingsForProject = function (projectName, compilerOptions, typeAcquisition, unresolvedImports, newTypings) {
                var typings = ts.sort(newTypings);
                this.perProjectCache.set(projectName, {
                    compilerOptions: compilerOptions,
                    typeAcquisition: typeAcquisition,
                    typings: typings,
                    unresolvedImports: unresolvedImports,
                    poisoned: false
                });
                return !typeAcquisition || !typeAcquisition.enable ? server.emptyArray : typings;
            };
            TypingsCache.prototype.onProjectClosed = function (project) {
                this.perProjectCache.delete(project.getProjectName());
                this.installer.onProjectClosed(project);
            };
            return TypingsCache;
        }());
        server.TypingsCache = TypingsCache;
    })(server = ts.server || (ts.server = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    var server;
    (function (server) {
        var ProjectKind;
        (function (ProjectKind) {
            ProjectKind[ProjectKind["Inferred"] = 0] = "Inferred";
            ProjectKind[ProjectKind["Configured"] = 1] = "Configured";
            ProjectKind[ProjectKind["External"] = 2] = "External";
        })(ProjectKind = server.ProjectKind || (server.ProjectKind = {}));
        /* @internal */
        function countEachFileTypes(infos, includeSizes) {
            if (includeSizes === void 0) { includeSizes = false; }
            var result = {
                js: 0, jsSize: 0,
                jsx: 0, jsxSize: 0,
                ts: 0, tsSize: 0,
                tsx: 0, tsxSize: 0,
                dts: 0, dtsSize: 0,
                deferred: 0, deferredSize: 0,
            };
            for (var _i = 0, infos_1 = infos; _i < infos_1.length; _i++) {
                var info = infos_1[_i];
                var fileSize = includeSizes ? info.getTelemetryFileSize() : 0;
                switch (info.scriptKind) {
                    case 1 /* JS */:
                        result.js += 1;
                        result.jsSize += fileSize;
                        break;
                    case 2 /* JSX */:
                        result.jsx += 1;
                        result.jsxSize += fileSize;
                        break;
                    case 3 /* TS */:
                        if (ts.fileExtensionIs(info.fileName, ".d.ts" /* Dts */)) {
                            result.dts += 1;
                            result.dtsSize += fileSize;
                        }
                        else {
                            result.ts += 1;
                            result.tsSize += fileSize;
                        }
                        break;
                    case 4 /* TSX */:
                        result.tsx += 1;
                        result.tsxSize += fileSize;
                        break;
                    case 7 /* Deferred */:
                        result.deferred += 1;
                        result.deferredSize += fileSize;
                        break;
                }
            }
            return result;
        }
        server.countEachFileTypes = countEachFileTypes;
        function hasOneOrMoreJsAndNoTsFiles(project) {
            var counts = countEachFileTypes(project.getScriptInfos());
            return counts.js > 0 && counts.ts === 0 && counts.tsx === 0;
        }
        function allRootFilesAreJsOrDts(project) {
            var counts = countEachFileTypes(project.getRootScriptInfos());
            return counts.ts === 0 && counts.tsx === 0;
        }
        server.allRootFilesAreJsOrDts = allRootFilesAreJsOrDts;
        function allFilesAreJsOrDts(project) {
            var counts = countEachFileTypes(project.getScriptInfos());
            return counts.ts === 0 && counts.tsx === 0;
        }
        server.allFilesAreJsOrDts = allFilesAreJsOrDts;
        /* @internal */
        function hasNoTypeScriptSource(fileNames) {
            return !fileNames.some(function (fileName) { return (ts.fileExtensionIs(fileName, ".ts" /* Ts */) && !ts.fileExtensionIs(fileName, ".d.ts" /* Dts */)) || ts.fileExtensionIs(fileName, ".tsx" /* Tsx */); });
        }
        server.hasNoTypeScriptSource = hasNoTypeScriptSource;
        /* @internal */
        function isScriptInfo(value) {
            return value instanceof server.ScriptInfo;
        }
        server.isScriptInfo = isScriptInfo;
        var Project = /** @class */ (function () {
            /*@internal*/
            function Project(
            /*@internal*/ projectName, projectKind, projectService, documentRegistry, hasExplicitListOfFiles, lastFileExceededProgramSize, compilerOptions, compileOnSaveEnabled, directoryStructureHost, currentDirectory) {
                var _this = this;
                this.projectName = projectName;
                this.projectKind = projectKind;
                this.projectService = projectService;
                this.documentRegistry = documentRegistry;
                this.compilerOptions = compilerOptions;
                this.compileOnSaveEnabled = compileOnSaveEnabled;
                this.rootFiles = [];
                this.rootFilesMap = ts.createMap();
                this.plugins = [];
                /*@internal*/
                /**
                 * This is map from files to unresolved imports in it
                 * Maop does not contain entries for files that do not have unresolved imports
                 * This helps in containing the set of files to invalidate
                 */
                this.cachedUnresolvedImportsPerFile = ts.createMap();
                /*@internal*/
                this.hasAddedorRemovedFiles = false;
                /**
                 * Last version that was reported.
                 */
                this.lastReportedVersion = 0;
                /**
                 * Current project's program version. (incremented everytime new program is created that is not complete reuse from the old one)
                 * This property is changed in 'updateGraph' based on the set of files in program
                 */
                this.projectProgramVersion = 0;
                /**
                 * Current version of the project state. It is changed when:
                 * - new root file was added/removed
                 * - edit happen in some file that is currently included in the project.
                 * This property is different from projectStructureVersion since in most cases edits don't affect set of files in the project
                 */
                this.projectStateVersion = 0;
                this.isInitialLoadPending = ts.returnFalse;
                /*@internal*/
                this.dirty = false;
                /*@internal*/
                this.hasChangedAutomaticTypeDirectiveNames = false;
                /*@internal*/
                this.typingFiles = server.emptyArray;
                this.directoryStructureHost = directoryStructureHost;
                this.currentDirectory = this.projectService.getNormalizedAbsolutePath(currentDirectory || "");
                this.getCanonicalFileName = this.projectService.toCanonicalFileName;
                this.cancellationToken = new ts.ThrottledCancellationToken(this.projectService.cancellationToken, this.projectService.throttleWaitMilliseconds);
                if (!this.compilerOptions) {
                    this.compilerOptions = ts.getDefaultCompilerOptions();
                    this.compilerOptions.allowNonTsExtensions = true;
                    this.compilerOptions.allowJs = true;
                }
                else if (hasExplicitListOfFiles || this.compilerOptions.allowJs || this.projectService.hasDeferredExtension()) {
                    // If files are listed explicitly or allowJs is specified, allow all extensions
                    this.compilerOptions.allowNonTsExtensions = true;
                }
                this.languageServiceEnabled = !projectService.syntaxOnly;
                this.setInternalCompilerOptionsForEmittingJsFiles();
                var host = this.projectService.host;
                if (this.projectService.logger.loggingEnabled()) {
                    this.trace = function (s) { return _this.writeLog(s); };
                }
                else if (host.trace) {
                    this.trace = function (s) { return host.trace(s); };
                }
                if (host.realpath) {
                    this.realpath = function (path) { return host.realpath(path); };
                }
                // Use the current directory as resolution root only if the project created using current directory string
                this.resolutionCache = ts.createResolutionCache(this, currentDirectory && this.currentDirectory, /*logChangesWhenResolvingModule*/ true);
                this.languageService = ts.createLanguageService(this, this.documentRegistry, projectService.syntaxOnly);
                if (lastFileExceededProgramSize) {
                    this.disableLanguageService(lastFileExceededProgramSize);
                }
                this.markAsDirty();
                this.projectService.pendingEnsureProjectForOpenFiles = true;
            }
            Project.prototype.isNonTsProject = function () {
                server.updateProjectIfDirty(this);
                return allFilesAreJsOrDts(this);
            };
            Project.prototype.isJsOnlyProject = function () {
                server.updateProjectIfDirty(this);
                return hasOneOrMoreJsAndNoTsFiles(this);
            };
            Project.resolveModule = function (moduleName, initialDir, host, log, logErrors) {
                var resolvedPath = ts.normalizeSlashes(host.resolvePath(ts.combinePaths(initialDir, "node_modules")));
                log("Loading " + moduleName + " from " + initialDir + " (resolved to " + resolvedPath + ")");
                var result = host.require(resolvedPath, moduleName); // TODO: GH#18217
                if (result.error) {
                    var err = result.error.stack || result.error.message || JSON.stringify(result.error);
                    (logErrors || log)("Failed to load module '" + moduleName + "' from " + resolvedPath + ": " + err);
                    return undefined;
                }
                return result.module;
            };
            Project.prototype.isKnownTypesPackageName = function (name) {
                return this.typingsCache.isKnownTypesPackageName(name);
            };
            Project.prototype.installPackage = function (options) {
                return this.typingsCache.installPackage(__assign({}, options, { projectName: this.projectName, projectRootPath: this.toPath(this.currentDirectory) }));
            };
            Object.defineProperty(Project.prototype, "typingsCache", {
                get: function () {
                    return this.projectService.typingsCache;
                },
                enumerable: true,
                configurable: true
            });
            // Method of LanguageServiceHost
            Project.prototype.getCompilationSettings = function () {
                return this.compilerOptions;
            };
            // Method to support public API
            Project.prototype.getCompilerOptions = function () {
                return this.getCompilationSettings();
            };
            Project.prototype.getNewLine = function () {
                return this.projectService.host.newLine;
            };
            Project.prototype.getProjectVersion = function () {
                return this.projectStateVersion.toString();
            };
            Project.prototype.getProjectReferences = function () {
                return undefined;
            };
            Project.prototype.getScriptFileNames = function () {
                var _this = this;
                if (!this.rootFiles) {
                    return ts.emptyArray;
                }
                var result;
                this.rootFilesMap.forEach(function (value) {
                    if (_this.languageServiceEnabled || (isScriptInfo(value) && value.isScriptOpen())) {
                        // if language service is disabled - process only files that are open
                        (result || (result = [])).push(isScriptInfo(value) ? value.fileName : value);
                    }
                });
                return ts.addRange(result, this.typingFiles) || ts.emptyArray;
            };
            Project.prototype.getOrCreateScriptInfoAndAttachToProject = function (fileName) {
                var scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(fileName, this.currentDirectory, this.directoryStructureHost);
                if (scriptInfo) {
                    var existingValue = this.rootFilesMap.get(scriptInfo.path);
                    if (existingValue !== scriptInfo && existingValue !== undefined) {
                        // This was missing path earlier but now the file exists. Update the root
                        this.rootFiles.push(scriptInfo);
                        this.rootFilesMap.set(scriptInfo.path, scriptInfo);
                    }
                    scriptInfo.attachToProject(this);
                }
                return scriptInfo;
            };
            Project.prototype.getScriptKind = function (fileName) {
                var info = this.getOrCreateScriptInfoAndAttachToProject(fileName);
                return (info && info.scriptKind); // TODO: GH#18217
            };
            Project.prototype.getScriptVersion = function (filename) {
                var info = this.getOrCreateScriptInfoAndAttachToProject(filename);
                return (info && info.getLatestVersion()); // TODO: GH#18217
            };
            Project.prototype.getScriptSnapshot = function (filename) {
                var scriptInfo = this.getOrCreateScriptInfoAndAttachToProject(filename);
                if (scriptInfo) {
                    return scriptInfo.getSnapshot();
                }
            };
            Project.prototype.getCancellationToken = function () {
                return this.cancellationToken;
            };
            Project.prototype.getCurrentDirectory = function () {
                return this.currentDirectory;
            };
            Project.prototype.getDefaultLibFileName = function () {
                var nodeModuleBinDir = ts.getDirectoryPath(ts.normalizePath(this.projectService.getExecutingFilePath()));
                return ts.combinePaths(nodeModuleBinDir, ts.getDefaultLibFileName(this.compilerOptions));
            };
            Project.prototype.useCaseSensitiveFileNames = function () {
                return this.projectService.host.useCaseSensitiveFileNames;
            };
            Project.prototype.readDirectory = function (path, extensions, exclude, include, depth) {
                return this.directoryStructureHost.readDirectory(path, extensions, exclude, include, depth);
            };
            Project.prototype.readFile = function (fileName) {
                return this.projectService.host.readFile(fileName);
            };
            Project.prototype.writeFile = function (fileName, content) {
                return this.projectService.host.writeFile(fileName, content);
            };
            Project.prototype.fileExists = function (file) {
                // As an optimization, don't hit the disks for files we already know don't exist
                // (because we're watching for their creation).
                var path = this.toPath(file);
                return !this.isWatchedMissingFile(path) && this.directoryStructureHost.fileExists(file);
            };
            Project.prototype.resolveModuleNames = function (moduleNames, containingFile, reusedNames, redirectedReference) {
                return this.resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference);
            };
            Project.prototype.getResolvedModuleWithFailedLookupLocationsFromCache = function (moduleName, containingFile) {
                return this.resolutionCache.getResolvedModuleWithFailedLookupLocationsFromCache(moduleName, containingFile);
            };
            Project.prototype.resolveTypeReferenceDirectives = function (typeDirectiveNames, containingFile, redirectedReference) {
                return this.resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile, redirectedReference);
            };
            Project.prototype.directoryExists = function (path) {
                return this.directoryStructureHost.directoryExists(path); // TODO: GH#18217
            };
            Project.prototype.getDirectories = function (path) {
                return this.directoryStructureHost.getDirectories(path); // TODO: GH#18217
            };
            /*@internal*/
            Project.prototype.getCachedDirectoryStructureHost = function () {
                return undefined; // TODO: GH#18217
            };
            /*@internal*/
            Project.prototype.toPath = function (fileName) {
                return ts.toPath(fileName, this.currentDirectory, this.projectService.toCanonicalFileName);
            };
            /*@internal*/
            Project.prototype.watchDirectoryOfFailedLookupLocation = function (directory, cb, flags) {
                return this.projectService.watchFactory.watchDirectory(this.projectService.host, directory, cb, flags, "Failed Lookup Locations" /* FailedLookupLocations */, this);
            };
            /*@internal*/
            Project.prototype.onInvalidatedResolution = function () {
                this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this);
            };
            /*@internal*/
            Project.prototype.watchTypeRootsDirectory = function (directory, cb, flags) {
                return this.projectService.watchFactory.watchDirectory(this.projectService.host, directory, cb, flags, "Type roots" /* TypeRoots */, this);
            };
            /*@internal*/
            Project.prototype.onChangedAutomaticTypeDirectiveNames = function () {
                this.hasChangedAutomaticTypeDirectiveNames = true;
                this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this);
            };
            /*@internal*/
            Project.prototype.getGlobalCache = function () {
                return this.getTypeAcquisition().enable ? this.projectService.typingsInstaller.globalTypingsCacheLocation : undefined;
            };
            /*@internal*/
            Project.prototype.fileIsOpen = function (filePath) {
                return this.projectService.openFiles.has(filePath);
            };
            /*@internal*/
            Project.prototype.writeLog = function (s) {
                this.projectService.logger.info(s);
            };
            Project.prototype.log = function (s) {
                this.writeLog(s);
            };
            Project.prototype.error = function (s) {
                this.projectService.logger.msg(s, server.Msg.Err);
            };
            Project.prototype.setInternalCompilerOptionsForEmittingJsFiles = function () {
                if (this.projectKind === ProjectKind.Inferred || this.projectKind === ProjectKind.External) {
                    this.compilerOptions.noEmitForJsFiles = true;
                }
            };
            /**
             * Get the errors that dont have any file name associated
             */
            Project.prototype.getGlobalProjectErrors = function () {
                return server.emptyArray;
            };
            Project.prototype.getAllProjectErrors = function () {
                return server.emptyArray;
            };
            Project.prototype.getLanguageService = function (ensureSynchronized) {
                if (ensureSynchronized === void 0) { ensureSynchronized = true; }
                if (ensureSynchronized) {
                    server.updateProjectIfDirty(this);
                }
                return this.languageService;
            };
            /** @internal */
            Project.prototype.getSourceMapper = function () {
                return this.getLanguageService().getSourceMapper();
            };
            /*@internal*/
            Project.prototype.getDocumentPositionMapper = function (generatedFileName, sourceFileName) {
                return this.projectService.getDocumentPositionMapper(this, generatedFileName, sourceFileName);
            };
            /*@internal*/
            Project.prototype.getSourceFileLike = function (fileName) {
                return this.projectService.getSourceFileLike(fileName, this);
            };
            Project.prototype.shouldEmitFile = function (scriptInfo) {
                return scriptInfo && !scriptInfo.isDynamicOrHasMixedContent();
            };
            Project.prototype.getCompileOnSaveAffectedFileList = function (scriptInfo) {
                var _this = this;
                if (!this.languageServiceEnabled) {
                    return [];
                }
                server.updateProjectIfDirty(this);
                this.builderState = ts.BuilderState.create(this.program, this.projectService.toCanonicalFileName, this.builderState);
                return ts.mapDefined(ts.BuilderState.getFilesAffectedBy(this.builderState, this.program, scriptInfo.path, this.cancellationToken, function (data) { return _this.projectService.host.createHash(data); }), // TODO: GH#18217
                function (// TODO: GH#18217
                sourceFile) { return _this.shouldEmitFile(_this.projectService.getScriptInfoForPath(sourceFile.path)) ? sourceFile.fileName : undefined; });
            };
            /**
             * Returns true if emit was conducted
             */
            Project.prototype.emitFile = function (scriptInfo, writeFile) {
                if (!this.languageServiceEnabled || !this.shouldEmitFile(scriptInfo)) {
                    return false;
                }
                var _a = this.getLanguageService(/*ensureSynchronized*/ false).getEmitOutput(scriptInfo.fileName), emitSkipped = _a.emitSkipped, outputFiles = _a.outputFiles;
                if (!emitSkipped) {
                    for (var _i = 0, outputFiles_1 = outputFiles; _i < outputFiles_1.length; _i++) {
                        var outputFile = outputFiles_1[_i];
                        var outputFileAbsoluteFileName = ts.getNormalizedAbsolutePath(outputFile.name, this.currentDirectory);
                        writeFile(outputFileAbsoluteFileName, outputFile.text, outputFile.writeByteOrderMark);
                    }
                }
                return !emitSkipped;
            };
            Project.prototype.enableLanguageService = function () {
                if (this.languageServiceEnabled || this.projectService.syntaxOnly) {
                    return;
                }
                this.languageServiceEnabled = true;
                this.lastFileExceededProgramSize = undefined;
                this.projectService.onUpdateLanguageServiceStateForProject(this, /*languageServiceEnabled*/ true);
            };
            Project.prototype.disableLanguageService = function (lastFileExceededProgramSize) {
                if (!this.languageServiceEnabled) {
                    return;
                }
                ts.Debug.assert(!this.projectService.syntaxOnly);
                this.languageService.cleanupSemanticCache();
                this.languageServiceEnabled = false;
                this.lastFileExceededProgramSize = lastFileExceededProgramSize;
                this.builderState = undefined;
                this.resolutionCache.closeTypeRootsWatch();
                this.projectService.onUpdateLanguageServiceStateForProject(this, /*languageServiceEnabled*/ false);
            };
            Project.prototype.getProjectName = function () {
                return this.projectName;
            };
            Project.prototype.removeLocalTypingsFromTypeAcquisition = function (newTypeAcquisition) {
                if (!newTypeAcquisition || !newTypeAcquisition.include) {
                    // Nothing to filter out, so just return as-is
                    return newTypeAcquisition;
                }
                return __assign({}, newTypeAcquisition, { include: this.removeExistingTypings(newTypeAcquisition.include) });
            };
            Project.prototype.getExternalFiles = function () {
                var _this = this;
                return ts.sort(ts.flatMap(this.plugins, function (plugin) {
                    if (typeof plugin.module.getExternalFiles !== "function")
                        return;
                    try {
                        return plugin.module.getExternalFiles(_this);
                    }
                    catch (e) {
                        _this.projectService.logger.info("A plugin threw an exception in getExternalFiles: " + e);
                        if (e.stack) {
                            _this.projectService.logger.info(e.stack);
                        }
                    }
                }));
            };
            Project.prototype.getSourceFile = function (path) {
                if (!this.program) {
                    return undefined;
                }
                return this.program.getSourceFileByPath(path);
            };
            /* @internal */
            Project.prototype.getSourceFileOrConfigFile = function (path) {
                var options = this.program.getCompilerOptions();
                return path === options.configFilePath ? options.configFile : this.getSourceFile(path);
            };
            Project.prototype.close = function () {
                var _this = this;
                if (this.program) {
                    // if we have a program - release all files that are enlisted in program but arent root
                    // The releasing of the roots happens later
                    // The project could have pending update remaining and hence the info could be in the files but not in program graph
                    for (var _i = 0, _a = this.program.getSourceFiles(); _i < _a.length; _i++) {
                        var f = _a[_i];
                        this.detachScriptInfoIfNotRoot(f.fileName);
                    }
                    this.program.forEachResolvedProjectReference(function (ref) {
                        if (ref) {
                            _this.detachScriptInfoFromProject(ref.sourceFile.fileName);
                        }
                    });
                }
                // Release external files
                ts.forEach(this.externalFiles, function (externalFile) { return _this.detachScriptInfoIfNotRoot(externalFile); });
                // Always remove root files from the project
                for (var _b = 0, _c = this.rootFiles; _b < _c.length; _b++) {
                    var root = _c[_b];
                    root.detachFromProject(this);
                }
                this.projectService.pendingEnsureProjectForOpenFiles = true;
                this.rootFiles = undefined;
                this.rootFilesMap = undefined;
                this.externalFiles = undefined;
                this.program = undefined;
                this.builderState = undefined;
                this.resolutionCache.clear();
                this.resolutionCache = undefined;
                this.cachedUnresolvedImportsPerFile = undefined;
                this.directoryStructureHost = undefined;
                // Clean up file watchers waiting for missing files
                if (this.missingFilesMap) {
                    ts.clearMap(this.missingFilesMap, ts.closeFileWatcher);
                    this.missingFilesMap = undefined;
                }
                // signal language service to release source files acquired from document registry
                this.languageService.dispose();
                this.languageService = undefined;
            };
            Project.prototype.detachScriptInfoIfNotRoot = function (uncheckedFilename) {
                var info = this.projectService.getScriptInfo(uncheckedFilename);
                // We might not find the script info in case its not associated with the project any more
                // and project graph was not updated (eg delayed update graph in case of files changed/deleted on the disk)
                if (info && !this.isRoot(info)) {
                    info.detachFromProject(this);
                }
            };
            Project.prototype.isClosed = function () {
                return this.rootFiles === undefined;
            };
            Project.prototype.hasRoots = function () {
                return this.rootFiles && this.rootFiles.length > 0;
            };
            /*@internal*/
            Project.prototype.isOrphan = function () {
                return false;
            };
            Project.prototype.getRootFiles = function () {
                return this.rootFiles && this.rootFiles.map(function (info) { return info.fileName; });
            };
            /*@internal*/
            Project.prototype.getRootFilesMap = function () {
                return this.rootFilesMap;
            };
            Project.prototype.getRootScriptInfos = function () {
                return this.rootFiles;
            };
            Project.prototype.getScriptInfos = function () {
                var _this = this;
                if (!this.languageServiceEnabled) {
                    // if language service is not enabled - return just root files
                    return this.rootFiles;
                }
                return ts.map(this.program.getSourceFiles(), function (sourceFile) {
                    var scriptInfo = _this.projectService.getScriptInfoForPath(sourceFile.resolvedPath);
                    ts.Debug.assert(!!scriptInfo, "getScriptInfo", function () { return "scriptInfo for a file '" + sourceFile.fileName + "' Path: '" + sourceFile.path + "' / '" + sourceFile.resolvedPath + "' is missing."; });
                    return scriptInfo;
                });
            };
            Project.prototype.getExcludedFiles = function () {
                return server.emptyArray;
            };
            Project.prototype.getFileNames = function (excludeFilesFromExternalLibraries, excludeConfigFiles) {
                if (!this.program) {
                    return [];
                }
                if (!this.languageServiceEnabled) {
                    // if language service is disabled assume that all files in program are root files + default library
                    var rootFiles = this.getRootFiles();
                    if (this.compilerOptions) {
                        var defaultLibrary = ts.getDefaultLibFilePath(this.compilerOptions);
                        if (defaultLibrary) {
                            (rootFiles || (rootFiles = [])).push(server.asNormalizedPath(defaultLibrary));
                        }
                    }
                    return rootFiles;
                }
                var result = [];
                for (var _i = 0, _a = this.program.getSourceFiles(); _i < _a.length; _i++) {
                    var f = _a[_i];
                    if (excludeFilesFromExternalLibraries && this.program.isSourceFileFromExternalLibrary(f)) {
                        continue;
                    }
                    result.push(server.asNormalizedPath(f.fileName));
                }
                if (!excludeConfigFiles) {
                    var configFile = this.program.getCompilerOptions().configFile;
                    if (configFile) {
                        result.push(server.asNormalizedPath(configFile.fileName));
                        if (configFile.extendedSourceFiles) {
                            for (var _b = 0, _c = configFile.extendedSourceFiles; _b < _c.length; _b++) {
                                var f = _c[_b];
                                result.push(server.asNormalizedPath(f));
                            }
                        }
                    }
                }
                return result;
            };
            Project.prototype.hasConfigFile = function (configFilePath) {
                if (this.program && this.languageServiceEnabled) {
                    var configFile = this.program.getCompilerOptions().configFile;
                    if (configFile) {
                        if (configFilePath === server.asNormalizedPath(configFile.fileName)) {
                            return true;
                        }
                        if (configFile.extendedSourceFiles) {
                            for (var _i = 0, _a = configFile.extendedSourceFiles; _i < _a.length; _i++) {
                                var f = _a[_i];
                                if (configFilePath === server.asNormalizedPath(f)) {
                                    return true;
                                }
                            }
                        }
                    }
                }
                return false;
            };
            Project.prototype.containsScriptInfo = function (info) {
                if (this.isRoot(info))
                    return true;
                if (!this.program)
                    return false;
                var file = this.program.getSourceFileByPath(info.path);
                return !!file && file.resolvedPath === info.path;
            };
            Project.prototype.containsFile = function (filename, requireOpen) {
                var info = this.projectService.getScriptInfoForNormalizedPath(filename);
                if (info && (info.isScriptOpen() || !requireOpen)) {
                    return this.containsScriptInfo(info);
                }
                return false;
            };
            Project.prototype.isRoot = function (info) {
                return this.rootFilesMap && this.rootFilesMap.get(info.path) === info;
            };
            // add a root file to project
            Project.prototype.addRoot = function (info) {
                ts.Debug.assert(!this.isRoot(info));
                this.rootFiles.push(info);
                this.rootFilesMap.set(info.path, info);
                info.attachToProject(this);
                this.markAsDirty();
            };
            // add a root file that doesnt exist on host
            Project.prototype.addMissingFileRoot = function (fileName) {
                var path = this.projectService.toPath(fileName);
                this.rootFilesMap.set(path, fileName);
                this.markAsDirty();
            };
            Project.prototype.removeFile = function (info, fileExists, detachFromProject) {
                if (this.isRoot(info)) {
                    this.removeRoot(info);
                }
                if (fileExists) {
                    // If file is present, just remove the resolutions for the file
                    this.resolutionCache.removeResolutionsOfFile(info.path);
                }
                else {
                    this.resolutionCache.invalidateResolutionOfFile(info.path);
                }
                this.cachedUnresolvedImportsPerFile.delete(info.path);
                if (detachFromProject) {
                    info.detachFromProject(this);
                }
                this.markAsDirty();
            };
            Project.prototype.registerFileUpdate = function (fileName) {
                (this.updatedFileNames || (this.updatedFileNames = ts.createMap())).set(fileName, true);
            };
            Project.prototype.markAsDirty = function () {
                if (!this.dirty) {
                    this.projectStateVersion++;
                    this.dirty = true;
                }
            };
            /* @internal */
            Project.prototype.onFileAddedOrRemoved = function () {
                this.hasAddedorRemovedFiles = true;
            };
            /**
             * Updates set of files that contribute to this project
             * @returns: true if set of files in the project stays the same and false - otherwise.
             */
            Project.prototype.updateGraph = function () {
                this.resolutionCache.startRecordingFilesWithChangedResolutions();
                var hasNewProgram = this.updateGraphWorker();
                var hasAddedorRemovedFiles = this.hasAddedorRemovedFiles;
                this.hasAddedorRemovedFiles = false;
                var changedFiles = this.resolutionCache.finishRecordingFilesWithChangedResolutions() || server.emptyArray;
                for (var _i = 0, changedFiles_1 = changedFiles; _i < changedFiles_1.length; _i++) {
                    var file = changedFiles_1[_i];
                    // delete cached information for changed files
                    this.cachedUnresolvedImportsPerFile.delete(file);
                }
                // update builder only if language service is enabled
                // otherwise tell it to drop its internal state
                if (this.languageServiceEnabled) {
                    // 1. no changes in structure, no changes in unresolved imports - do nothing
                    // 2. no changes in structure, unresolved imports were changed - collect unresolved imports for all files
                    // (can reuse cached imports for files that were not changed)
                    // 3. new files were added/removed, but compilation settings stays the same - collect unresolved imports for all new/modified files
                    // (can reuse cached imports for files that were not changed)
                    // 4. compilation settings were changed in the way that might affect module resolution - drop all caches and collect all data from the scratch
                    if (hasNewProgram || changedFiles.length) {
                        this.lastCachedUnresolvedImportsList = getUnresolvedImports(this.program, this.cachedUnresolvedImportsPerFile);
                    }
                    this.projectService.typingsCache.enqueueInstallTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasAddedorRemovedFiles);
                }
                else {
                    this.lastCachedUnresolvedImportsList = undefined;
                }
                if (hasNewProgram) {
                    this.projectProgramVersion++;
                }
                return !hasNewProgram;
            };
            /*@internal*/
            Project.prototype.updateTypingFiles = function (typingFiles) {
                var _this = this;
                ts.enumerateInsertsAndDeletes(typingFiles, this.typingFiles, ts.getStringComparer(!this.useCaseSensitiveFileNames()), 
                /*inserted*/ ts.noop, function (removed) { return _this.detachScriptInfoFromProject(removed); });
                this.typingFiles = typingFiles;
                // Invalidate files with unresolved imports
                this.resolutionCache.setFilesWithInvalidatedNonRelativeUnresolvedImports(this.cachedUnresolvedImportsPerFile);
            };
            /* @internal */
            Project.prototype.getCurrentProgram = function () {
                return this.program;
            };
            Project.prototype.removeExistingTypings = function (include) {
                var existing = ts.getAutomaticTypeDirectiveNames(this.getCompilerOptions(), this.directoryStructureHost);
                return include.filter(function (i) { return existing.indexOf(i) < 0; });
            };
            Project.prototype.updateGraphWorker = function () {
                var _this = this;
                var oldProgram = this.program;
                ts.Debug.assert(!this.isClosed(), "Called update graph worker of closed project");
                this.writeLog("Starting updateGraphWorker: Project: " + this.getProjectName());
                var start = ts.timestamp();
                this.hasInvalidatedResolution = this.resolutionCache.createHasInvalidatedResolution();
                this.resolutionCache.startCachingPerDirectoryResolution();
                this.program = this.languageService.getProgram(); // TODO: GH#18217
                this.dirty = false;
                this.resolutionCache.finishCachingPerDirectoryResolution();
                ts.Debug.assert(oldProgram === undefined || this.program !== undefined);
                // bump up the version if
                // - oldProgram is not set - this is a first time updateGraph is called
                // - newProgram is different from the old program and structure of the old program was not reused.
                var hasNewProgram = this.program && (!oldProgram || (this.program !== oldProgram && !(oldProgram.structureIsReused & 2 /* Completely */)));
                this.hasChangedAutomaticTypeDirectiveNames = false;
                if (hasNewProgram) {
                    if (oldProgram) {
                        for (var _i = 0, _a = oldProgram.getSourceFiles(); _i < _a.length; _i++) {
                            var f = _a[_i];
                            var newFile = this.program.getSourceFileByPath(f.resolvedPath);
                            if (!newFile || (f.resolvedPath === f.path && newFile.resolvedPath !== f.path)) {
                                // new program does not contain this file - detach it from the project
                                // - remove resolutions only if the new program doesnt contain source file by the path (not resolvedPath since path is used for resolution)
                                this.detachScriptInfoFromProject(f.fileName, !!this.program.getSourceFileByPath(f.path));
                            }
                        }
                        oldProgram.forEachResolvedProjectReference(function (resolvedProjectReference, resolvedProjectReferencePath) {
                            if (resolvedProjectReference && !_this.program.getResolvedProjectReferenceByPath(resolvedProjectReferencePath)) {
                                _this.detachScriptInfoFromProject(resolvedProjectReference.sourceFile.fileName);
                            }
                        });
                    }
                    // Update the missing file paths watcher
                    ts.updateMissingFilePathsWatch(this.program, this.missingFilesMap || (this.missingFilesMap = ts.createMap()), 
                    // Watch the missing files
                    function (missingFilePath) { return _this.addMissingFileWatcher(missingFilePath); });
                    // Watch the type locations that would be added to program as part of automatic type resolutions
                    if (this.languageServiceEnabled) {
                        this.resolutionCache.updateTypeRootsWatch();
                    }
                }
                var oldExternalFiles = this.externalFiles || server.emptyArray;
                this.externalFiles = this.getExternalFiles();
                ts.enumerateInsertsAndDeletes(this.externalFiles, oldExternalFiles, ts.getStringComparer(!this.useCaseSensitiveFileNames()), 
                // Ensure a ScriptInfo is created for new external files. This is performed indirectly
                // by the LSHost for files in the program when the program is retrieved above but
                // the program doesn't contain external files so this must be done explicitly.
                function (inserted) {
                    var scriptInfo = _this.projectService.getOrCreateScriptInfoNotOpenedByClient(inserted, _this.currentDirectory, _this.directoryStructureHost);
                    scriptInfo.attachToProject(_this);
                }, function (removed) { return _this.detachScriptInfoFromProject(removed); });
                var elapsed = ts.timestamp() - start;
                this.writeLog("Finishing updateGraphWorker: Project: " + this.getProjectName() + " Version: " + this.getProjectVersion() + " structureChanged: " + hasNewProgram + " Elapsed: " + elapsed + "ms");
                if (this.program !== oldProgram) {
                    this.print();
                }
                return hasNewProgram;
            };
            Project.prototype.detachScriptInfoFromProject = function (uncheckedFileName, noRemoveResolution) {
                var scriptInfoToDetach = this.projectService.getScriptInfo(uncheckedFileName);
                if (scriptInfoToDetach) {
                    scriptInfoToDetach.detachFromProject(this);
                    if (!noRemoveResolution) {
                        this.resolutionCache.removeResolutionsOfFile(scriptInfoToDetach.path);
                    }
                }
            };
            Project.prototype.addMissingFileWatcher = function (missingFilePath) {
                var _this = this;
                var fileWatcher = this.projectService.watchFactory.watchFile(this.projectService.host, missingFilePath, function (fileName, eventKind) {
                    if (_this.projectKind === ProjectKind.Configured) {
                        _this.getCachedDirectoryStructureHost().addOrDeleteFile(fileName, missingFilePath, eventKind);
                    }
                    if (eventKind === ts.FileWatcherEventKind.Created && _this.missingFilesMap.has(missingFilePath)) {
                        _this.missingFilesMap.delete(missingFilePath);
                        fileWatcher.close();
                        // When a missing file is created, we should update the graph.
                        _this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(_this);
                    }
                }, ts.PollingInterval.Medium, "Missing file" /* MissingFile */, this);
                return fileWatcher;
            };
            Project.prototype.isWatchedMissingFile = function (path) {
                return !!this.missingFilesMap && this.missingFilesMap.has(path);
            };
            Project.prototype.getScriptInfoForNormalizedPath = function (fileName) {
                var scriptInfo = this.projectService.getScriptInfoForPath(this.toPath(fileName));
                if (scriptInfo && !scriptInfo.isAttached(this)) {
                    return server.Errors.ThrowProjectDoesNotContainDocument(fileName, this);
                }
                return scriptInfo;
            };
            Project.prototype.getScriptInfo = function (uncheckedFileName) {
                return this.projectService.getScriptInfo(uncheckedFileName);
            };
            Project.prototype.filesToString = function (writeProjectFileNames) {
                if (!this.program) {
                    return "\tFiles (0)\n";
                }
                var sourceFiles = this.program.getSourceFiles();
                var strBuilder = "\tFiles (" + sourceFiles.length + ")\n";
                if (writeProjectFileNames) {
                    for (var _i = 0, sourceFiles_1 = sourceFiles; _i < sourceFiles_1.length; _i++) {
                        var file = sourceFiles_1[_i];
                        strBuilder += "\t" + file.fileName + "\n";
                    }
                }
                return strBuilder;
            };
            /*@internal*/
            Project.prototype.print = function (counter) {
                this.writeLog("Project '" + this.projectName + "' (" + ProjectKind[this.projectKind] + ") " + (counter === undefined ? "" : counter));
                this.writeLog(this.filesToString(this.projectService.logger.hasLevel(server.LogLevel.verbose)));
                this.writeLog("-----------------------------------------------");
            };
            Project.prototype.setCompilerOptions = function (compilerOptions) {
                if (compilerOptions) {
                    compilerOptions.allowNonTsExtensions = true;
                    var oldOptions = this.compilerOptions;
                    this.compilerOptions = compilerOptions;
                    this.setInternalCompilerOptionsForEmittingJsFiles();
                    if (ts.changesAffectModuleResolution(oldOptions, compilerOptions)) {
                        // reset cached unresolved imports if changes in compiler options affected module resolution
                        this.cachedUnresolvedImportsPerFile.clear();
                        this.lastCachedUnresolvedImportsList = undefined;
                        this.resolutionCache.clear();
                    }
                    this.markAsDirty();
                }
            };
            /* @internal */
            Project.prototype.getChangesSinceVersion = function (lastKnownVersion) {
                // Update the graph only if initial configured project load is not pending
                if (!this.isInitialLoadPending()) {
                    server.updateProjectIfDirty(this);
                }
                var info = {
                    projectName: this.getProjectName(),
                    version: this.projectProgramVersion,
                    isInferred: this.projectKind === ProjectKind.Inferred,
                    options: this.getCompilationSettings(),
                    languageServiceDisabled: !this.languageServiceEnabled,
                    lastFileExceededProgramSize: this.lastFileExceededProgramSize
                };
                var updatedFileNames = this.updatedFileNames;
                this.updatedFileNames = undefined;
                // check if requested version is the same that we have reported last time
                if (this.lastReportedFileNames && lastKnownVersion === this.lastReportedVersion) {
                    // if current structure version is the same - return info without any changes
                    if (this.projectProgramVersion === this.lastReportedVersion && !updatedFileNames) {
                        return { info: info, projectErrors: this.getGlobalProjectErrors() };
                    }
                    // compute and return the difference
                    var lastReportedFileNames_1 = this.lastReportedFileNames;
                    var externalFiles = this.getExternalFiles().map(function (f) { return server.toNormalizedPath(f); });
                    var currentFiles_1 = ts.arrayToSet(this.getFileNames().concat(externalFiles));
                    var added_1 = [];
                    var removed_1 = [];
                    var updated = updatedFileNames ? ts.arrayFrom(updatedFileNames.keys()) : [];
                    ts.forEachKey(currentFiles_1, function (id) {
                        if (!lastReportedFileNames_1.has(id)) {
                            added_1.push(id);
                        }
                    });
                    ts.forEachKey(lastReportedFileNames_1, function (id) {
                        if (!currentFiles_1.has(id)) {
                            removed_1.push(id);
                        }
                    });
                    this.lastReportedFileNames = currentFiles_1;
                    this.lastReportedVersion = this.projectProgramVersion;
                    return { info: info, changes: { added: added_1, removed: removed_1, updated: updated }, projectErrors: this.getGlobalProjectErrors() };
                }
                else {
                    // unknown version - return everything
                    var projectFileNames = this.getFileNames();
                    var externalFiles = this.getExternalFiles().map(function (f) { return server.toNormalizedPath(f); });
                    var allFiles = projectFileNames.concat(externalFiles);
                    this.lastReportedFileNames = ts.arrayToSet(allFiles);
                    this.lastReportedVersion = this.projectProgramVersion;
                    return { info: info, files: allFiles, projectErrors: this.getGlobalProjectErrors() };
                }
            };
            // remove a root file from project
            Project.prototype.removeRoot = function (info) {
                ts.orderedRemoveItem(this.rootFiles, info);
                this.rootFilesMap.delete(info.path);
            };
            Project.prototype.enableGlobalPlugins = function (options, pluginConfigOverrides) {
                var host = this.projectService.host;
                if (!host.require) {
                    this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded");
                    return;
                }
                // Search our peer node_modules, then any globally-specified probe paths
                // ../../.. to walk from X/node_modules/typescript/lib/tsserver.js to X/node_modules/
                var searchPaths = [ts.combinePaths(this.projectService.getExecutingFilePath(), "../../..")].concat(this.projectService.pluginProbeLocations);
                if (this.projectService.globalPlugins) {
                    var _loop_1 = function (globalPluginName) {
                        // Skip empty names from odd commandline parses
                        if (!globalPluginName)
                            return "continue";
                        // Skip already-locally-loaded plugins
                        if (options.plugins && options.plugins.some(function (p) { return p.name === globalPluginName; }))
                            return "continue";
                        // Provide global: true so plugins can detect why they can't find their config
                        this_1.projectService.logger.info("Loading global plugin " + globalPluginName);
                        this_1.enablePlugin({ name: globalPluginName, global: true }, searchPaths, pluginConfigOverrides);
                    };
                    var this_1 = this;
                    // Enable global plugins with synthetic configuration entries
                    for (var _i = 0, _a = this.projectService.globalPlugins; _i < _a.length; _i++) {
                        var globalPluginName = _a[_i];
                        _loop_1(globalPluginName);
                    }
                }
            };
            Project.prototype.enablePlugin = function (pluginConfigEntry, searchPaths, pluginConfigOverrides) {
                var _this = this;
                this.projectService.logger.info("Enabling plugin " + pluginConfigEntry.name + " from candidate paths: " + searchPaths.join(","));
                var log = function (message) { return _this.projectService.logger.info(message); };
                var errorLogs;
                var logError = function (message) { (errorLogs || (errorLogs = [])).push(message); };
                var resolvedModule = ts.firstDefined(searchPaths, function (searchPath) {
                    return Project.resolveModule(pluginConfigEntry.name, searchPath, _this.projectService.host, log, logError);
                });
                if (resolvedModule) {
                    var configurationOverride = pluginConfigOverrides && pluginConfigOverrides.get(pluginConfigEntry.name);
                    if (configurationOverride) {
                        // Preserve the name property since it's immutable
                        var pluginName = pluginConfigEntry.name;
                        pluginConfigEntry = configurationOverride;
                        pluginConfigEntry.name = pluginName;
                    }
                    this.enableProxy(resolvedModule, pluginConfigEntry);
                }
                else {
                    ts.forEach(errorLogs, log);
                    this.projectService.logger.info("Couldn't find " + pluginConfigEntry.name);
                }
            };
            Project.prototype.enableProxy = function (pluginModuleFactory, configEntry) {
                try {
                    if (typeof pluginModuleFactory !== "function") {
                        this.projectService.logger.info("Skipped loading plugin " + configEntry.name + " because it did expose a proper factory function");
                        return;
                    }
                    var info = {
                        config: configEntry,
                        project: this,
                        languageService: this.languageService,
                        languageServiceHost: this,
                        serverHost: this.projectService.host
                    };
                    var pluginModule = pluginModuleFactory({ typescript: ts });
                    var newLS = pluginModule.create(info);
                    for (var _i = 0, _a = Object.keys(this.languageService); _i < _a.length; _i++) {
                        var k = _a[_i];
                        if (!(k in newLS)) {
                            this.projectService.logger.info("Plugin activation warning: Missing proxied method " + k + " in created LS. Patching.");
                            newLS[k] = this.languageService[k];
                        }
                    }
                    this.projectService.logger.info("Plugin validation succeded");
                    this.languageService = newLS;
                    this.plugins.push({ name: configEntry.name, module: pluginModule });
                }
                catch (e) {
                    this.projectService.logger.info("Plugin activation failed: " + e);
                }
            };
            /*@internal*/
            Project.prototype.onPluginConfigurationChanged = function (pluginName, configuration) {
                this.plugins.filter(function (plugin) { return plugin.name === pluginName; }).forEach(function (plugin) {
                    if (plugin.module.onConfigurationChanged) {
                        plugin.module.onConfigurationChanged(configuration);
                    }
                });
            };
            /** Starts a new check for diagnostics. Call this if some file has updated that would cause diagnostics to be changed. */
            Project.prototype.refreshDiagnostics = function () {
                this.projectService.sendProjectsUpdatedInBackgroundEvent();
            };
            return Project;
        }());
        server.Project = Project;
        function getUnresolvedImports(program, cachedUnresolvedImportsPerFile) {
            var ambientModules = program.getTypeChecker().getAmbientModules().map(function (mod) { return ts.stripQuotes(mod.getName()); });
            return ts.sortAndDeduplicate(ts.flatMap(program.getSourceFiles(), function (sourceFile) {
                return extractUnresolvedImportsFromSourceFile(sourceFile, ambientModules, cachedUnresolvedImportsPerFile);
            }));
        }
        function extractUnresolvedImportsFromSourceFile(file, ambientModules, cachedUnresolvedImportsPerFile) {
            return ts.getOrUpdate(cachedUnresolvedImportsPerFile, file.path, function () {
                if (!file.resolvedModules)
                    return server.emptyArray;
                var unresolvedImports;
                file.resolvedModules.forEach(function (resolvedModule, name) {
                    // pick unresolved non-relative names
                    if ((!resolvedModule || !ts.resolutionExtensionIsTSOrJson(resolvedModule.extension)) &&
                        !ts.isExternalModuleNameRelative(name) &&
                        !ambientModules.some(function (m) { return m === name; })) {
                        unresolvedImports = ts.append(unresolvedImports, ts.parsePackageName(name).packageName);
                    }
                });
                return unresolvedImports || server.emptyArray;
            });
        }
        /**
         * If a file is opened and no tsconfig (or jsconfig) is found,
         * the file and its imports/references are put into an InferredProject.
         */
        var InferredProject = /** @class */ (function (_super) {
            __extends(InferredProject, _super);
            /*@internal*/
            function InferredProject(projectService, documentRegistry, compilerOptions, projectRootPath, currentDirectory, pluginConfigOverrides) {
                var _this = _super.call(this, InferredProject.newName(), ProjectKind.Inferred, projectService, documentRegistry, 
                // TODO: GH#18217
                /*files*/ undefined, 
                /*lastFileExceededProgramSize*/ undefined, compilerOptions, 
                /*compileOnSaveEnabled*/ false, projectService.host, currentDirectory) || this;
                _this._isJsInferredProject = false;
                _this.projectRootPath = projectRootPath && projectService.toCanonicalFileName(projectRootPath);
                if (!projectRootPath && !projectService.useSingleInferredProject) {
                    _this.canonicalCurrentDirectory = projectService.toCanonicalFileName(_this.currentDirectory);
                }
                _this.enableGlobalPlugins(_this.getCompilerOptions(), pluginConfigOverrides);
                return _this;
            }
            InferredProject.prototype.toggleJsInferredProject = function (isJsInferredProject) {
                if (isJsInferredProject !== this._isJsInferredProject) {
                    this._isJsInferredProject = isJsInferredProject;
                    this.setCompilerOptions();
                }
            };
            InferredProject.prototype.setCompilerOptions = function (options) {
                // Avoid manipulating the given options directly
                if (!options && !this.getCompilationSettings()) {
                    return;
                }
                var newOptions = ts.cloneCompilerOptions(options || this.getCompilationSettings());
                if (this._isJsInferredProject && typeof newOptions.maxNodeModuleJsDepth !== "number") {
                    newOptions.maxNodeModuleJsDepth = 2;
                }
                else if (!this._isJsInferredProject) {
                    newOptions.maxNodeModuleJsDepth = undefined;
                }
                newOptions.allowJs = true;
                _super.prototype.setCompilerOptions.call(this, newOptions);
            };
            InferredProject.prototype.addRoot = function (info) {
                ts.Debug.assert(info.isScriptOpen());
                this.projectService.startWatchingConfigFilesForInferredProjectRoot(info);
                if (!this._isJsInferredProject && info.isJavaScript()) {
                    this.toggleJsInferredProject(/*isJsInferredProject*/ true);
                }
                _super.prototype.addRoot.call(this, info);
            };
            InferredProject.prototype.removeRoot = function (info) {
                this.projectService.stopWatchingConfigFilesForInferredProjectRoot(info);
                _super.prototype.removeRoot.call(this, info);
                if (this._isJsInferredProject && info.isJavaScript()) {
                    if (ts.every(this.getRootScriptInfos(), function (rootInfo) { return !rootInfo.isJavaScript(); })) {
                        this.toggleJsInferredProject(/*isJsInferredProject*/ false);
                    }
                }
            };
            /*@internal*/
            InferredProject.prototype.isOrphan = function () {
                return !this.hasRoots();
            };
            InferredProject.prototype.isProjectWithSingleRoot = function () {
                // - when useSingleInferredProject is not set and projectRootPath is not set,
                //   we can guarantee that this will be the only root
                // - other wise it has single root if it has single root script info
                return (!this.projectRootPath && !this.projectService.useSingleInferredProject) ||
                    this.getRootScriptInfos().length === 1;
            };
            InferredProject.prototype.close = function () {
                var _this = this;
                ts.forEach(this.getRootScriptInfos(), function (info) { return _this.projectService.stopWatchingConfigFilesForInferredProjectRoot(info); });
                _super.prototype.close.call(this);
            };
            InferredProject.prototype.getTypeAcquisition = function () {
                return {
                    enable: allRootFilesAreJsOrDts(this),
                    include: [],
                    exclude: []
                };
            };
            InferredProject.newName = (function () {
                var nextId = 1;
                return function () {
                    var id = nextId;
                    nextId++;
                    return server.makeInferredProjectName(id);
                };
            })();
            return InferredProject;
        }(Project));
        server.InferredProject = InferredProject;
        /**
         * If a file is opened, the server will look for a tsconfig (or jsconfig)
         * and if successfull create a ConfiguredProject for it.
         * Otherwise it will create an InferredProject.
         */
        var ConfiguredProject = /** @class */ (function (_super) {
            __extends(ConfiguredProject, _super);
            /*@internal*/
            function ConfiguredProject(configFileName, projectService, documentRegistry, cachedDirectoryStructureHost) {
                var _this = _super.call(this, configFileName, ProjectKind.Configured, projectService, documentRegistry, 
                /*hasExplicitListOfFiles*/ false, 
                /*lastFileExceededProgramSize*/ undefined, 
                /*compilerOptions*/ {}, 
                /*compileOnSaveEnabled*/ false, cachedDirectoryStructureHost, ts.getDirectoryPath(configFileName)) || this;
                /*@internal*/
                _this.canConfigFileJsonReportNoInputFiles = false;
                /** Ref count to the project when opened from external project */
                _this.externalProjectRefCount = 0;
                _this.isInitialLoadPending = ts.returnTrue;
                /*@internal*/
                _this.sendLoadingProjectFinish = false;
                _this.canonicalConfigFilePath = server.asNormalizedPath(projectService.toCanonicalFileName(configFileName));
                return _this;
            }
            /**
             * If the project has reload from disk pending, it reloads (and then updates graph as part of that) instead of just updating the graph
             * @returns: true if set of files in the project stays the same and false - otherwise.
             */
            ConfiguredProject.prototype.updateGraph = function () {
                this.isInitialLoadPending = ts.returnFalse;
                var reloadLevel = this.pendingReload;
                this.pendingReload = ts.ConfigFileProgramReloadLevel.None;
                var result;
                switch (reloadLevel) {
                    case ts.ConfigFileProgramReloadLevel.Partial:
                        result = this.projectService.reloadFileNamesOfConfiguredProject(this);
                        break;
                    case ts.ConfigFileProgramReloadLevel.Full:
                        var reason = ts.Debug.assertDefined(this.pendingReloadReason);
                        this.pendingReloadReason = undefined;
                        this.projectService.reloadConfiguredProject(this, reason);
                        result = true;
                        break;
                    default:
                        result = _super.prototype.updateGraph.call(this);
                }
                this.projectService.sendProjectLoadingFinishEvent(this);
                this.projectService.sendProjectTelemetry(this);
                return result;
            };
            /*@internal*/
            ConfiguredProject.prototype.getCachedDirectoryStructureHost = function () {
                return this.directoryStructureHost;
            };
            ConfiguredProject.prototype.getConfigFilePath = function () {
                return server.asNormalizedPath(this.getProjectName());
            };
            ConfiguredProject.prototype.getProjectReferences = function () {
                return this.projectReferences;
            };
            ConfiguredProject.prototype.updateReferences = function (refs) {
                this.projectReferences = refs;
            };
            /*@internal*/
            ConfiguredProject.prototype.forEachResolvedProjectReference = function (cb) {
                var program = this.getCurrentProgram();
                return program && program.forEachResolvedProjectReference(cb);
            };
            /*@internal*/
            ConfiguredProject.prototype.enablePluginsWithOptions = function (options, pluginConfigOverrides) {
                var host = this.projectService.host;
                if (!host.require) {
                    this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded");
                    return;
                }
                // Search our peer node_modules, then any globally-specified probe paths
                // ../../.. to walk from X/node_modules/typescript/lib/tsserver.js to X/node_modules/
                var searchPaths = [ts.combinePaths(this.projectService.getExecutingFilePath(), "../../..")].concat(this.projectService.pluginProbeLocations);
                if (this.projectService.allowLocalPluginLoads) {
                    var local = ts.getDirectoryPath(this.canonicalConfigFilePath);
                    this.projectService.logger.info("Local plugin loading enabled; adding " + local + " to search paths");
                    searchPaths.unshift(local);
                }
                // Enable tsconfig-specified plugins
                if (options.plugins) {
                    for (var _i = 0, _a = options.plugins; _i < _a.length; _i++) {
                        var pluginConfigEntry = _a[_i];
                        this.enablePlugin(pluginConfigEntry, searchPaths, pluginConfigOverrides);
                    }
                }
                this.enableGlobalPlugins(options, pluginConfigOverrides);
            };
            /**
             * Get the errors that dont have any file name associated
             */
            ConfiguredProject.prototype.getGlobalProjectErrors = function () {
                return ts.filter(this.projectErrors, function (diagnostic) { return !diagnostic.file; }) || server.emptyArray;
            };
            /**
             * Get all the project errors
             */
            ConfiguredProject.prototype.getAllProjectErrors = function () {
                return this.projectErrors || server.emptyArray;
            };
            ConfiguredProject.prototype.setProjectErrors = function (projectErrors) {
                this.projectErrors = projectErrors;
            };
            ConfiguredProject.prototype.setTypeAcquisition = function (newTypeAcquisition) {
                this.typeAcquisition = this.removeLocalTypingsFromTypeAcquisition(newTypeAcquisition);
            };
            ConfiguredProject.prototype.getTypeAcquisition = function () {
                return this.typeAcquisition;
            };
            /*@internal*/
            ConfiguredProject.prototype.watchWildcards = function (wildcardDirectories) {
                var _this = this;
                ts.updateWatchingWildcardDirectories(this.directoriesWatchedForWildcards || (this.directoriesWatchedForWildcards = ts.createMap()), wildcardDirectories, 
                // Create new directory watcher
                function (directory, flags) { return _this.projectService.watchWildcardDirectory(directory, flags, _this); });
            };
            /*@internal*/
            ConfiguredProject.prototype.stopWatchingWildCards = function () {
                if (this.directoriesWatchedForWildcards) {
                    ts.clearMap(this.directoriesWatchedForWildcards, ts.closeFileWatcherOf);
                    this.directoriesWatchedForWildcards = undefined;
                }
            };
            ConfiguredProject.prototype.close = function () {
                if (this.configFileWatcher) {
                    this.configFileWatcher.close();
                    this.configFileWatcher = undefined;
                }
                this.stopWatchingWildCards();
                this.projectErrors = undefined;
                this.configFileSpecs = undefined;
                _super.prototype.close.call(this);
            };
            /* @internal */
            ConfiguredProject.prototype.addExternalProjectReference = function () {
                this.externalProjectRefCount++;
            };
            /* @internal */
            ConfiguredProject.prototype.deleteExternalProjectReference = function () {
                this.externalProjectRefCount--;
            };
            /** Returns true if the project is needed by any of the open script info/external project */
            /* @internal */
            ConfiguredProject.prototype.hasOpenRef = function () {
                var _this = this;
                if (!!this.externalProjectRefCount) {
                    return true;
                }
                // Closed project doesnt have any reference
                if (this.isClosed()) {
                    return false;
                }
                var configFileExistenceInfo = this.projectService.getConfigFileExistenceInfo(this);
                if (this.projectService.hasPendingProjectUpdate(this)) {
                    // If there is pending update for this project,
                    // we dont know if this project would be needed by any of the open files impacted by this config file
                    // In that case keep the project alive if there are open files impacted by this project
                    return !!configFileExistenceInfo.openFilesImpactedByConfigFile.size;
                }
                // If there is no pending update for this project,
                // We know exact set of open files that get impacted by this configured project as the files in the project
                // The project is referenced only if open files impacted by this project are present in this project
                return ts.forEachEntry(configFileExistenceInfo.openFilesImpactedByConfigFile, function (_value, infoPath) { return _this.containsScriptInfo(_this.projectService.getScriptInfoForPath(infoPath)); }) || false;
            };
            /*@internal*/
            ConfiguredProject.prototype.hasExternalProjectRef = function () {
                return !!this.externalProjectRefCount;
            };
            ConfiguredProject.prototype.getEffectiveTypeRoots = function () {
                return ts.getEffectiveTypeRoots(this.getCompilationSettings(), this.directoryStructureHost) || [];
            };
            /*@internal*/
            ConfiguredProject.prototype.updateErrorOnNoInputFiles = function (fileNameResult) {
                ts.updateErrorForNoInputFiles(fileNameResult, this.getConfigFilePath(), this.configFileSpecs, this.projectErrors, this.canConfigFileJsonReportNoInputFiles);
            };
            return ConfiguredProject;
        }(Project));
        server.ConfiguredProject = ConfiguredProject;
        /**
         * Project whose configuration is handled externally, such as in a '.csproj'.
         * These are created only if a host explicitly calls `openExternalProject`.
         */
        var ExternalProject = /** @class */ (function (_super) {
            __extends(ExternalProject, _super);
            /*@internal*/
            function ExternalProject(externalProjectName, projectService, documentRegistry, compilerOptions, lastFileExceededProgramSize, compileOnSaveEnabled, projectFilePath, pluginConfigOverrides) {
                var _this = _super.call(this, externalProjectName, ProjectKind.External, projectService, documentRegistry, 
                /*hasExplicitListOfFiles*/ true, lastFileExceededProgramSize, compilerOptions, compileOnSaveEnabled, projectService.host, ts.getDirectoryPath(projectFilePath || ts.normalizeSlashes(externalProjectName))) || this;
                _this.externalProjectName = externalProjectName;
                _this.compileOnSaveEnabled = compileOnSaveEnabled;
                _this.excludedFiles = [];
                _this.enableGlobalPlugins(_this.getCompilerOptions(), pluginConfigOverrides);
                return _this;
            }
            ExternalProject.prototype.updateGraph = function () {
                var result = _super.prototype.updateGraph.call(this);
                this.projectService.sendProjectTelemetry(this);
                return result;
            };
            ExternalProject.prototype.getExcludedFiles = function () {
                return this.excludedFiles;
            };
            ExternalProject.prototype.getTypeAcquisition = function () {
                return this.typeAcquisition;
            };
            ExternalProject.prototype.setTypeAcquisition = function (newTypeAcquisition) {
                ts.Debug.assert(!!newTypeAcquisition, "newTypeAcquisition may not be null/undefined");
                ts.Debug.assert(!!newTypeAcquisition.include, "newTypeAcquisition.include may not be null/undefined");
                ts.Debug.assert(!!newTypeAcquisition.exclude, "newTypeAcquisition.exclude may not be null/undefined");
                ts.Debug.assert(typeof newTypeAcquisition.enable === "boolean", "newTypeAcquisition.enable may not be null/undefined");
                this.typeAcquisition = this.removeLocalTypingsFromTypeAcquisition(newTypeAcquisition);
            };
            return ExternalProject;
        }(Project));
        server.ExternalProject = ExternalProject;
    })(server = ts.server || (ts.server = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    var server;
    (function (server) {
        server.maxProgramSizeForNonTsFiles = 20 * 1024 * 1024;
        /*@internal*/
        server.maxFileSize = 4 * 1024 * 1024;
        // tslint:disable variable-name
        server.ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground";
        server.ProjectLoadingStartEvent = "projectLoadingStart";
        server.ProjectLoadingFinishEvent = "projectLoadingFinish";
        server.LargeFileReferencedEvent = "largeFileReferenced";
        server.ConfigFileDiagEvent = "configFileDiag";
        server.ProjectLanguageServiceStateEvent = "projectLanguageServiceState";
        server.ProjectInfoTelemetryEvent = "projectInfo";
        server.OpenFileInfoTelemetryEvent = "openFileInfo";
        function prepareConvertersForEnumLikeCompilerOptions(commandLineOptions) {
            var map = ts.createMap();
            for (var _i = 0, commandLineOptions_1 = commandLineOptions; _i < commandLineOptions_1.length; _i++) {
                var option = commandLineOptions_1[_i];
                if (typeof option.type === "object") {
                    var optionMap = option.type;
                    // verify that map contains only numbers
                    optionMap.forEach(function (value) {
                        ts.Debug.assert(typeof value === "number");
                    });
                    map.set(option.name, optionMap);
                }
            }
            return map;
        }
        var compilerOptionConverters = prepareConvertersForEnumLikeCompilerOptions(ts.optionDeclarations);
        var indentStyle = ts.createMapFromTemplate({
            none: ts.IndentStyle.None,
            block: ts.IndentStyle.Block,
            smart: ts.IndentStyle.Smart
        });
        /**
         * How to understand this block:
         *  * The 'match' property is a regexp that matches a filename.
         *  * If 'match' is successful, then:
         *     * All files from 'exclude' are removed from the project. See below.
         *     * All 'types' are included in ATA
         *  * What the heck is 'exclude' ?
         *     * An array of an array of strings and numbers
         *     * Each array is:
         *       * An array of strings and numbers
         *       * The strings are literals
         *       * The numbers refer to capture group indices from the 'match' regexp
         *          * Remember that '1' is the first group
         *       * These are concatenated together to form a new regexp
         *       * Filenames matching these regexps are excluded from the project
         * This default value is tested in tsserverProjectSystem.ts; add tests there
         *   if you are changing this so that you can be sure your regexp works!
         */
        var defaultTypeSafeList = {
            "jquery": {
                // jquery files can have names like "jquery-1.10.2.min.js" (or "jquery.intellisense.js")
                match: /jquery(-(\.?\d+)+)?(\.intellisense)?(\.min)?\.js$/i,
                types: ["jquery"]
            },
            "WinJS": {
                // e.g. c:/temp/UWApp1/lib/winjs-4.0.1/js/base.js
                match: /^(.*\/winjs-[.\d]+)\/js\/base\.js$/i,
                exclude: [["^", 1, "/.*"]],
                types: ["winjs"] // And fetch the @types package for WinJS
            },
            "Kendo": {
                // e.g. /Kendo3/wwwroot/lib/kendo/kendo.all.min.js
                match: /^(.*\/kendo(-ui)?)\/kendo\.all(\.min)?\.js$/i,
                exclude: [["^", 1, "/.*"]],
                types: ["kendo-ui"]
            },
            "Office Nuget": {
                // e.g. /scripts/Office/1/excel-15.debug.js
                match: /^(.*\/office\/1)\/excel-\d+\.debug\.js$/i,
                exclude: [["^", 1, "/.*"]],
                types: ["office"] // @types package to fetch instead
            },
            "References": {
                match: /^(.*\/_references\.js)$/i,
                exclude: [["^", 1, "$"]]
            }
        };
        function convertFormatOptions(protocolOptions) {
            if (ts.isString(protocolOptions.indentStyle)) {
                protocolOptions.indentStyle = indentStyle.get(protocolOptions.indentStyle.toLowerCase());
                ts.Debug.assert(protocolOptions.indentStyle !== undefined);
            }
            return protocolOptions;
        }
        server.convertFormatOptions = convertFormatOptions;
        function convertCompilerOptions(protocolOptions) {
            compilerOptionConverters.forEach(function (mappedValues, id) {
                var propertyValue = protocolOptions[id];
                if (ts.isString(propertyValue)) {
                    protocolOptions[id] = mappedValues.get(propertyValue.toLowerCase());
                }
            });
            return protocolOptions;
        }
        server.convertCompilerOptions = convertCompilerOptions;
        function tryConvertScriptKindName(scriptKindName) {
            return ts.isString(scriptKindName) ? convertScriptKindName(scriptKindName) : scriptKindName;
        }
        server.tryConvertScriptKindName = tryConvertScriptKindName;
        function convertScriptKindName(scriptKindName) {
            switch (scriptKindName) {
                case "JS":
                    return 1 /* JS */;
                case "JSX":
                    return 2 /* JSX */;
                case "TS":
                    return 3 /* TS */;
                case "TSX":
                    return 4 /* TSX */;
                default:
                    return 0 /* Unknown */;
            }
        }
        server.convertScriptKindName = convertScriptKindName;
        /*@internal*/
        function convertUserPreferences(preferences) {
            var lazyConfiguredProjectsFromExternalProject = preferences.lazyConfiguredProjectsFromExternalProject, userPreferences = __rest(preferences, ["lazyConfiguredProjectsFromExternalProject"]);
            return userPreferences;
        }
        server.convertUserPreferences = convertUserPreferences;
        var fileNamePropertyReader = {
            getFileName: function (x) { return x; },
            getScriptKind: function (fileName, extraFileExtensions) {
                var result;
                if (extraFileExtensions) {
                    var fileExtension_1 = ts.getAnyExtensionFromPath(fileName);
                    if (fileExtension_1) {
                        ts.some(extraFileExtensions, function (info) {
                            if (info.extension === fileExtension_1) {
                                result = info.scriptKind;
                                return true;
                            }
                            return false;
                        });
                    }
                }
                return result; // TODO: GH#18217
            },
            hasMixedContent: function (fileName, extraFileExtensions) { return ts.some(extraFileExtensions, function (ext) { return ext.isMixedContent && ts.fileExtensionIs(fileName, ext.extension); }); },
        };
        var externalFilePropertyReader = {
            getFileName: function (x) { return x.fileName; },
            getScriptKind: function (x) { return tryConvertScriptKindName(x.scriptKind); },
            hasMixedContent: function (x) { return !!x.hasMixedContent; },
        };
        function findProjectByName(projectName, projects) {
            for (var _i = 0, projects_1 = projects; _i < projects_1.length; _i++) {
                var proj = projects_1[_i];
                if (proj.getProjectName() === projectName) {
                    return proj;
                }
            }
        }
        var ConfigFileWatcherStatus;
        (function (ConfigFileWatcherStatus) {
            ConfigFileWatcherStatus["ReloadingFiles"] = "Reloading configured projects for files";
            ConfigFileWatcherStatus["ReloadingInferredRootFiles"] = "Reloading configured projects for only inferred root files";
            ConfigFileWatcherStatus["UpdatedCallback"] = "Updated the callback";
            ConfigFileWatcherStatus["OpenFilesImpactedByConfigFileAdd"] = "File added to open files impacted by this config file";
            ConfigFileWatcherStatus["OpenFilesImpactedByConfigFileRemove"] = "File removed from open files impacted by this config file";
            ConfigFileWatcherStatus["RootOfInferredProjectTrue"] = "Open file was set as Inferred root";
            ConfigFileWatcherStatus["RootOfInferredProjectFalse"] = "Open file was set as not inferred root";
        })(ConfigFileWatcherStatus || (ConfigFileWatcherStatus = {}));
        function isOpenScriptInfo(infoOrFileName) {
            return !!infoOrFileName.containingProjects;
        }
        function getDetailWatchInfo(watchType, project) {
            return "Project: " + (project ? project.getProjectName() : "") + " WatchType: " + watchType;
        }
        function isScriptInfoWatchedFromNodeModules(info) {
            return !info.isScriptOpen() && info.mTime !== undefined;
        }
        /*@internal*/
        function updateProjectIfDirty(project) {
            return project.dirty && project.updateGraph();
        }
        server.updateProjectIfDirty = updateProjectIfDirty;
        function setProjectOptionsUsed(project) {
            if (project.projectKind === server.ProjectKind.Configured) {
                project.projectOptions = true;
            }
        }
        var ProjectService = /** @class */ (function () {
            function ProjectService(opts) {
                var _this = this;
                /**
                 * Container of all known scripts
                 */
                /*@internal*/
                this.filenameToScriptInfo = ts.createMap();
                this.scriptInfoInNodeModulesWatchers = ts.createMap();
                /**
                 * Contains all the deleted script info's version information so that
                 * it does not reset when creating script info again
                 * (and could have potentially collided with version where contents mismatch)
                 */
                this.filenameToScriptInfoVersion = ts.createMap();
                // Set of all '.js' files ever opened.
                this.allJsFilesForOpenFileTelemetry = ts.createMap();
                /**
                 * maps external project file name to list of config files that were the part of this project
                 */
                this.externalProjectToConfiguredProjectMap = ts.createMap();
                /**
                 * external projects (configuration and list of root files is not controlled by tsserver)
                 */
                this.externalProjects = [];
                /**
                 * projects built from openFileRoots
                 */
                this.inferredProjects = [];
                /**
                 * projects specified by a tsconfig.json file
                 */
                this.configuredProjects = ts.createMap();
                /**
                 * Open files: with value being project root path, and key being Path of the file that is open
                 */
                this.openFiles = ts.createMap();
                /**
                 * Map of open files that are opened without complete path but have projectRoot as current directory
                 */
                this.openFilesWithNonRootedDiskPath = ts.createMap();
                this.compilerOptionsForInferredProjectsPerProjectRoot = ts.createMap();
                /**
                 * Project size for configured or external projects
                 */
                this.projectToSizeMap = ts.createMap();
                /**
                 * This is a map of config file paths existance that doesnt need query to disk
                 * - The entry can be present because there is inferred project that needs to watch addition of config file to directory
                 *   In this case the exists could be true/false based on config file is present or not
                 * - Or it is present if we have configured project open with config file at that location
                 *   In this case the exists property is always true
                 */
                this.configFileExistenceInfoCache = ts.createMap();
                this.safelist = defaultTypeSafeList;
                this.legacySafelist = ts.createMap();
                this.pendingProjectUpdates = ts.createMap();
                /* @internal */
                this.pendingEnsureProjectForOpenFiles = false;
                /** Tracks projects that we have already sent telemetry for. */
                this.seenProjects = ts.createMap();
                this.host = opts.host;
                this.logger = opts.logger;
                this.cancellationToken = opts.cancellationToken;
                this.useSingleInferredProject = opts.useSingleInferredProject;
                this.useInferredProjectPerProjectRoot = opts.useInferredProjectPerProjectRoot;
                this.typingsInstaller = opts.typingsInstaller || server.nullTypingsInstaller;
                this.throttleWaitMilliseconds = opts.throttleWaitMilliseconds;
                this.eventHandler = opts.eventHandler;
                this.suppressDiagnosticEvents = opts.suppressDiagnosticEvents;
                this.globalPlugins = opts.globalPlugins || server.emptyArray;
                this.pluginProbeLocations = opts.pluginProbeLocations || server.emptyArray;
                this.allowLocalPluginLoads = !!opts.allowLocalPluginLoads;
                this.typesMapLocation = (opts.typesMapLocation === undefined) ? ts.combinePaths(ts.getDirectoryPath(this.getExecutingFilePath()), "typesMap.json") : opts.typesMapLocation;
                this.syntaxOnly = opts.syntaxOnly;
                ts.Debug.assert(!!this.host.createHash, "'ServerHost.createHash' is required for ProjectService");
                if (this.host.realpath) {
                    this.realpathToScriptInfos = ts.createMultiMap();
                }
                this.currentDirectory = server.toNormalizedPath(this.host.getCurrentDirectory());
                this.toCanonicalFileName = ts.createGetCanonicalFileName(this.host.useCaseSensitiveFileNames);
                this.globalCacheLocationDirectoryPath = this.typingsInstaller.globalTypingsCacheLocation
                    ? ts.ensureTrailingDirectorySeparator(this.toPath(this.typingsInstaller.globalTypingsCacheLocation))
                    : undefined;
                this.throttledOperations = new server.ThrottledOperations(this.host, this.logger);
                if (this.typesMapLocation) {
                    this.loadTypesMap();
                }
                else {
                    this.logger.info("No types map provided; using the default");
                }
                this.typingsInstaller.attach(this);
                this.typingsCache = new server.TypingsCache(this.typingsInstaller);
                this.hostConfiguration = {
                    formatCodeOptions: ts.getDefaultFormatCodeSettings(this.host.newLine),
                    preferences: ts.emptyOptions,
                    hostInfo: "Unknown host",
                    extraFileExtensions: []
                };
                this.documentRegistry = ts.createDocumentRegistryInternal(this.host.useCaseSensitiveFileNames, this.currentDirectory, this);
                var watchLogLevel = this.logger.hasLevel(server.LogLevel.verbose) ? ts.WatchLogLevel.Verbose :
                    this.logger.loggingEnabled() ? ts.WatchLogLevel.TriggerOnly : ts.WatchLogLevel.None;
                var log = watchLogLevel !== ts.WatchLogLevel.None ? (function (s) { return _this.logger.info(s); }) : ts.noop;
                this.watchFactory = ts.getWatchFactory(watchLogLevel, log, getDetailWatchInfo);
            }
            ProjectService.prototype.toPath = function (fileName) {
                return ts.toPath(fileName, this.currentDirectory, this.toCanonicalFileName);
            };
            /*@internal*/
            ProjectService.prototype.getExecutingFilePath = function () {
                return this.getNormalizedAbsolutePath(this.host.getExecutingFilePath());
            };
            /*@internal*/
            ProjectService.prototype.getNormalizedAbsolutePath = function (fileName) {
                return ts.getNormalizedAbsolutePath(fileName, this.host.getCurrentDirectory());
            };
            /*@internal*/
            ProjectService.prototype.setDocument = function (key, path, sourceFile) {
                var info = ts.Debug.assertDefined(this.getScriptInfoForPath(path));
                info.cacheSourceFile = { key: key, sourceFile: sourceFile };
            };
            /*@internal*/
            ProjectService.prototype.getDocument = function (key, path) {
                var info = this.getScriptInfoForPath(path);
                return info && info.cacheSourceFile && info.cacheSourceFile.key === key ? info.cacheSourceFile.sourceFile : undefined;
            };
            /* @internal */
            ProjectService.prototype.ensureInferredProjectsUpToDate_TestOnly = function () {
                this.ensureProjectStructuresUptoDate();
            };
            /* @internal */
            ProjectService.prototype.getCompilerOptionsForInferredProjects = function () {
                return this.compilerOptionsForInferredProjects;
            };
            /* @internal */
            ProjectService.prototype.onUpdateLanguageServiceStateForProject = function (project, languageServiceEnabled) {
                if (!this.eventHandler) {
                    return;
                }
                var event = {
                    eventName: server.ProjectLanguageServiceStateEvent,
                    data: { project: project, languageServiceEnabled: languageServiceEnabled }
                };
                this.eventHandler(event);
            };
            ProjectService.prototype.loadTypesMap = function () {
                try {
                    var fileContent = this.host.readFile(this.typesMapLocation); // TODO: GH#18217
                    if (fileContent === undefined) {
                        this.logger.info("Provided types map file \"" + this.typesMapLocation + "\" doesn't exist");
                        return;
                    }
                    var raw = JSON.parse(fileContent);
                    // Parse the regexps
                    for (var _i = 0, _a = Object.keys(raw.typesMap); _i < _a.length; _i++) {
                        var k = _a[_i];
                        raw.typesMap[k].match = new RegExp(raw.typesMap[k].match, "i");
                    }
                    // raw is now fixed and ready
                    this.safelist = raw.typesMap;
                    for (var key in raw.simpleMap) {
                        if (raw.simpleMap.hasOwnProperty(key)) {
                            this.legacySafelist.set(key, raw.simpleMap[key].toLowerCase());
                        }
                    }
                }
                catch (e) {
                    this.logger.info("Error loading types map: " + e);
                    this.safelist = defaultTypeSafeList;
                    this.legacySafelist.clear();
                }
            };
            ProjectService.prototype.updateTypingsForProject = function (response) {
                var project = this.findProject(response.projectName);
                if (!project) {
                    return;
                }
                switch (response.kind) {
                    case server.ActionSet:
                        // Update the typing files and update the project
                        project.updateTypingFiles(this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typeAcquisition, response.unresolvedImports, response.typings));
                        break;
                    case server.ActionInvalidate:
                        // Do not clear resolution cache, there was changes detected in typings, so enque typing request and let it get us correct results
                        this.typingsCache.enqueueInstallTypingsForProject(project, project.lastCachedUnresolvedImportsList, /*forceRefresh*/ true);
                        return;
                }
                this.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(project);
            };
            ProjectService.prototype.delayEnsureProjectForOpenFiles = function () {
                var _this = this;
                this.pendingEnsureProjectForOpenFiles = true;
                this.throttledOperations.schedule("*ensureProjectForOpenFiles*", /*delay*/ 250, function () {
                    if (_this.pendingProjectUpdates.size !== 0) {
                        _this.delayEnsureProjectForOpenFiles();
                    }
                    else {
                        if (_this.pendingEnsureProjectForOpenFiles) {
                            _this.ensureProjectForOpenFiles();
                            // Send the event to notify that there were background project updates
                            // send current list of open files
                            _this.sendProjectsUpdatedInBackgroundEvent();
                        }
                    }
                });
            };
            ProjectService.prototype.delayUpdateProjectGraph = function (project) {
                var _this = this;
                project.markAsDirty();
                var projectName = project.getProjectName();
                this.pendingProjectUpdates.set(projectName, project);
                this.throttledOperations.schedule(projectName, /*delay*/ 250, function () {
                    if (_this.pendingProjectUpdates.delete(projectName)) {
                        updateProjectIfDirty(project);
                    }
                });
            };
            /*@internal*/
            ProjectService.prototype.hasPendingProjectUpdate = function (project) {
                return this.pendingProjectUpdates.has(project.getProjectName());
            };
            /* @internal */
            ProjectService.prototype.sendProjectsUpdatedInBackgroundEvent = function () {
                var _this = this;
                if (!this.eventHandler) {
                    return;
                }
                var event = {
                    eventName: server.ProjectsUpdatedInBackgroundEvent,
                    data: {
                        openFiles: ts.arrayFrom(this.openFiles.keys(), function (path) { return _this.getScriptInfoForPath(path).fileName; })
                    }
                };
                this.eventHandler(event);
            };
            /* @internal */
            ProjectService.prototype.sendLargeFileReferencedEvent = function (file, fileSize) {
                if (!this.eventHandler) {
                    return;
                }
                var event = {
                    eventName: server.LargeFileReferencedEvent,
                    data: { file: file, fileSize: fileSize, maxFileSize: server.maxFileSize }
                };
                this.eventHandler(event);
            };
            /* @internal */
            ProjectService.prototype.sendProjectLoadingStartEvent = function (project, reason) {
                if (!this.eventHandler) {
                    return;
                }
                project.sendLoadingProjectFinish = true;
                var event = {
                    eventName: server.ProjectLoadingStartEvent,
                    data: { project: project, reason: reason }
                };
                this.eventHandler(event);
            };
            /* @internal */
            ProjectService.prototype.sendProjectLoadingFinishEvent = function (project) {
                if (!this.eventHandler || !project.sendLoadingProjectFinish) {
                    return;
                }
                project.sendLoadingProjectFinish = false;
                var event = {
                    eventName: server.ProjectLoadingFinishEvent,
                    data: { project: project }
                };
                this.eventHandler(event);
            };
            /* @internal */
            ProjectService.prototype.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles = function (project) {
                this.delayUpdateProjectGraph(project);
                this.delayEnsureProjectForOpenFiles();
            };
            ProjectService.prototype.delayUpdateProjectGraphs = function (projects) {
                if (projects.length) {
                    for (var _i = 0, projects_2 = projects; _i < projects_2.length; _i++) {
                        var project = projects_2[_i];
                        this.delayUpdateProjectGraph(project);
                    }
                    this.delayEnsureProjectForOpenFiles();
                }
            };
            ProjectService.prototype.setCompilerOptionsForInferredProjects = function (projectCompilerOptions, projectRootPath) {
                ts.Debug.assert(projectRootPath === undefined || this.useInferredProjectPerProjectRoot, "Setting compiler options per project root path is only supported when useInferredProjectPerProjectRoot is enabled");
                var compilerOptions = convertCompilerOptions(projectCompilerOptions);
                // always set 'allowNonTsExtensions' for inferred projects since user cannot configure it from the outside
                // previously we did not expose a way for user to change these settings and this option was enabled by default
                compilerOptions.allowNonTsExtensions = true;
                var canonicalProjectRootPath = projectRootPath && this.toCanonicalFileName(projectRootPath);
                if (canonicalProjectRootPath) {
                    this.compilerOptionsForInferredProjectsPerProjectRoot.set(canonicalProjectRootPath, compilerOptions);
                }
                else {
                    this.compilerOptionsForInferredProjects = compilerOptions;
                }
                for (var _i = 0, _a = this.inferredProjects; _i < _a.length; _i++) {
                    var project = _a[_i];
                    // Only update compiler options in the following cases:
                    // - Inferred projects without a projectRootPath, if the new options do not apply to
                    //   a workspace root
                    // - Inferred projects with a projectRootPath, if the new options do not apply to a
                    //   workspace root and there is no more specific set of options for that project's
                    //   root path
                    // - Inferred projects with a projectRootPath, if the new options apply to that
                    //   project root path.
                    if (canonicalProjectRootPath ?
                        project.projectRootPath === canonicalProjectRootPath :
                        !project.projectRootPath || !this.compilerOptionsForInferredProjectsPerProjectRoot.has(project.projectRootPath)) {
                        project.setCompilerOptions(compilerOptions);
                        project.compileOnSaveEnabled = compilerOptions.compileOnSave;
                        project.markAsDirty();
                        this.delayUpdateProjectGraph(project);
                    }
                }
                this.delayEnsureProjectForOpenFiles();
            };
            ProjectService.prototype.findProject = function (projectName) {
                if (projectName === undefined) {
                    return undefined;
                }
                if (server.isInferredProjectName(projectName)) {
                    return findProjectByName(projectName, this.inferredProjects);
                }
                return this.findExternalProjectByProjectName(projectName) || this.findConfiguredProjectByProjectName(server.toNormalizedPath(projectName));
            };
            /* @internal */
            ProjectService.prototype.forEachProject = function (cb) {
                this.externalProjects.forEach(cb);
                this.configuredProjects.forEach(cb);
                this.inferredProjects.forEach(cb);
            };
            /* @internal */
            ProjectService.prototype.forEachEnabledProject = function (cb) {
                this.forEachProject(function (project) {
                    if (!project.isOrphan() && project.languageServiceEnabled) {
                        cb(project);
                    }
                });
            };
            ProjectService.prototype.getDefaultProjectForFile = function (fileName, ensureProject) {
                return ensureProject ? this.ensureDefaultProjectForFile(fileName) : this.tryGetDefaultProjectForFile(fileName);
            };
            /* @internal */
            ProjectService.prototype.tryGetDefaultProjectForFile = function (fileName) {
                var scriptInfo = this.getScriptInfoForNormalizedPath(fileName);
                return scriptInfo && !scriptInfo.isOrphan() ? scriptInfo.getDefaultProject() : undefined;
            };
            /* @internal */
            ProjectService.prototype.ensureDefaultProjectForFile = function (fileName) {
                return this.tryGetDefaultProjectForFile(fileName) || this.doEnsureDefaultProjectForFile(fileName);
            };
            ProjectService.prototype.doEnsureDefaultProjectForFile = function (fileName) {
                this.ensureProjectStructuresUptoDate();
                var scriptInfo = this.getScriptInfoForNormalizedPath(fileName);
                return scriptInfo ? scriptInfo.getDefaultProject() : (this.logErrorForScriptInfoNotFound(fileName), server.Errors.ThrowNoProject());
            };
            ProjectService.prototype.getScriptInfoEnsuringProjectsUptoDate = function (uncheckedFileName) {
                this.ensureProjectStructuresUptoDate();
                return this.getScriptInfo(uncheckedFileName);
            };
            /**
             * Ensures the project structures are upto date
             * This means,
             * - we go through all the projects and update them if they are dirty
             * - if updates reflect some change in structure or there was pending request to ensure projects for open files
             *   ensure that each open script info has project
             */
            ProjectService.prototype.ensureProjectStructuresUptoDate = function () {
                var hasChanges = this.pendingEnsureProjectForOpenFiles;
                this.pendingProjectUpdates.clear();
                var updateGraph = function (project) {
                    hasChanges = updateProjectIfDirty(project) || hasChanges;
                };
                this.externalProjects.forEach(updateGraph);
                this.configuredProjects.forEach(updateGraph);
                this.inferredProjects.forEach(updateGraph);
                if (hasChanges) {
                    this.ensureProjectForOpenFiles();
                }
            };
            ProjectService.prototype.getFormatCodeOptions = function (file) {
                var info = this.getScriptInfoForNormalizedPath(file);
                return info && info.getFormatCodeSettings() || this.hostConfiguration.formatCodeOptions;
            };
            ProjectService.prototype.getPreferences = function (file) {
                var info = this.getScriptInfoForNormalizedPath(file);
                return __assign({}, this.hostConfiguration.preferences, info && info.getPreferences());
            };
            ProjectService.prototype.getHostFormatCodeOptions = function () {
                return this.hostConfiguration.formatCodeOptions;
            };
            ProjectService.prototype.getHostPreferences = function () {
                return this.hostConfiguration.preferences;
            };
            ProjectService.prototype.onSourceFileChanged = function (fileName, eventKind, path) {
                var info = this.getScriptInfoForPath(path);
                if (!info) {
                    this.logger.msg("Error: got watch notification for unknown file: " + fileName);
                }
                else {
                    if (info.containingProjects) {
                        info.containingProjects.forEach(function (project) { return project.resolutionCache.removeResolutionsFromProjectReferenceRedirects(info.path); });
                    }
                    if (eventKind === ts.FileWatcherEventKind.Deleted) {
                        // File was deleted
                        this.handleDeletedFile(info);
                    }
                    else if (!info.isScriptOpen()) {
                        // file has been changed which might affect the set of referenced files in projects that include
                        // this file and set of inferred projects
                        info.delayReloadNonMixedContentFile();
                        this.delayUpdateProjectGraphs(info.containingProjects);
                        this.handleSourceMapProjects(info);
                    }
                }
            };
            ProjectService.prototype.handleSourceMapProjects = function (info) {
                // Change in d.ts, update source projects as well
                if (info.sourceMapFilePath) {
                    if (ts.isString(info.sourceMapFilePath)) {
                        var sourceMapFileInfo = this.getScriptInfoForPath(info.sourceMapFilePath);
                        this.delayUpdateSourceInfoProjects(sourceMapFileInfo && sourceMapFileInfo.sourceInfos);
                    }
                    else {
                        this.delayUpdateSourceInfoProjects(info.sourceMapFilePath.sourceInfos);
                    }
                }
                // Change in mapInfo, update declarationProjects and source projects
                this.delayUpdateSourceInfoProjects(info.sourceInfos);
                if (info.declarationInfoPath) {
                    this.delayUpdateProjectsOfScriptInfoPath(info.declarationInfoPath);
                }
            };
            ProjectService.prototype.delayUpdateSourceInfoProjects = function (sourceInfos) {
                var _this = this;
                if (sourceInfos) {
                    sourceInfos.forEach(function (_value, path) { return _this.delayUpdateProjectsOfScriptInfoPath(path); });
                }
            };
            ProjectService.prototype.delayUpdateProjectsOfScriptInfoPath = function (path) {
                var info = this.getScriptInfoForPath(path);
                if (info) {
                    this.delayUpdateProjectGraphs(info.containingProjects);
                }
            };
            ProjectService.prototype.handleDeletedFile = function (info) {
                this.stopWatchingScriptInfo(info);
                if (!info.isScriptOpen()) {
                    this.deleteScriptInfo(info);
                    // capture list of projects since detachAllProjects will wipe out original list
                    var containingProjects = info.containingProjects.slice();
                    info.detachAllProjects();
                    // update projects to make sure that set of referenced files is correct
                    this.delayUpdateProjectGraphs(containingProjects);
                    this.handleSourceMapProjects(info);
                    info.closeSourceMapFileWatcher();
                    // need to recalculate source map from declaration file
                    if (info.declarationInfoPath) {
                        var declarationInfo = this.getScriptInfoForPath(info.declarationInfoPath);
                        if (declarationInfo) {
                            declarationInfo.sourceMapFilePath = undefined;
                        }
                    }
                }
            };
            /**
             * This is to watch whenever files are added or removed to the wildcard directories
             */
            /*@internal*/
            ProjectService.prototype.watchWildcardDirectory = function (directory, flags, project) {
                var _this = this;
                return this.watchFactory.watchDirectory(this.host, directory, function (fileOrDirectory) {
                    var fileOrDirectoryPath = _this.toPath(fileOrDirectory);
                    project.getCachedDirectoryStructureHost().addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
                    // don't trigger callback on open, existing files
                    if (project.fileIsOpen(fileOrDirectoryPath)) {
                        return;
                    }
                    if (ts.isPathIgnored(fileOrDirectoryPath))
                        return;
                    var configFilename = project.getConfigFilePath();
                    // 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, project.getCompilationSettings(), _this.hostConfiguration.extraFileExtensions)) {
                        _this.logger.info("Project: " + configFilename + " Detected file add/remove of non supported extension: " + fileOrDirectory);
                        return;
                    }
                    // Reload is pending, do the reload
                    if (project.pendingReload !== ts.ConfigFileProgramReloadLevel.Full) {
                        project.pendingReload = ts.ConfigFileProgramReloadLevel.Partial;
                        _this.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(project);
                    }
                }, flags, "Wild card directory" /* WildcardDirectory */, project);
            };
            /** Gets the config file existence info for the configured project */
            /*@internal*/
            ProjectService.prototype.getConfigFileExistenceInfo = function (project) {
                return this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath);
            };
            ProjectService.prototype.onConfigChangedForConfiguredProject = function (project, eventKind) {
                var configFileExistenceInfo = this.getConfigFileExistenceInfo(project);
                if (eventKind === ts.FileWatcherEventKind.Deleted) {
                    // Update the cached status
                    // We arent updating or removing the cached config file presence info as that will be taken care of by
                    // setConfigFilePresenceByClosedConfigFile when the project is closed (depending on tracking open files)
                    configFileExistenceInfo.exists = false;
                    this.removeProject(project);
                    // Reload the configured projects for the open files in the map as they are affected by this config file
                    // Since the configured project was deleted, we want to reload projects for all the open files including files
                    // that are not root of the inferred project
                    this.logConfigFileWatchUpdate(project.getConfigFilePath(), project.canonicalConfigFilePath, configFileExistenceInfo, "Reloading configured projects for files" /* ReloadingFiles */);
                    this.delayReloadConfiguredProjectForFiles(configFileExistenceInfo, /*ignoreIfNotInferredProjectRoot*/ false);
                }
                else {
                    this.logConfigFileWatchUpdate(project.getConfigFilePath(), project.canonicalConfigFilePath, configFileExistenceInfo, "Reloading configured projects for only inferred root files" /* ReloadingInferredRootFiles */);
                    project.pendingReload = ts.ConfigFileProgramReloadLevel.Full;
                    project.pendingReloadReason = "Change in config file detected";
                    this.delayUpdateProjectGraph(project);
                    // As we scheduled the update on configured project graph,
                    // we would need to schedule the project reload for only the root of inferred projects
                    this.delayReloadConfiguredProjectForFiles(configFileExistenceInfo, /*ignoreIfNotInferredProjectRoot*/ true);
                }
            };
            /**
             * This is the callback function for the config file add/remove/change at any location
             * that matters to open script info but doesnt have configured project open
             * for the config file
             */
            ProjectService.prototype.onConfigFileChangeForOpenScriptInfo = function (configFileName, eventKind) {
                // This callback is called only if we dont have config file project for this config file
                var canonicalConfigPath = server.normalizedPathToPath(configFileName, this.currentDirectory, this.toCanonicalFileName);
                var configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigPath);
                configFileExistenceInfo.exists = (eventKind !== ts.FileWatcherEventKind.Deleted);
                this.logConfigFileWatchUpdate(configFileName, canonicalConfigPath, configFileExistenceInfo, "Reloading configured projects for files" /* ReloadingFiles */);
                // Because there is no configured project open for the config file, the tracking open files map
                // will only have open files that need the re-detection of the project and hence
                // reload projects for all the tracking open files in the map
                this.delayReloadConfiguredProjectForFiles(configFileExistenceInfo, /*ignoreIfNotInferredProjectRoot*/ false);
            };
            ProjectService.prototype.removeProject = function (project) {
                var _this = this;
                this.logger.info("`remove Project::");
                project.print();
                project.close();
                if (ts.Debug.shouldAssert(1 /* Normal */)) {
                    this.filenameToScriptInfo.forEach(function (info) { return ts.Debug.assert(!info.isAttached(project), "Found script Info still attached to project", function () { return project.projectName + ": ScriptInfos still attached: " + JSON.stringify(ts.mapDefined(ts.arrayFrom(_this.filenameToScriptInfo.values()), function (info) { return info.isAttached(project) ? info : undefined; })); }); });
                }
                // Remove the project from pending project updates
                this.pendingProjectUpdates.delete(project.getProjectName());
                switch (project.projectKind) {
                    case server.ProjectKind.External:
                        ts.unorderedRemoveItem(this.externalProjects, project);
                        this.projectToSizeMap.delete(project.getProjectName());
                        break;
                    case server.ProjectKind.Configured:
                        this.configuredProjects.delete(project.canonicalConfigFilePath);
                        this.projectToSizeMap.delete(project.canonicalConfigFilePath);
                        this.setConfigFileExistenceInfoByClosedConfiguredProject(project);
                        break;
                    case server.ProjectKind.Inferred:
                        ts.unorderedRemoveItem(this.inferredProjects, project);
                        break;
                }
            };
            /*@internal*/
            ProjectService.prototype.assignOrphanScriptInfoToInferredProject = function (info, projectRootPath) {
                ts.Debug.assert(info.isOrphan());
                var project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath) ||
                    this.getOrCreateSingleInferredProjectIfEnabled() ||
                    this.getOrCreateSingleInferredWithoutProjectRoot(info.isDynamic ? this.currentDirectory : ts.getDirectoryPath(info.path));
                project.addRoot(info);
                if (info.containingProjects[0] !== project) {
                    // Ensure this is first project, we could be in this scenario because info could be part of orphan project
                    info.detachFromProject(project);
                    info.containingProjects.unshift(project);
                }
                project.updateGraph();
                if (!this.useSingleInferredProject && !project.projectRootPath) {
                    var _loop_2 = function (inferredProject) {
                        if (inferredProject === project || inferredProject.isOrphan()) {
                            return "continue";
                        }
                        // Remove the inferred project if the root of it is now part of newly created inferred project
                        // e.g through references
                        // Which means if any root of inferred project is part of more than 1 project can be removed
                        // This logic is same as iterating over all open files and calling
                        // this.removeRootOfInferredProjectIfNowPartOfOtherProject(f);
                        // Since this is also called from refreshInferredProject and closeOpen file
                        // to update inferred projects of the open file, this iteration might be faster
                        // instead of scanning all open files
                        var roots = inferredProject.getRootScriptInfos();
                        ts.Debug.assert(roots.length === 1 || !!inferredProject.projectRootPath);
                        if (roots.length === 1 && ts.forEach(roots[0].containingProjects, function (p) { return p !== roots[0].containingProjects[0] && !p.isOrphan(); })) {
                            inferredProject.removeFile(roots[0], /*fileExists*/ true, /*detachFromProject*/ true);
                        }
                    };
                    // Note that we need to create a copy of the array since the list of project can change
                    for (var _i = 0, _a = this.inferredProjects; _i < _a.length; _i++) {
                        var inferredProject = _a[_i];
                        _loop_2(inferredProject);
                    }
                }
                return project;
            };
            ProjectService.prototype.assignOrphanScriptInfosToInferredProject = function () {
                var _this = this;
                // collect orphaned files and assign them to inferred project just like we treat open of a file
                this.openFiles.forEach(function (projectRootPath, path) {
                    var info = _this.getScriptInfoForPath(path);
                    // collect all orphaned script infos from open files
                    if (info.isOrphan()) {
                        _this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
                    }
                });
            };
            /**
             * Remove this file from the set of open, non-configured files.
             * @param info The file that has been closed or newly configured
             */
            ProjectService.prototype.closeOpenFile = function (info, skipAssignOrphanScriptInfosToInferredProject) {
                // Closing file should trigger re-reading the file content from disk. This is
                // because the user may chose to discard the buffer content before saving
                // to the disk, and the server's version of the file can be out of sync.
                var fileExists = this.host.fileExists(info.fileName);
                info.close(fileExists);
                this.stopWatchingConfigFilesForClosedScriptInfo(info);
                var canonicalFileName = this.toCanonicalFileName(info.fileName);
                if (this.openFilesWithNonRootedDiskPath.get(canonicalFileName) === info) {
                    this.openFilesWithNonRootedDiskPath.delete(canonicalFileName);
                }
                // collect all projects that should be removed
                var ensureProjectsForOpenFiles = false;
                for (var _i = 0, _a = info.containingProjects; _i < _a.length; _i++) {
                    var p = _a[_i];
                    if (p.projectKind === server.ProjectKind.Configured) {
                        if (info.hasMixedContent) {
                            info.registerFileUpdate();
                        }
                        // Do not remove the project so that we can reuse this project
                        // if it would need to be re-created with next file open
                    }
                    else if (p.projectKind === server.ProjectKind.Inferred && p.isRoot(info)) {
                        // If this was the last open root file of inferred project
                        if (p.isProjectWithSingleRoot()) {
                            ensureProjectsForOpenFiles = true;
                        }
                        p.removeFile(info, fileExists, /*detachFromProject*/ true);
                        // Do not remove the project even if this was last root of the inferred project
                        // so that we can reuse this project, if it would need to be re-created with next file open
                    }
                    if (!p.languageServiceEnabled) {
                        // if project language service is disabled then we create a program only for open files.
                        // this means that project should be marked as dirty to force rebuilding of the program
                        // on the next request
                        p.markAsDirty();
                    }
                }
                this.openFiles.delete(info.path);
                if (!skipAssignOrphanScriptInfosToInferredProject && ensureProjectsForOpenFiles) {
                    this.assignOrphanScriptInfosToInferredProject();
                }
                // Cleanup script infos that arent part of any project (eg. those could be closed script infos not referenced by any project)
                // is postponed to next file open so that if file from same project is opened,
                // we wont end up creating same script infos
                // If the current info is being just closed - add the watcher file to track changes
                // But if file was deleted, handle that part
                if (fileExists) {
                    this.watchClosedScriptInfo(info);
                }
                else {
                    this.handleDeletedFile(info);
                }
                return ensureProjectsForOpenFiles;
            };
            ProjectService.prototype.deleteScriptInfo = function (info) {
                this.filenameToScriptInfo.delete(info.path);
                this.filenameToScriptInfoVersion.set(info.path, info.getVersion());
                var realpath = info.getRealpathIfDifferent();
                if (realpath) {
                    this.realpathToScriptInfos.remove(realpath, info); // TODO: GH#18217
                }
            };
            ProjectService.prototype.configFileExists = function (configFileName, canonicalConfigFilePath, info) {
                var configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
                if (configFileExistenceInfo) {
                    // By default the info would get impacted by presence of config file since its in the detection path
                    // Only adding the info as a root to inferred project will need the existence to be watched by file watcher
                    if (isOpenScriptInfo(info) && !configFileExistenceInfo.openFilesImpactedByConfigFile.has(info.path)) {
                        configFileExistenceInfo.openFilesImpactedByConfigFile.set(info.path, false);
                        this.logConfigFileWatchUpdate(configFileName, canonicalConfigFilePath, configFileExistenceInfo, "File added to open files impacted by this config file" /* OpenFilesImpactedByConfigFileAdd */);
                    }
                    return configFileExistenceInfo.exists;
                }
                // Theoretically we should be adding watch for the directory here itself.
                // In practice there will be very few scenarios where the config file gets added
                // somewhere inside the another config file directory.
                // And technically we could handle that case in configFile's directory watcher in some cases
                // But given that its a rare scenario it seems like too much overhead. (we werent watching those directories earlier either)
                // So what we are now watching is: configFile if the configured project corresponding to it is open
                // Or the whole chain of config files for the roots of the inferred projects
                // Cache the host value of file exists and add the info to map of open files impacted by this config file
                var exists = this.host.fileExists(configFileName);
                var openFilesImpactedByConfigFile = ts.createMap();
                if (isOpenScriptInfo(info)) {
                    openFilesImpactedByConfigFile.set(info.path, false);
                }
                configFileExistenceInfo = { exists: exists, openFilesImpactedByConfigFile: openFilesImpactedByConfigFile };
                this.configFileExistenceInfoCache.set(canonicalConfigFilePath, configFileExistenceInfo);
                this.logConfigFileWatchUpdate(configFileName, canonicalConfigFilePath, configFileExistenceInfo, "File added to open files impacted by this config file" /* OpenFilesImpactedByConfigFileAdd */);
                return exists;
            };
            ProjectService.prototype.setConfigFileExistenceByNewConfiguredProject = function (project) {
                var configFileExistenceInfo = this.getConfigFileExistenceInfo(project);
                if (configFileExistenceInfo) {
                    // The existance might not be set if the file watcher is not invoked by the time config project is created by external project
                    configFileExistenceInfo.exists = true;
                    // close existing watcher
                    if (configFileExistenceInfo.configFileWatcherForRootOfInferredProject) {
                        var configFileName = project.getConfigFilePath();
                        configFileExistenceInfo.configFileWatcherForRootOfInferredProject.close();
                        configFileExistenceInfo.configFileWatcherForRootOfInferredProject = undefined;
                        this.logConfigFileWatchUpdate(configFileName, project.canonicalConfigFilePath, configFileExistenceInfo, "Updated the callback" /* UpdatedCallback */);
                    }
                }
                else {
                    // We could be in this scenario if project is the configured project tracked by external project
                    // Since that route doesnt check if the config file is present or not
                    this.configFileExistenceInfoCache.set(project.canonicalConfigFilePath, {
                        exists: true,
                        openFilesImpactedByConfigFile: ts.createMap()
                    });
                }
            };
            /**
             * Returns true if the configFileExistenceInfo is needed/impacted by open files that are root of inferred project
             */
            ProjectService.prototype.configFileExistenceImpactsRootOfInferredProject = function (configFileExistenceInfo) {
                return ts.forEachEntry(configFileExistenceInfo.openFilesImpactedByConfigFile, function (isRootOfInferredProject) { return isRootOfInferredProject; });
            };
            ProjectService.prototype.setConfigFileExistenceInfoByClosedConfiguredProject = function (closedProject) {
                var configFileExistenceInfo = this.getConfigFileExistenceInfo(closedProject);
                ts.Debug.assert(!!configFileExistenceInfo);
                if (configFileExistenceInfo.openFilesImpactedByConfigFile.size) {
                    var configFileName = closedProject.getConfigFilePath();
                    // If there are open files that are impacted by this config file existence
                    // but none of them are root of inferred project, the config file watcher will be
                    // created when any of the script infos are added as root of inferred project
                    if (this.configFileExistenceImpactsRootOfInferredProject(configFileExistenceInfo)) {
                        ts.Debug.assert(!configFileExistenceInfo.configFileWatcherForRootOfInferredProject);
                        this.createConfigFileWatcherOfConfigFileExistence(configFileName, closedProject.canonicalConfigFilePath, configFileExistenceInfo);
                    }
                }
                else {
                    // There is not a single file open thats tracking the status of this config file. Remove from cache
                    this.configFileExistenceInfoCache.delete(closedProject.canonicalConfigFilePath);
                }
            };
            ProjectService.prototype.logConfigFileWatchUpdate = function (configFileName, canonicalConfigFilePath, configFileExistenceInfo, status) {
                var _this = this;
                if (!this.logger.hasLevel(server.LogLevel.verbose)) {
                    return;
                }
                var inferredRoots = [];
                var otherFiles = [];
                configFileExistenceInfo.openFilesImpactedByConfigFile.forEach(function (isRootOfInferredProject, key) {
                    var info = _this.getScriptInfoForPath(key);
                    (isRootOfInferredProject ? inferredRoots : otherFiles).push(info.fileName);
                });
                var watches = [];
                if (configFileExistenceInfo.configFileWatcherForRootOfInferredProject) {
                    watches.push("Config file for the inferred project root" /* ConfigFileForInferredRoot */);
                }
                if (this.configuredProjects.has(canonicalConfigFilePath)) {
                    watches.push("Config file" /* ConfigFile */);
                }
                this.logger.info("ConfigFilePresence:: Current Watches: " + watches + ":: File: " + configFileName + " Currently impacted open files: RootsOfInferredProjects: " + inferredRoots + " OtherOpenFiles: " + otherFiles + " Status: " + status);
            };
            /**
             * Create the watcher for the configFileExistenceInfo
             */
            ProjectService.prototype.createConfigFileWatcherOfConfigFileExistence = function (configFileName, canonicalConfigFilePath, configFileExistenceInfo) {
                var _this = this;
                configFileExistenceInfo.configFileWatcherForRootOfInferredProject = this.watchFactory.watchFile(this.host, configFileName, function (_filename, eventKind) { return _this.onConfigFileChangeForOpenScriptInfo(configFileName, eventKind); }, ts.PollingInterval.High, "Config file for the inferred project root" /* ConfigFileForInferredRoot */);
                this.logConfigFileWatchUpdate(configFileName, canonicalConfigFilePath, configFileExistenceInfo, "Updated the callback" /* UpdatedCallback */);
            };
            /**
             * Close the config file watcher in the cached ConfigFileExistenceInfo
             *   if there arent any open files that are root of inferred project
             */
            ProjectService.prototype.closeConfigFileWatcherOfConfigFileExistenceInfo = function (configFileExistenceInfo) {
                // Close the config file watcher if there are no more open files that are root of inferred project
                if (configFileExistenceInfo.configFileWatcherForRootOfInferredProject &&
                    !this.configFileExistenceImpactsRootOfInferredProject(configFileExistenceInfo)) {
                    configFileExistenceInfo.configFileWatcherForRootOfInferredProject.close();
                    configFileExistenceInfo.configFileWatcherForRootOfInferredProject = undefined;
                }
            };
            /**
             * This is called on file close, so that we stop watching the config file for this script info
             */
            ProjectService.prototype.stopWatchingConfigFilesForClosedScriptInfo = function (info) {
                var _this = this;
                ts.Debug.assert(!info.isScriptOpen());
                this.forEachConfigFileLocation(info, function (configFileName, canonicalConfigFilePath) {
                    var configFileExistenceInfo = _this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
                    if (configFileExistenceInfo) {
                        var infoIsRootOfInferredProject = configFileExistenceInfo.openFilesImpactedByConfigFile.get(info.path);
                        // Delete the info from map, since this file is no more open
                        configFileExistenceInfo.openFilesImpactedByConfigFile.delete(info.path);
                        _this.logConfigFileWatchUpdate(configFileName, canonicalConfigFilePath, configFileExistenceInfo, "File removed from open files impacted by this config file" /* OpenFilesImpactedByConfigFileRemove */);
                        // If the script info was not root of inferred project,
                        // there wont be config file watch open because of this script info
                        if (infoIsRootOfInferredProject) {
                            // But if it is a root, it could be the last script info that is root of inferred project
                            // and hence we would need to close the config file watcher
                            _this.closeConfigFileWatcherOfConfigFileExistenceInfo(configFileExistenceInfo);
                        }
                        // If there are no open files that are impacted by configFileExistenceInfo after closing this script info
                        // there is no configured project present, remove the cached existence info
                        if (!configFileExistenceInfo.openFilesImpactedByConfigFile.size &&
                            !_this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath)) {
                            ts.Debug.assert(!configFileExistenceInfo.configFileWatcherForRootOfInferredProject);
                            _this.configFileExistenceInfoCache.delete(canonicalConfigFilePath);
                        }
                    }
                });
            };
            /**
             * This is called by inferred project whenever script info is added as a root
             */
            /* @internal */
            ProjectService.prototype.startWatchingConfigFilesForInferredProjectRoot = function (info) {
                var _this = this;
                ts.Debug.assert(info.isScriptOpen());
                this.forEachConfigFileLocation(info, function (configFileName, canonicalConfigFilePath) {
                    var configFileExistenceInfo = _this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
                    if (!configFileExistenceInfo) {
                        // Create the cache
                        configFileExistenceInfo = {
                            exists: _this.host.fileExists(configFileName),
                            openFilesImpactedByConfigFile: ts.createMap()
                        };
                        _this.configFileExistenceInfoCache.set(canonicalConfigFilePath, configFileExistenceInfo);
                    }
                    // Set this file as the root of inferred project
                    configFileExistenceInfo.openFilesImpactedByConfigFile.set(info.path, true);
                    _this.logConfigFileWatchUpdate(configFileName, canonicalConfigFilePath, configFileExistenceInfo, "Open file was set as Inferred root" /* RootOfInferredProjectTrue */);
                    // If there is no configured project for this config file, add the file watcher
                    if (!configFileExistenceInfo.configFileWatcherForRootOfInferredProject &&
                        !_this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath)) {
                        _this.createConfigFileWatcherOfConfigFileExistence(configFileName, canonicalConfigFilePath, configFileExistenceInfo);
                    }
                });
            };
            /**
             * This is called by inferred project whenever root script info is removed from it
             */
            /* @internal */
            ProjectService.prototype.stopWatchingConfigFilesForInferredProjectRoot = function (info) {
                var _this = this;
                this.forEachConfigFileLocation(info, function (configFileName, canonicalConfigFilePath) {
                    var configFileExistenceInfo = _this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
                    if (configFileExistenceInfo && configFileExistenceInfo.openFilesImpactedByConfigFile.has(info.path)) {
                        ts.Debug.assert(info.isScriptOpen());
                        // Info is not root of inferred project any more
                        configFileExistenceInfo.openFilesImpactedByConfigFile.set(info.path, false);
                        _this.logConfigFileWatchUpdate(configFileName, canonicalConfigFilePath, configFileExistenceInfo, "Open file was set as not inferred root" /* RootOfInferredProjectFalse */);
                        // Close the config file watcher
                        _this.closeConfigFileWatcherOfConfigFileExistenceInfo(configFileExistenceInfo);
                    }
                });
            };
            /**
             * This function tries to search for a tsconfig.json for the given file.
             * This is different from the method the compiler uses because
             * the compiler can assume it will always start searching in the
             * current directory (the directory in which tsc was invoked).
             * The server must start searching from the directory containing
             * the newly opened file.
             */
            ProjectService.prototype.forEachConfigFileLocation = function (info, action) {
                var _this = this;
                if (this.syntaxOnly) {
                    return undefined;
                }
                ts.Debug.assert(!isOpenScriptInfo(info) || this.openFiles.has(info.path));
                var projectRootPath = this.openFiles.get(info.path);
                var searchPath = server.asNormalizedPath(ts.getDirectoryPath(info.fileName));
                var isSearchPathInProjectRoot = function () { return ts.containsPath(projectRootPath, searchPath, _this.currentDirectory, !_this.host.useCaseSensitiveFileNames); };
                // If projectRootPath doesn't contain info.path, then do normal search for config file
                var anySearchPathOk = !projectRootPath || !isSearchPathInProjectRoot();
                do {
                    var canonicalSearchPath = server.normalizedPathToPath(searchPath, this.currentDirectory, this.toCanonicalFileName);
                    var tsconfigFileName = server.asNormalizedPath(ts.combinePaths(searchPath, "tsconfig.json"));
                    var result = action(tsconfigFileName, ts.combinePaths(canonicalSearchPath, "tsconfig.json"));
                    if (result) {
                        return tsconfigFileName;
                    }
                    var jsconfigFileName = server.asNormalizedPath(ts.combinePaths(searchPath, "jsconfig.json"));
                    result = action(jsconfigFileName, ts.combinePaths(canonicalSearchPath, "jsconfig.json"));
                    if (result) {
                        return jsconfigFileName;
                    }
                    var parentPath = server.asNormalizedPath(ts.getDirectoryPath(searchPath));
                    if (parentPath === searchPath) {
                        break;
                    }
                    searchPath = parentPath;
                } while (anySearchPathOk || isSearchPathInProjectRoot());
                return undefined;
            };
            /**
             * This function tries to search for a tsconfig.json for the given file.
             * This is different from the method the compiler uses because
             * the compiler can assume it will always start searching in the
             * current directory (the directory in which tsc was invoked).
             * The server must start searching from the directory containing
             * the newly opened file.
             * If script info is passed in, it is asserted to be open script info
             * otherwise just file name
             */
            ProjectService.prototype.getConfigFileNameForFile = function (info) {
                var _this = this;
                if (isOpenScriptInfo(info))
                    ts.Debug.assert(info.isScriptOpen());
                this.logger.info("Search path: " + ts.getDirectoryPath(info.fileName));
                var configFileName = this.forEachConfigFileLocation(info, function (configFileName, canonicalConfigFilePath) {
                    return _this.configFileExists(configFileName, canonicalConfigFilePath, info);
                });
                if (configFileName) {
                    this.logger.info("For info: " + info.fileName + " :: Config file name: " + configFileName);
                }
                else {
                    this.logger.info("For info: " + info.fileName + " :: No config files found.");
                }
                return configFileName;
            };
            ProjectService.prototype.printProjects = function () {
                var _this = this;
                if (!this.logger.hasLevel(server.LogLevel.normal)) {
                    return;
                }
                var writeProjectFileNames = this.logger.hasLevel(server.LogLevel.verbose);
                this.logger.startGroup();
                var counter = printProjectsWithCounter(this.externalProjects, 0);
                counter = printProjectsWithCounter(ts.arrayFrom(this.configuredProjects.values()), counter);
                printProjectsWithCounter(this.inferredProjects, counter);
                this.logger.info("Open files: ");
                this.openFiles.forEach(function (projectRootPath, path) {
                    var info = _this.getScriptInfoForPath(path);
                    _this.logger.info("\tFileName: " + info.fileName + " ProjectRootPath: " + projectRootPath);
                    if (writeProjectFileNames) {
                        _this.logger.info("\t\tProjects: " + info.containingProjects.map(function (p) { return p.getProjectName(); }));
                    }
                });
                this.logger.endGroup();
            };
            ProjectService.prototype.findConfiguredProjectByProjectName = function (configFileName) {
                // make sure that casing of config file name is consistent
                var canonicalConfigFilePath = server.asNormalizedPath(this.toCanonicalFileName(configFileName));
                return this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath);
            };
            ProjectService.prototype.getConfiguredProjectByCanonicalConfigFilePath = function (canonicalConfigFilePath) {
                return this.configuredProjects.get(canonicalConfigFilePath);
            };
            ProjectService.prototype.findExternalProjectByProjectName = function (projectFileName) {
                return findProjectByName(projectFileName, this.externalProjects);
            };
            /** Get a filename if the language service exceeds the maximum allowed program size; otherwise returns undefined. */
            ProjectService.prototype.getFilenameForExceededTotalSizeLimitForNonTsFiles = function (name, options, fileNames, propertyReader) {
                if (options && options.disableSizeLimit || !this.host.getFileSize) {
                    return;
                }
                var availableSpace = server.maxProgramSizeForNonTsFiles;
                this.projectToSizeMap.set(name, 0);
                this.projectToSizeMap.forEach(function (val) { return (availableSpace -= (val || 0)); });
                var totalNonTsFileSize = 0;
                for (var _i = 0, fileNames_1 = fileNames; _i < fileNames_1.length; _i++) {
                    var f = fileNames_1[_i];
                    var fileName = propertyReader.getFileName(f);
                    if (ts.hasTSFileExtension(fileName)) {
                        continue;
                    }
                    totalNonTsFileSize += this.host.getFileSize(fileName);
                    if (totalNonTsFileSize > server.maxProgramSizeForNonTsFiles || totalNonTsFileSize > availableSpace) {
                        this.logger.info(getExceedLimitMessage({ propertyReader: propertyReader, hasTSFileExtension: ts.hasTSFileExtension, host: this.host }, totalNonTsFileSize));
                        // Keep the size as zero since it's disabled
                        return fileName;
                    }
                }
                this.projectToSizeMap.set(name, totalNonTsFileSize);
                return;
                function getExceedLimitMessage(context, totalNonTsFileSize) {
                    var files = getTop5LargestFiles(context);
                    return "Non TS file size exceeded limit (" + totalNonTsFileSize + "). Largest files: " + files.map(function (file) { return file.name + ":" + file.size; }).join(", ");
                }
                function getTop5LargestFiles(_a) {
                    var propertyReader = _a.propertyReader, hasTSFileExtension = _a.hasTSFileExtension, host = _a.host;
                    return fileNames.map(function (f) { return propertyReader.getFileName(f); })
                        .filter(function (name) { return hasTSFileExtension(name); })
                        .map(function (name) { return ({ name: name, size: host.getFileSize(name) }); }) // TODO: GH#18217
                        .sort(function (a, b) { return b.size - a.size; })
                        .slice(0, 5);
                }
            };
            ProjectService.prototype.createExternalProject = function (projectFileName, files, options, typeAcquisition, excludedFiles) {
                var compilerOptions = convertCompilerOptions(options);
                var project = new server.ExternalProject(projectFileName, this, this.documentRegistry, compilerOptions, 
                /*lastFileExceededProgramSize*/ this.getFilenameForExceededTotalSizeLimitForNonTsFiles(projectFileName, compilerOptions, files, externalFilePropertyReader), options.compileOnSave === undefined ? true : options.compileOnSave, 
                /*projectFilePath*/ undefined, this.currentPluginConfigOverrides);
                project.excludedFiles = excludedFiles;
                this.addFilesToNonInferredProject(project, files, externalFilePropertyReader, typeAcquisition);
                this.externalProjects.push(project);
                return project;
            };
            /*@internal*/
            ProjectService.prototype.sendProjectTelemetry = function (project) {
                if (this.seenProjects.has(project.projectName)) {
                    setProjectOptionsUsed(project);
                    return;
                }
                this.seenProjects.set(project.projectName, true);
                if (!this.eventHandler || !this.host.createSHA256Hash) {
                    setProjectOptionsUsed(project);
                    return;
                }
                var projectOptions = project.projectKind === server.ProjectKind.Configured ? project.projectOptions : undefined;
                setProjectOptionsUsed(project);
                var data = {
                    projectId: this.host.createSHA256Hash(project.projectName),
                    fileStats: server.countEachFileTypes(project.getScriptInfos(), /*includeSizes*/ true),
                    compilerOptions: ts.convertCompilerOptionsForTelemetry(project.getCompilationSettings()),
                    typeAcquisition: convertTypeAcquisition(project.getTypeAcquisition()),
                    extends: projectOptions && projectOptions.configHasExtendsProperty,
                    files: projectOptions && projectOptions.configHasFilesProperty,
                    include: projectOptions && projectOptions.configHasIncludeProperty,
                    exclude: projectOptions && projectOptions.configHasExcludeProperty,
                    compileOnSave: project.compileOnSaveEnabled,
                    configFileName: configFileName(),
                    projectType: project instanceof server.ExternalProject ? "external" : "configured",
                    languageServiceEnabled: project.languageServiceEnabled,
                    version: ts.version,
                };
                this.eventHandler({ eventName: server.ProjectInfoTelemetryEvent, data: data });
                function configFileName() {
                    if (!(project instanceof server.ConfiguredProject)) {
                        return "other";
                    }
                    return server.getBaseConfigFileName(project.getConfigFilePath()) || "other";
                }
                function convertTypeAcquisition(_a) {
                    var enable = _a.enable, include = _a.include, exclude = _a.exclude;
                    return {
                        enable: enable,
                        include: include !== undefined && include.length !== 0,
                        exclude: exclude !== undefined && exclude.length !== 0,
                    };
                }
            };
            ProjectService.prototype.addFilesToNonInferredProject = function (project, files, propertyReader, typeAcquisition) {
                this.updateNonInferredProjectFiles(project, files, propertyReader);
                project.setTypeAcquisition(typeAcquisition);
            };
            ProjectService.prototype.createConfiguredProject = function (configFileName) {
                var _this = this;
                var cachedDirectoryStructureHost = ts.createCachedDirectoryStructureHost(this.host, this.host.getCurrentDirectory(), this.host.useCaseSensitiveFileNames); // TODO: GH#18217
                this.logger.info("Opened configuration file " + configFileName);
                var project = new server.ConfiguredProject(configFileName, this, this.documentRegistry, cachedDirectoryStructureHost);
                // TODO: We probably should also watch the configFiles that are extended
                project.configFileWatcher = this.watchFactory.watchFile(this.host, configFileName, function (_fileName, eventKind) { return _this.onConfigChangedForConfiguredProject(project, eventKind); }, ts.PollingInterval.High, "Config file" /* ConfigFile */, project);
                this.configuredProjects.set(project.canonicalConfigFilePath, project);
                this.setConfigFileExistenceByNewConfiguredProject(project);
                return project;
            };
            /* @internal */
            ProjectService.prototype.createConfiguredProjectWithDelayLoad = function (configFileName, reason) {
                var project = this.createConfiguredProject(configFileName);
                project.pendingReload = ts.ConfigFileProgramReloadLevel.Full;
                project.pendingReloadReason = reason;
                return project;
            };
            /* @internal */
            ProjectService.prototype.createAndLoadConfiguredProject = function (configFileName, reason) {
                var project = this.createConfiguredProject(configFileName);
                this.loadConfiguredProject(project, reason);
                return project;
            };
            /* @internal */
            ProjectService.prototype.createLoadAndUpdateConfiguredProject = function (configFileName, reason) {
                var project = this.createAndLoadConfiguredProject(configFileName, reason);
                project.updateGraph();
                return project;
            };
            /**
             * Read the config file of the project, and update the project root file names.
             */
            /* @internal */
            ProjectService.prototype.loadConfiguredProject = function (project, reason) {
                this.sendProjectLoadingStartEvent(project, reason);
                // Read updated contents from disk
                var configFilename = ts.normalizePath(project.getConfigFilePath());
                var configFileContent = this.host.readFile(configFilename); // TODO: GH#18217
                var result = ts.parseJsonText(configFilename, configFileContent);
                if (!result.endOfFileToken) {
                    result.endOfFileToken = { kind: 1 /* EndOfFileToken */ };
                }
                var configFileErrors = result.parseDiagnostics;
                var parsedCommandLine = ts.parseJsonSourceFileConfigFileContent(result, project.getCachedDirectoryStructureHost(), ts.getDirectoryPath(configFilename), 
                /*existingOptions*/ {}, configFilename, 
                /*resolutionStack*/ [], this.hostConfiguration.extraFileExtensions);
                if (parsedCommandLine.errors.length) {
                    configFileErrors.push.apply(configFileErrors, parsedCommandLine.errors);
                }
                ts.Debug.assert(!!parsedCommandLine.fileNames);
                var compilerOptions = parsedCommandLine.options;
                // Update the project
                if (!project.projectOptions) {
                    project.projectOptions = {
                        configHasExtendsProperty: parsedCommandLine.raw.extends !== undefined,
                        configHasFilesProperty: parsedCommandLine.raw.files !== undefined,
                        configHasIncludeProperty: parsedCommandLine.raw.include !== undefined,
                        configHasExcludeProperty: parsedCommandLine.raw.exclude !== undefined
                    };
                }
                project.configFileSpecs = parsedCommandLine.configFileSpecs;
                project.canConfigFileJsonReportNoInputFiles = ts.canJsonReportNoInutFiles(parsedCommandLine.raw);
                project.setProjectErrors(configFileErrors);
                project.updateReferences(parsedCommandLine.projectReferences);
                var lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, compilerOptions, parsedCommandLine.fileNames, fileNamePropertyReader);
                if (lastFileExceededProgramSize) {
                    project.disableLanguageService(lastFileExceededProgramSize);
                    project.stopWatchingWildCards();
                }
                else {
                    project.enableLanguageService();
                    project.watchWildcards(ts.createMapFromTemplate(parsedCommandLine.wildcardDirectories)); // TODO: GH#18217
                }
                project.enablePluginsWithOptions(compilerOptions, this.currentPluginConfigOverrides);
                var filesToAdd = parsedCommandLine.fileNames.concat(project.getExternalFiles());
                this.updateRootAndOptionsOfNonInferredProject(project, filesToAdd, fileNamePropertyReader, compilerOptions, parsedCommandLine.typeAcquisition, parsedCommandLine.compileOnSave); // TODO: GH#18217
            };
            ProjectService.prototype.updateNonInferredProjectFiles = function (project, files, propertyReader) {
                var projectRootFilesMap = project.getRootFilesMap();
                var newRootScriptInfoMap = ts.createMap();
                for (var _i = 0, files_1 = files; _i < files_1.length; _i++) {
                    var f = files_1[_i];
                    var newRootFile = propertyReader.getFileName(f);
                    var normalizedPath = server.toNormalizedPath(newRootFile);
                    var isDynamic = server.isDynamicFileName(normalizedPath);
                    var scriptInfo = void 0;
                    var path = void 0;
                    // Use the project's fileExists so that it can use caching instead of reaching to disk for the query
                    if (!isDynamic && !project.fileExists(newRootFile)) {
                        path = server.normalizedPathToPath(normalizedPath, this.currentDirectory, this.toCanonicalFileName);
                        var existingValue = projectRootFilesMap.get(path);
                        if (server.isScriptInfo(existingValue)) {
                            project.removeFile(existingValue, /*fileExists*/ false, /*detachFromProject*/ true);
                        }
                        projectRootFilesMap.set(path, normalizedPath);
                        scriptInfo = normalizedPath;
                    }
                    else {
                        var scriptKind = propertyReader.getScriptKind(f, this.hostConfiguration.extraFileExtensions);
                        var hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.extraFileExtensions);
                        scriptInfo = this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(normalizedPath, project.currentDirectory, scriptKind, hasMixedContent, project.directoryStructureHost); // TODO: GH#18217
                        path = scriptInfo.path;
                        // If this script info is not already a root add it
                        if (!project.isRoot(scriptInfo)) {
                            project.addRoot(scriptInfo);
                            if (scriptInfo.isScriptOpen()) {
                                // if file is already root in some inferred project
                                // - remove the file from that project and delete the project if necessary
                                this.removeRootOfInferredProjectIfNowPartOfOtherProject(scriptInfo);
                            }
                        }
                    }
                    newRootScriptInfoMap.set(path, scriptInfo);
                }
                // project's root file map size is always going to be same or larger than new roots map
                // as we have already all the new files to the project
                if (projectRootFilesMap.size > newRootScriptInfoMap.size) {
                    projectRootFilesMap.forEach(function (value, path) {
                        if (!newRootScriptInfoMap.has(path)) {
                            if (server.isScriptInfo(value)) {
                                project.removeFile(value, project.fileExists(path), /*detachFromProject*/ true);
                            }
                            else {
                                projectRootFilesMap.delete(path);
                            }
                        }
                    });
                }
                // Just to ensure that even if root files dont change, the changes to the non root file are picked up,
                // mark the project as dirty unconditionally
                project.markAsDirty();
            };
            ProjectService.prototype.updateRootAndOptionsOfNonInferredProject = function (project, newUncheckedFiles, propertyReader, newOptions, newTypeAcquisition, compileOnSave) {
                project.setCompilerOptions(newOptions);
                // VS only set the CompileOnSaveEnabled option in the request if the option was changed recently
                // therefore if it is undefined, it should not be updated.
                if (compileOnSave !== undefined) {
                    project.compileOnSaveEnabled = compileOnSave;
                }
                this.addFilesToNonInferredProject(project, newUncheckedFiles, propertyReader, newTypeAcquisition);
            };
            /**
             * Reload the file names from config file specs and update the project graph
             */
            /*@internal*/
            ProjectService.prototype.reloadFileNamesOfConfiguredProject = function (project) {
                var configFileSpecs = project.configFileSpecs; // TODO: GH#18217
                var configFileName = project.getConfigFilePath();
                var fileNamesResult = ts.getFileNamesFromConfigSpecs(configFileSpecs, ts.getDirectoryPath(configFileName), project.getCompilationSettings(), project.getCachedDirectoryStructureHost(), this.hostConfiguration.extraFileExtensions);
                project.updateErrorOnNoInputFiles(fileNamesResult);
                this.updateNonInferredProjectFiles(project, fileNamesResult.fileNames.concat(project.getExternalFiles()), fileNamePropertyReader);
                return project.updateGraph();
            };
            /**
             * Read the config file of the project again by clearing the cache and update the project graph
             */
            /* @internal */
            ProjectService.prototype.reloadConfiguredProject = function (project, reason) {
                // At this point, there is no reason to not have configFile in the host
                var host = project.getCachedDirectoryStructureHost();
                // Clear the cache since we are reloading the project from disk
                host.clearCache();
                var configFileName = project.getConfigFilePath();
                this.logger.info("Reloading configured project " + configFileName);
                // Load project from the disk
                this.loadConfiguredProject(project, reason);
                project.updateGraph();
                this.sendConfigFileDiagEvent(project, configFileName);
            };
            ProjectService.prototype.sendConfigFileDiagEvent = function (project, triggerFile) {
                if (!this.eventHandler || this.suppressDiagnosticEvents) {
                    return;
                }
                var diagnostics = project.getLanguageService().getCompilerOptionsDiagnostics();
                diagnostics.push.apply(diagnostics, project.getAllProjectErrors());
                this.eventHandler({
                    eventName: server.ConfigFileDiagEvent,
                    data: { configFileName: project.getConfigFilePath(), diagnostics: diagnostics, triggerFile: triggerFile }
                });
            };
            ProjectService.prototype.getOrCreateInferredProjectForProjectRootPathIfEnabled = function (info, projectRootPath) {
                if (info.isDynamic || !this.useInferredProjectPerProjectRoot) {
                    return undefined;
                }
                if (projectRootPath) {
                    var canonicalProjectRootPath = this.toCanonicalFileName(projectRootPath);
                    // if we have an explicit project root path, find (or create) the matching inferred project.
                    for (var _i = 0, _a = this.inferredProjects; _i < _a.length; _i++) {
                        var project = _a[_i];
                        if (project.projectRootPath === canonicalProjectRootPath) {
                            return project;
                        }
                    }
                    return this.createInferredProject(projectRootPath, /*isSingleInferredProject*/ false, projectRootPath);
                }
                // we don't have an explicit root path, so we should try to find an inferred project
                // that more closely contains the file.
                var bestMatch;
                for (var _b = 0, _c = this.inferredProjects; _b < _c.length; _b++) {
                    var project = _c[_b];
                    // ignore single inferred projects (handled elsewhere)
                    if (!project.projectRootPath)
                        continue;
                    // ignore inferred projects that don't contain the root's path
                    if (!ts.containsPath(project.projectRootPath, info.path, this.host.getCurrentDirectory(), !this.host.useCaseSensitiveFileNames))
                        continue;
                    // ignore inferred projects that are higher up in the project root.
                    // TODO(rbuckton): Should we add the file as a root to these as well?
                    if (bestMatch && bestMatch.projectRootPath.length > project.projectRootPath.length)
                        continue;
                    bestMatch = project;
                }
                return bestMatch;
            };
            ProjectService.prototype.getOrCreateSingleInferredProjectIfEnabled = function () {
                if (!this.useSingleInferredProject) {
                    return undefined;
                }
                // If `useInferredProjectPerProjectRoot` is not enabled, then there will only be one
                // inferred project for all files. If `useInferredProjectPerProjectRoot` is enabled
                // then we want to put all files that are not opened with a `projectRootPath` into
                // the same inferred project.
                //
                // To avoid the cost of searching through the array and to optimize for the case where
                // `useInferredProjectPerProjectRoot` is not enabled, we will always put the inferred
                // project for non-rooted files at the front of the array.
                if (this.inferredProjects.length > 0 && this.inferredProjects[0].projectRootPath === undefined) {
                    return this.inferredProjects[0];
                }
                // Single inferred project does not have a project root and hence no current directory
                return this.createInferredProject(/*currentDirectory*/ undefined, /*isSingleInferredProject*/ true);
            };
            ProjectService.prototype.getOrCreateSingleInferredWithoutProjectRoot = function (currentDirectory) {
                ts.Debug.assert(!this.useSingleInferredProject);
                var expectedCurrentDirectory = this.toCanonicalFileName(this.getNormalizedAbsolutePath(currentDirectory || ""));
                // Reuse the project with same current directory but no roots
                for (var _i = 0, _a = this.inferredProjects; _i < _a.length; _i++) {
                    var inferredProject = _a[_i];
                    if (!inferredProject.projectRootPath &&
                        inferredProject.isOrphan() &&
                        inferredProject.canonicalCurrentDirectory === expectedCurrentDirectory) {
                        return inferredProject;
                    }
                }
                return this.createInferredProject(currentDirectory);
            };
            ProjectService.prototype.createInferredProject = function (currentDirectory, isSingleInferredProject, projectRootPath) {
                var compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects; // TODO: GH#18217
                var project = new server.InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath, currentDirectory, this.currentPluginConfigOverrides);
                if (isSingleInferredProject) {
                    this.inferredProjects.unshift(project);
                }
                else {
                    this.inferredProjects.push(project);
                }
                return project;
            };
            /*@internal*/
            ProjectService.prototype.getOrCreateScriptInfoNotOpenedByClient = function (uncheckedFileName, currentDirectory, hostToQueryFileExistsOn) {
                return this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(server.toNormalizedPath(uncheckedFileName), currentDirectory, /*scriptKind*/ undefined, 
                /*hasMixedContent*/ undefined, hostToQueryFileExistsOn);
            };
            ProjectService.prototype.getScriptInfo = function (uncheckedFileName) {
                return this.getScriptInfoForNormalizedPath(server.toNormalizedPath(uncheckedFileName));
            };
            /* @internal */
            ProjectService.prototype.getScriptInfoOrConfig = function (uncheckedFileName) {
                var path = server.toNormalizedPath(uncheckedFileName);
                var info = this.getScriptInfoForNormalizedPath(path);
                if (info)
                    return info;
                var configProject = this.configuredProjects.get(this.toPath(uncheckedFileName));
                return configProject && configProject.getCompilerOptions().configFile;
            };
            /* @internal */
            ProjectService.prototype.logErrorForScriptInfoNotFound = function (fileName) {
                var names = ts.arrayFrom(this.filenameToScriptInfo.entries()).map(function (_a) {
                    var path = _a[0], scriptInfo = _a[1];
                    return ({ path: path, fileName: scriptInfo.fileName });
                });
                this.logger.msg("Could not find file " + JSON.stringify(fileName) + ".\nAll files are: " + JSON.stringify(names), server.Msg.Err);
            };
            /**
             * Returns the projects that contain script info through SymLink
             * Note that this does not return projects in info.containingProjects
             */
            /*@internal*/
            ProjectService.prototype.getSymlinkedProjects = function (info) {
                var projects;
                if (this.realpathToScriptInfos) {
                    var realpath = info.getRealpathIfDifferent();
                    if (realpath) {
                        ts.forEach(this.realpathToScriptInfos.get(realpath), combineProjects);
                    }
                    ts.forEach(this.realpathToScriptInfos.get(info.path), combineProjects);
                }
                return projects;
                function combineProjects(toAddInfo) {
                    if (toAddInfo !== info) {
                        var _loop_3 = function (project) {
                            // Add the projects only if they can use symLink targets and not already in the list
                            if (project.languageServiceEnabled &&
                                !project.isOrphan() &&
                                !project.getCompilerOptions().preserveSymlinks &&
                                !ts.contains(info.containingProjects, project)) {
                                if (!projects) {
                                    projects = ts.createMultiMap();
                                    projects.add(toAddInfo.path, project);
                                }
                                else if (!ts.forEachEntry(projects, function (projs, path) { return path === toAddInfo.path ? false : ts.contains(projs, project); })) {
                                    projects.add(toAddInfo.path, project);
                                }
                            }
                        };
                        for (var _i = 0, _a = toAddInfo.containingProjects; _i < _a.length; _i++) {
                            var project = _a[_i];
                            _loop_3(project);
                        }
                    }
                }
            };
            ProjectService.prototype.watchClosedScriptInfo = function (info) {
                var _this = this;
                ts.Debug.assert(!info.fileWatcher);
                // do not watch files with mixed content - server doesn't know how to interpret it
                // do not watch files in the global cache location
                if (!info.isDynamicOrHasMixedContent() &&
                    (!this.globalCacheLocationDirectoryPath ||
                        !ts.startsWith(info.path, this.globalCacheLocationDirectoryPath))) {
                    var indexOfNodeModules = info.path.indexOf("/node_modules/");
                    if (!this.host.getModifiedTime || indexOfNodeModules === -1) {
                        info.fileWatcher = this.watchFactory.watchFilePath(this.host, info.fileName, function (fileName, eventKind, path) { return _this.onSourceFileChanged(fileName, eventKind, path); }, ts.PollingInterval.Medium, info.path, "Closed Script info" /* ClosedScriptInfo */);
                    }
                    else {
                        info.mTime = this.getModifiedTime(info);
                        info.fileWatcher = this.watchClosedScriptInfoInNodeModules(info.path.substr(0, indexOfNodeModules));
                    }
                }
            };
            ProjectService.prototype.watchClosedScriptInfoInNodeModules = function (dir) {
                var _this = this;
                // Watch only directory
                var existing = this.scriptInfoInNodeModulesWatchers.get(dir);
                if (existing) {
                    existing.refCount++;
                    return existing;
                }
                var watchDir = dir + "/node_modules";
                var watcher = this.watchFactory.watchDirectory(this.host, watchDir, function (fileOrDirectory) {
                    var fileOrDirectoryPath = _this.toPath(fileOrDirectory);
                    if (ts.isPathIgnored(fileOrDirectoryPath))
                        return;
                    // Has extension
                    ts.Debug.assert(result.refCount > 0);
                    if (watchDir === fileOrDirectoryPath) {
                        _this.refreshScriptInfosInDirectory(watchDir);
                    }
                    else {
                        var info = _this.getScriptInfoForPath(fileOrDirectoryPath);
                        if (info) {
                            if (isScriptInfoWatchedFromNodeModules(info)) {
                                _this.refreshScriptInfo(info);
                            }
                        }
                        // Folder
                        else if (!ts.hasExtension(fileOrDirectoryPath)) {
                            _this.refreshScriptInfosInDirectory(fileOrDirectoryPath);
                        }
                    }
                }, 1 /* Recursive */, "node_modules for closed script infos in them" /* NodeModulesForClosedScriptInfo */);
                var result = {
                    close: function () {
                        if (result.refCount === 1) {
                            watcher.close();
                            _this.scriptInfoInNodeModulesWatchers.delete(dir);
                        }
                        else {
                            result.refCount--;
                        }
                    },
                    refCount: 1
                };
                this.scriptInfoInNodeModulesWatchers.set(dir, result);
                return result;
            };
            ProjectService.prototype.getModifiedTime = function (info) {
                return (this.host.getModifiedTime(info.path) || ts.missingFileModifiedTime).getTime();
            };
            ProjectService.prototype.refreshScriptInfo = function (info) {
                var mTime = this.getModifiedTime(info);
                if (mTime !== info.mTime) {
                    var eventKind = ts.getFileWatcherEventKind(info.mTime, mTime);
                    info.mTime = mTime;
                    this.onSourceFileChanged(info.fileName, eventKind, info.path);
                }
            };
            ProjectService.prototype.refreshScriptInfosInDirectory = function (dir) {
                var _this = this;
                dir = dir + ts.directorySeparator;
                this.filenameToScriptInfo.forEach(function (info) {
                    if (isScriptInfoWatchedFromNodeModules(info) && ts.startsWith(info.path, dir)) {
                        _this.refreshScriptInfo(info);
                    }
                });
            };
            ProjectService.prototype.stopWatchingScriptInfo = function (info) {
                if (info.fileWatcher) {
                    info.fileWatcher.close();
                    info.fileWatcher = undefined;
                }
            };
            ProjectService.prototype.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath = function (fileName, currentDirectory, scriptKind, hasMixedContent, hostToQueryFileExistsOn) {
                if (ts.isRootedDiskPath(fileName) || server.isDynamicFileName(fileName)) {
                    return this.getOrCreateScriptInfoWorker(fileName, currentDirectory, /*openedByClient*/ false, /*fileContent*/ undefined, scriptKind, hasMixedContent, hostToQueryFileExistsOn);
                }
                // This is non rooted path with different current directory than project service current directory
                // Only paths recognized are open relative file paths
                var info = this.openFilesWithNonRootedDiskPath.get(this.toCanonicalFileName(fileName));
                if (info) {
                    return info;
                }
                // This means triple slash references wont be resolved in dynamic and unsaved files
                // which is intentional since we dont know what it means to be relative to non disk files
                return undefined;
            };
            ProjectService.prototype.getOrCreateScriptInfoOpenedByClientForNormalizedPath = function (fileName, currentDirectory, fileContent, scriptKind, hasMixedContent) {
                return this.getOrCreateScriptInfoWorker(fileName, currentDirectory, /*openedByClient*/ true, fileContent, scriptKind, hasMixedContent);
            };
            ProjectService.prototype.getOrCreateScriptInfoForNormalizedPath = function (fileName, openedByClient, fileContent, scriptKind, hasMixedContent, hostToQueryFileExistsOn) {
                return this.getOrCreateScriptInfoWorker(fileName, this.currentDirectory, openedByClient, fileContent, scriptKind, hasMixedContent, hostToQueryFileExistsOn);
            };
            ProjectService.prototype.getOrCreateScriptInfoWorker = function (fileName, currentDirectory, openedByClient, fileContent, scriptKind, hasMixedContent, hostToQueryFileExistsOn) {
                var _this = this;
                ts.Debug.assert(fileContent === undefined || openedByClient, "ScriptInfo needs to be opened by client to be able to set its user defined content");
                var path = server.normalizedPathToPath(fileName, currentDirectory, this.toCanonicalFileName);
                var info = this.getScriptInfoForPath(path);
                if (!info) {
                    var isDynamic = server.isDynamicFileName(fileName);
                    ts.Debug.assert(ts.isRootedDiskPath(fileName) || isDynamic || openedByClient, "", function () { return JSON.stringify({ fileName: fileName, currentDirectory: currentDirectory, hostCurrentDirectory: _this.currentDirectory, openKeys: ts.arrayFrom(_this.openFilesWithNonRootedDiskPath.keys()) }) + "\nScript info with non-dynamic relative file name can only be open script info or in context of host currentDirectory"; });
                    ts.Debug.assert(!ts.isRootedDiskPath(fileName) || this.currentDirectory === currentDirectory || !this.openFilesWithNonRootedDiskPath.has(this.toCanonicalFileName(fileName)), "", function () { return JSON.stringify({ fileName: fileName, currentDirectory: currentDirectory, hostCurrentDirectory: _this.currentDirectory, openKeys: ts.arrayFrom(_this.openFilesWithNonRootedDiskPath.keys()) }) + "\nOpen script files with non rooted disk path opened with current directory context cannot have same canonical names"; });
                    ts.Debug.assert(!isDynamic || this.currentDirectory === currentDirectory, "", function () { return JSON.stringify({ fileName: fileName, currentDirectory: currentDirectory, hostCurrentDirectory: _this.currentDirectory, openKeys: ts.arrayFrom(_this.openFilesWithNonRootedDiskPath.keys()) }) + "\nDynamic files must always have current directory context since containing external project name will always match the script info name."; });
                    // If the file is not opened by client and the file doesnot exist on the disk, return
                    if (!openedByClient && !isDynamic && !(hostToQueryFileExistsOn || this.host).fileExists(fileName)) {
                        return;
                    }
                    info = new server.ScriptInfo(this.host, fileName, scriptKind, !!hasMixedContent, path, this.filenameToScriptInfoVersion.get(path)); // TODO: GH#18217
                    this.filenameToScriptInfo.set(info.path, info);
                    this.filenameToScriptInfoVersion.delete(info.path);
                    if (!openedByClient) {
                        this.watchClosedScriptInfo(info);
                    }
                    else if (!ts.isRootedDiskPath(fileName) && !isDynamic) {
                        // File that is opened by user but isn't rooted disk path
                        this.openFilesWithNonRootedDiskPath.set(this.toCanonicalFileName(fileName), info);
                    }
                }
                if (openedByClient && !info.isScriptOpen()) {
                    // Opening closed script info
                    // either it was created just now, or was part of projects but was closed
                    this.stopWatchingScriptInfo(info);
                    info.open(fileContent);
                    if (hasMixedContent) {
                        info.registerFileUpdate();
                    }
                }
                else {
                    ts.Debug.assert(fileContent === undefined);
                }
                return info;
            };
            /**
             * This gets the script info for the normalized path. If the path is not rooted disk path then the open script info with project root context is preferred
             */
            ProjectService.prototype.getScriptInfoForNormalizedPath = function (fileName) {
                return !ts.isRootedDiskPath(fileName) && this.openFilesWithNonRootedDiskPath.get(this.toCanonicalFileName(fileName)) ||
                    this.getScriptInfoForPath(server.normalizedPathToPath(fileName, this.currentDirectory, this.toCanonicalFileName));
            };
            ProjectService.prototype.getScriptInfoForPath = function (fileName) {
                return this.filenameToScriptInfo.get(fileName);
            };
            /*@internal*/
            ProjectService.prototype.getDocumentPositionMapper = function (project, generatedFileName, sourceFileName) {
                var _this = this;
                // Since declaration info and map file watches arent updating project's directory structure host (which can cache file structure) use host
                var declarationInfo = this.getOrCreateScriptInfoNotOpenedByClient(generatedFileName, project.currentDirectory, this.host);
                if (!declarationInfo)
                    return undefined;
                // Try to get from cache
                declarationInfo.getSnapshot(); // Ensure synchronized
                if (ts.isString(declarationInfo.sourceMapFilePath)) {
                    // Ensure mapper is synchronized
                    var sourceMapFileInfo_1 = this.getScriptInfoForPath(declarationInfo.sourceMapFilePath);
                    if (sourceMapFileInfo_1) {
                        sourceMapFileInfo_1.getSnapshot();
                        if (sourceMapFileInfo_1.documentPositionMapper !== undefined) {
                            sourceMapFileInfo_1.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, sourceMapFileInfo_1.sourceInfos);
                            return sourceMapFileInfo_1.documentPositionMapper ? sourceMapFileInfo_1.documentPositionMapper : undefined;
                        }
                    }
                    declarationInfo.sourceMapFilePath = undefined;
                }
                else if (declarationInfo.sourceMapFilePath) {
                    declarationInfo.sourceMapFilePath.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, declarationInfo.sourceMapFilePath.sourceInfos);
                    return undefined;
                }
                else if (declarationInfo.sourceMapFilePath !== undefined) {
                    // Doesnt have sourceMap
                    return undefined;
                }
                // Create the mapper
                var sourceMapFileInfo;
                var mapFileNameFromDeclarationInfo;
                var readMapFile = function (mapFileName, mapFileNameFromDts) {
                    var mapInfo = _this.getOrCreateScriptInfoNotOpenedByClient(mapFileName, project.currentDirectory, _this.host);
                    if (!mapInfo) {
                        mapFileNameFromDeclarationInfo = mapFileNameFromDts;
                        return undefined;
                    }
                    sourceMapFileInfo = mapInfo;
                    var snap = mapInfo.getSnapshot();
                    if (mapInfo.documentPositionMapper !== undefined)
                        return mapInfo.documentPositionMapper;
                    return snap.getText(0, snap.getLength());
                };
                var projectName = project.projectName;
                var documentPositionMapper = ts.getDocumentPositionMapper({ getCanonicalFileName: this.toCanonicalFileName, log: function (s) { return _this.logger.info(s); }, getSourceFileLike: function (f) { return _this.getSourceFileLike(f, projectName, declarationInfo); } }, declarationInfo.fileName, declarationInfo.getLineInfo(), readMapFile);
                readMapFile = undefined; // Remove ref to project
                if (sourceMapFileInfo) {
                    declarationInfo.sourceMapFilePath = sourceMapFileInfo.path;
                    sourceMapFileInfo.declarationInfoPath = declarationInfo.path;
                    sourceMapFileInfo.documentPositionMapper = documentPositionMapper || false;
                    sourceMapFileInfo.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, sourceMapFileInfo.sourceInfos);
                }
                else if (mapFileNameFromDeclarationInfo) {
                    declarationInfo.sourceMapFilePath = {
                        watcher: this.addMissingSourceMapFile(project.currentDirectory === this.currentDirectory ?
                            mapFileNameFromDeclarationInfo :
                            ts.getNormalizedAbsolutePath(mapFileNameFromDeclarationInfo, project.currentDirectory), declarationInfo.path),
                        sourceInfos: this.addSourceInfoToSourceMap(sourceFileName, project)
                    };
                }
                else {
                    declarationInfo.sourceMapFilePath = false;
                }
                return documentPositionMapper;
            };
            ProjectService.prototype.addSourceInfoToSourceMap = function (sourceFileName, project, sourceInfos) {
                if (sourceFileName) {
                    // Attach as source
                    var sourceInfo = this.getOrCreateScriptInfoNotOpenedByClient(sourceFileName, project.currentDirectory, project.directoryStructureHost);
                    (sourceInfos || (sourceInfos = ts.createMap())).set(sourceInfo.path, true);
                }
                return sourceInfos;
            };
            ProjectService.prototype.addMissingSourceMapFile = function (mapFileName, declarationInfoPath) {
                var _this = this;
                var fileWatcher = this.watchFactory.watchFile(this.host, mapFileName, function () {
                    var declarationInfo = _this.getScriptInfoForPath(declarationInfoPath);
                    if (declarationInfo && declarationInfo.sourceMapFilePath && !ts.isString(declarationInfo.sourceMapFilePath)) {
                        // Update declaration and source projects
                        _this.delayUpdateProjectGraphs(declarationInfo.containingProjects);
                        _this.delayUpdateSourceInfoProjects(declarationInfo.sourceMapFilePath.sourceInfos);
                        declarationInfo.closeSourceMapFileWatcher();
                    }
                }, ts.PollingInterval.High, "Missing source map file" /* MissingSourceMapFile */);
                return fileWatcher;
            };
            /*@internal*/
            ProjectService.prototype.getSourceFileLike = function (fileName, projectNameOrProject, declarationInfo) {
                var project = projectNameOrProject.projectName ? projectNameOrProject : this.findProject(projectNameOrProject);
                if (project) {
                    var path = project.toPath(fileName);
                    var sourceFile = project.getSourceFile(path);
                    if (sourceFile && sourceFile.resolvedPath === path)
                        return sourceFile;
                }
                // Need to look for other files.
                var info = this.getOrCreateScriptInfoNotOpenedByClient(fileName, (project || this).currentDirectory, project ? project.directoryStructureHost : this.host);
                if (!info)
                    return undefined;
                // Attach as source
                if (declarationInfo && ts.isString(declarationInfo.sourceMapFilePath) && info !== declarationInfo) {
                    var sourceMapInfo = this.getScriptInfoForPath(declarationInfo.sourceMapFilePath);
                    if (sourceMapInfo) {
                        (sourceMapInfo.sourceInfos || (sourceMapInfo.sourceInfos = ts.createMap())).set(info.path, true);
                    }
                }
                // Key doesnt matter since its only for text and lines
                if (info.cacheSourceFile)
                    return info.cacheSourceFile.sourceFile;
                // Create sourceFileLike
                if (!info.sourceFileLike) {
                    info.sourceFileLike = {
                        get text() {
                            ts.Debug.fail("shouldnt need text");
                            return "";
                        },
                        getLineAndCharacterOfPosition: function (pos) {
                            var lineOffset = info.positionToLineOffset(pos);
                            return { line: lineOffset.line - 1, character: lineOffset.offset - 1 };
                        },
                        getPositionOfLineAndCharacter: function (line, character, allowEdits) { return info.lineOffsetToPosition(line + 1, character + 1, allowEdits); }
                    };
                }
                return info.sourceFileLike;
            };
            ProjectService.prototype.setHostConfiguration = function (args) {
                var _this = this;
                if (args.file) {
                    var info = this.getScriptInfoForNormalizedPath(server.toNormalizedPath(args.file));
                    if (info) {
                        info.setOptions(convertFormatOptions(args.formatOptions), args.preferences);
                        this.logger.info("Host configuration update for file " + args.file);
                    }
                }
                else {
                    if (args.hostInfo !== undefined) {
                        this.hostConfiguration.hostInfo = args.hostInfo;
                        this.logger.info("Host information " + args.hostInfo);
                    }
                    if (args.formatOptions) {
                        this.hostConfiguration.formatCodeOptions = __assign({}, this.hostConfiguration.formatCodeOptions, convertFormatOptions(args.formatOptions));
                        this.logger.info("Format host information updated");
                    }
                    if (args.preferences) {
                        var lazyConfiguredProjectsFromExternalProject = this.hostConfiguration.preferences.lazyConfiguredProjectsFromExternalProject;
                        this.hostConfiguration.preferences = __assign({}, this.hostConfiguration.preferences, args.preferences);
                        if (lazyConfiguredProjectsFromExternalProject && !this.hostConfiguration.preferences.lazyConfiguredProjectsFromExternalProject) {
                            // Load configured projects for external projects that are pending reload
                            this.configuredProjects.forEach(function (project) {
                                if (project.hasExternalProjectRef() &&
                                    project.pendingReload === ts.ConfigFileProgramReloadLevel.Full &&
                                    !_this.pendingProjectUpdates.has(project.getProjectName())) {
                                    project.updateGraph();
                                }
                            });
                        }
                    }
                    if (args.extraFileExtensions) {
                        this.hostConfiguration.extraFileExtensions = args.extraFileExtensions;
                        // We need to update the project structures again as it is possible that existing
                        // project structure could have more or less files depending on extensions permitted
                        this.reloadProjects();
                        this.logger.info("Host file extension mappings updated");
                    }
                }
            };
            ProjectService.prototype.closeLog = function () {
                this.logger.close();
            };
            /**
             * This function rebuilds the project for every file opened by the client
             * This does not reload contents of open files from disk. But we could do that if needed
             */
            ProjectService.prototype.reloadProjects = function () {
                this.logger.info("reload projects.");
                // If we want this to also reload open files from disk, we could do that,
                // but then we need to make sure we arent calling this function
                // (and would separate out below reloading of projects to be called when immediate reload is needed)
                // as there is no need to load contents of the files from the disk
                // Reload Projects
                this.reloadConfiguredProjectForFiles(this.openFiles, /*delayReload*/ false, ts.returnTrue, "User requested reload projects");
                this.ensureProjectForOpenFiles();
            };
            ProjectService.prototype.delayReloadConfiguredProjectForFiles = function (configFileExistenceInfo, ignoreIfNotRootOfInferredProject) {
                // Get open files to reload projects for
                this.reloadConfiguredProjectForFiles(configFileExistenceInfo.openFilesImpactedByConfigFile, 
                /*delayReload*/ true, ignoreIfNotRootOfInferredProject ?
                    function (isRootOfInferredProject) { return isRootOfInferredProject; } : // Reload open files if they are root of inferred project
                    ts.returnTrue, // Reload all the open files impacted by config file
                "Change in config file detected");
                this.delayEnsureProjectForOpenFiles();
            };
            /**
             * This function goes through all the openFiles and tries to file the config file for them.
             * If the config file is found and it refers to existing project, it reloads it either immediately
             * or schedules it for reload depending on delayReload option
             * If the there is no existing project it just opens the configured project for the config file
             * reloadForInfo provides a way to filter out files to reload configured project for
             */
            ProjectService.prototype.reloadConfiguredProjectForFiles = function (openFiles, delayReload, shouldReloadProjectFor, reason) {
                var _this = this;
                var updatedProjects = ts.createMap();
                // try to reload config file for all open files
                openFiles.forEach(function (openFileValue, path) {
                    // Filter out the files that need to be ignored
                    if (!shouldReloadProjectFor(openFileValue)) {
                        return;
                    }
                    var info = _this.getScriptInfoForPath(path); // TODO: GH#18217
                    ts.Debug.assert(info.isScriptOpen());
                    // This tries to search for a tsconfig.json for the given file. If we found it,
                    // we first detect if there is already a configured project created for it: if so,
                    // we re- read the tsconfig file content and update the project only if we havent already done so
                    // otherwise we create a new one.
                    var configFileName = _this.getConfigFileNameForFile(info);
                    if (configFileName) {
                        var project = _this.findConfiguredProjectByProjectName(configFileName) || _this.createConfiguredProject(configFileName);
                        if (!updatedProjects.has(configFileName)) {
                            if (delayReload) {
                                project.pendingReload = ts.ConfigFileProgramReloadLevel.Full;
                                project.pendingReloadReason = reason;
                                _this.delayUpdateProjectGraph(project);
                            }
                            else {
                                // reload from the disk
                                _this.reloadConfiguredProject(project, reason);
                            }
                            updatedProjects.set(configFileName, true);
                        }
                    }
                });
            };
            /**
             * Remove the root of inferred project if script info is part of another project
             */
            ProjectService.prototype.removeRootOfInferredProjectIfNowPartOfOtherProject = function (info) {
                // If the script info is root of inferred project, it could only be first containing project
                // since info is added as root to the inferred project only when there are no other projects containing it
                // So when it is root of the inferred project and after project structure updates its now part
                // of multiple project it needs to be removed from that inferred project because:
                // - references in inferred project supercede the root part
                // - root / reference in non - inferred project beats root in inferred project
                // eg. say this is structure /a/b/a.ts /a/b/c.ts where c.ts references a.ts
                // When a.ts is opened, since there is no configured project/external project a.ts can be part of
                // a.ts is added as root to inferred project.
                // Now at time of opening c.ts, c.ts is also not aprt of any existing project,
                // so it will be added to inferred project as a root. (for sake of this example assume single inferred project is false)
                // So at this poing a.ts is part of first inferred project and second inferred project (of which c.ts is root)
                // And hence it needs to be removed from the first inferred project.
                ts.Debug.assert(info.containingProjects.length > 0);
                var firstProject = info.containingProjects[0];
                if (!firstProject.isOrphan() &&
                    firstProject.projectKind === server.ProjectKind.Inferred &&
                    firstProject.isRoot(info) &&
                    ts.forEach(info.containingProjects, function (p) { return p !== firstProject && !p.isOrphan(); })) {
                    firstProject.removeFile(info, /*fileExists*/ true, /*detachFromProject*/ true);
                }
            };
            /**
             * This function is to update the project structure for every inferred project.
             * It is called on the premise that all the configured projects are
             * up to date.
             * This will go through open files and assign them to inferred project if open file is not part of any other project
             * After that all the inferred project graphs are updated
             */
            ProjectService.prototype.ensureProjectForOpenFiles = function () {
                var _this = this;
                this.logger.info("Structure before ensureProjectForOpenFiles:");
                this.printProjects();
                this.openFiles.forEach(function (projectRootPath, path) {
                    var info = _this.getScriptInfoForPath(path);
                    // collect all orphaned script infos from open files
                    if (info.isOrphan()) {
                        _this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
                    }
                    else {
                        // Or remove the root of inferred project if is referenced in more than one projects
                        _this.removeRootOfInferredProjectIfNowPartOfOtherProject(info);
                    }
                });
                this.pendingEnsureProjectForOpenFiles = false;
                this.inferredProjects.forEach(updateProjectIfDirty);
                this.logger.info("Structure after ensureProjectForOpenFiles:");
                this.printProjects();
            };
            /**
             * Open file whose contents is managed by the client
             * @param filename is absolute pathname
             * @param fileContent is a known version of the file content that is more up to date than the one on disk
             */
            ProjectService.prototype.openClientFile = function (fileName, fileContent, scriptKind, projectRootPath) {
                return this.openClientFileWithNormalizedPath(server.toNormalizedPath(fileName), fileContent, scriptKind, /*hasMixedContent*/ false, projectRootPath ? server.toNormalizedPath(projectRootPath) : undefined);
            };
            /*@internal*/
            ProjectService.prototype.getOriginalLocationEnsuringConfiguredProject = function (project, location) {
                var originalLocation = project.getSourceMapper().tryGetSourcePosition(location);
                if (!originalLocation)
                    return undefined;
                var fileName = originalLocation.fileName;
                if (!this.getScriptInfo(fileName) && !this.host.fileExists(fileName))
                    return undefined;
                var originalFileInfo = { fileName: server.toNormalizedPath(fileName), path: this.toPath(fileName) };
                var configFileName = this.getConfigFileNameForFile(originalFileInfo);
                if (!configFileName)
                    return undefined;
                var configuredProject = this.findConfiguredProjectByProjectName(configFileName) ||
                    this.createAndLoadConfiguredProject(configFileName, "Creating project for original file: " + originalFileInfo.fileName + " for location: " + location.fileName);
                updateProjectIfDirty(configuredProject);
                // Keep this configured project as referenced from project
                addOriginalConfiguredProject(configuredProject);
                var originalScriptInfo = this.getScriptInfo(fileName);
                if (!originalScriptInfo || !originalScriptInfo.containingProjects.length)
                    return undefined;
                // Add configured projects as referenced
                originalScriptInfo.containingProjects.forEach(function (project) {
                    if (project.projectKind === server.ProjectKind.Configured) {
                        addOriginalConfiguredProject(project);
                    }
                });
                return originalLocation;
                function addOriginalConfiguredProject(originalProject) {
                    if (!project.originalConfiguredProjects) {
                        project.originalConfiguredProjects = ts.createMap();
                    }
                    project.originalConfiguredProjects.set(originalProject.canonicalConfigFilePath, true);
                }
            };
            /** @internal */
            ProjectService.prototype.fileExists = function (fileName) {
                return !!this.getScriptInfoForNormalizedPath(fileName) || this.host.fileExists(fileName);
            };
            ProjectService.prototype.findExternalProjectContainingOpenScriptInfo = function (info) {
                return ts.find(this.externalProjects, function (proj) {
                    // Ensure project structure is up-to-date to check if info is present in external project
                    updateProjectIfDirty(proj);
                    return proj.containsScriptInfo(info);
                });
            };
            ProjectService.prototype.getOrCreateOpenScriptInfo = function (fileName, fileContent, scriptKind, hasMixedContent, projectRootPath) {
                var info = this.getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName, projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory, fileContent, scriptKind, hasMixedContent); // TODO: GH#18217
                this.openFiles.set(info.path, projectRootPath);
                return info;
            };
            ProjectService.prototype.assignProjectToOpenedScriptInfo = function (info) {
                var configFileName;
                var configFileErrors;
                var project = this.findExternalProjectContainingOpenScriptInfo(info);
                if (!project && !this.syntaxOnly) { // Checking syntaxOnly is an optimization
                    configFileName = this.getConfigFileNameForFile(info);
                    if (configFileName) {
                        project = this.findConfiguredProjectByProjectName(configFileName);
                        if (!project) {
                            project = this.createLoadAndUpdateConfiguredProject(configFileName, "Creating possible configured project for " + info.fileName + " to open");
                            // Send the event only if the project got created as part of this open request and info is part of the project
                            if (info.isOrphan()) {
                                // Since the file isnt part of configured project, do not send config file info
                                configFileName = undefined;
                            }
                            else {
                                configFileErrors = project.getAllProjectErrors();
                                this.sendConfigFileDiagEvent(project, info.fileName);
                            }
                        }
                        else {
                            // Ensure project is ready to check if it contains opened script info
                            updateProjectIfDirty(project);
                        }
                    }
                }
                // Project we have at this point is going to be updated since its either found through
                // - external project search, which updates the project before checking if info is present in it
                // - configured project - either created or updated to ensure we know correct status of info
                // At this point we need to ensure that containing projects of the info are uptodate
                // This will ensure that later question of info.isOrphan() will return correct answer
                // and we correctly create inferred project for the info
                info.containingProjects.forEach(updateProjectIfDirty);
                // At this point if file is part of any any configured or external project, then it would be present in the containing projects
                // So if it still doesnt have any containing projects, it needs to be part of inferred project
                if (info.isOrphan()) {
                    ts.Debug.assert(this.openFiles.has(info.path));
                    this.assignOrphanScriptInfoToInferredProject(info, this.openFiles.get(info.path));
                }
                ts.Debug.assert(!info.isOrphan());
                return { configFileName: configFileName, configFileErrors: configFileErrors };
            };
            ProjectService.prototype.cleanupAfterOpeningFile = function () {
                // This was postponed from closeOpenFile to after opening next file,
                // so that we can reuse the project if we need to right away
                this.removeOrphanConfiguredProjects();
                // Remove orphan inferred projects now that we have reused projects
                // We need to create a duplicate because we cant guarantee order after removal
                for (var _i = 0, _a = this.inferredProjects.slice(); _i < _a.length; _i++) {
                    var inferredProject = _a[_i];
                    if (inferredProject.isOrphan()) {
                        this.removeProject(inferredProject);
                    }
                }
                // Delete the orphan files here because there might be orphan script infos (which are not part of project)
                // when some file/s were closed which resulted in project removal.
                // It was then postponed to cleanup these script infos so that they can be reused if
                // the file from that old project is reopened because of opening file from here.
                this.removeOrphanScriptInfos();
                this.printProjects();
            };
            ProjectService.prototype.openClientFileWithNormalizedPath = function (fileName, fileContent, scriptKind, hasMixedContent, projectRootPath) {
                var info = this.getOrCreateOpenScriptInfo(fileName, fileContent, scriptKind, hasMixedContent, projectRootPath);
                var result = this.assignProjectToOpenedScriptInfo(info);
                this.cleanupAfterOpeningFile();
                this.telemetryOnOpenFile(info);
                return result;
            };
            ProjectService.prototype.removeOrphanConfiguredProjects = function () {
                var _this = this;
                var toRemoveConfiguredProjects = ts.cloneMap(this.configuredProjects);
                // Do not remove configured projects that are used as original projects of other
                this.inferredProjects.forEach(markOriginalProjectsAsUsed);
                this.externalProjects.forEach(markOriginalProjectsAsUsed);
                this.configuredProjects.forEach(function (project) {
                    // If project has open ref (there are more than zero references from external project/open file), keep it alive as well as any project it references
                    if (project.hasOpenRef()) {
                        toRemoveConfiguredProjects.delete(project.canonicalConfigFilePath);
                        markOriginalProjectsAsUsed(project);
                    }
                    else {
                        // If the configured project for project reference has more than zero references, keep it alive
                        project.forEachResolvedProjectReference(function (ref) {
                            if (ref) {
                                var refProject = _this.configuredProjects.get(ref.sourceFile.path);
                                if (refProject && refProject.hasOpenRef()) {
                                    toRemoveConfiguredProjects.delete(project.canonicalConfigFilePath);
                                }
                            }
                        });
                    }
                });
                // Remove all the non marked projects
                toRemoveConfiguredProjects.forEach(function (project) { return _this.removeProject(project); });
                function markOriginalProjectsAsUsed(project) {
                    if (!project.isOrphan() && project.originalConfiguredProjects) {
                        project.originalConfiguredProjects.forEach(function (_value, configuredProjectPath) { return toRemoveConfiguredProjects.delete(configuredProjectPath); });
                    }
                }
            };
            ProjectService.prototype.removeOrphanScriptInfos = function () {
                var _this = this;
                var toRemoveScriptInfos = ts.cloneMap(this.filenameToScriptInfo);
                this.filenameToScriptInfo.forEach(function (info) {
                    // If script info is open or orphan, retain it and its dependencies
                    if (!info.isScriptOpen() && info.isOrphan()) {
                        // Otherwise if there is any source info that is alive, this alive too
                        if (!info.sourceMapFilePath)
                            return;
                        var sourceInfos = void 0;
                        if (ts.isString(info.sourceMapFilePath)) {
                            var sourceMapInfo = _this.getScriptInfoForPath(info.sourceMapFilePath);
                            sourceInfos = sourceMapInfo && sourceMapInfo.sourceInfos;
                        }
                        else {
                            sourceInfos = info.sourceMapFilePath.sourceInfos;
                        }
                        if (!sourceInfos)
                            return;
                        if (!ts.forEachKey(sourceInfos, function (path) {
                            var info = _this.getScriptInfoForPath(path);
                            return !!info && (info.isScriptOpen() || !info.isOrphan());
                        })) {
                            return;
                        }
                    }
                    // Retain this script info
                    toRemoveScriptInfos.delete(info.path);
                    if (info.sourceMapFilePath) {
                        var sourceInfos = void 0;
                        if (ts.isString(info.sourceMapFilePath)) {
                            // And map file info and source infos
                            toRemoveScriptInfos.delete(info.sourceMapFilePath);
                            var sourceMapInfo = _this.getScriptInfoForPath(info.sourceMapFilePath);
                            sourceInfos = sourceMapInfo && sourceMapInfo.sourceInfos;
                        }
                        else {
                            sourceInfos = info.sourceMapFilePath.sourceInfos;
                        }
                        if (sourceInfos) {
                            sourceInfos.forEach(function (_value, path) { return toRemoveScriptInfos.delete(path); });
                        }
                    }
                });
                toRemoveScriptInfos.forEach(function (info) {
                    // if there are not projects that include this script info - delete it
                    _this.stopWatchingScriptInfo(info);
                    _this.deleteScriptInfo(info);
                    info.closeSourceMapFileWatcher();
                });
            };
            ProjectService.prototype.telemetryOnOpenFile = function (scriptInfo) {
                if (this.syntaxOnly || !this.eventHandler || !scriptInfo.isJavaScript() || !ts.addToSeen(this.allJsFilesForOpenFileTelemetry, scriptInfo.path)) {
                    return;
                }
                var project = scriptInfo.getDefaultProject();
                if (!project.languageServiceEnabled) {
                    return;
                }
                var info = { checkJs: !!project.getSourceFile(scriptInfo.path).checkJsDirective };
                this.eventHandler({ eventName: server.OpenFileInfoTelemetryEvent, data: { info: info } });
            };
            ProjectService.prototype.closeClientFile = function (uncheckedFileName, skipAssignOrphanScriptInfosToInferredProject) {
                var info = this.getScriptInfoForNormalizedPath(server.toNormalizedPath(uncheckedFileName));
                var result = info ? this.closeOpenFile(info, skipAssignOrphanScriptInfosToInferredProject) : false;
                if (!skipAssignOrphanScriptInfosToInferredProject) {
                    this.printProjects();
                }
                return result;
            };
            ProjectService.prototype.collectChanges = function (lastKnownProjectVersions, currentProjects, result) {
                var _loop_4 = function (proj) {
                    var knownProject = ts.find(lastKnownProjectVersions, function (p) { return p.projectName === proj.getProjectName(); });
                    result.push(proj.getChangesSinceVersion(knownProject && knownProject.version));
                };
                for (var _i = 0, currentProjects_1 = currentProjects; _i < currentProjects_1.length; _i++) {
                    var proj = currentProjects_1[_i];
                    _loop_4(proj);
                }
            };
            /* @internal */
            ProjectService.prototype.synchronizeProjectList = function (knownProjects) {
                var files = [];
                this.collectChanges(knownProjects, this.externalProjects, files);
                this.collectChanges(knownProjects, ts.arrayFrom(this.configuredProjects.values()), files);
                this.collectChanges(knownProjects, this.inferredProjects, files);
                return files;
            };
            /* @internal */
            ProjectService.prototype.applyChangesInOpenFiles = function (openFiles, changedFiles, closedFiles) {
                var _this = this;
                var openScriptInfos;
                var assignOrphanScriptInfosToInferredProject = false;
                if (openFiles) {
                    while (true) {
                        var _a = openFiles.next(), file = _a.value, done = _a.done;
                        if (done)
                            break;
                        var scriptInfo = this.getScriptInfo(file.fileName);
                        ts.Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen(), "Script should not exist and not be open already");
                        // Create script infos so we have the new content for all the open files before we do any updates to projects
                        var info = this.getOrCreateOpenScriptInfo(scriptInfo ? scriptInfo.fileName : server.toNormalizedPath(file.fileName), file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent, file.projectRootPath ? server.toNormalizedPath(file.projectRootPath) : undefined);
                        (openScriptInfos || (openScriptInfos = [])).push(info);
                    }
                }
                if (changedFiles) {
                    while (true) {
                        var _b = changedFiles.next(), file = _b.value, done = _b.done;
                        if (done)
                            break;
                        var scriptInfo = this.getScriptInfo(file.fileName);
                        ts.Debug.assert(!!scriptInfo);
                        // Make edits to script infos and marks containing project as dirty
                        this.applyChangesToFile(scriptInfo, file.changes);
                    }
                }
                if (closedFiles) {
                    for (var _i = 0, closedFiles_1 = closedFiles; _i < closedFiles_1.length; _i++) {
                        var file = closedFiles_1[_i];
                        // Close files, but dont assign projects to orphan open script infos, that part comes later
                        assignOrphanScriptInfosToInferredProject = this.closeClientFile(file, /*skipAssignOrphanScriptInfosToInferredProject*/ true) || assignOrphanScriptInfosToInferredProject;
                    }
                }
                // All the script infos now exist, so ok to go update projects for open files
                if (openScriptInfos) {
                    openScriptInfos.forEach(function (info) { return _this.assignProjectToOpenedScriptInfo(info); });
                }
                // While closing files there could be open files that needed assigning new inferred projects, do it now
                if (assignOrphanScriptInfosToInferredProject) {
                    this.assignOrphanScriptInfosToInferredProject();
                }
                // Cleanup projects
                this.cleanupAfterOpeningFile();
                // Telemetry
                ts.forEach(openScriptInfos, function (info) { return _this.telemetryOnOpenFile(info); });
                this.printProjects();
            };
            /* @internal */
            ProjectService.prototype.applyChangesToFile = function (scriptInfo, changes) {
                while (true) {
                    var _a = changes.next(), change = _a.value, done = _a.done;
                    if (done)
                        break;
                    scriptInfo.editContent(change.span.start, change.span.start + change.span.length, change.newText);
                }
            };
            ProjectService.prototype.closeConfiguredProjectReferencedFromExternalProject = function (configFile) {
                var configuredProject = this.findConfiguredProjectByProjectName(configFile);
                if (configuredProject) {
                    configuredProject.deleteExternalProjectReference();
                    if (!configuredProject.hasOpenRef()) {
                        this.removeProject(configuredProject);
                        return;
                    }
                }
            };
            ProjectService.prototype.closeExternalProject = function (uncheckedFileName) {
                var fileName = server.toNormalizedPath(uncheckedFileName);
                var configFiles = this.externalProjectToConfiguredProjectMap.get(fileName);
                if (configFiles) {
                    for (var _i = 0, configFiles_1 = configFiles; _i < configFiles_1.length; _i++) {
                        var configFile = configFiles_1[_i];
                        this.closeConfiguredProjectReferencedFromExternalProject(configFile);
                    }
                    this.externalProjectToConfiguredProjectMap.delete(fileName);
                }
                else {
                    // close external project
                    var externalProject = this.findExternalProjectByProjectName(uncheckedFileName);
                    if (externalProject) {
                        this.removeProject(externalProject);
                    }
                }
            };
            ProjectService.prototype.openExternalProjects = function (projects) {
                var _this = this;
                // record project list before the update
                var projectsToClose = ts.arrayToMap(this.externalProjects, function (p) { return p.getProjectName(); }, function (_) { return true; });
                ts.forEachKey(this.externalProjectToConfiguredProjectMap, function (externalProjectName) {
                    projectsToClose.set(externalProjectName, true);
                });
                for (var _i = 0, projects_3 = projects; _i < projects_3.length; _i++) {
                    var externalProject = projects_3[_i];
                    this.openExternalProject(externalProject);
                    // delete project that is present in input list
                    projectsToClose.delete(externalProject.projectFileName);
                }
                // close projects that were missing in the input list
                ts.forEachKey(projectsToClose, function (externalProjectName) {
                    _this.closeExternalProject(externalProjectName);
                });
            };
            ProjectService.escapeFilenameForRegex = function (filename) {
                return filename.replace(this.filenameEscapeRegexp, "\\$&");
            };
            ProjectService.prototype.resetSafeList = function () {
                this.safelist = defaultTypeSafeList;
            };
            ProjectService.prototype.applySafeList = function (proj) {
                var _this = this;
                var rootFiles = proj.rootFiles;
                var typeAcquisition = proj.typeAcquisition;
                ts.Debug.assert(!!typeAcquisition, "proj.typeAcquisition should be set by now");
                // If type acquisition has been explicitly disabled, do not exclude anything from the project
                if (typeAcquisition.enable === false) {
                    return [];
                }
                var typeAcqInclude = typeAcquisition.include || (typeAcquisition.include = []);
                var excludeRules = [];
                var normalizedNames = rootFiles.map(function (f) { return ts.normalizeSlashes(f.fileName); });
                var excludedFiles = [];
                var _loop_5 = function (name) {
                    var rule = this_2.safelist[name];
                    for (var _i = 0, normalizedNames_1 = normalizedNames; _i < normalizedNames_1.length; _i++) {
                        var root = normalizedNames_1[_i];
                        if (rule.match.test(root)) {
                            this_2.logger.info("Excluding files based on rule " + name + " matching file '" + root + "'");
                            // If the file matches, collect its types packages and exclude rules
                            if (rule.types) {
                                for (var _a = 0, _b = rule.types; _a < _b.length; _a++) {
                                    var type = _b[_a];
                                    // Best-effort de-duping here - doesn't need to be unduplicated but
                                    // we don't want the list to become a 400-element array of just 'kendo'
                                    if (typeAcqInclude.indexOf(type) < 0) {
                                        typeAcqInclude.push(type);
                                    }
                                }
                            }
                            if (rule.exclude) {
                                var _loop_7 = function (exclude) {
                                    var processedRule = root.replace(rule.match, function () {
                                        var groups = [];
                                        for (var _i = 0; _i < arguments.length; _i++) {
                                            groups[_i] = arguments[_i];
                                        }
                                        return exclude.map(function (groupNumberOrString) {
                                            // RegExp group numbers are 1-based, but the first element in groups
                                            // is actually the original string, so it all works out in the end.
                                            if (typeof groupNumberOrString === "number") {
                                                if (!ts.isString(groups[groupNumberOrString])) {
                                                    // Specification was wrong - exclude nothing!
                                                    _this.logger.info("Incorrect RegExp specification in safelist rule " + name + " - not enough groups");
                                                    // * can't appear in a filename; escape it because it's feeding into a RegExp
                                                    return "\\*";
                                                }
                                                return ProjectService.escapeFilenameForRegex(groups[groupNumberOrString]);
                                            }
                                            return groupNumberOrString;
                                        }).join("");
                                    });
                                    if (excludeRules.indexOf(processedRule) === -1) {
                                        excludeRules.push(processedRule);
                                    }
                                };
                                for (var _c = 0, _d = rule.exclude; _c < _d.length; _c++) {
                                    var exclude = _d[_c];
                                    _loop_7(exclude);
                                }
                            }
                            else {
                                // If not rules listed, add the default rule to exclude the matched file
                                var escaped = ProjectService.escapeFilenameForRegex(root);
                                if (excludeRules.indexOf(escaped) < 0) {
                                    excludeRules.push(escaped);
                                }
                            }
                        }
                    }
                };
                var this_2 = this;
                for (var _i = 0, _a = Object.keys(this.safelist); _i < _a.length; _i++) {
                    var name = _a[_i];
                    _loop_5(name);
                }
                var excludeRegexes = excludeRules.map(function (e) { return new RegExp(e, "i"); });
                var filesToKeep = [];
                var _loop_6 = function (i) {
                    if (excludeRegexes.some(function (re) { return re.test(normalizedNames[i]); })) {
                        excludedFiles.push(normalizedNames[i]);
                    }
                    else {
                        var exclude = false;
                        if (typeAcquisition.enable || typeAcquisition.enableAutoDiscovery) {
                            var baseName = ts.getBaseFileName(normalizedNames[i].toLowerCase());
                            if (ts.fileExtensionIs(baseName, "js")) {
                                var inferredTypingName = ts.removeFileExtension(baseName);
                                var cleanedTypingName = ts.removeMinAndVersionNumbers(inferredTypingName);
                                var typeName = this_3.legacySafelist.get(cleanedTypingName);
                                if (typeName !== undefined) {
                                    this_3.logger.info("Excluded '" + normalizedNames[i] + "' because it matched " + cleanedTypingName + " from the legacy safelist");
                                    excludedFiles.push(normalizedNames[i]);
                                    // *exclude* it from the project...
                                    exclude = true;
                                    // ... but *include* it in the list of types to acquire
                                    // Same best-effort dedupe as above
                                    if (typeAcqInclude.indexOf(typeName) < 0) {
                                        typeAcqInclude.push(typeName);
                                    }
                                }
                            }
                        }
                        if (!exclude) {
                            // Exclude any minified files that get this far
                            if (/^.+[\.-]min\.js$/.test(normalizedNames[i])) {
                                excludedFiles.push(normalizedNames[i]);
                            }
                            else {
                                filesToKeep.push(proj.rootFiles[i]);
                            }
                        }
                    }
                };
                var this_3 = this;
                for (var i = 0; i < proj.rootFiles.length; i++) {
                    _loop_6(i);
                }
                proj.rootFiles = filesToKeep;
                return excludedFiles;
            };
            ProjectService.prototype.openExternalProject = function (proj) {
                // typingOptions has been deprecated and is only supported for backward compatibility
                // purposes. It should be removed in future releases - use typeAcquisition instead.
                if (proj.typingOptions && !proj.typeAcquisition) {
                    var typeAcquisition = ts.convertEnableAutoDiscoveryToEnable(proj.typingOptions);
                    proj.typeAcquisition = typeAcquisition;
                }
                proj.typeAcquisition = proj.typeAcquisition || {};
                proj.typeAcquisition.include = proj.typeAcquisition.include || [];
                proj.typeAcquisition.exclude = proj.typeAcquisition.exclude || [];
                if (proj.typeAcquisition.enable === undefined) {
                    proj.typeAcquisition.enable = server.hasNoTypeScriptSource(proj.rootFiles.map(function (f) { return f.fileName; }));
                }
                var excludedFiles = this.applySafeList(proj);
                var tsConfigFiles;
                var rootFiles = [];
                for (var _i = 0, _a = proj.rootFiles; _i < _a.length; _i++) {
                    var file = _a[_i];
                    var normalized = server.toNormalizedPath(file.fileName);
                    if (server.getBaseConfigFileName(normalized)) {
                        if (!this.syntaxOnly && this.host.fileExists(normalized)) {
                            (tsConfigFiles || (tsConfigFiles = [])).push(normalized);
                        }
                    }
                    else {
                        rootFiles.push(file);
                    }
                }
                // sort config files to simplify comparison later
                if (tsConfigFiles) {
                    tsConfigFiles.sort();
                }
                var externalProject = this.findExternalProjectByProjectName(proj.projectFileName);
                var exisingConfigFiles;
                if (externalProject) {
                    externalProject.excludedFiles = excludedFiles;
                    if (!tsConfigFiles) {
                        var compilerOptions = convertCompilerOptions(proj.options);
                        var lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(proj.projectFileName, compilerOptions, proj.rootFiles, externalFilePropertyReader);
                        if (lastFileExceededProgramSize) {
                            externalProject.disableLanguageService(lastFileExceededProgramSize);
                        }
                        else {
                            externalProject.enableLanguageService();
                        }
                        // external project already exists and not config files were added - update the project and return;
                        // The graph update here isnt postponed since any file open operation needs all updated external projects
                        this.updateRootAndOptionsOfNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, compilerOptions, proj.typeAcquisition, proj.options.compileOnSave);
                        externalProject.updateGraph();
                        return;
                    }
                    // some config files were added to external project (that previously were not there)
                    // close existing project and later we'll open a set of configured projects for these files
                    this.closeExternalProject(proj.projectFileName);
                }
                else if (this.externalProjectToConfiguredProjectMap.get(proj.projectFileName)) {
                    // this project used to include config files
                    if (!tsConfigFiles) {
                        // config files were removed from the project - close existing external project which in turn will close configured projects
                        this.closeExternalProject(proj.projectFileName);
                    }
                    else {
                        // project previously had some config files - compare them with new set of files and close all configured projects that correspond to unused files
                        var oldConfigFiles = this.externalProjectToConfiguredProjectMap.get(proj.projectFileName);
                        var iNew = 0;
                        var iOld = 0;
                        while (iNew < tsConfigFiles.length && iOld < oldConfigFiles.length) {
                            var newConfig = tsConfigFiles[iNew];
                            var oldConfig = oldConfigFiles[iOld];
                            if (oldConfig < newConfig) {
                                this.closeConfiguredProjectReferencedFromExternalProject(oldConfig);
                                iOld++;
                            }
                            else if (oldConfig > newConfig) {
                                iNew++;
                            }
                            else {
                                // record existing config files so avoid extra add-refs
                                (exisingConfigFiles || (exisingConfigFiles = [])).push(oldConfig);
                                iOld++;
                                iNew++;
                            }
                        }
                        for (var i = iOld; i < oldConfigFiles.length; i++) {
                            // projects for all remaining old config files should be closed
                            this.closeConfiguredProjectReferencedFromExternalProject(oldConfigFiles[i]);
                        }
                    }
                }
                if (tsConfigFiles) {
                    // store the list of tsconfig files that belong to the external project
                    this.externalProjectToConfiguredProjectMap.set(proj.projectFileName, tsConfigFiles);
                    for (var _b = 0, tsConfigFiles_1 = tsConfigFiles; _b < tsConfigFiles_1.length; _b++) {
                        var tsconfigFile = tsConfigFiles_1[_b];
                        var project = this.findConfiguredProjectByProjectName(tsconfigFile);
                        if (!project) {
                            // errors are stored in the project, do not need to update the graph
                            project = this.getHostPreferences().lazyConfiguredProjectsFromExternalProject ?
                                this.createConfiguredProjectWithDelayLoad(tsconfigFile, "Creating configured project in external project: " + proj.projectFileName) :
                                this.createLoadAndUpdateConfiguredProject(tsconfigFile, "Creating configured project in external project: " + proj.projectFileName);
                        }
                        if (project && !ts.contains(exisingConfigFiles, tsconfigFile)) {
                            // keep project alive even if no documents are opened - its lifetime is bound to the lifetime of containing external project
                            project.addExternalProjectReference();
                        }
                    }
                }
                else {
                    // no config files - remove the item from the collection
                    // Create external project and update its graph, do not delay update since
                    // any file open operation needs all updated external projects
                    this.externalProjectToConfiguredProjectMap.delete(proj.projectFileName);
                    var project = this.createExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition, excludedFiles);
                    project.updateGraph();
                }
            };
            ProjectService.prototype.hasDeferredExtension = function () {
                for (var _i = 0, _a = this.hostConfiguration.extraFileExtensions; _i < _a.length; _i++) { // TODO: GH#18217
                    var extension = _a[_i];
                    if (extension.scriptKind === 7 /* Deferred */) {
                        return true;
                    }
                }
                return false;
            };
            ProjectService.prototype.configurePlugin = function (args) {
                // For any projects that already have the plugin loaded, configure the plugin
                this.forEachEnabledProject(function (project) { return project.onPluginConfigurationChanged(args.pluginName, args.configuration); });
                // Also save the current configuration to pass on to any projects that are yet to be loaded.
                // If a plugin is configured twice, only the latest configuration will be remembered.
                this.currentPluginConfigOverrides = this.currentPluginConfigOverrides || ts.createMap();
                this.currentPluginConfigOverrides.set(args.pluginName, args.configuration);
            };
            /** Makes a filename safe to insert in a RegExp */
            ProjectService.filenameEscapeRegexp = /[-\/\\^$*+?.()|[\]{}]/g;
            return ProjectService;
        }());
        server.ProjectService = ProjectService;
        /* @internal */
        function isConfigFile(config) {
            return config.kind !== undefined;
        }
        server.isConfigFile = isConfigFile;
        function printProjectsWithCounter(projects, counter) {
            for (var _i = 0, projects_4 = projects; _i < projects_4.length; _i++) {
                var project = projects_4[_i];
                project.print(counter);
                counter++;
            }
            return counter;
        }
    })(server = ts.server || (ts.server = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    var server;
    (function (server) {
        server.nullCancellationToken = {
            isCancellationRequested: function () { return false; },
            setRequest: function () { return void 0; },
            resetRequest: function () { return void 0; }
        };
        function hrTimeToMilliseconds(time) {
            var seconds = time[0];
            var nanoseconds = time[1];
            return ((1e9 * seconds) + nanoseconds) / 1000000.0;
        }
        function isDeclarationFileInJSOnlyNonConfiguredProject(project, file) {
            // Checking for semantic diagnostics is an expensive process. We want to avoid it if we
            // know for sure it is not needed.
            // For instance, .d.ts files injected by ATA automatically do not produce any relevant
            // errors to a JS- only project.
            //
            // Note that configured projects can set skipLibCheck (on by default in jsconfig.json) to
            // disable checking for declaration files. We only need to verify for inferred projects (e.g.
            // miscellaneous context in VS) and external projects(e.g.VS.csproj project) with only JS
            // files.
            //
            // We still want to check .js files in a JS-only inferred or external project (e.g. if the
            // file has '// @ts-check').
            if ((project.projectKind === server.ProjectKind.Inferred || project.projectKind === server.ProjectKind.External) &&
                project.isJsOnlyProject()) {
                var scriptInfo = project.getScriptInfoForNormalizedPath(file);
                return scriptInfo && !scriptInfo.isJavaScript();
            }
            return false;
        }
        function formatDiag(fileName, project, diag) {
            var scriptInfo = project.getScriptInfoForNormalizedPath(fileName); // TODO: GH#18217
            return {
                start: scriptInfo.positionToLineOffset(diag.start),
                end: scriptInfo.positionToLineOffset(diag.start + diag.length),
                text: ts.flattenDiagnosticMessageText(diag.messageText, "\n"),
                code: diag.code,
                category: ts.diagnosticCategoryName(diag),
                reportsUnnecessary: diag.reportsUnnecessary,
                source: diag.source,
                relatedInformation: ts.map(diag.relatedInformation, formatRelatedInformation),
            };
        }
        function formatRelatedInformation(info) {
            if (!info.file) {
                return {
                    message: ts.flattenDiagnosticMessageText(info.messageText, "\n"),
                    category: ts.diagnosticCategoryName(info),
                    code: info.code
                };
            }
            return {
                span: {
                    start: convertToLocation(ts.getLineAndCharacterOfPosition(info.file, info.start)),
                    end: convertToLocation(ts.getLineAndCharacterOfPosition(info.file, info.start + info.length)),
                    file: info.file.fileName
                },
                message: ts.flattenDiagnosticMessageText(info.messageText, "\n"),
                category: ts.diagnosticCategoryName(info),
                code: info.code
            };
        }
        function convertToLocation(lineAndCharacter) {
            return { line: lineAndCharacter.line + 1, offset: lineAndCharacter.character + 1 };
        }
        function formatConfigFileDiag(diag, includeFileName) {
            var start = (diag.file && convertToLocation(ts.getLineAndCharacterOfPosition(diag.file, diag.start))); // TODO: GH#18217
            var end = (diag.file && convertToLocation(ts.getLineAndCharacterOfPosition(diag.file, diag.start + diag.length))); // TODO: GH#18217
            var text = ts.flattenDiagnosticMessageText(diag.messageText, "\n");
            var code = diag.code, source = diag.source;
            var category = ts.diagnosticCategoryName(diag);
            var common = {
                start: start,
                end: end,
                text: text,
                code: code,
                category: category,
                reportsUnnecessary: diag.reportsUnnecessary,
                source: source,
                relatedInformation: ts.map(diag.relatedInformation, formatRelatedInformation),
            };
            return includeFileName
                ? __assign({}, common, { fileName: diag.file && diag.file.fileName }) : common;
        }
        function allEditsBeforePos(edits, pos) {
            return edits.every(function (edit) { return ts.textSpanEnd(edit.span) < pos; });
        }
        server.CommandNames = server.protocol.CommandTypes; // tslint:disable-line variable-name
        function formatMessage(msg, logger, byteLength, newLine) {
            var verboseLogging = logger.hasLevel(server.LogLevel.verbose);
            var json = JSON.stringify(msg);
            if (verboseLogging) {
                logger.info(msg.type + ":" + server.indent(json));
            }
            var len = byteLength(json, "utf8");
            return "Content-Length: " + (1 + len) + "\r\n\r\n" + json + newLine;
        }
        server.formatMessage = formatMessage;
        /**
         * Represents operation that can schedule its next step to be executed later.
         * Scheduling is done via instance of NextStep. If on current step subsequent step was not scheduled - operation is assumed to be completed.
         */
        var MultistepOperation = /** @class */ (function () {
            function MultistepOperation(operationHost) {
                this.operationHost = operationHost;
            }
            MultistepOperation.prototype.startNew = function (action) {
                this.complete();
                this.requestId = this.operationHost.getCurrentRequestId();
                this.executeAction(action);
            };
            MultistepOperation.prototype.complete = function () {
                if (this.requestId !== undefined) {
                    this.operationHost.sendRequestCompletedEvent(this.requestId);
                    this.requestId = undefined;
                }
                this.setTimerHandle(undefined);
                this.setImmediateId(undefined);
            };
            MultistepOperation.prototype.immediate = function (action) {
                var _this = this;
                var requestId = this.requestId;
                ts.Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "immediate: incorrect request id");
                this.setImmediateId(this.operationHost.getServerHost().setImmediate(function () {
                    _this.immediateId = undefined;
                    _this.operationHost.executeWithRequestId(requestId, function () { return _this.executeAction(action); });
                }));
            };
            MultistepOperation.prototype.delay = function (ms, action) {
                var _this = this;
                var requestId = this.requestId;
                ts.Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "delay: incorrect request id");
                this.setTimerHandle(this.operationHost.getServerHost().setTimeout(function () {
                    _this.timerHandle = undefined;
                    _this.operationHost.executeWithRequestId(requestId, function () { return _this.executeAction(action); });
                }, ms));
            };
            MultistepOperation.prototype.executeAction = function (action) {
                var stop = false;
                try {
                    if (this.operationHost.isCancellationRequested()) {
                        stop = true;
                    }
                    else {
                        action(this);
                    }
                }
                catch (e) {
                    stop = true;
                    // ignore cancellation request
                    if (!(e instanceof ts.OperationCanceledException)) {
                        this.operationHost.logError(e, "delayed processing of request " + this.requestId);
                    }
                }
                if (stop || !this.hasPendingWork()) {
                    this.complete();
                }
            };
            MultistepOperation.prototype.setTimerHandle = function (timerHandle) {
                if (this.timerHandle !== undefined) {
                    this.operationHost.getServerHost().clearTimeout(this.timerHandle);
                }
                this.timerHandle = timerHandle;
            };
            MultistepOperation.prototype.setImmediateId = function (immediateId) {
                if (this.immediateId !== undefined) {
                    this.operationHost.getServerHost().clearImmediate(this.immediateId);
                }
                this.immediateId = immediateId;
            };
            MultistepOperation.prototype.hasPendingWork = function () {
                return !!this.timerHandle || !!this.immediateId;
            };
            return MultistepOperation;
        }());
        /** @internal */
        function toEvent(eventName, body) {
            return {
                seq: 0,
                type: "event",
                event: eventName,
                body: body
            };
        }
        server.toEvent = toEvent;
        /**
         * This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project.
         */
        function combineProjectOutput(defaultValue, getValue, projects, action) {
            var outputs = ts.flatMapToMutable(ts.isArray(projects) ? projects : projects.projects, function (project) { return action(project, defaultValue); });
            if (!ts.isArray(projects) && projects.symLinkedProjects) {
                projects.symLinkedProjects.forEach(function (projects, path) {
                    var value = getValue(path);
                    outputs.push.apply(outputs, ts.flatMap(projects, function (project) { return action(project, value); }));
                });
            }
            return ts.deduplicate(outputs, ts.equateValues);
        }
        function combineProjectOutputFromEveryProject(projectService, action, areEqual) {
            var outputs = [];
            projectService.forEachEnabledProject(function (project) {
                var theseOutputs = action(project);
                outputs.push.apply(outputs, theseOutputs.filter(function (output) { return !outputs.some(function (o) { return areEqual(o, output); }); }));
            });
            return outputs;
        }
        function combineProjectOutputWhileOpeningReferencedProjects(projects, defaultProject, action, getLocation, resultsEqual) {
            var outputs = [];
            combineProjectOutputWorker(projects, defaultProject, 
            /*initialLocation*/ undefined, function (_a, tryAddToTodo) {
                var project = _a.project;
                for (var _i = 0, _b = action(project); _i < _b.length; _i++) {
                    var output = _b[_i];
                    if (!ts.contains(outputs, output, resultsEqual) && !tryAddToTodo(project, getLocation(output))) {
                        outputs.push(output);
                    }
                }
            }, 
            /*getDefinition*/ undefined);
            return outputs;
        }
        function combineProjectOutputForRenameLocations(projects, defaultProject, initialLocation, findInStrings, findInComments, hostPreferences) {
            var outputs = [];
            combineProjectOutputWorker(projects, defaultProject, initialLocation, function (_a, tryAddToTodo) {
                var project = _a.project, location = _a.location;
                for (var _i = 0, _b = project.getLanguageService().findRenameLocations(location.fileName, location.pos, findInStrings, findInComments, hostPreferences.providePrefixAndSuffixTextForRename) || server.emptyArray; _i < _b.length; _i++) {
                    var output = _b[_i];
                    if (!ts.contains(outputs, output, ts.documentSpansEqual) && !tryAddToTodo(project, documentSpanLocation(output))) {
                        outputs.push(output);
                    }
                }
            }, function () { return getDefinitionLocation(defaultProject, initialLocation); });
            return outputs;
        }
        function getDefinitionLocation(defaultProject, initialLocation) {
            var infos = defaultProject.getLanguageService().getDefinitionAtPosition(initialLocation.fileName, initialLocation.pos);
            var info = infos && ts.firstOrUndefined(infos);
            return info && { fileName: info.fileName, pos: info.textSpan.start };
        }
        function combineProjectOutputForReferences(projects, defaultProject, initialLocation) {
            var outputs = [];
            combineProjectOutputWorker(projects, defaultProject, initialLocation, function (_a, getMappedLocation) {
                var project = _a.project, location = _a.location;
                var _loop_8 = function (outputReferencedSymbol) {
                    var mappedDefinitionFile = getMappedLocation(project, documentSpanLocation(outputReferencedSymbol.definition));
                    var definition = mappedDefinitionFile === undefined ? outputReferencedSymbol.definition : __assign({}, outputReferencedSymbol.definition, { textSpan: ts.createTextSpan(mappedDefinitionFile.pos, outputReferencedSymbol.definition.textSpan.length), fileName: mappedDefinitionFile.fileName });
                    var symbolToAddTo = ts.find(outputs, function (o) { return ts.documentSpansEqual(o.definition, definition); });
                    if (!symbolToAddTo) {
                        symbolToAddTo = { definition: definition, references: [] };
                        outputs.push(symbolToAddTo);
                    }
                    for (var _i = 0, _a = outputReferencedSymbol.references; _i < _a.length; _i++) {
                        var ref = _a[_i];
                        // If it's in a mapped file, that is added to the todo list by `getMappedLocation`.
                        if (!ts.contains(symbolToAddTo.references, ref, ts.documentSpansEqual) && !getMappedLocation(project, documentSpanLocation(ref))) {
                            symbolToAddTo.references.push(ref);
                        }
                    }
                };
                for (var _i = 0, _b = project.getLanguageService().findReferences(location.fileName, location.pos) || server.emptyArray; _i < _b.length; _i++) {
                    var outputReferencedSymbol = _b[_i];
                    _loop_8(outputReferencedSymbol);
                }
            }, function () { return getDefinitionLocation(defaultProject, initialLocation); });
            return outputs.filter(function (o) { return o.references.length !== 0; });
        }
        function forEachProjectInProjects(projects, path, cb) {
            for (var _i = 0, _a = ts.isArray(projects) ? projects : projects.projects; _i < _a.length; _i++) {
                var project = _a[_i];
                cb(project, path);
            }
            if (!ts.isArray(projects) && projects.symLinkedProjects) {
                projects.symLinkedProjects.forEach(function (symlinkedProjects, symlinkedPath) {
                    for (var _i = 0, symlinkedProjects_1 = symlinkedProjects; _i < symlinkedProjects_1.length; _i++) {
                        var project = symlinkedProjects_1[_i];
                        cb(project, symlinkedPath);
                    }
                });
            }
        }
        function combineProjectOutputWorker(projects, defaultProject, initialLocation, cb, getDefinition) {
            var projectService = defaultProject.projectService;
            var toDo;
            var seenProjects = ts.createMap();
            forEachProjectInProjects(projects, initialLocation && initialLocation.fileName, function (project, path) {
                // TLocation shoud be either `DocumentPosition` or `undefined`. Since `initialLocation` is `TLocation` this cast should be valid.
                var location = (initialLocation ? { fileName: path, pos: initialLocation.pos } : undefined);
                toDo = callbackProjectAndLocation({ project: project, location: location }, projectService, toDo, seenProjects, cb);
            });
            // After initial references are collected, go over every other project and see if it has a reference for the symbol definition.
            if (getDefinition) {
                var memGetDefinition_1 = ts.memoize(getDefinition);
                projectService.forEachEnabledProject(function (project) {
                    if (!ts.addToSeen(seenProjects, project.projectName))
                        return;
                    var definition = getDefinitionInProject(memGetDefinition_1(), defaultProject, project);
                    if (definition) {
                        toDo = callbackProjectAndLocation({ project: project, location: definition }, projectService, toDo, seenProjects, cb);
                    }
                });
            }
            while (toDo && toDo.length) {
                toDo = callbackProjectAndLocation(ts.Debug.assertDefined(toDo.pop()), projectService, toDo, seenProjects, cb);
            }
        }
        function getDefinitionInProject(definition, definingProject, project) {
            if (!definition || project.containsFile(server.toNormalizedPath(definition.fileName)))
                return definition;
            var mappedDefinition = definingProject.getLanguageService().getSourceMapper().tryGetGeneratedPosition(definition);
            return mappedDefinition && project.containsFile(server.toNormalizedPath(mappedDefinition.fileName)) ? mappedDefinition : undefined;
        }
        function callbackProjectAndLocation(projectAndLocation, projectService, toDo, seenProjects, cb) {
            if (projectAndLocation.project.getCancellationToken().isCancellationRequested())
                return undefined; // Skip rest of toDo if cancelled
            cb(projectAndLocation, function (project, location) {
                seenProjects.set(projectAndLocation.project.projectName, true);
                var originalLocation = projectService.getOriginalLocationEnsuringConfiguredProject(project, location);
                if (!originalLocation)
                    return undefined;
                var originalScriptInfo = projectService.getScriptInfo(originalLocation.fileName);
                toDo = toDo || [];
                for (var _i = 0, _a = originalScriptInfo.containingProjects; _i < _a.length; _i++) {
                    var project_1 = _a[_i];
                    addToTodo({ project: project_1, location: originalLocation }, toDo, seenProjects);
                }
                var symlinkedProjectsMap = projectService.getSymlinkedProjects(originalScriptInfo);
                if (symlinkedProjectsMap) {
                    symlinkedProjectsMap.forEach(function (symlinkedProjects) {
                        for (var _i = 0, symlinkedProjects_2 = symlinkedProjects; _i < symlinkedProjects_2.length; _i++) {
                            var symlinkedProject = symlinkedProjects_2[_i];
                            addToTodo({ project: symlinkedProject, location: originalLocation }, toDo, seenProjects);
                        }
                    });
                }
                return originalLocation;
            });
            return toDo;
        }
        function addToTodo(projectAndLocation, toDo, seenProjects) {
            if (ts.addToSeen(seenProjects, projectAndLocation.project.projectName))
                toDo.push(projectAndLocation);
        }
        function documentSpanLocation(_a) {
            var fileName = _a.fileName, textSpan = _a.textSpan;
            return { fileName: fileName, pos: textSpan.start };
        }
        function getMappedLocation(location, projectService, project) {
            var mapsTo = project.getSourceMapper().tryGetSourcePosition(location);
            return mapsTo && projectService.fileExists(server.toNormalizedPath(mapsTo.fileName)) ? mapsTo : undefined;
        }
        var Session = /** @class */ (function () {
            function Session(opts) {
                var _a;
                var _this = this;
                this.changeSeq = 0;
                this.handlers = ts.createMapFromTemplate((_a = {},
                    _a[server.CommandNames.Status] = function () {
                        var response = { version: ts.version };
                        return _this.requiredResponse(response);
                    },
                    _a[server.CommandNames.OpenExternalProject] = function (request) {
                        _this.projectService.openExternalProject(request.arguments);
                        // TODO: GH#20447 report errors
                        return _this.requiredResponse(/*response*/ true);
                    },
                    _a[server.CommandNames.OpenExternalProjects] = function (request) {
                        _this.projectService.openExternalProjects(request.arguments.projects);
                        // TODO: GH#20447 report errors
                        return _this.requiredResponse(/*response*/ true);
                    },
                    _a[server.CommandNames.CloseExternalProject] = function (request) {
                        _this.projectService.closeExternalProject(request.arguments.projectFileName);
                        // TODO: GH#20447 report errors
                        return _this.requiredResponse(/*response*/ true);
                    },
                    _a[server.CommandNames.SynchronizeProjectList] = function (request) {
                        var result = _this.projectService.synchronizeProjectList(request.arguments.knownProjects);
                        if (!result.some(function (p) { return p.projectErrors && p.projectErrors.length !== 0; })) {
                            return _this.requiredResponse(result);
                        }
                        var converted = ts.map(result, function (p) {
                            if (!p.projectErrors || p.projectErrors.length === 0) {
                                return p;
                            }
                            return {
                                info: p.info,
                                changes: p.changes,
                                files: p.files,
                                projectErrors: _this.convertToDiagnosticsWithLinePosition(p.projectErrors, /*scriptInfo*/ undefined)
                            };
                        });
                        return _this.requiredResponse(converted);
                    },
                    _a[server.CommandNames.UpdateOpen] = function (request) {
                        _this.changeSeq++;
                        _this.projectService.applyChangesInOpenFiles(request.arguments.openFiles && ts.mapIterator(ts.arrayIterator(request.arguments.openFiles), function (file) { return ({
                            fileName: file.file,
                            content: file.fileContent,
                            scriptKind: file.scriptKindName,
                            projectRootPath: file.projectRootPath
                        }); }), request.arguments.changedFiles && ts.mapIterator(ts.arrayIterator(request.arguments.changedFiles), function (file) { return ({
                            fileName: file.fileName,
                            changes: ts.mapDefinedIterator(ts.arrayReverseIterator(file.textChanges), function (change) {
                                var scriptInfo = ts.Debug.assertDefined(_this.projectService.getScriptInfo(file.fileName));
                                var start = scriptInfo.lineOffsetToPosition(change.start.line, change.start.offset);
                                var end = scriptInfo.lineOffsetToPosition(change.end.line, change.end.offset);
                                return start >= 0 ? { span: { start: start, length: end - start }, newText: change.newText } : undefined;
                            })
                        }); }), request.arguments.closedFiles);
                        return _this.requiredResponse(/*response*/ true);
                    },
                    _a[server.CommandNames.ApplyChangedToOpenFiles] = function (request) {
                        _this.changeSeq++;
                        _this.projectService.applyChangesInOpenFiles(request.arguments.openFiles && ts.arrayIterator(request.arguments.openFiles), request.arguments.changedFiles && ts.mapIterator(ts.arrayIterator(request.arguments.changedFiles), function (file) { return ({
                            fileName: file.fileName,
                            // apply changes in reverse order
                            changes: ts.arrayReverseIterator(file.changes)
                        }); }), request.arguments.closedFiles);
                        // TODO: report errors
                        return _this.requiredResponse(/*response*/ true);
                    },
                    _a[server.CommandNames.Exit] = function () {
                        _this.exit();
                        return _this.notRequired();
                    },
                    _a[server.CommandNames.Definition] = function (request) {
                        return _this.requiredResponse(_this.getDefinition(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.DefinitionFull] = function (request) {
                        return _this.requiredResponse(_this.getDefinition(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.DefinitionAndBoundSpan] = function (request) {
                        return _this.requiredResponse(_this.getDefinitionAndBoundSpan(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.DefinitionAndBoundSpanFull] = function (request) {
                        return _this.requiredResponse(_this.getDefinitionAndBoundSpan(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.EmitOutput] = function (request) {
                        return _this.requiredResponse(_this.getEmitOutput(request.arguments));
                    },
                    _a[server.CommandNames.TypeDefinition] = function (request) {
                        return _this.requiredResponse(_this.getTypeDefinition(request.arguments));
                    },
                    _a[server.CommandNames.Implementation] = function (request) {
                        return _this.requiredResponse(_this.getImplementation(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.ImplementationFull] = function (request) {
                        return _this.requiredResponse(_this.getImplementation(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.References] = function (request) {
                        return _this.requiredResponse(_this.getReferences(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.ReferencesFull] = function (request) {
                        return _this.requiredResponse(_this.getReferences(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.Rename] = function (request) {
                        return _this.requiredResponse(_this.getRenameLocations(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.RenameLocationsFull] = function (request) {
                        return _this.requiredResponse(_this.getRenameLocations(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.RenameInfoFull] = function (request) {
                        return _this.requiredResponse(_this.getRenameInfo(request.arguments));
                    },
                    _a[server.CommandNames.Open] = function (request) {
                        _this.openClientFile(server.toNormalizedPath(request.arguments.file), request.arguments.fileContent, server.convertScriptKindName(request.arguments.scriptKindName), // TODO: GH#18217
                        request.arguments.projectRootPath ? server.toNormalizedPath(request.arguments.projectRootPath) : undefined);
                        return _this.notRequired();
                    },
                    _a[server.CommandNames.Quickinfo] = function (request) {
                        return _this.requiredResponse(_this.getQuickInfoWorker(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.QuickinfoFull] = function (request) {
                        return _this.requiredResponse(_this.getQuickInfoWorker(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.GetOutliningSpans] = function (request) {
                        return _this.requiredResponse(_this.getOutliningSpans(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.GetOutliningSpansFull] = function (request) {
                        return _this.requiredResponse(_this.getOutliningSpans(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.TodoComments] = function (request) {
                        return _this.requiredResponse(_this.getTodoComments(request.arguments));
                    },
                    _a[server.CommandNames.Indentation] = function (request) {
                        return _this.requiredResponse(_this.getIndentation(request.arguments));
                    },
                    _a[server.CommandNames.NameOrDottedNameSpan] = function (request) {
                        return _this.requiredResponse(_this.getNameOrDottedNameSpan(request.arguments));
                    },
                    _a[server.CommandNames.BreakpointStatement] = function (request) {
                        return _this.requiredResponse(_this.getBreakpointStatement(request.arguments));
                    },
                    _a[server.CommandNames.BraceCompletion] = function (request) {
                        return _this.requiredResponse(_this.isValidBraceCompletion(request.arguments));
                    },
                    _a[server.CommandNames.DocCommentTemplate] = function (request) {
                        return _this.requiredResponse(_this.getDocCommentTemplate(request.arguments));
                    },
                    _a[server.CommandNames.GetSpanOfEnclosingComment] = function (request) {
                        return _this.requiredResponse(_this.getSpanOfEnclosingComment(request.arguments));
                    },
                    _a[server.CommandNames.Format] = function (request) {
                        return _this.requiredResponse(_this.getFormattingEditsForRange(request.arguments));
                    },
                    _a[server.CommandNames.Formatonkey] = function (request) {
                        return _this.requiredResponse(_this.getFormattingEditsAfterKeystroke(request.arguments));
                    },
                    _a[server.CommandNames.FormatFull] = function (request) {
                        return _this.requiredResponse(_this.getFormattingEditsForDocumentFull(request.arguments));
                    },
                    _a[server.CommandNames.FormatonkeyFull] = function (request) {
                        return _this.requiredResponse(_this.getFormattingEditsAfterKeystrokeFull(request.arguments));
                    },
                    _a[server.CommandNames.FormatRangeFull] = function (request) {
                        return _this.requiredResponse(_this.getFormattingEditsForRangeFull(request.arguments));
                    },
                    _a[server.CommandNames.CompletionInfo] = function (request) {
                        return _this.requiredResponse(_this.getCompletions(request.arguments, server.CommandNames.CompletionInfo));
                    },
                    _a[server.CommandNames.Completions] = function (request) {
                        return _this.requiredResponse(_this.getCompletions(request.arguments, server.CommandNames.Completions));
                    },
                    _a[server.CommandNames.CompletionsFull] = function (request) {
                        return _this.requiredResponse(_this.getCompletions(request.arguments, server.CommandNames.CompletionsFull));
                    },
                    _a[server.CommandNames.CompletionDetails] = function (request) {
                        return _this.requiredResponse(_this.getCompletionEntryDetails(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.CompletionDetailsFull] = function (request) {
                        return _this.requiredResponse(_this.getCompletionEntryDetails(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.CompileOnSaveAffectedFileList] = function (request) {
                        return _this.requiredResponse(_this.getCompileOnSaveAffectedFileList(request.arguments));
                    },
                    _a[server.CommandNames.CompileOnSaveEmitFile] = function (request) {
                        return _this.requiredResponse(_this.emitFile(request.arguments));
                    },
                    _a[server.CommandNames.SignatureHelp] = function (request) {
                        return _this.requiredResponse(_this.getSignatureHelpItems(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.SignatureHelpFull] = function (request) {
                        return _this.requiredResponse(_this.getSignatureHelpItems(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.CompilerOptionsDiagnosticsFull] = function (request) {
                        return _this.requiredResponse(_this.getCompilerOptionsDiagnostics(request.arguments));
                    },
                    _a[server.CommandNames.EncodedSemanticClassificationsFull] = function (request) {
                        return _this.requiredResponse(_this.getEncodedSemanticClassifications(request.arguments));
                    },
                    _a[server.CommandNames.Cleanup] = function () {
                        _this.cleanup();
                        return _this.requiredResponse(/*response*/ true);
                    },
                    _a[server.CommandNames.SemanticDiagnosticsSync] = function (request) {
                        return _this.requiredResponse(_this.getSemanticDiagnosticsSync(request.arguments));
                    },
                    _a[server.CommandNames.SyntacticDiagnosticsSync] = function (request) {
                        return _this.requiredResponse(_this.getSyntacticDiagnosticsSync(request.arguments));
                    },
                    _a[server.CommandNames.SuggestionDiagnosticsSync] = function (request) {
                        return _this.requiredResponse(_this.getSuggestionDiagnosticsSync(request.arguments));
                    },
                    _a[server.CommandNames.Geterr] = function (request) {
                        _this.errorCheck.startNew(function (next) { return _this.getDiagnostics(next, request.arguments.delay, request.arguments.files); });
                        return _this.notRequired();
                    },
                    _a[server.CommandNames.GeterrForProject] = function (request) {
                        _this.errorCheck.startNew(function (next) { return _this.getDiagnosticsForProject(next, request.arguments.delay, request.arguments.file); });
                        return _this.notRequired();
                    },
                    _a[server.CommandNames.Change] = function (request) {
                        _this.change(request.arguments);
                        return _this.notRequired();
                    },
                    _a[server.CommandNames.Configure] = function (request) {
                        _this.projectService.setHostConfiguration(request.arguments);
                        _this.doOutput(/*info*/ undefined, server.CommandNames.Configure, request.seq, /*success*/ true);
                        return _this.notRequired();
                    },
                    _a[server.CommandNames.Reload] = function (request) {
                        _this.reload(request.arguments, request.seq);
                        return _this.requiredResponse({ reloadFinished: true });
                    },
                    _a[server.CommandNames.Saveto] = function (request) {
                        var savetoArgs = request.arguments;
                        _this.saveToTmp(savetoArgs.file, savetoArgs.tmpfile);
                        return _this.notRequired();
                    },
                    _a[server.CommandNames.Close] = function (request) {
                        var closeArgs = request.arguments;
                        _this.closeClientFile(closeArgs.file);
                        return _this.notRequired();
                    },
                    _a[server.CommandNames.Navto] = function (request) {
                        return _this.requiredResponse(_this.getNavigateToItems(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.NavtoFull] = function (request) {
                        return _this.requiredResponse(_this.getNavigateToItems(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.Brace] = function (request) {
                        return _this.requiredResponse(_this.getBraceMatching(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.BraceFull] = function (request) {
                        return _this.requiredResponse(_this.getBraceMatching(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.NavBar] = function (request) {
                        return _this.requiredResponse(_this.getNavigationBarItems(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.NavBarFull] = function (request) {
                        return _this.requiredResponse(_this.getNavigationBarItems(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.NavTree] = function (request) {
                        return _this.requiredResponse(_this.getNavigationTree(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.NavTreeFull] = function (request) {
                        return _this.requiredResponse(_this.getNavigationTree(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.Occurrences] = function (request) {
                        return _this.requiredResponse(_this.getOccurrences(request.arguments));
                    },
                    _a[server.CommandNames.DocumentHighlights] = function (request) {
                        return _this.requiredResponse(_this.getDocumentHighlights(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.DocumentHighlightsFull] = function (request) {
                        return _this.requiredResponse(_this.getDocumentHighlights(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.CompilerOptionsForInferredProjects] = function (request) {
                        _this.setCompilerOptionsForInferredProjects(request.arguments);
                        return _this.requiredResponse(/*response*/ true);
                    },
                    _a[server.CommandNames.ProjectInfo] = function (request) {
                        return _this.requiredResponse(_this.getProjectInfo(request.arguments));
                    },
                    _a[server.CommandNames.ReloadProjects] = function () {
                        _this.projectService.reloadProjects();
                        return _this.notRequired();
                    },
                    _a[server.CommandNames.JsxClosingTag] = function (request) {
                        return _this.requiredResponse(_this.getJsxClosingTag(request.arguments));
                    },
                    _a[server.CommandNames.GetCodeFixes] = function (request) {
                        return _this.requiredResponse(_this.getCodeFixes(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.GetCodeFixesFull] = function (request) {
                        return _this.requiredResponse(_this.getCodeFixes(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.GetCombinedCodeFix] = function (request) {
                        return _this.requiredResponse(_this.getCombinedCodeFix(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.GetCombinedCodeFixFull] = function (request) {
                        return _this.requiredResponse(_this.getCombinedCodeFix(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.ApplyCodeActionCommand] = function (request) {
                        return _this.requiredResponse(_this.applyCodeActionCommand(request.arguments));
                    },
                    _a[server.CommandNames.GetSupportedCodeFixes] = function () {
                        return _this.requiredResponse(_this.getSupportedCodeFixes());
                    },
                    _a[server.CommandNames.GetApplicableRefactors] = function (request) {
                        return _this.requiredResponse(_this.getApplicableRefactors(request.arguments));
                    },
                    _a[server.CommandNames.GetEditsForRefactor] = function (request) {
                        return _this.requiredResponse(_this.getEditsForRefactor(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.GetEditsForRefactorFull] = function (request) {
                        return _this.requiredResponse(_this.getEditsForRefactor(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.OrganizeImports] = function (request) {
                        return _this.requiredResponse(_this.organizeImports(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.OrganizeImportsFull] = function (request) {
                        return _this.requiredResponse(_this.organizeImports(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.GetEditsForFileRename] = function (request) {
                        return _this.requiredResponse(_this.getEditsForFileRename(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.GetEditsForFileRenameFull] = function (request) {
                        return _this.requiredResponse(_this.getEditsForFileRename(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a[server.CommandNames.ConfigurePlugin] = function (request) {
                        _this.configurePlugin(request.arguments);
                        _this.doOutput(/*info*/ undefined, server.CommandNames.ConfigurePlugin, request.seq, /*success*/ true);
                        return _this.notRequired();
                    },
                    _a[server.CommandNames.SelectionRange] = function (request) {
                        return _this.requiredResponse(_this.getSmartSelectionRange(request.arguments, /*simplifiedResult*/ true));
                    },
                    _a[server.CommandNames.SelectionRangeFull] = function (request) {
                        return _this.requiredResponse(_this.getSmartSelectionRange(request.arguments, /*simplifiedResult*/ false));
                    },
                    _a));
                this.host = opts.host;
                this.cancellationToken = opts.cancellationToken;
                this.typingsInstaller = opts.typingsInstaller;
                this.byteLength = opts.byteLength;
                this.hrtime = opts.hrtime;
                this.logger = opts.logger;
                this.canUseEvents = opts.canUseEvents;
                this.suppressDiagnosticEvents = opts.suppressDiagnosticEvents;
                this.noGetErrOnBackgroundUpdate = opts.noGetErrOnBackgroundUpdate;
                var throttleWaitMilliseconds = opts.throttleWaitMilliseconds;
                this.eventHandler = this.canUseEvents
                    ? opts.eventHandler || (function (event) { return _this.defaultEventHandler(event); })
                    : undefined;
                var multistepOperationHost = {
                    executeWithRequestId: function (requestId, action) { return _this.executeWithRequestId(requestId, action); },
                    getCurrentRequestId: function () { return _this.currentRequestId; },
                    getServerHost: function () { return _this.host; },
                    logError: function (err, cmd) { return _this.logError(err, cmd); },
                    sendRequestCompletedEvent: function (requestId) { return _this.sendRequestCompletedEvent(requestId); },
                    isCancellationRequested: function () { return _this.cancellationToken.isCancellationRequested(); }
                };
                this.errorCheck = new MultistepOperation(multistepOperationHost);
                var settings = {
                    host: this.host,
                    logger: this.logger,
                    cancellationToken: this.cancellationToken,
                    useSingleInferredProject: opts.useSingleInferredProject,
                    useInferredProjectPerProjectRoot: opts.useInferredProjectPerProjectRoot,
                    typingsInstaller: this.typingsInstaller,
                    throttleWaitMilliseconds: throttleWaitMilliseconds,
                    eventHandler: this.eventHandler,
                    suppressDiagnosticEvents: this.suppressDiagnosticEvents,
                    globalPlugins: opts.globalPlugins,
                    pluginProbeLocations: opts.pluginProbeLocations,
                    allowLocalPluginLoads: opts.allowLocalPluginLoads,
                    typesMapLocation: opts.typesMapLocation,
                    syntaxOnly: opts.syntaxOnly,
                };
                this.projectService = new server.ProjectService(settings);
                this.gcTimer = new server.GcTimer(this.host, /*delay*/ 7000, this.logger);
            }
            Session.prototype.sendRequestCompletedEvent = function (requestId) {
                this.event({ request_seq: requestId }, "requestCompleted");
            };
            Session.prototype.defaultEventHandler = function (event) {
                switch (event.eventName) {
                    case server.ProjectsUpdatedInBackgroundEvent:
                        var openFiles = event.data.openFiles;
                        this.projectsUpdatedInBackgroundEvent(openFiles);
                        break;
                    case server.ProjectLoadingStartEvent:
                        var _a = event.data, project = _a.project, reason = _a.reason;
                        this.event({ projectName: project.getProjectName(), reason: reason }, server.ProjectLoadingStartEvent);
                        break;
                    case server.ProjectLoadingFinishEvent:
                        var finishProject = event.data.project;
                        this.event({ projectName: finishProject.getProjectName() }, server.ProjectLoadingFinishEvent);
                        break;
                    case server.LargeFileReferencedEvent:
                        var _b = event.data, file = _b.file, fileSize = _b.fileSize, maxFileSize_1 = _b.maxFileSize;
                        this.event({ file: file, fileSize: fileSize, maxFileSize: maxFileSize_1 }, server.LargeFileReferencedEvent);
                        break;
                    case server.ConfigFileDiagEvent:
                        var _c = event.data, triggerFile = _c.triggerFile, configFile = _c.configFileName, diagnostics = _c.diagnostics;
                        var bakedDiags = ts.map(diagnostics, function (diagnostic) { return formatConfigFileDiag(diagnostic, /*includeFileName*/ true); });
                        this.event({
                            triggerFile: triggerFile,
                            configFile: configFile,
                            diagnostics: bakedDiags
                        }, server.ConfigFileDiagEvent);
                        break;
                    case server.ProjectLanguageServiceStateEvent: {
                        var eventName = server.ProjectLanguageServiceStateEvent;
                        this.event({
                            projectName: event.data.project.getProjectName(),
                            languageServiceEnabled: event.data.languageServiceEnabled
                        }, eventName);
                        break;
                    }
                    case server.ProjectInfoTelemetryEvent: {
                        var eventName = "telemetry";
                        this.event({
                            telemetryEventName: event.eventName,
                            payload: event.data,
                        }, eventName);
                        break;
                    }
                }
            };
            Session.prototype.projectsUpdatedInBackgroundEvent = function (openFiles) {
                var _this = this;
                this.projectService.logger.info("got projects updated in background, updating diagnostics for " + openFiles);
                if (openFiles.length) {
                    if (!this.suppressDiagnosticEvents && !this.noGetErrOnBackgroundUpdate) {
                        var checkList_1 = this.createCheckList(openFiles);
                        // For now only queue error checking for open files. We can change this to include non open files as well
                        this.errorCheck.startNew(function (next) { return _this.updateErrorCheck(next, checkList_1, 100, /*requireOpen*/ true); });
                    }
                    // Send project changed event
                    this.event({
                        openFiles: openFiles
                    }, server.ProjectsUpdatedInBackgroundEvent);
                }
            };
            Session.prototype.logError = function (err, cmd) {
                this.logErrorWorker(err, cmd);
            };
            Session.prototype.logErrorWorker = function (err, cmd, fileRequest) {
                var msg = "Exception on executing command " + cmd;
                if (err.message) {
                    msg += ":\n" + server.indent(err.message);
                    if (err.stack) {
                        msg += "\n" + server.indent(err.stack);
                    }
                }
                if (this.logger.hasLevel(server.LogLevel.verbose)) {
                    if (fileRequest) {
                        try {
                            var _a = this.getFileAndProject(fileRequest), file = _a.file, project = _a.project;
                            var scriptInfo = project.getScriptInfoForNormalizedPath(file);
                            if (scriptInfo) {
                                var text = ts.getSnapshotText(scriptInfo.getSnapshot());
                                msg += "\n\nFile text of " + fileRequest.file + ":" + server.indent(text) + "\n";
                            }
                        }
                        catch (_b) { } // tslint:disable-line no-empty
                    }
                    if (err.message && err.message.indexOf("Could not find sourceFile:") !== -1) {
                        msg += "\n\nProjects::\n";
                        var counter_1 = 0;
                        var addProjectInfo = function (project) {
                            msg += "\nProject '" + project.projectName + "' (" + server.ProjectKind[project.projectKind] + ") " + counter_1 + "\n";
                            msg += project.filesToString(/*writeProjectFileNames*/ true);
                            msg += "\n-----------------------------------------------\n";
                            counter_1++;
                        };
                        this.projectService.externalProjects.forEach(addProjectInfo);
                        this.projectService.configuredProjects.forEach(addProjectInfo);
                        this.projectService.inferredProjects.forEach(addProjectInfo);
                    }
                }
                this.logger.msg(msg, server.Msg.Err);
            };
            Session.prototype.send = function (msg) {
                if (msg.type === "event" && !this.canUseEvents) {
                    if (this.logger.hasLevel(server.LogLevel.verbose)) {
                        this.logger.info("Session does not support events: ignored event: " + JSON.stringify(msg));
                    }
                    return;
                }
                this.host.write(formatMessage(msg, this.logger, this.byteLength, this.host.newLine));
            };
            Session.prototype.event = function (body, eventName) {
                this.send(toEvent(eventName, body));
            };
            // For backwards-compatibility only.
            /** @deprecated */
            Session.prototype.output = function (info, cmdName, reqSeq, errorMsg) {
                this.doOutput(info, cmdName, reqSeq, /*success*/ !errorMsg, errorMsg); // TODO: GH#18217
            };
            Session.prototype.doOutput = function (info, cmdName, reqSeq, success, message) {
                var res = {
                    seq: 0,
                    type: "response",
                    command: cmdName,
                    request_seq: reqSeq,
                    success: success,
                };
                if (success) {
                    var metadata = void 0;
                    if (ts.isArray(info)) {
                        res.body = info;
                        metadata = info.metadata;
                        delete info.metadata;
                    }
                    else if (typeof info === "object") {
                        if (info.metadata) {
                            var _a = info, infoMetadata = _a.metadata, body = __rest(_a, ["metadata"]);
                            res.body = body;
                            metadata = infoMetadata;
                        }
                        else {
                            res.body = info;
                        }
                    }
                    else {
                        res.body = info;
                    }
                    if (metadata)
                        res.metadata = metadata;
                }
                else {
                    ts.Debug.assert(info === undefined);
                }
                if (message) {
                    res.message = message;
                }
                this.send(res);
            };
            Session.prototype.semanticCheck = function (file, project) {
                var diags = isDeclarationFileInJSOnlyNonConfiguredProject(project, file)
                    ? server.emptyArray
                    : project.getLanguageService().getSemanticDiagnostics(file);
                this.sendDiagnosticsEvent(file, project, diags, "semanticDiag");
            };
            Session.prototype.syntacticCheck = function (file, project) {
                this.sendDiagnosticsEvent(file, project, project.getLanguageService().getSyntacticDiagnostics(file), "syntaxDiag");
            };
            Session.prototype.suggestionCheck = function (file, project) {
                this.sendDiagnosticsEvent(file, project, project.getLanguageService().getSuggestionDiagnostics(file), "suggestionDiag");
            };
            Session.prototype.sendDiagnosticsEvent = function (file, project, diagnostics, kind) {
                try {
                    this.event({ file: file, diagnostics: diagnostics.map(function (diag) { return formatDiag(file, project, diag); }) }, kind);
                }
                catch (err) {
                    this.logError(err, kind);
                }
            };
            /** It is the caller's responsibility to verify that `!this.suppressDiagnosticEvents`. */
            Session.prototype.updateErrorCheck = function (next, checkList, ms, requireOpen) {
                var _this = this;
                if (requireOpen === void 0) { requireOpen = true; }
                ts.Debug.assert(!this.suppressDiagnosticEvents); // Caller's responsibility
                var seq = this.changeSeq;
                var followMs = Math.min(ms, 200);
                var index = 0;
                var checkOne = function () {
                    if (_this.changeSeq !== seq) {
                        return;
                    }
                    var _a = checkList[index], fileName = _a.fileName, project = _a.project;
                    index++;
                    // Ensure the project is upto date before checking if this file is present in the project
                    server.updateProjectIfDirty(project);
                    if (!project.containsFile(fileName, requireOpen)) {
                        return;
                    }
                    _this.syntacticCheck(fileName, project);
                    if (_this.changeSeq !== seq) {
                        return;
                    }
                    next.immediate(function () {
                        _this.semanticCheck(fileName, project);
                        if (_this.changeSeq !== seq) {
                            return;
                        }
                        var goNext = function () {
                            if (checkList.length > index) {
                                next.delay(followMs, checkOne);
                            }
                        };
                        if (_this.getPreferences(fileName).disableSuggestions) {
                            goNext();
                        }
                        else {
                            next.immediate(function () {
                                _this.suggestionCheck(fileName, project);
                                goNext();
                            });
                        }
                    });
                };
                if (checkList.length > index && this.changeSeq === seq) {
                    next.delay(ms, checkOne);
                }
            };
            Session.prototype.cleanProjects = function (caption, projects) {
                if (!projects) {
                    return;
                }
                this.logger.info("cleaning " + caption);
                for (var _i = 0, projects_5 = projects; _i < projects_5.length; _i++) {
                    var p = projects_5[_i];
                    p.getLanguageService(/*ensureSynchronized*/ false).cleanupSemanticCache();
                }
            };
            Session.prototype.cleanup = function () {
                this.cleanProjects("inferred projects", this.projectService.inferredProjects);
                this.cleanProjects("configured projects", ts.arrayFrom(this.projectService.configuredProjects.values()));
                this.cleanProjects("external projects", this.projectService.externalProjects);
                if (this.host.gc) {
                    this.logger.info("host.gc()");
                    this.host.gc();
                }
            };
            Session.prototype.getEncodedSemanticClassifications = function (args) {
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                return project.getLanguageService().getEncodedSemanticClassifications(file, args);
            };
            Session.prototype.getProject = function (projectFileName) {
                return projectFileName === undefined ? undefined : this.projectService.findProject(projectFileName);
            };
            Session.prototype.getConfigFileAndProject = function (args) {
                var project = this.getProject(args.projectFileName);
                var file = server.toNormalizedPath(args.file);
                return {
                    configFile: project && project.hasConfigFile(file) ? file : undefined,
                    project: project
                };
            };
            Session.prototype.getConfigFileDiagnostics = function (configFile, project, includeLinePosition) {
                var projectErrors = project.getAllProjectErrors();
                var optionsErrors = project.getLanguageService().getCompilerOptionsDiagnostics();
                var diagnosticsForConfigFile = ts.filter(ts.concatenate(projectErrors, optionsErrors), function (diagnostic) { return !!diagnostic.file && diagnostic.file.fileName === configFile; });
                return includeLinePosition ?
                    this.convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnosticsForConfigFile) :
                    ts.map(diagnosticsForConfigFile, function (diagnostic) { return formatConfigFileDiag(diagnostic, /*includeFileName*/ false); });
            };
            Session.prototype.convertToDiagnosticsWithLinePositionFromDiagnosticFile = function (diagnostics) {
                var _this = this;
                return diagnostics.map(function (d) { return ({
                    message: ts.flattenDiagnosticMessageText(d.messageText, _this.host.newLine),
                    start: d.start,
                    length: d.length,
                    category: ts.diagnosticCategoryName(d),
                    code: d.code,
                    startLocation: (d.file && convertToLocation(ts.getLineAndCharacterOfPosition(d.file, d.start))),
                    endLocation: (d.file && convertToLocation(ts.getLineAndCharacterOfPosition(d.file, d.start + d.length))),
                    relatedInformation: ts.map(d.relatedInformation, formatRelatedInformation)
                }); });
            };
            Session.prototype.getCompilerOptionsDiagnostics = function (args) {
                var project = this.getProject(args.projectFileName);
                // Get diagnostics that dont have associated file with them
                // The diagnostics which have file would be in config file and
                // would be reported as part of configFileDiagnostics
                return this.convertToDiagnosticsWithLinePosition(ts.filter(project.getLanguageService().getCompilerOptionsDiagnostics(), function (diagnostic) { return !diagnostic.file; }), 
                /*scriptInfo*/ undefined);
            };
            Session.prototype.convertToDiagnosticsWithLinePosition = function (diagnostics, scriptInfo) {
                var _this = this;
                return diagnostics.map(function (d) { return ({
                    message: ts.flattenDiagnosticMessageText(d.messageText, _this.host.newLine),
                    start: d.start,
                    length: d.length,
                    category: ts.diagnosticCategoryName(d),
                    code: d.code,
                    source: d.source,
                    startLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start),
                    endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start + d.length),
                    reportsUnnecessary: d.reportsUnnecessary,
                    relatedInformation: ts.map(d.relatedInformation, formatRelatedInformation),
                }); });
            };
            Session.prototype.getDiagnosticsWorker = function (args, isSemantic, selector, includeLinePosition) {
                var _a = this.getFileAndProject(args), project = _a.project, file = _a.file;
                if (isSemantic && isDeclarationFileInJSOnlyNonConfiguredProject(project, file)) {
                    return server.emptyArray;
                }
                var scriptInfo = project.getScriptInfoForNormalizedPath(file);
                var diagnostics = selector(project, file);
                return includeLinePosition
                    ? this.convertToDiagnosticsWithLinePosition(diagnostics, scriptInfo)
                    : diagnostics.map(function (d) { return formatDiag(file, project, d); });
            };
            Session.prototype.getDefinition = function (args, simplifiedResult) {
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                var position = this.getPositionInFile(args, file);
                var definitions = this.mapDefinitionInfoLocations(project.getLanguageService().getDefinitionAtPosition(file, position) || server.emptyArray, project);
                return simplifiedResult ? this.mapDefinitionInfo(definitions, project) : definitions.map(Session.mapToOriginalLocation);
            };
            Session.prototype.mapDefinitionInfoLocations = function (definitions, project) {
                var _this = this;
                return definitions.map(function (info) {
                    var newLoc = getMappedLocation(documentSpanLocation(info), _this.projectService, project);
                    return !newLoc ? info : {
                        containerKind: info.containerKind,
                        containerName: info.containerName,
                        fileName: newLoc.fileName,
                        kind: info.kind,
                        name: info.name,
                        textSpan: {
                            start: newLoc.pos,
                            length: info.textSpan.length
                        },
                        originalFileName: info.fileName,
                        originalTextSpan: info.textSpan,
                    };
                });
            };
            Session.prototype.getDefinitionAndBoundSpan = function (args, simplifiedResult) {
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                var position = this.getPositionInFile(args, file);
                var scriptInfo = ts.Debug.assertDefined(project.getScriptInfo(file));
                var unmappedDefinitionAndBoundSpan = project.getLanguageService().getDefinitionAndBoundSpan(file, position);
                if (!unmappedDefinitionAndBoundSpan || !unmappedDefinitionAndBoundSpan.definitions) {
                    return {
                        definitions: server.emptyArray,
                        textSpan: undefined // TODO: GH#18217
                    };
                }
                var definitions = this.mapDefinitionInfoLocations(unmappedDefinitionAndBoundSpan.definitions, project);
                var textSpan = unmappedDefinitionAndBoundSpan.textSpan;
                if (simplifiedResult) {
                    return {
                        definitions: this.mapDefinitionInfo(definitions, project),
                        textSpan: this.toLocationTextSpan(textSpan, scriptInfo)
                    };
                }
                return {
                    definitions: definitions.map(Session.mapToOriginalLocation),
                    textSpan: textSpan,
                };
            };
            Session.prototype.getEmitOutput = function (args) {
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                return project.getLanguageService().getEmitOutput(file);
            };
            Session.prototype.mapDefinitionInfo = function (definitions, project) {
                var _this = this;
                return definitions.map(function (def) { return _this.toFileSpan(def.fileName, def.textSpan, project); });
            };
            /*
             * When we map a .d.ts location to .ts, Visual Studio gets confused because there's no associated Roslyn Document in
             * the same project which corresponds to the file. VS Code has no problem with this, and luckily we have two protocols.
             * This retains the existing behavior for the "simplified" (VS Code) protocol but stores the .d.ts location in a
             * set of additional fields, and does the reverse for VS (store the .d.ts location where
             * it used to be and stores the .ts location in the additional fields).
            */
            Session.mapToOriginalLocation = function (def) {
                if (def.originalFileName) {
                    ts.Debug.assert(def.originalTextSpan !== undefined, "originalTextSpan should be present if originalFileName is");
                    return __assign({}, def, { fileName: def.originalFileName, textSpan: def.originalTextSpan, targetFileName: def.fileName, targetTextSpan: def.textSpan });
                }
                return def;
            };
            Session.prototype.toFileSpan = function (fileName, textSpan, project) {
                var ls = project.getLanguageService();
                var start = ls.toLineColumnOffset(fileName, textSpan.start); // TODO: GH#18217
                var end = ls.toLineColumnOffset(fileName, ts.textSpanEnd(textSpan));
                return {
                    file: fileName,
                    start: { line: start.line + 1, offset: start.character + 1 },
                    end: { line: end.line + 1, offset: end.character + 1 }
                };
            };
            Session.prototype.getTypeDefinition = function (args) {
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                var position = this.getPositionInFile(args, file);
                var definitions = this.mapDefinitionInfoLocations(project.getLanguageService().getTypeDefinitionAtPosition(file, position) || server.emptyArray, project);
                return this.mapDefinitionInfo(definitions, project);
            };
            Session.prototype.mapImplementationLocations = function (implementations, project) {
                var _this = this;
                return implementations.map(function (info) {
                    var newLoc = getMappedLocation(documentSpanLocation(info), _this.projectService, project);
                    return !newLoc ? info : {
                        fileName: newLoc.fileName,
                        kind: info.kind,
                        displayParts: info.displayParts,
                        textSpan: {
                            start: newLoc.pos,
                            length: info.textSpan.length
                        },
                        originalFileName: info.fileName,
                        originalTextSpan: info.textSpan,
                    };
                });
            };
            Session.prototype.getImplementation = function (args, simplifiedResult) {
                var _this = this;
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                var position = this.getPositionInFile(args, file);
                var implementations = this.mapImplementationLocations(project.getLanguageService().getImplementationAtPosition(file, position) || server.emptyArray, project);
                if (simplifiedResult) {
                    return implementations.map(function (_a) {
                        var fileName = _a.fileName, textSpan = _a.textSpan;
                        return _this.toFileSpan(fileName, textSpan, project);
                    });
                }
                return implementations.map(Session.mapToOriginalLocation);
            };
            Session.prototype.getOccurrences = function (args) {
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                var position = this.getPositionInFile(args, file);
                var occurrences = project.getLanguageService().getOccurrencesAtPosition(file, position);
                if (!occurrences) {
                    return server.emptyArray;
                }
                return occurrences.map(function (occurrence) {
                    var fileName = occurrence.fileName, isWriteAccess = occurrence.isWriteAccess, textSpan = occurrence.textSpan, isInString = occurrence.isInString;
                    var scriptInfo = project.getScriptInfo(fileName);
                    var result = {
                        start: scriptInfo.positionToLineOffset(textSpan.start),
                        end: scriptInfo.positionToLineOffset(ts.textSpanEnd(textSpan)),
                        file: fileName,
                        isWriteAccess: isWriteAccess,
                    };
                    // no need to serialize the property if it is not true
                    if (isInString) {
                        result.isInString = isInString;
                    }
                    return result;
                });
            };
            Session.prototype.getSyntacticDiagnosticsSync = function (args) {
                var configFile = this.getConfigFileAndProject(args).configFile;
                if (configFile) {
                    // all the config file errors are reported as part of semantic check so nothing to report here
                    return server.emptyArray;
                }
                return this.getDiagnosticsWorker(args, /*isSemantic*/ false, function (project, file) { return project.getLanguageService().getSyntacticDiagnostics(file); }, !!args.includeLinePosition);
            };
            Session.prototype.getSemanticDiagnosticsSync = function (args) {
                var _a = this.getConfigFileAndProject(args), configFile = _a.configFile, project = _a.project;
                if (configFile) {
                    return this.getConfigFileDiagnostics(configFile, project, !!args.includeLinePosition); // TODO: GH#18217
                }
                return this.getDiagnosticsWorker(args, /*isSemantic*/ true, function (project, file) { return project.getLanguageService().getSemanticDiagnostics(file); }, !!args.includeLinePosition);
            };
            Session.prototype.getSuggestionDiagnosticsSync = function (args) {
                var configFile = this.getConfigFileAndProject(args).configFile;
                if (configFile) {
                    // Currently there are no info diagnostics for config files.
                    return server.emptyArray;
                }
                // isSemantic because we don't want to info diagnostics in declaration files for JS-only users
                return this.getDiagnosticsWorker(args, /*isSemantic*/ true, function (project, file) { return project.getLanguageService().getSuggestionDiagnostics(file); }, !!args.includeLinePosition);
            };
            Session.prototype.getJsxClosingTag = function (args) {
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                var position = this.getPositionInFile(args, file);
                var tag = project.getLanguageService().getJsxClosingTagAtPosition(file, position);
                return tag === undefined ? undefined : { newText: tag.newText, caretOffset: 0 };
            };
            Session.prototype.getDocumentHighlights = function (args, simplifiedResult) {
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                var position = this.getPositionInFile(args, file);
                var documentHighlights = project.getLanguageService().getDocumentHighlights(file, position, args.filesToSearch);
                if (!documentHighlights) {
                    return server.emptyArray;
                }
                if (simplifiedResult) {
                    return documentHighlights.map(convertToDocumentHighlightsItem);
                }
                else {
                    return documentHighlights;
                }
                function convertToDocumentHighlightsItem(documentHighlights) {
                    var fileName = documentHighlights.fileName, highlightSpans = documentHighlights.highlightSpans;
                    var scriptInfo = project.getScriptInfo(fileName);
                    return {
                        file: fileName,
                        highlightSpans: highlightSpans.map(convertHighlightSpan)
                    };
                    function convertHighlightSpan(highlightSpan) {
                        var textSpan = highlightSpan.textSpan, kind = highlightSpan.kind;
                        var start = scriptInfo.positionToLineOffset(textSpan.start);
                        var end = scriptInfo.positionToLineOffset(ts.textSpanEnd(textSpan));
                        return { start: start, end: end, kind: kind };
                    }
                }
            };
            Session.prototype.setCompilerOptionsForInferredProjects = function (args) {
                this.projectService.setCompilerOptionsForInferredProjects(args.options, args.projectRootPath);
            };
            Session.prototype.getProjectInfo = function (args) {
                return this.getProjectInfoWorker(args.file, args.projectFileName, args.needFileNameList, /*excludeConfigFiles*/ false);
            };
            Session.prototype.getProjectInfoWorker = function (uncheckedFileName, projectFileName, needFileNameList, excludeConfigFiles) {
                var project = this.getFileAndProjectWorker(uncheckedFileName, projectFileName).project;
                server.updateProjectIfDirty(project);
                var projectInfo = {
                    configFileName: project.getProjectName(),
                    languageServiceDisabled: !project.languageServiceEnabled,
                    fileNames: needFileNameList ? project.getFileNames(/*excludeFilesFromExternalLibraries*/ false, excludeConfigFiles) : undefined
                };
                return projectInfo;
            };
            Session.prototype.getRenameInfo = function (args) {
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                var position = this.getPositionInFile(args, file);
                return project.getLanguageService().getRenameInfo(file, position, { allowRenameOfImportPath: this.getPreferences(file).allowRenameOfImportPath });
            };
            Session.prototype.getProjects = function (args, getScriptInfoEnsuringProjectsUptoDate, ignoreNoProjectError) {
                var projects;
                var symLinkedProjects;
                if (args.projectFileName) {
                    var project = this.getProject(args.projectFileName);
                    if (project) {
                        projects = [project];
                    }
                }
                else {
                    var scriptInfo = getScriptInfoEnsuringProjectsUptoDate ?
                        this.projectService.getScriptInfoEnsuringProjectsUptoDate(args.file) :
                        this.projectService.getScriptInfo(args.file);
                    if (!scriptInfo) {
                        if (ignoreNoProjectError)
                            return server.emptyArray;
                        this.projectService.logErrorForScriptInfoNotFound(args.file);
                        return server.Errors.ThrowNoProject();
                    }
                    projects = scriptInfo.containingProjects;
                    symLinkedProjects = this.projectService.getSymlinkedProjects(scriptInfo);
                }
                // filter handles case when 'projects' is undefined
                projects = ts.filter(projects, function (p) { return p.languageServiceEnabled && !p.isOrphan(); });
                if (!ignoreNoProjectError && (!projects || !projects.length) && !symLinkedProjects) {
                    this.projectService.logErrorForScriptInfoNotFound(args.file);
                    return server.Errors.ThrowNoProject();
                }
                return symLinkedProjects ? { projects: projects, symLinkedProjects: symLinkedProjects } : projects; // TODO: GH#18217
            };
            Session.prototype.getDefaultProject = function (args) {
                if (args.projectFileName) {
                    var project = this.getProject(args.projectFileName);
                    if (project) {
                        return project;
                    }
                }
                var info = this.projectService.getScriptInfo(args.file);
                return info.getDefaultProject();
            };
            Session.prototype.getRenameLocations = function (args, simplifiedResult) {
                var file = server.toNormalizedPath(args.file);
                var position = this.getPositionInFile(args, file);
                var projects = this.getProjects(args);
                var locations = combineProjectOutputForRenameLocations(projects, this.getDefaultProject(args), { fileName: args.file, pos: position }, !!args.findInStrings, !!args.findInComments, this.getPreferences(file));
                if (!simplifiedResult)
                    return locations;
                var defaultProject = this.getDefaultProject(args);
                var renameInfo = this.mapRenameInfo(defaultProject.getLanguageService().getRenameInfo(file, position, { allowRenameOfImportPath: this.getPreferences(file).allowRenameOfImportPath }), ts.Debug.assertDefined(this.projectService.getScriptInfo(file)));
                return { info: renameInfo, locs: this.toSpanGroups(locations) };
            };
            Session.prototype.mapRenameInfo = function (info, scriptInfo) {
                if (info.canRename) {
                    var canRename = info.canRename, fileToRename = info.fileToRename, displayName = info.displayName, fullDisplayName = info.fullDisplayName, kind = info.kind, kindModifiers = info.kindModifiers, triggerSpan = info.triggerSpan;
                    return ts.identity({ canRename: canRename, fileToRename: fileToRename, displayName: displayName, fullDisplayName: fullDisplayName, kind: kind, kindModifiers: kindModifiers, triggerSpan: this.toLocationTextSpan(triggerSpan, scriptInfo) });
                }
                else {
                    return info;
                }
            };
            Session.prototype.toSpanGroups = function (locations) {
                var map = ts.createMap();
                for (var _i = 0, locations_1 = locations; _i < locations_1.length; _i++) {
                    var _a = locations_1[_i];
                    var fileName = _a.fileName, textSpan = _a.textSpan, _ = _a.originalTextSpan, _1 = _a.originalFileName, prefixSuffixText = __rest(_a, ["fileName", "textSpan", "originalTextSpan", "originalFileName"]);
                    var group_1 = map.get(fileName);
                    if (!group_1)
                        map.set(fileName, group_1 = { file: fileName, locs: [] });
                    var scriptInfo = ts.Debug.assertDefined(this.projectService.getScriptInfo(fileName));
                    group_1.locs.push(__assign({}, this.toLocationTextSpan(textSpan, scriptInfo), prefixSuffixText));
                }
                return ts.arrayFrom(map.values());
            };
            Session.prototype.getReferences = function (args, simplifiedResult) {
                var _this = this;
                var file = server.toNormalizedPath(args.file);
                var projects = this.getProjects(args);
                var position = this.getPositionInFile(args, file);
                var references = combineProjectOutputForReferences(projects, this.getDefaultProject(args), { fileName: args.file, pos: position });
                if (simplifiedResult) {
                    var defaultProject = this.getDefaultProject(args);
                    var scriptInfo = defaultProject.getScriptInfoForNormalizedPath(file);
                    var nameInfo = defaultProject.getLanguageService().getQuickInfoAtPosition(file, position);
                    var symbolDisplayString = nameInfo ? ts.displayPartsToString(nameInfo.displayParts) : "";
                    var nameSpan = nameInfo && nameInfo.textSpan;
                    var symbolStartOffset = nameSpan ? scriptInfo.positionToLineOffset(nameSpan.start).offset : 0;
                    var symbolName_1 = nameSpan ? scriptInfo.getSnapshot().getText(nameSpan.start, ts.textSpanEnd(nameSpan)) : "";
                    var refs = ts.flatMap(references, function (referencedSymbol) {
                        return referencedSymbol.references.map(function (_a) {
                            var fileName = _a.fileName, textSpan = _a.textSpan, isWriteAccess = _a.isWriteAccess, isDefinition = _a.isDefinition;
                            var scriptInfo = ts.Debug.assertDefined(_this.projectService.getScriptInfo(fileName));
                            var start = scriptInfo.positionToLineOffset(textSpan.start);
                            var lineSpan = scriptInfo.lineToTextSpan(start.line - 1);
                            var lineText = scriptInfo.getSnapshot().getText(lineSpan.start, ts.textSpanEnd(lineSpan)).replace(/\r|\n/g, "");
                            return __assign({}, toFileSpan(fileName, textSpan, scriptInfo), { lineText: lineText, isWriteAccess: isWriteAccess, isDefinition: isDefinition });
                        });
                    });
                    var result = { refs: refs, symbolName: symbolName_1, symbolStartOffset: symbolStartOffset, symbolDisplayString: symbolDisplayString };
                    return result;
                }
                else {
                    return references;
                }
            };
            /**
             * @param fileName is the name of the file to be opened
             * @param fileContent is a version of the file content that is known to be more up to date than the one on disk
             */
            Session.prototype.openClientFile = function (fileName, fileContent, scriptKind, projectRootPath) {
                this.projectService.openClientFileWithNormalizedPath(fileName, fileContent, scriptKind, /*hasMixedContent*/ false, projectRootPath);
            };
            Session.prototype.getPosition = function (args, scriptInfo) {
                return args.position !== undefined ? args.position : scriptInfo.lineOffsetToPosition(args.line, args.offset);
            };
            Session.prototype.getPositionInFile = function (args, file) {
                var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
                return this.getPosition(args, scriptInfo);
            };
            Session.prototype.getFileAndProject = function (args) {
                return this.getFileAndProjectWorker(args.file, args.projectFileName);
            };
            Session.prototype.getFileAndLanguageServiceForSyntacticOperation = function (args) {
                // Since this is syntactic operation, there should always be project for the file
                // we wouldnt have to ensure project but rather throw if we dont get project
                var file = server.toNormalizedPath(args.file);
                var project = this.getProject(args.projectFileName) || this.projectService.tryGetDefaultProjectForFile(file);
                if (!project) {
                    return server.Errors.ThrowNoProject();
                }
                return {
                    file: file,
                    languageService: project.getLanguageService(/*ensureSynchronized*/ false)
                };
            };
            Session.prototype.getFileAndProjectWorker = function (uncheckedFileName, projectFileName) {
                var file = server.toNormalizedPath(uncheckedFileName);
                var project = this.getProject(projectFileName) || this.projectService.ensureDefaultProjectForFile(file);
                return { file: file, project: project };
            };
            Session.prototype.getOutliningSpans = function (args, simplifiedResult) {
                var _this = this;
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var spans = languageService.getOutliningSpans(file);
                if (simplifiedResult) {
                    var scriptInfo_1 = this.projectService.getScriptInfoForNormalizedPath(file);
                    return spans.map(function (s) { return ({
                        textSpan: _this.toLocationTextSpan(s.textSpan, scriptInfo_1),
                        hintSpan: _this.toLocationTextSpan(s.hintSpan, scriptInfo_1),
                        bannerText: s.bannerText,
                        autoCollapse: s.autoCollapse,
                        kind: s.kind
                    }); });
                }
                else {
                    return spans;
                }
            };
            Session.prototype.getTodoComments = function (args) {
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                return project.getLanguageService().getTodoComments(file, args.descriptors);
            };
            Session.prototype.getDocCommentTemplate = function (args) {
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var position = this.getPositionInFile(args, file);
                return languageService.getDocCommentTemplateAtPosition(file, position);
            };
            Session.prototype.getSpanOfEnclosingComment = function (args) {
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var onlyMultiLine = args.onlyMultiLine;
                var position = this.getPositionInFile(args, file);
                return languageService.getSpanOfEnclosingComment(file, position, onlyMultiLine);
            };
            Session.prototype.getIndentation = function (args) {
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var position = this.getPositionInFile(args, file);
                var options = args.options ? server.convertFormatOptions(args.options) : this.getFormatOptions(file);
                var indentation = languageService.getIndentationAtPosition(file, position, options);
                return { position: position, indentation: indentation };
            };
            Session.prototype.getBreakpointStatement = function (args) {
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var position = this.getPositionInFile(args, file);
                return languageService.getBreakpointStatementAtPosition(file, position);
            };
            Session.prototype.getNameOrDottedNameSpan = function (args) {
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var position = this.getPositionInFile(args, file);
                return languageService.getNameOrDottedNameSpan(file, position, position);
            };
            Session.prototype.isValidBraceCompletion = function (args) {
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var position = this.getPositionInFile(args, file);
                return languageService.isValidBraceCompletionAtPosition(file, position, args.openingBrace.charCodeAt(0));
            };
            Session.prototype.getQuickInfoWorker = function (args, simplifiedResult) {
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
                var quickInfo = project.getLanguageService().getQuickInfoAtPosition(file, this.getPosition(args, scriptInfo));
                if (!quickInfo) {
                    return undefined;
                }
                if (simplifiedResult) {
                    var displayString = ts.displayPartsToString(quickInfo.displayParts);
                    var docString = ts.displayPartsToString(quickInfo.documentation);
                    return {
                        kind: quickInfo.kind,
                        kindModifiers: quickInfo.kindModifiers,
                        start: scriptInfo.positionToLineOffset(quickInfo.textSpan.start),
                        end: scriptInfo.positionToLineOffset(ts.textSpanEnd(quickInfo.textSpan)),
                        displayString: displayString,
                        documentation: docString,
                        tags: quickInfo.tags || []
                    };
                }
                else {
                    return quickInfo;
                }
            };
            Session.prototype.getFormattingEditsForRange = function (args) {
                var _this = this;
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
                var startPosition = scriptInfo.lineOffsetToPosition(args.line, args.offset);
                var endPosition = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset);
                // TODO: avoid duplicate code (with formatonkey)
                var edits = languageService.getFormattingEditsForRange(file, startPosition, endPosition, this.getFormatOptions(file));
                if (!edits) {
                    return undefined;
                }
                return edits.map(function (edit) { return _this.convertTextChangeToCodeEdit(edit, scriptInfo); });
            };
            Session.prototype.getFormattingEditsForRangeFull = function (args) {
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var options = args.options ? server.convertFormatOptions(args.options) : this.getFormatOptions(file);
                return languageService.getFormattingEditsForRange(file, args.position, args.endPosition, options); // TODO: GH#18217
            };
            Session.prototype.getFormattingEditsForDocumentFull = function (args) {
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var options = args.options ? server.convertFormatOptions(args.options) : this.getFormatOptions(file);
                return languageService.getFormattingEditsForDocument(file, options);
            };
            Session.prototype.getFormattingEditsAfterKeystrokeFull = function (args) {
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var options = args.options ? server.convertFormatOptions(args.options) : this.getFormatOptions(file);
                return languageService.getFormattingEditsAfterKeystroke(file, args.position, args.key, options); // TODO: GH#18217
            };
            Session.prototype.getFormattingEditsAfterKeystroke = function (args) {
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
                var position = scriptInfo.lineOffsetToPosition(args.line, args.offset);
                var formatOptions = this.getFormatOptions(file);
                var edits = languageService.getFormattingEditsAfterKeystroke(file, position, args.key, formatOptions);
                // Check whether we should auto-indent. This will be when
                // the position is on a line containing only whitespace.
                // This should leave the edits returned from
                // getFormattingEditsAfterKeystroke either empty or pertaining
                // only to the previous line.  If all this is true, then
                // add edits necessary to properly indent the current line.
                if ((args.key === "\n") && ((!edits) || (edits.length === 0) || allEditsBeforePos(edits, position))) {
                    var _b = scriptInfo.getAbsolutePositionAndLineText(args.line), lineText = _b.lineText, absolutePosition = _b.absolutePosition;
                    if (lineText && lineText.search("\\S") < 0) {
                        var preferredIndent = languageService.getIndentationAtPosition(file, position, formatOptions);
                        var hasIndent = 0;
                        var i = void 0, len = void 0;
                        for (i = 0, len = lineText.length; i < len; i++) {
                            if (lineText.charAt(i) === " ") {
                                hasIndent++;
                            }
                            else if (lineText.charAt(i) === "\t") {
                                hasIndent += formatOptions.tabSize; // TODO: GH#18217
                            }
                            else {
                                break;
                            }
                        }
                        // i points to the first non whitespace character
                        if (preferredIndent !== hasIndent) {
                            var firstNoWhiteSpacePosition = absolutePosition + i;
                            edits.push({
                                span: ts.createTextSpanFromBounds(absolutePosition, firstNoWhiteSpacePosition),
                                newText: ts.formatting.getIndentationString(preferredIndent, formatOptions)
                            });
                        }
                    }
                }
                if (!edits) {
                    return undefined;
                }
                return edits.map(function (edit) {
                    return {
                        start: scriptInfo.positionToLineOffset(edit.span.start),
                        end: scriptInfo.positionToLineOffset(ts.textSpanEnd(edit.span)),
                        newText: edit.newText ? edit.newText : ""
                    };
                });
            };
            Session.prototype.getCompletions = function (args, kind) {
                var _this = this;
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
                var position = this.getPosition(args, scriptInfo);
                var completions = project.getLanguageService().getCompletionsAtPosition(file, position, __assign({}, server.convertUserPreferences(this.getPreferences(file)), { triggerCharacter: args.triggerCharacter, includeExternalModuleExports: args.includeExternalModuleExports, includeInsertTextCompletions: args.includeInsertTextCompletions }));
                if (completions === undefined)
                    return undefined;
                if (kind === "completions-full" /* CompletionsFull */)
                    return completions;
                var prefix = args.prefix || "";
                var entries = ts.mapDefined(completions.entries, function (entry) {
                    if (completions.isMemberCompletion || ts.startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) {
                        var name = entry.name, kind_1 = entry.kind, kindModifiers = entry.kindModifiers, sortText = entry.sortText, insertText = entry.insertText, replacementSpan = entry.replacementSpan, hasAction = entry.hasAction, source = entry.source, isRecommended = entry.isRecommended;
                        var convertedSpan = replacementSpan ? _this.toLocationTextSpan(replacementSpan, scriptInfo) : undefined;
                        // Use `hasAction || undefined` to avoid serializing `false`.
                        return { name: name, kind: kind_1, kindModifiers: kindModifiers, sortText: sortText, insertText: insertText, replacementSpan: convertedSpan, hasAction: hasAction || undefined, source: source, isRecommended: isRecommended };
                    }
                }).sort(function (a, b) { return ts.compareStringsCaseSensitiveUI(a.name, b.name); });
                if (kind === "completions" /* Completions */) {
                    if (completions.metadata)
                        entries.metadata = completions.metadata;
                    return entries;
                }
                var res = __assign({}, completions, { entries: entries });
                return res;
            };
            Session.prototype.getCompletionEntryDetails = function (args, simplifiedResult) {
                var _this = this;
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
                var position = this.getPosition(args, scriptInfo);
                var formattingOptions = project.projectService.getFormatCodeOptions(file);
                var result = ts.mapDefined(args.entryNames, function (entryName) {
                    var _a = typeof entryName === "string" ? { name: entryName, source: undefined } : entryName, name = _a.name, source = _a.source;
                    return project.getLanguageService().getCompletionEntryDetails(file, position, name, formattingOptions, source, _this.getPreferences(file));
                });
                return simplifiedResult
                    ? result.map(function (details) { return (__assign({}, details, { codeActions: ts.map(details.codeActions, function (action) { return _this.mapCodeAction(action); }) })); })
                    : result;
            };
            Session.prototype.getCompileOnSaveAffectedFileList = function (args) {
                var _this = this;
                var projects = this.getProjects(args, /*getScriptInfoEnsuringProjectsUptoDate*/ true, /*ignoreNoProjectError*/ true);
                var info = this.projectService.getScriptInfo(args.file);
                if (!info) {
                    return server.emptyArray;
                }
                return combineProjectOutput(info, function (path) { return _this.projectService.getScriptInfoForPath(path); }, projects, function (project, info) {
                    var result;
                    if (project.compileOnSaveEnabled && project.languageServiceEnabled && !project.isOrphan() && !project.getCompilationSettings().noEmit) {
                        result = {
                            projectFileName: project.getProjectName(),
                            fileNames: project.getCompileOnSaveAffectedFileList(info),
                            projectUsesOutFile: !!project.getCompilationSettings().outFile || !!project.getCompilationSettings().out
                        };
                    }
                    return result;
                });
            };
            Session.prototype.emitFile = function (args) {
                var _this = this;
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                if (!project) {
                    server.Errors.ThrowNoProject();
                }
                if (!project.languageServiceEnabled) {
                    return false;
                }
                var scriptInfo = project.getScriptInfo(file);
                return project.emitFile(scriptInfo, function (path, data, writeByteOrderMark) { return _this.host.writeFile(path, data, writeByteOrderMark); });
            };
            Session.prototype.getSignatureHelpItems = function (args, simplifiedResult) {
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
                var position = this.getPosition(args, scriptInfo);
                var helpItems = project.getLanguageService().getSignatureHelpItems(file, position, args);
                if (!helpItems) {
                    return undefined;
                }
                if (simplifiedResult) {
                    var span = helpItems.applicableSpan;
                    return {
                        items: helpItems.items,
                        applicableSpan: {
                            start: scriptInfo.positionToLineOffset(span.start),
                            end: scriptInfo.positionToLineOffset(span.start + span.length)
                        },
                        selectedItemIndex: helpItems.selectedItemIndex,
                        argumentIndex: helpItems.argumentIndex,
                        argumentCount: helpItems.argumentCount,
                    };
                }
                else {
                    return helpItems;
                }
            };
            Session.prototype.createCheckList = function (fileNames, defaultProject) {
                var _this = this;
                return ts.mapDefined(fileNames, function (uncheckedFileName) {
                    var fileName = server.toNormalizedPath(uncheckedFileName);
                    var project = defaultProject || _this.projectService.tryGetDefaultProjectForFile(fileName);
                    return project && { fileName: fileName, project: project };
                });
            };
            Session.prototype.getDiagnostics = function (next, delay, fileNames) {
                if (this.suppressDiagnosticEvents) {
                    return;
                }
                var checkList = this.createCheckList(fileNames);
                if (checkList.length > 0) {
                    this.updateErrorCheck(next, checkList, delay);
                }
            };
            Session.prototype.change = function (args) {
                var scriptInfo = this.projectService.getScriptInfo(args.file);
                ts.Debug.assert(!!scriptInfo);
                var start = scriptInfo.lineOffsetToPosition(args.line, args.offset);
                var end = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset);
                if (start >= 0) {
                    this.changeSeq++;
                    this.projectService.applyChangesToFile(scriptInfo, ts.singleIterator({
                        span: { start: start, length: end - start },
                        newText: args.insertString // TODO: GH#18217
                    }));
                }
            };
            Session.prototype.reload = function (args, reqSeq) {
                var file = server.toNormalizedPath(args.file);
                var tempFileName = args.tmpfile === undefined ? undefined : server.toNormalizedPath(args.tmpfile);
                var info = this.projectService.getScriptInfoForNormalizedPath(file);
                if (info) {
                    this.changeSeq++;
                    // make sure no changes happen before this one is finished
                    if (info.reloadFromFile(tempFileName)) {
                        this.doOutput(/*info*/ undefined, server.CommandNames.Reload, reqSeq, /*success*/ true);
                    }
                }
            };
            Session.prototype.saveToTmp = function (fileName, tempFileName) {
                var scriptInfo = this.projectService.getScriptInfo(fileName);
                if (scriptInfo) {
                    scriptInfo.saveTo(tempFileName);
                }
            };
            Session.prototype.closeClientFile = function (fileName) {
                if (!fileName) {
                    return;
                }
                var file = ts.normalizePath(fileName);
                this.projectService.closeClientFile(file);
            };
            Session.prototype.mapLocationNavigationBarItems = function (items, scriptInfo) {
                var _this = this;
                return ts.map(items, function (item) { return ({
                    text: item.text,
                    kind: item.kind,
                    kindModifiers: item.kindModifiers,
                    spans: item.spans.map(function (span) { return _this.toLocationTextSpan(span, scriptInfo); }),
                    childItems: _this.mapLocationNavigationBarItems(item.childItems, scriptInfo),
                    indent: item.indent
                }); });
            };
            Session.prototype.getNavigationBarItems = function (args, simplifiedResult) {
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var items = languageService.getNavigationBarItems(file);
                return !items
                    ? undefined
                    : simplifiedResult
                        ? this.mapLocationNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file))
                        : items;
            };
            Session.prototype.toLocationNavigationTree = function (tree, scriptInfo) {
                var _this = this;
                return {
                    text: tree.text,
                    kind: tree.kind,
                    kindModifiers: tree.kindModifiers,
                    spans: tree.spans.map(function (span) { return _this.toLocationTextSpan(span, scriptInfo); }),
                    nameSpan: tree.nameSpan && this.toLocationTextSpan(tree.nameSpan, scriptInfo),
                    childItems: ts.map(tree.childItems, function (item) { return _this.toLocationNavigationTree(item, scriptInfo); })
                };
            };
            Session.prototype.toLocationTextSpan = function (span, scriptInfo) {
                return {
                    start: scriptInfo.positionToLineOffset(span.start),
                    end: scriptInfo.positionToLineOffset(ts.textSpanEnd(span))
                };
            };
            Session.prototype.getNavigationTree = function (args, simplifiedResult) {
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var tree = languageService.getNavigationTree(file);
                return !tree
                    ? undefined
                    : simplifiedResult
                        ? this.toLocationNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file))
                        : tree;
            };
            Session.prototype.getNavigateToItems = function (args, simplifiedResult) {
                var _this = this;
                var full = this.getFullNavigateToItems(args);
                return !simplifiedResult ? full : full.map(function (navItem) {
                    var _a = _this.getFileAndProject({ file: navItem.fileName }), file = _a.file, project = _a.project;
                    var scriptInfo = project.getScriptInfo(file);
                    var bakedItem = {
                        name: navItem.name,
                        kind: navItem.kind,
                        isCaseSensitive: navItem.isCaseSensitive,
                        matchKind: navItem.matchKind,
                        file: navItem.fileName,
                        start: scriptInfo.positionToLineOffset(navItem.textSpan.start),
                        end: scriptInfo.positionToLineOffset(ts.textSpanEnd(navItem.textSpan))
                    };
                    if (navItem.kindModifiers && (navItem.kindModifiers !== "")) {
                        bakedItem.kindModifiers = navItem.kindModifiers;
                    }
                    if (navItem.containerName && (navItem.containerName.length > 0)) {
                        bakedItem.containerName = navItem.containerName;
                    }
                    if (navItem.containerKind && (navItem.containerKind.length > 0)) {
                        bakedItem.containerKind = navItem.containerKind;
                    }
                    return bakedItem;
                });
            };
            Session.prototype.getFullNavigateToItems = function (args) {
                var currentFileOnly = args.currentFileOnly, searchValue = args.searchValue, maxResultCount = args.maxResultCount;
                if (currentFileOnly) {
                    var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                    return project.getLanguageService().getNavigateToItems(searchValue, maxResultCount, file);
                }
                else {
                    return combineProjectOutputWhileOpeningReferencedProjects(this.getProjects(args), this.getDefaultProject(args), function (project) {
                        return project.getLanguageService().getNavigateToItems(searchValue, maxResultCount, /*fileName*/ undefined, /*excludeDts*/ project.isNonTsProject());
                    }, documentSpanLocation, navigateToItemIsEqualTo);
                }
                function navigateToItemIsEqualTo(a, b) {
                    if (a === b) {
                        return true;
                    }
                    if (!a || !b) {
                        return false;
                    }
                    return a.containerKind === b.containerKind &&
                        a.containerName === b.containerName &&
                        a.fileName === b.fileName &&
                        a.isCaseSensitive === b.isCaseSensitive &&
                        a.kind === b.kind &&
                        a.kindModifiers === b.containerName &&
                        a.matchKind === b.matchKind &&
                        a.name === b.name &&
                        a.textSpan.start === b.textSpan.start &&
                        a.textSpan.length === b.textSpan.length;
                }
            };
            Session.prototype.getSupportedCodeFixes = function () {
                return ts.getSupportedCodeFixes();
            };
            Session.prototype.isLocation = function (locationOrSpan) {
                return locationOrSpan.line !== undefined;
            };
            Session.prototype.extractPositionOrRange = function (args, scriptInfo) {
                var position;
                var textRange;
                if (this.isLocation(args)) {
                    position = getPosition(args);
                }
                else {
                    var _a = this.getStartAndEndPosition(args, scriptInfo), startPosition = _a.startPosition, endPosition = _a.endPosition;
                    textRange = { pos: startPosition, end: endPosition };
                }
                return ts.Debug.assertDefined(position === undefined ? textRange : position);
                function getPosition(loc) {
                    return loc.position !== undefined ? loc.position : scriptInfo.lineOffsetToPosition(loc.line, loc.offset);
                }
            };
            Session.prototype.getApplicableRefactors = function (args) {
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                var scriptInfo = project.getScriptInfoForNormalizedPath(file);
                return project.getLanguageService().getApplicableRefactors(file, this.extractPositionOrRange(args, scriptInfo), this.getPreferences(file));
            };
            Session.prototype.getEditsForRefactor = function (args, simplifiedResult) {
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                var scriptInfo = project.getScriptInfoForNormalizedPath(file);
                var result = project.getLanguageService().getEditsForRefactor(file, this.getFormatOptions(file), this.extractPositionOrRange(args, scriptInfo), args.refactor, args.action, this.getPreferences(file));
                if (result === undefined) {
                    return {
                        edits: []
                    };
                }
                if (simplifiedResult) {
                    var renameFilename = result.renameFilename, renameLocation = result.renameLocation, edits = result.edits;
                    var mappedRenameLocation = void 0;
                    if (renameFilename !== undefined && renameLocation !== undefined) {
                        var renameScriptInfo = project.getScriptInfoForNormalizedPath(server.toNormalizedPath(renameFilename));
                        mappedRenameLocation = getLocationInNewDocument(ts.getSnapshotText(renameScriptInfo.getSnapshot()), renameFilename, renameLocation, edits);
                    }
                    return { renameLocation: mappedRenameLocation, renameFilename: renameFilename, edits: this.mapTextChangesToCodeEdits(edits) };
                }
                else {
                    return result;
                }
            };
            Session.prototype.organizeImports = function (_a, simplifiedResult) {
                var scope = _a.scope;
                ts.Debug.assert(scope.type === "file");
                var _b = this.getFileAndProject(scope.args), file = _b.file, project = _b.project;
                var changes = project.getLanguageService().organizeImports({ type: "file", fileName: file }, this.getFormatOptions(file), this.getPreferences(file));
                if (simplifiedResult) {
                    return this.mapTextChangesToCodeEdits(changes);
                }
                else {
                    return changes;
                }
            };
            Session.prototype.getEditsForFileRename = function (args, simplifiedResult) {
                var _this = this;
                var oldPath = server.toNormalizedPath(args.oldFilePath);
                var newPath = server.toNormalizedPath(args.newFilePath);
                var formatOptions = this.getHostFormatOptions();
                var preferences = this.getHostPreferences();
                var changes = combineProjectOutputFromEveryProject(this.projectService, function (project) { return project.getLanguageService().getEditsForFileRename(oldPath, newPath, formatOptions, preferences); }, function (a, b) { return a.fileName === b.fileName; });
                return simplifiedResult ? changes.map(function (c) { return _this.mapTextChangeToCodeEdit(c); }) : changes;
            };
            Session.prototype.getCodeFixes = function (args, simplifiedResult) {
                var _this = this;
                var _a = this.getFileAndProject(args), file = _a.file, project = _a.project;
                var scriptInfo = project.getScriptInfoForNormalizedPath(file);
                var _b = this.getStartAndEndPosition(args, scriptInfo), startPosition = _b.startPosition, endPosition = _b.endPosition;
                var codeActions = project.getLanguageService().getCodeFixesAtPosition(file, startPosition, endPosition, args.errorCodes, this.getFormatOptions(file), this.getPreferences(file));
                return simplifiedResult ? codeActions.map(function (codeAction) { return _this.mapCodeFixAction(codeAction); }) : codeActions;
            };
            Session.prototype.getCombinedCodeFix = function (_a, simplifiedResult) {
                var scope = _a.scope, fixId = _a.fixId;
                ts.Debug.assert(scope.type === "file");
                var _b = this.getFileAndProject(scope.args), file = _b.file, project = _b.project;
                var res = project.getLanguageService().getCombinedCodeFix({ type: "file", fileName: file }, fixId, this.getFormatOptions(file), this.getPreferences(file));
                if (simplifiedResult) {
                    return { changes: this.mapTextChangesToCodeEdits(res.changes), commands: res.commands };
                }
                else {
                    return res;
                }
            };
            Session.prototype.applyCodeActionCommand = function (args) {
                var commands = args.command; // They should be sending back the command we sent them.
                for (var _i = 0, _a = ts.toArray(commands); _i < _a.length; _i++) {
                    var command = _a[_i];
                    var _b = this.getFileAndProject(command), file = _b.file, project = _b.project;
                    project.getLanguageService().applyCodeActionCommand(command, this.getFormatOptions(file)).then(function (_result) { }, function (_error) { });
                }
                return {};
            };
            Session.prototype.getStartAndEndPosition = function (args, scriptInfo) {
                var startPosition, endPosition;
                if (args.startPosition !== undefined) {
                    startPosition = args.startPosition;
                }
                else {
                    startPosition = scriptInfo.lineOffsetToPosition(args.startLine, args.startOffset);
                    // save the result so we don't always recompute
                    args.startPosition = startPosition;
                }
                if (args.endPosition !== undefined) {
                    endPosition = args.endPosition;
                }
                else {
                    endPosition = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset);
                    args.endPosition = endPosition;
                }
                return { startPosition: startPosition, endPosition: endPosition };
            };
            Session.prototype.mapCodeAction = function (_a) {
                var description = _a.description, changes = _a.changes, commands = _a.commands;
                return { description: description, changes: this.mapTextChangesToCodeEdits(changes), commands: commands };
            };
            Session.prototype.mapCodeFixAction = function (_a) {
                var fixName = _a.fixName, description = _a.description, changes = _a.changes, commands = _a.commands, fixId = _a.fixId, fixAllDescription = _a.fixAllDescription;
                return { fixName: fixName, description: description, changes: this.mapTextChangesToCodeEdits(changes), commands: commands, fixId: fixId, fixAllDescription: fixAllDescription };
            };
            Session.prototype.mapTextChangesToCodeEdits = function (textChanges) {
                var _this = this;
                return textChanges.map(function (change) { return _this.mapTextChangeToCodeEdit(change); });
            };
            Session.prototype.mapTextChangeToCodeEdit = function (textChanges) {
                var scriptInfo = this.projectService.getScriptInfoOrConfig(textChanges.fileName);
                if (!!textChanges.isNewFile === !!scriptInfo) {
                    if (!scriptInfo) { // and !isNewFile
                        this.projectService.logErrorForScriptInfoNotFound(textChanges.fileName);
                    }
                    ts.Debug.fail("Expected isNewFile for (only) new files. " + JSON.stringify({ isNewFile: !!textChanges.isNewFile, hasScriptInfo: !!scriptInfo }));
                }
                return scriptInfo
                    ? { fileName: textChanges.fileName, textChanges: textChanges.textChanges.map(function (textChange) { return convertTextChangeToCodeEdit(textChange, scriptInfo); }) }
                    : convertNewFileTextChangeToCodeEdit(textChanges);
            };
            Session.prototype.convertTextChangeToCodeEdit = function (change, scriptInfo) {
                return {
                    start: scriptInfo.positionToLineOffset(change.span.start),
                    end: scriptInfo.positionToLineOffset(change.span.start + change.span.length),
                    newText: change.newText ? change.newText : ""
                };
            };
            Session.prototype.getBraceMatching = function (args, simplifiedResult) {
                var _this = this;
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
                var position = this.getPosition(args, scriptInfo);
                var spans = languageService.getBraceMatchingAtPosition(file, position);
                return !spans
                    ? undefined
                    : simplifiedResult
                        ? spans.map(function (span) { return _this.toLocationTextSpan(span, scriptInfo); })
                        : spans;
            };
            Session.prototype.getDiagnosticsForProject = function (next, delay, fileName) {
                if (this.suppressDiagnosticEvents) {
                    return;
                }
                var _a = this.getProjectInfoWorker(fileName, /*projectFileName*/ undefined, /*needFileNameList*/ true, /*excludeConfigFiles*/ true), fileNames = _a.fileNames, languageServiceDisabled = _a.languageServiceDisabled;
                if (languageServiceDisabled) {
                    return;
                }
                // No need to analyze lib.d.ts
                var fileNamesInProject = fileNames.filter(function (value) { return !ts.stringContains(value, "lib.d.ts"); }); // TODO: GH#18217
                if (fileNamesInProject.length === 0) {
                    return;
                }
                // Sort the file name list to make the recently touched files come first
                var highPriorityFiles = [];
                var mediumPriorityFiles = [];
                var lowPriorityFiles = [];
                var veryLowPriorityFiles = [];
                var normalizedFileName = server.toNormalizedPath(fileName);
                var project = this.projectService.ensureDefaultProjectForFile(normalizedFileName);
                for (var _i = 0, fileNamesInProject_1 = fileNamesInProject; _i < fileNamesInProject_1.length; _i++) {
                    var fileNameInProject = fileNamesInProject_1[_i];
                    if (this.getCanonicalFileName(fileNameInProject) === this.getCanonicalFileName(fileName)) {
                        highPriorityFiles.push(fileNameInProject);
                    }
                    else {
                        var info = this.projectService.getScriptInfo(fileNameInProject); // TODO: GH#18217
                        if (!info.isScriptOpen()) {
                            if (ts.fileExtensionIs(fileNameInProject, ".d.ts" /* Dts */)) {
                                veryLowPriorityFiles.push(fileNameInProject);
                            }
                            else {
                                lowPriorityFiles.push(fileNameInProject);
                            }
                        }
                        else {
                            mediumPriorityFiles.push(fileNameInProject);
                        }
                    }
                }
                var sortedFiles = highPriorityFiles.concat(mediumPriorityFiles, lowPriorityFiles, veryLowPriorityFiles);
                var checkList = sortedFiles.map(function (fileName) { return ({ fileName: fileName, project: project }); });
                // Project level error analysis runs on background files too, therefore
                // doesn't require the file to be opened
                this.updateErrorCheck(next, checkList, delay, /*requireOpen*/ false);
            };
            Session.prototype.configurePlugin = function (args) {
                this.projectService.configurePlugin(args);
            };
            Session.prototype.getSmartSelectionRange = function (args, simplifiedResult) {
                var _this = this;
                var locations = args.locations;
                var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService;
                var scriptInfo = ts.Debug.assertDefined(this.projectService.getScriptInfo(file));
                return ts.map(locations, function (location) {
                    var pos = _this.getPosition(location, scriptInfo);
                    var selectionRange = languageService.getSmartSelectionRange(file, pos);
                    return simplifiedResult ? _this.mapSelectionRange(selectionRange, scriptInfo) : selectionRange;
                });
            };
            Session.prototype.mapSelectionRange = function (selectionRange, scriptInfo) {
                var result = {
                    textSpan: this.toLocationTextSpan(selectionRange.textSpan, scriptInfo),
                };
                if (selectionRange.parent) {
                    result.parent = this.mapSelectionRange(selectionRange.parent, scriptInfo);
                }
                return result;
            };
            Session.prototype.getCanonicalFileName = function (fileName) {
                var name = this.host.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
                return ts.normalizePath(name);
            };
            Session.prototype.exit = function () { };
            Session.prototype.notRequired = function () {
                return { responseRequired: false };
            };
            Session.prototype.requiredResponse = function (response) {
                return { response: response, responseRequired: true };
            };
            Session.prototype.addProtocolHandler = function (command, handler) {
                if (this.handlers.has(command)) {
                    throw new Error("Protocol handler already exists for command \"" + command + "\"");
                }
                this.handlers.set(command, handler);
            };
            Session.prototype.setCurrentRequest = function (requestId) {
                ts.Debug.assert(this.currentRequestId === undefined);
                this.currentRequestId = requestId;
                this.cancellationToken.setRequest(requestId);
            };
            Session.prototype.resetCurrentRequest = function (requestId) {
                ts.Debug.assert(this.currentRequestId === requestId);
                this.currentRequestId = undefined; // TODO: GH#18217
                this.cancellationToken.resetRequest(requestId);
            };
            Session.prototype.executeWithRequestId = function (requestId, f) {
                try {
                    this.setCurrentRequest(requestId);
                    return f();
                }
                finally {
                    this.resetCurrentRequest(requestId);
                }
            };
            Session.prototype.executeCommand = function (request) {
                var handler = this.handlers.get(request.command);
                if (handler) {
                    return this.executeWithRequestId(request.seq, function () { return handler(request); });
                }
                else {
                    this.logger.msg("Unrecognized JSON command:" + server.stringifyIndented(request), server.Msg.Err);
                    this.doOutput(/*info*/ undefined, server.CommandNames.Unknown, request.seq, /*success*/ false, "Unrecognized JSON command: " + request.command);
                    return { responseRequired: false };
                }
            };
            Session.prototype.onMessage = function (message) {
                this.gcTimer.scheduleCollect();
                var start;
                if (this.logger.hasLevel(server.LogLevel.requestTime)) {
                    start = this.hrtime();
                    if (this.logger.hasLevel(server.LogLevel.verbose)) {
                        this.logger.info("request:" + server.indent(message));
                    }
                }
                var request;
                var relevantFile;
                try {
                    request = JSON.parse(message);
                    relevantFile = request.arguments && request.arguments.file ? request.arguments : undefined;
                    var _a = this.executeCommand(request), response = _a.response, responseRequired = _a.responseRequired;
                    if (this.logger.hasLevel(server.LogLevel.requestTime)) {
                        var elapsedTime = hrTimeToMilliseconds(this.hrtime(start)).toFixed(4);
                        if (responseRequired) {
                            this.logger.perftrc(request.seq + "::" + request.command + ": elapsed time (in milliseconds) " + elapsedTime);
                        }
                        else {
                            this.logger.perftrc(request.seq + "::" + request.command + ": async elapsed time (in milliseconds) " + elapsedTime);
                        }
                    }
                    if (response) {
                        this.doOutput(response, request.command, request.seq, /*success*/ true);
                    }
                    else if (responseRequired) {
                        this.doOutput(/*info*/ undefined, request.command, request.seq, /*success*/ false, "No content available.");
                    }
                }
                catch (err) {
                    if (err instanceof ts.OperationCanceledException) {
                        // Handle cancellation exceptions
                        this.doOutput({ canceled: true }, request.command, request.seq, /*success*/ true);
                        return;
                    }
                    this.logErrorWorker(err, message, relevantFile);
                    this.doOutput(
                    /*info*/ undefined, request ? request.command : server.CommandNames.Unknown, request ? request.seq : 0, 
                    /*success*/ false, "Error processing request. " + err.message + "\n" + err.stack);
                }
            };
            Session.prototype.getFormatOptions = function (file) {
                return this.projectService.getFormatCodeOptions(file);
            };
            Session.prototype.getPreferences = function (file) {
                return this.projectService.getPreferences(file);
            };
            Session.prototype.getHostFormatOptions = function () {
                return this.projectService.getHostFormatCodeOptions();
            };
            Session.prototype.getHostPreferences = function () {
                return this.projectService.getHostPreferences();
            };
            return Session;
        }());
        server.Session = Session;
        function toFileSpan(fileName, textSpan, scriptInfo) {
            return { file: fileName, start: scriptInfo.positionToLineOffset(textSpan.start), end: scriptInfo.positionToLineOffset(ts.textSpanEnd(textSpan)) };
        }
        function convertTextChangeToCodeEdit(change, scriptInfo) {
            return { start: positionToLineOffset(scriptInfo, change.span.start), end: positionToLineOffset(scriptInfo, ts.textSpanEnd(change.span)), newText: change.newText };
        }
        function positionToLineOffset(info, position) {
            return server.isConfigFile(info) ? locationFromLineAndCharacter(info.getLineAndCharacterOfPosition(position)) : info.positionToLineOffset(position);
        }
        function locationFromLineAndCharacter(lc) {
            return { line: lc.line + 1, offset: lc.character + 1 };
        }
        function convertNewFileTextChangeToCodeEdit(textChanges) {
            ts.Debug.assert(textChanges.textChanges.length === 1);
            var change = ts.first(textChanges.textChanges);
            ts.Debug.assert(change.span.start === 0 && change.span.length === 0);
            return { fileName: textChanges.fileName, textChanges: [{ start: { line: 0, offset: 0 }, end: { line: 0, offset: 0 }, newText: change.newText }] };
        }
        /* @internal */ // Exported only for tests
        function getLocationInNewDocument(oldText, renameFilename, renameLocation, edits) {
            var newText = applyEdits(oldText, renameFilename, edits);
            var _a = ts.computeLineAndCharacterOfPosition(ts.computeLineStarts(newText), renameLocation), line = _a.line, character = _a.character;
            return { line: line + 1, offset: character + 1 };
        }
        server.getLocationInNewDocument = getLocationInNewDocument;
        function applyEdits(text, textFilename, edits) {
            for (var _i = 0, edits_1 = edits; _i < edits_1.length; _i++) {
                var _a = edits_1[_i], fileName = _a.fileName, textChanges_1 = _a.textChanges;
                if (fileName !== textFilename) {
                    continue;
                }
                for (var i = textChanges_1.length - 1; i >= 0; i--) {
                    var _b = textChanges_1[i], newText = _b.newText, _c = _b.span, start = _c.start, length_1 = _c.length;
                    text = text.slice(0, start) + newText + text.slice(start + length_1);
                }
            }
            return text;
        }
    })(server = ts.server || (ts.server = {}));
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var server;
    (function (server) {
        var lineCollectionCapacity = 4;
        var CharRangeSection;
        (function (CharRangeSection) {
            CharRangeSection[CharRangeSection["PreStart"] = 0] = "PreStart";
            CharRangeSection[CharRangeSection["Start"] = 1] = "Start";
            CharRangeSection[CharRangeSection["Entire"] = 2] = "Entire";
            CharRangeSection[CharRangeSection["Mid"] = 3] = "Mid";
            CharRangeSection[CharRangeSection["End"] = 4] = "End";
            CharRangeSection[CharRangeSection["PostEnd"] = 5] = "PostEnd";
        })(CharRangeSection || (CharRangeSection = {}));
        var EditWalker = /** @class */ (function () {
            function EditWalker() {
                this.goSubtree = true;
                this.lineIndex = new LineIndex();
                this.endBranch = [];
                this.state = 2 /* Entire */;
                this.initialText = "";
                this.trailingText = "";
                this.lineIndex.root = new LineNode();
                this.startPath = [this.lineIndex.root];
                this.stack = [this.lineIndex.root];
            }
            Object.defineProperty(EditWalker.prototype, "done", {
                get: function () { return false; },
                enumerable: true,
                configurable: true
            });
            EditWalker.prototype.insertLines = function (insertedText, suppressTrailingText) {
                if (suppressTrailingText) {
                    this.trailingText = "";
                }
                if (insertedText) {
                    insertedText = this.initialText + insertedText + this.trailingText;
                }
                else {
                    insertedText = this.initialText + this.trailingText;
                }
                var lm = LineIndex.linesFromText(insertedText);
                var lines = lm.lines;
                if (lines.length > 1) {
                    if (lines[lines.length - 1] === "") {
                        lines.pop();
                    }
                }
                var branchParent;
                var lastZeroCount;
                for (var k = this.endBranch.length - 1; k >= 0; k--) {
                    this.endBranch[k].updateCounts();
                    if (this.endBranch[k].charCount() === 0) {
                        lastZeroCount = this.endBranch[k];
                        if (k > 0) {
                            branchParent = this.endBranch[k - 1];
                        }
                        else {
                            branchParent = this.branchNode;
                        }
                    }
                }
                if (lastZeroCount) {
                    branchParent.remove(lastZeroCount);
                }
                // path at least length two (root and leaf)
                var leafNode = this.startPath[this.startPath.length - 1];
                if (lines.length > 0) {
                    leafNode.text = lines[0];
                    if (lines.length > 1) {
                        var insertedNodes = new Array(lines.length - 1);
                        var startNode = leafNode;
                        for (var i = 1; i < lines.length; i++) {
                            insertedNodes[i - 1] = new LineLeaf(lines[i]);
                        }
                        var pathIndex = this.startPath.length - 2;
                        while (pathIndex >= 0) {
                            var insertionNode = this.startPath[pathIndex];
                            insertedNodes = insertionNode.insertAt(startNode, insertedNodes);
                            pathIndex--;
                            startNode = insertionNode;
                        }
                        var insertedNodesLen = insertedNodes.length;
                        while (insertedNodesLen > 0) {
                            var newRoot = new LineNode();
                            newRoot.add(this.lineIndex.root);
                            insertedNodes = newRoot.insertAt(this.lineIndex.root, insertedNodes);
                            insertedNodesLen = insertedNodes.length;
                            this.lineIndex.root = newRoot;
                        }
                        this.lineIndex.root.updateCounts();
                    }
                    else {
                        for (var j = this.startPath.length - 2; j >= 0; j--) {
                            this.startPath[j].updateCounts();
                        }
                    }
                }
                else {
                    var insertionNode = this.startPath[this.startPath.length - 2];
                    // no content for leaf node, so delete it
                    insertionNode.remove(leafNode);
                    for (var j = this.startPath.length - 2; j >= 0; j--) {
                        this.startPath[j].updateCounts();
                    }
                }
                return this.lineIndex;
            };
            EditWalker.prototype.post = function (_relativeStart, _relativeLength, lineCollection) {
                // have visited the path for start of range, now looking for end
                // if range is on single line, we will never make this state transition
                if (lineCollection === this.lineCollectionAtBranch) {
                    this.state = 4 /* End */;
                }
                // always pop stack because post only called when child has been visited
                this.stack.pop();
            };
            EditWalker.prototype.pre = function (_relativeStart, _relativeLength, lineCollection, _parent, nodeType) {
                // currentNode corresponds to parent, but in the new tree
                var currentNode = this.stack[this.stack.length - 1];
                if ((this.state === 2 /* Entire */) && (nodeType === 1 /* Start */)) {
                    // if range is on single line, we will never make this state transition
                    this.state = 1 /* Start */;
                    this.branchNode = currentNode;
                    this.lineCollectionAtBranch = lineCollection;
                }
                var child;
                function fresh(node) {
                    if (node.isLeaf()) {
                        return new LineLeaf("");
                    }
                    else
                        return new LineNode();
                }
                switch (nodeType) {
                    case 0 /* PreStart */:
                        this.goSubtree = false;
                        if (this.state !== 4 /* End */) {
                            currentNode.add(lineCollection);
                        }
                        break;
                    case 1 /* Start */:
                        if (this.state === 4 /* End */) {
                            this.goSubtree = false;
                        }
                        else {
                            child = fresh(lineCollection);
                            currentNode.add(child);
                            this.startPath.push(child);
                        }
                        break;
                    case 2 /* Entire */:
                        if (this.state !== 4 /* End */) {
                            child = fresh(lineCollection);
                            currentNode.add(child);
                            this.startPath.push(child);
                        }
                        else {
                            if (!lineCollection.isLeaf()) {
                                child = fresh(lineCollection);
                                currentNode.add(child);
                                this.endBranch.push(child);
                            }
                        }
                        break;
                    case 3 /* Mid */:
                        this.goSubtree = false;
                        break;
                    case 4 /* End */:
                        if (this.state !== 4 /* End */) {
                            this.goSubtree = false;
                        }
                        else {
                            if (!lineCollection.isLeaf()) {
                                child = fresh(lineCollection);
                                currentNode.add(child);
                                this.endBranch.push(child);
                            }
                        }
                        break;
                    case 5 /* PostEnd */:
                        this.goSubtree = false;
                        if (this.state !== 1 /* Start */) {
                            currentNode.add(lineCollection);
                        }
                        break;
                }
                if (this.goSubtree) {
                    this.stack.push(child);
                }
            };
            // just gather text from the leaves
            EditWalker.prototype.leaf = function (relativeStart, relativeLength, ll) {
                if (this.state === 1 /* Start */) {
                    this.initialText = ll.text.substring(0, relativeStart);
                }
                else if (this.state === 2 /* Entire */) {
                    this.initialText = ll.text.substring(0, relativeStart);
                    this.trailingText = ll.text.substring(relativeStart + relativeLength);
                }
                else {
                    // state is CharRangeSection.End
                    this.trailingText = ll.text.substring(relativeStart + relativeLength);
                }
            };
            return EditWalker;
        }());
        // text change information
        var TextChange = /** @class */ (function () {
            function TextChange(pos, deleteLen, insertedText) {
                this.pos = pos;
                this.deleteLen = deleteLen;
                this.insertedText = insertedText;
            }
            TextChange.prototype.getTextChangeRange = function () {
                return ts.createTextChangeRange(ts.createTextSpan(this.pos, this.deleteLen), this.insertedText ? this.insertedText.length : 0);
            };
            return TextChange;
        }());
        var ScriptVersionCache = /** @class */ (function () {
            function ScriptVersionCache() {
                this.changes = [];
                this.versions = new Array(ScriptVersionCache.maxVersions);
                this.minVersion = 0; // no versions earlier than min version will maintain change history
                this.currentVersion = 0;
            }
            ScriptVersionCache.prototype.versionToIndex = function (version) {
                if (version < this.minVersion || version > this.currentVersion) {
                    return undefined;
                }
                return version % ScriptVersionCache.maxVersions;
            };
            ScriptVersionCache.prototype.currentVersionToIndex = function () {
                return this.currentVersion % ScriptVersionCache.maxVersions;
            };
            // REVIEW: can optimize by coalescing simple edits
            ScriptVersionCache.prototype.edit = function (pos, deleteLen, insertedText) {
                this.changes.push(new TextChange(pos, deleteLen, insertedText));
                if (this.changes.length > ScriptVersionCache.changeNumberThreshold ||
                    deleteLen > ScriptVersionCache.changeLengthThreshold ||
                    insertedText && insertedText.length > ScriptVersionCache.changeLengthThreshold) {
                    this.getSnapshot();
                }
            };
            ScriptVersionCache.prototype.getSnapshot = function () { return this._getSnapshot(); };
            ScriptVersionCache.prototype._getSnapshot = function () {
                var snap = this.versions[this.currentVersionToIndex()];
                if (this.changes.length > 0) {
                    var snapIndex = snap.index;
                    for (var _i = 0, _a = this.changes; _i < _a.length; _i++) {
                        var change = _a[_i];
                        snapIndex = snapIndex.edit(change.pos, change.deleteLen, change.insertedText);
                    }
                    snap = new LineIndexSnapshot(this.currentVersion + 1, this, snapIndex, this.changes);
                    this.currentVersion = snap.version;
                    this.versions[this.currentVersionToIndex()] = snap;
                    this.changes = [];
                    if ((this.currentVersion - this.minVersion) >= ScriptVersionCache.maxVersions) {
                        this.minVersion = (this.currentVersion - ScriptVersionCache.maxVersions) + 1;
                    }
                }
                return snap;
            };
            ScriptVersionCache.prototype.getSnapshotVersion = function () {
                return this._getSnapshot().version;
            };
            ScriptVersionCache.prototype.getAbsolutePositionAndLineText = function (oneBasedLine) {
                return this._getSnapshot().index.lineNumberToInfo(oneBasedLine);
            };
            ScriptVersionCache.prototype.lineOffsetToPosition = function (line, column) {
                return this._getSnapshot().index.absolutePositionOfStartOfLine(line) + (column - 1);
            };
            ScriptVersionCache.prototype.positionToLineOffset = function (position) {
                return this._getSnapshot().index.positionToLineOffset(position);
            };
            ScriptVersionCache.prototype.lineToTextSpan = function (line) {
                var index = this._getSnapshot().index;
                var _a = index.lineNumberToInfo(line + 1), lineText = _a.lineText, absolutePosition = _a.absolutePosition;
                var len = lineText !== undefined ? lineText.length : index.absolutePositionOfStartOfLine(line + 2) - absolutePosition;
                return ts.createTextSpan(absolutePosition, len);
            };
            ScriptVersionCache.prototype.getTextChangesBetweenVersions = function (oldVersion, newVersion) {
                if (oldVersion < newVersion) {
                    if (oldVersion >= this.minVersion) {
                        var textChangeRanges = [];
                        for (var i = oldVersion + 1; i <= newVersion; i++) {
                            var snap = this.versions[this.versionToIndex(i)]; // TODO: GH#18217
                            for (var _i = 0, _a = snap.changesSincePreviousVersion; _i < _a.length; _i++) {
                                var textChange = _a[_i];
                                textChangeRanges.push(textChange.getTextChangeRange());
                            }
                        }
                        return ts.collapseTextChangeRangesAcrossMultipleVersions(textChangeRanges);
                    }
                    else {
                        return undefined;
                    }
                }
                else {
                    return ts.unchangedTextChangeRange;
                }
            };
            ScriptVersionCache.prototype.getLineCount = function () {
                return this._getSnapshot().index.getLineCount();
            };
            ScriptVersionCache.fromString = function (script) {
                var svc = new ScriptVersionCache();
                var snap = new LineIndexSnapshot(0, svc, new LineIndex());
                svc.versions[svc.currentVersion] = snap;
                var lm = LineIndex.linesFromText(script);
                snap.index.load(lm.lines);
                return svc;
            };
            ScriptVersionCache.changeNumberThreshold = 8;
            ScriptVersionCache.changeLengthThreshold = 256;
            ScriptVersionCache.maxVersions = 8;
            return ScriptVersionCache;
        }());
        server.ScriptVersionCache = ScriptVersionCache;
        var LineIndexSnapshot = /** @class */ (function () {
            function LineIndexSnapshot(version, cache, index, changesSincePreviousVersion) {
                if (changesSincePreviousVersion === void 0) { changesSincePreviousVersion = server.emptyArray; }
                this.version = version;
                this.cache = cache;
                this.index = index;
                this.changesSincePreviousVersion = changesSincePreviousVersion;
            }
            LineIndexSnapshot.prototype.getText = function (rangeStart, rangeEnd) {
                return this.index.getText(rangeStart, rangeEnd - rangeStart);
            };
            LineIndexSnapshot.prototype.getLength = function () {
                return this.index.getLength();
            };
            LineIndexSnapshot.prototype.getChangeRange = function (oldSnapshot) {
                if (oldSnapshot instanceof LineIndexSnapshot && this.cache === oldSnapshot.cache) {
                    if (this.version <= oldSnapshot.version) {
                        return ts.unchangedTextChangeRange;
                    }
                    else {
                        return this.cache.getTextChangesBetweenVersions(oldSnapshot.version, this.version);
                    }
                }
            };
            return LineIndexSnapshot;
        }());
        var LineIndex = /** @class */ (function () {
            function LineIndex() {
                // set this to true to check each edit for accuracy
                this.checkEdits = false;
            }
            LineIndex.prototype.absolutePositionOfStartOfLine = function (oneBasedLine) {
                return this.lineNumberToInfo(oneBasedLine).absolutePosition;
            };
            LineIndex.prototype.positionToLineOffset = function (position) {
                var _a = this.root.charOffsetToLineInfo(1, position), oneBasedLine = _a.oneBasedLine, zeroBasedColumn = _a.zeroBasedColumn;
                return { line: oneBasedLine, offset: zeroBasedColumn + 1 };
            };
            LineIndex.prototype.positionToColumnAndLineText = function (position) {
                return this.root.charOffsetToLineInfo(1, position);
            };
            LineIndex.prototype.getLineCount = function () {
                return this.root.lineCount();
            };
            LineIndex.prototype.lineNumberToInfo = function (oneBasedLine) {
                var lineCount = this.getLineCount();
                if (oneBasedLine <= lineCount) {
                    var _a = this.root.lineNumberToInfo(oneBasedLine, 0), position = _a.position, leaf = _a.leaf;
                    return { absolutePosition: position, lineText: leaf && leaf.text };
                }
                else {
                    return { absolutePosition: this.root.charCount(), lineText: undefined };
                }
            };
            LineIndex.prototype.load = function (lines) {
                if (lines.length > 0) {
                    var leaves = [];
                    for (var i = 0; i < lines.length; i++) {
                        leaves[i] = new LineLeaf(lines[i]);
                    }
                    this.root = LineIndex.buildTreeFromBottom(leaves);
                }
                else {
                    this.root = new LineNode();
                }
            };
            LineIndex.prototype.walk = function (rangeStart, rangeLength, walkFns) {
                this.root.walk(rangeStart, rangeLength, walkFns);
            };
            LineIndex.prototype.getText = function (rangeStart, rangeLength) {
                var accum = "";
                if ((rangeLength > 0) && (rangeStart < this.root.charCount())) {
                    this.walk(rangeStart, rangeLength, {
                        goSubtree: true,
                        done: false,
                        leaf: function (relativeStart, relativeLength, ll) {
                            accum = accum.concat(ll.text.substring(relativeStart, relativeStart + relativeLength));
                        }
                    });
                }
                return accum;
            };
            LineIndex.prototype.getLength = function () {
                return this.root.charCount();
            };
            LineIndex.prototype.every = function (f, rangeStart, rangeEnd) {
                if (!rangeEnd) {
                    rangeEnd = this.root.charCount();
                }
                var walkFns = {
                    goSubtree: true,
                    done: false,
                    leaf: function (relativeStart, relativeLength, ll) {
                        if (!f(ll, relativeStart, relativeLength)) {
                            this.done = true;
                        }
                    }
                };
                this.walk(rangeStart, rangeEnd - rangeStart, walkFns);
                return !walkFns.done;
            };
            LineIndex.prototype.edit = function (pos, deleteLength, newText) {
                if (this.root.charCount() === 0) {
                    ts.Debug.assert(deleteLength === 0); // Can't delete from empty document
                    if (newText !== undefined) {
                        this.load(LineIndex.linesFromText(newText).lines);
                        return this;
                    }
                    return undefined; // TODO: GH#18217
                }
                else {
                    var checkText = void 0;
                    if (this.checkEdits) {
                        var source = this.getText(0, this.root.charCount());
                        checkText = source.slice(0, pos) + newText + source.slice(pos + deleteLength);
                    }
                    var walker = new EditWalker();
                    var suppressTrailingText = false;
                    if (pos >= this.root.charCount()) {
                        // insert at end
                        pos = this.root.charCount() - 1;
                        var endString = this.getText(pos, 1);
                        if (newText) {
                            newText = endString + newText;
                        }
                        else {
                            newText = endString;
                        }
                        deleteLength = 0;
                        suppressTrailingText = true;
                    }
                    else if (deleteLength > 0) {
                        // check whether last characters deleted are line break
                        var e = pos + deleteLength;
                        var _a = this.positionToColumnAndLineText(e), zeroBasedColumn = _a.zeroBasedColumn, lineText = _a.lineText;
                        if (zeroBasedColumn === 0) {
                            // move range end just past line that will merge with previous line
                            deleteLength += lineText.length; // TODO: GH#18217
                            // store text by appending to end of insertedText
                            newText = newText ? newText + lineText : lineText;
                        }
                    }
                    this.root.walk(pos, deleteLength, walker);
                    walker.insertLines(newText, suppressTrailingText);
                    if (this.checkEdits) {
                        var updatedText = walker.lineIndex.getText(0, walker.lineIndex.getLength());
                        ts.Debug.assert(checkText === updatedText, "buffer edit mismatch");
                    }
                    return walker.lineIndex;
                }
            };
            LineIndex.buildTreeFromBottom = function (nodes) {
                if (nodes.length < lineCollectionCapacity) {
                    return new LineNode(nodes);
                }
                var interiorNodes = new Array(Math.ceil(nodes.length / lineCollectionCapacity));
                var nodeIndex = 0;
                for (var i = 0; i < interiorNodes.length; i++) {
                    var end = Math.min(nodeIndex + lineCollectionCapacity, nodes.length);
                    interiorNodes[i] = new LineNode(nodes.slice(nodeIndex, end));
                    nodeIndex = end;
                }
                return this.buildTreeFromBottom(interiorNodes);
            };
            LineIndex.linesFromText = function (text) {
                var lineMap = ts.computeLineStarts(text);
                if (lineMap.length === 0) {
                    return { lines: [], lineMap: lineMap };
                }
                var lines = new Array(lineMap.length);
                var lc = lineMap.length - 1;
                for (var lmi = 0; lmi < lc; lmi++) {
                    lines[lmi] = text.substring(lineMap[lmi], lineMap[lmi + 1]);
                }
                var endText = text.substring(lineMap[lc]);
                if (endText.length > 0) {
                    lines[lc] = endText;
                }
                else {
                    lines.pop();
                }
                return { lines: lines, lineMap: lineMap };
            };
            return LineIndex;
        }());
        server.LineIndex = LineIndex;
        var LineNode = /** @class */ (function () {
            function LineNode(children) {
                if (children === void 0) { children = []; }
                this.children = children;
                this.totalChars = 0;
                this.totalLines = 0;
                if (children.length)
                    this.updateCounts();
            }
            LineNode.prototype.isLeaf = function () {
                return false;
            };
            LineNode.prototype.updateCounts = function () {
                this.totalChars = 0;
                this.totalLines = 0;
                for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
                    var child = _a[_i];
                    this.totalChars += child.charCount();
                    this.totalLines += child.lineCount();
                }
            };
            LineNode.prototype.execWalk = function (rangeStart, rangeLength, walkFns, childIndex, nodeType) {
                if (walkFns.pre) {
                    walkFns.pre(rangeStart, rangeLength, this.children[childIndex], this, nodeType);
                }
                if (walkFns.goSubtree) {
                    this.children[childIndex].walk(rangeStart, rangeLength, walkFns);
                    if (walkFns.post) {
                        walkFns.post(rangeStart, rangeLength, this.children[childIndex], this, nodeType);
                    }
                }
                else {
                    walkFns.goSubtree = true;
                }
                return walkFns.done;
            };
            LineNode.prototype.skipChild = function (relativeStart, relativeLength, childIndex, walkFns, nodeType) {
                if (walkFns.pre && (!walkFns.done)) {
                    walkFns.pre(relativeStart, relativeLength, this.children[childIndex], this, nodeType);
                    walkFns.goSubtree = true;
                }
            };
            LineNode.prototype.walk = function (rangeStart, rangeLength, walkFns) {
                // assume (rangeStart < this.totalChars) && (rangeLength <= this.totalChars)
                var childIndex = 0;
                var childCharCount = this.children[childIndex].charCount();
                // find sub-tree containing start
                var adjustedStart = rangeStart;
                while (adjustedStart >= childCharCount) {
                    this.skipChild(adjustedStart, rangeLength, childIndex, walkFns, 0 /* PreStart */);
                    adjustedStart -= childCharCount;
                    childIndex++;
                    childCharCount = this.children[childIndex].charCount();
                }
                // Case I: both start and end of range in same subtree
                if ((adjustedStart + rangeLength) <= childCharCount) {
                    if (this.execWalk(adjustedStart, rangeLength, walkFns, childIndex, 2 /* Entire */)) {
                        return;
                    }
                }
                else {
                    // Case II: start and end of range in different subtrees (possibly with subtrees in the middle)
                    if (this.execWalk(adjustedStart, childCharCount - adjustedStart, walkFns, childIndex, 1 /* Start */)) {
                        return;
                    }
                    var adjustedLength = rangeLength - (childCharCount - adjustedStart);
                    childIndex++;
                    var child = this.children[childIndex];
                    childCharCount = child.charCount();
                    while (adjustedLength > childCharCount) {
                        if (this.execWalk(0, childCharCount, walkFns, childIndex, 3 /* Mid */)) {
                            return;
                        }
                        adjustedLength -= childCharCount;
                        childIndex++;
                        childCharCount = this.children[childIndex].charCount();
                    }
                    if (adjustedLength > 0) {
                        if (this.execWalk(0, adjustedLength, walkFns, childIndex, 4 /* End */)) {
                            return;
                        }
                    }
                }
                // Process any subtrees after the one containing range end
                if (walkFns.pre) {
                    var clen = this.children.length;
                    if (childIndex < (clen - 1)) {
                        for (var ej = childIndex + 1; ej < clen; ej++) {
                            this.skipChild(0, 0, ej, walkFns, 5 /* PostEnd */);
                        }
                    }
                }
            };
            // Input position is relative to the start of this node.
            // Output line number is absolute.
            LineNode.prototype.charOffsetToLineInfo = function (lineNumberAccumulator, relativePosition) {
                if (this.children.length === 0) {
                    // Root node might have no children if this is an empty document.
                    return { oneBasedLine: lineNumberAccumulator, zeroBasedColumn: relativePosition, lineText: undefined };
                }
                for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
                    var child = _a[_i];
                    if (child.charCount() > relativePosition) {
                        if (child.isLeaf()) {
                            return { oneBasedLine: lineNumberAccumulator, zeroBasedColumn: relativePosition, lineText: child.text };
                        }
                        else {
                            return child.charOffsetToLineInfo(lineNumberAccumulator, relativePosition);
                        }
                    }
                    else {
                        relativePosition -= child.charCount();
                        lineNumberAccumulator += child.lineCount();
                    }
                }
                // Skipped all children
                var leaf = this.lineNumberToInfo(this.lineCount(), 0).leaf;
                return { oneBasedLine: this.lineCount(), zeroBasedColumn: leaf ? leaf.charCount() : 0, lineText: undefined };
            };
            /**
             * Input line number is relative to the start of this node.
             * Output line number is relative to the child.
             * positionAccumulator will be an absolute position once relativeLineNumber reaches 0.
             */
            LineNode.prototype.lineNumberToInfo = function (relativeOneBasedLine, positionAccumulator) {
                for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
                    var child = _a[_i];
                    var childLineCount = child.lineCount();
                    if (childLineCount >= relativeOneBasedLine) {
                        return child.isLeaf() ? { position: positionAccumulator, leaf: child } : child.lineNumberToInfo(relativeOneBasedLine, positionAccumulator);
                    }
                    else {
                        relativeOneBasedLine -= childLineCount;
                        positionAccumulator += child.charCount();
                    }
                }
                return { position: positionAccumulator, leaf: undefined };
            };
            LineNode.prototype.splitAfter = function (childIndex) {
                var splitNode;
                var clen = this.children.length;
                childIndex++;
                var endLength = childIndex;
                if (childIndex < clen) {
                    splitNode = new LineNode();
                    while (childIndex < clen) {
                        splitNode.add(this.children[childIndex]);
                        childIndex++;
                    }
                    splitNode.updateCounts();
                }
                this.children.length = endLength;
                return splitNode;
            };
            LineNode.prototype.remove = function (child) {
                var childIndex = this.findChildIndex(child);
                var clen = this.children.length;
                if (childIndex < (clen - 1)) {
                    for (var i = childIndex; i < (clen - 1); i++) {
                        this.children[i] = this.children[i + 1];
                    }
                }
                this.children.pop();
            };
            LineNode.prototype.findChildIndex = function (child) {
                var childIndex = this.children.indexOf(child);
                ts.Debug.assert(childIndex !== -1);
                return childIndex;
            };
            LineNode.prototype.insertAt = function (child, nodes) {
                var childIndex = this.findChildIndex(child);
                var clen = this.children.length;
                var nodeCount = nodes.length;
                // if child is last and there is more room and only one node to place, place it
                if ((clen < lineCollectionCapacity) && (childIndex === (clen - 1)) && (nodeCount === 1)) {
                    this.add(nodes[0]);
                    this.updateCounts();
                    return [];
                }
                else {
                    var shiftNode = this.splitAfter(childIndex);
                    var nodeIndex = 0;
                    childIndex++;
                    while ((childIndex < lineCollectionCapacity) && (nodeIndex < nodeCount)) {
                        this.children[childIndex] = nodes[nodeIndex];
                        childIndex++;
                        nodeIndex++;
                    }
                    var splitNodes = [];
                    var splitNodeCount = 0;
                    if (nodeIndex < nodeCount) {
                        splitNodeCount = Math.ceil((nodeCount - nodeIndex) / lineCollectionCapacity);
                        splitNodes = new Array(splitNodeCount);
                        var splitNodeIndex = 0;
                        for (var i = 0; i < splitNodeCount; i++) {
                            splitNodes[i] = new LineNode();
                        }
                        var splitNode = splitNodes[0];
                        while (nodeIndex < nodeCount) {
                            splitNode.add(nodes[nodeIndex]);
                            nodeIndex++;
                            if (splitNode.children.length === lineCollectionCapacity) {
                                splitNodeIndex++;
                                splitNode = splitNodes[splitNodeIndex];
                            }
                        }
                        for (var i = splitNodes.length - 1; i >= 0; i--) {
                            if (splitNodes[i].children.length === 0) {
                                splitNodes.pop();
                            }
                        }
                    }
                    if (shiftNode) {
                        splitNodes.push(shiftNode);
                    }
                    this.updateCounts();
                    for (var i = 0; i < splitNodeCount; i++) {
                        splitNodes[i].updateCounts();
                    }
                    return splitNodes;
                }
            };
            // assume there is room for the item; return true if more room
            LineNode.prototype.add = function (collection) {
                this.children.push(collection);
                ts.Debug.assert(this.children.length <= lineCollectionCapacity);
            };
            LineNode.prototype.charCount = function () {
                return this.totalChars;
            };
            LineNode.prototype.lineCount = function () {
                return this.totalLines;
            };
            return LineNode;
        }());
        var LineLeaf = /** @class */ (function () {
            function LineLeaf(text) {
                this.text = text;
            }
            LineLeaf.prototype.isLeaf = function () {
                return true;
            };
            LineLeaf.prototype.walk = function (rangeStart, rangeLength, walkFns) {
                walkFns.leaf(rangeStart, rangeLength, this);
            };
            LineLeaf.prototype.charCount = function () {
                return this.text.length;
            };
            LineLeaf.prototype.lineCount = function () {
                return 1;
            };
            return LineLeaf;
        }());
    })(server = ts.server || (ts.server = {}));
})(ts || (ts = {}));
// tslint:disable no-unnecessary-type-assertion (TODO: tslint can't find node types)
var ts;
(function (ts) {
    var server;
    (function (server) {
        var childProcess = require("child_process");
        var os = require("os");
        var net = require("net");
        function getGlobalTypingsCacheLocation() {
            switch (process.platform) {
                case "win32": {
                    var basePath = process.env.LOCALAPPDATA ||
                        process.env.APPDATA ||
                        (os.homedir && os.homedir()) ||
                        process.env.USERPROFILE ||
                        (process.env.HOMEDRIVE && process.env.HOMEPATH && ts.normalizeSlashes(process.env.HOMEDRIVE + process.env.HOMEPATH)) ||
                        os.tmpdir();
                    return ts.combinePaths(ts.combinePaths(ts.normalizeSlashes(basePath), "Microsoft/TypeScript"), ts.versionMajorMinor);
                }
                case "openbsd":
                case "freebsd":
                case "darwin":
                case "linux":
                case "android": {
                    var cacheLocation = getNonWindowsCacheLocation(process.platform === "darwin");
                    return ts.combinePaths(ts.combinePaths(cacheLocation, "typescript"), ts.versionMajorMinor);
                }
                default:
                    return ts.Debug.fail("unsupported platform '" + process.platform + "'");
            }
        }
        function getNonWindowsCacheLocation(platformIsDarwin) {
            if (process.env.XDG_CACHE_HOME) {
                return process.env.XDG_CACHE_HOME;
            }
            var usersDir = platformIsDarwin ? "Users" : "home";
            var homePath = (os.homedir && os.homedir()) ||
                process.env.HOME ||
                ((process.env.LOGNAME || process.env.USER) && "/" + usersDir + "/" + (process.env.LOGNAME || process.env.USER)) ||
                os.tmpdir();
            var cacheFolder = platformIsDarwin
                ? "Library/Caches"
                : ".cache";
            return ts.combinePaths(ts.normalizeSlashes(homePath), cacheFolder);
        }
        var readline = require("readline");
        var fs = require("fs");
        var rl = readline.createInterface({
            input: process.stdin,
            output: process.stdout,
            terminal: false,
        });
        var Logger = /** @class */ (function () {
            function Logger(logFilename, traceToConsole, level) {
                this.logFilename = logFilename;
                this.traceToConsole = traceToConsole;
                this.level = level;
                this.fd = -1;
                this.seq = 0;
                this.inGroup = false;
                this.firstInGroup = true;
                if (this.logFilename) {
                    try {
                        this.fd = fs.openSync(this.logFilename, "w");
                    }
                    catch (_) {
                        // swallow the error and keep logging disabled if file cannot be opened
                    }
                }
            }
            Logger.padStringRight = function (str, padding) {
                return (str + padding).slice(0, padding.length);
            };
            Logger.prototype.close = function () {
                if (this.fd >= 0) {
                    fs.close(this.fd, ts.noop);
                }
            };
            Logger.prototype.getLogFileName = function () {
                return this.logFilename;
            };
            Logger.prototype.perftrc = function (s) {
                this.msg(s, server.Msg.Perf);
            };
            Logger.prototype.info = function (s) {
                this.msg(s, server.Msg.Info);
            };
            Logger.prototype.err = function (s) {
                this.msg(s, server.Msg.Err);
            };
            Logger.prototype.startGroup = function () {
                this.inGroup = true;
                this.firstInGroup = true;
            };
            Logger.prototype.endGroup = function () {
                this.inGroup = false;
            };
            Logger.prototype.loggingEnabled = function () {
                return !!this.logFilename || this.traceToConsole;
            };
            Logger.prototype.hasLevel = function (level) {
                return this.loggingEnabled() && this.level >= level;
            };
            Logger.prototype.msg = function (s, type) {
                if (type === void 0) { type = server.Msg.Err; }
                if (!this.canWrite)
                    return;
                s = "[" + server.nowString() + "] " + s + "\n";
                if (!this.inGroup || this.firstInGroup) {
                    var prefix = Logger.padStringRight(type + " " + this.seq.toString(), "          ");
                    s = prefix + s;
                }
                this.write(s);
                if (!this.inGroup) {
                    this.seq++;
                }
            };
            Object.defineProperty(Logger.prototype, "canWrite", {
                get: function () {
                    return this.fd >= 0 || this.traceToConsole;
                },
                enumerable: true,
                configurable: true
            });
            Logger.prototype.write = function (s) {
                if (this.fd >= 0) {
                    var buf = sys.bufferFrom(s);
                    // tslint:disable-next-line no-null-keyword
                    fs.writeSync(this.fd, buf, 0, buf.length, /*position*/ null); // TODO: GH#18217
                }
                if (this.traceToConsole) {
                    console.warn(s);
                }
            };
            return Logger;
        }());
        var NodeTypingsInstaller = /** @class */ (function () {
            function NodeTypingsInstaller(telemetryEnabled, logger, host, globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, validateDefaultNpmLocation, event) {
                this.telemetryEnabled = telemetryEnabled;
                this.logger = logger;
                this.host = host;
                this.globalTypingsCacheLocation = globalTypingsCacheLocation;
                this.typingSafeListLocation = typingSafeListLocation;
                this.typesMapLocation = typesMapLocation;
                this.npmLocation = npmLocation;
                this.validateDefaultNpmLocation = validateDefaultNpmLocation;
                this.event = event;
                this.activeRequestCount = 0;
                this.requestQueue = [];
                this.requestMap = ts.createMap(); // Maps operation ID to newest requestQueue entry with that ID
                /** We will lazily request the types registry on the first call to `isKnownTypesPackageName` and store it in `typesRegistryCache`. */
                this.requestedRegistry = false;
            }
            NodeTypingsInstaller.prototype.isKnownTypesPackageName = function (name) {
                // We want to avoid looking this up in the registry as that is expensive. So first check that it's actually an NPM package.
                var validationResult = ts.JsTyping.validatePackageName(name);
                if (validationResult !== 0 /* Ok */) {
                    return false;
                }
                if (this.requestedRegistry) {
                    return !!this.typesRegistryCache && this.typesRegistryCache.has(name);
                }
                this.requestedRegistry = true;
                this.send({ kind: "typesRegistry" });
                return false;
            };
            NodeTypingsInstaller.prototype.installPackage = function (options) {
                var _this = this;
                this.send(__assign({ kind: "installPackage" }, options));
                ts.Debug.assert(this.packageInstalledPromise === undefined);
                return new Promise(function (resolve, reject) {
                    _this.packageInstalledPromise = { resolve: resolve, reject: reject };
                });
            };
            NodeTypingsInstaller.prototype.attach = function (projectService) {
                var _this = this;
                this.projectService = projectService;
                if (this.logger.hasLevel(server.LogLevel.requestTime)) {
                    this.logger.info("Binding...");
                }
                var args = [server.Arguments.GlobalCacheLocation, this.globalTypingsCacheLocation];
                if (this.telemetryEnabled) {
                    args.push(server.Arguments.EnableTelemetry);
                }
                if (this.logger.loggingEnabled() && this.logger.getLogFileName()) {
                    args.push(server.Arguments.LogFile, ts.combinePaths(ts.getDirectoryPath(ts.normalizeSlashes(this.logger.getLogFileName())), "ti-" + process.pid + ".log"));
                }
                if (this.typingSafeListLocation) {
                    args.push(server.Arguments.TypingSafeListLocation, this.typingSafeListLocation);
                }
                if (this.typesMapLocation) {
                    args.push(server.Arguments.TypesMapLocation, this.typesMapLocation);
                }
                if (this.npmLocation) {
                    args.push(server.Arguments.NpmLocation, this.npmLocation);
                }
                if (this.validateDefaultNpmLocation) {
                    args.push(server.Arguments.ValidateDefaultNpmLocation);
                }
                var execArgv = [];
                for (var _i = 0, _a = process.execArgv; _i < _a.length; _i++) {
                    var arg = _a[_i];
                    var match = /^--((?:debug|inspect)(?:-brk)?)(?:=(\d+))?$/.exec(arg);
                    if (match) {
                        // if port is specified - use port + 1
                        // otherwise pick a default port depending on if 'debug' or 'inspect' and use its value + 1
                        var currentPort = match[2] !== undefined
                            ? +match[2]
                            : match[1].charAt(0) === "d" ? 5858 : 9229;
                        execArgv.push("--" + match[1] + "=" + (currentPort + 1));
                        break;
                    }
                }
                this.installer = childProcess.fork(ts.combinePaths(__dirname, "typingsInstaller.js"), args, { execArgv: execArgv });
                this.installer.on("message", function (m) { return _this.handleMessage(m); });
                this.event({ pid: this.installer.pid }, "typingsInstallerPid");
                process.on("exit", function () {
                    _this.installer.kill();
                });
            };
            NodeTypingsInstaller.prototype.onProjectClosed = function (p) {
                this.send({ projectName: p.getProjectName(), kind: "closeProject" });
            };
            NodeTypingsInstaller.prototype.send = function (rq) {
                this.installer.send(rq);
            };
            NodeTypingsInstaller.prototype.enqueueInstallTypingsRequest = function (project, typeAcquisition, unresolvedImports) {
                var _this = this;
                var request = server.createInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
                if (this.logger.hasLevel(server.LogLevel.verbose)) {
                    if (this.logger.hasLevel(server.LogLevel.verbose)) {
                        this.logger.info("Scheduling throttled operation:" + server.stringifyIndented(request));
                    }
                }
                var operationId = project.getProjectName();
                var operation = function () {
                    if (_this.logger.hasLevel(server.LogLevel.verbose)) {
                        _this.logger.info("Sending request:" + server.stringifyIndented(request));
                    }
                    _this.send(request);
                };
                var queuedRequest = { operationId: operationId, operation: operation };
                if (this.activeRequestCount < NodeTypingsInstaller.maxActiveRequestCount) {
                    this.scheduleRequest(queuedRequest);
                }
                else {
                    if (this.logger.hasLevel(server.LogLevel.verbose)) {
                        this.logger.info("Deferring request for: " + operationId);
                    }
                    this.requestQueue.push(queuedRequest);
                    this.requestMap.set(operationId, queuedRequest);
                }
            };
            NodeTypingsInstaller.prototype.handleMessage = function (response) {
                if (this.logger.hasLevel(server.LogLevel.verbose)) {
                    this.logger.info("Received response:" + server.stringifyIndented(response));
                }
                switch (response.kind) {
                    case server.EventTypesRegistry:
                        this.typesRegistryCache = ts.createMapFromTemplate(response.typesRegistry);
                        break;
                    case server.ActionPackageInstalled: {
                        var success = response.success, message = response.message;
                        if (success) {
                            this.packageInstalledPromise.resolve({ successMessage: message });
                        }
                        else {
                            this.packageInstalledPromise.reject(message);
                        }
                        this.packageInstalledPromise = undefined;
                        this.projectService.updateTypingsForProject(response);
                        // The behavior is the same as for setTypings, so send the same event.
                        this.event(response, "setTypings");
                        break;
                    }
                    case server.EventInitializationFailed: {
                        var body = {
                            message: response.message
                        };
                        var eventName = "typesInstallerInitializationFailed";
                        this.event(body, eventName);
                        break;
                    }
                    case server.EventBeginInstallTypes: {
                        var body = {
                            eventId: response.eventId,
                            packages: response.packagesToInstall,
                        };
                        var eventName = "beginInstallTypes";
                        this.event(body, eventName);
                        break;
                    }
                    case server.EventEndInstallTypes: {
                        if (this.telemetryEnabled) {
                            var body_1 = {
                                telemetryEventName: "typingsInstalled",
                                payload: {
                                    installedPackages: response.packagesToInstall.join(","),
                                    installSuccess: response.installSuccess,
                                    typingsInstallerVersion: response.typingsInstallerVersion
                                }
                            };
                            var eventName_1 = "telemetry";
                            this.event(body_1, eventName_1);
                        }
                        var body = {
                            eventId: response.eventId,
                            packages: response.packagesToInstall,
                            success: response.installSuccess,
                        };
                        var eventName = "endInstallTypes";
                        this.event(body, eventName);
                        break;
                    }
                    case server.ActionInvalidate: {
                        this.projectService.updateTypingsForProject(response);
                        break;
                    }
                    case server.ActionSet: {
                        if (this.activeRequestCount > 0) {
                            this.activeRequestCount--;
                        }
                        else {
                            ts.Debug.fail("Received too many responses");
                        }
                        while (this.requestQueue.length > 0) {
                            var queuedRequest = this.requestQueue.shift();
                            if (this.requestMap.get(queuedRequest.operationId) === queuedRequest) {
                                this.requestMap.delete(queuedRequest.operationId);
                                this.scheduleRequest(queuedRequest);
                                break;
                            }
                            if (this.logger.hasLevel(server.LogLevel.verbose)) {
                                this.logger.info("Skipping defunct request for: " + queuedRequest.operationId);
                            }
                        }
                        this.projectService.updateTypingsForProject(response);
                        this.event(response, "setTypings");
                        break;
                    }
                    default:
                        ts.assertType(response);
                }
            };
            NodeTypingsInstaller.prototype.scheduleRequest = function (request) {
                if (this.logger.hasLevel(server.LogLevel.verbose)) {
                    this.logger.info("Scheduling request for: " + request.operationId);
                }
                this.activeRequestCount++;
                this.host.setTimeout(request.operation, NodeTypingsInstaller.requestDelayMillis);
            };
            // This number is essentially arbitrary.  Processing more than one typings request
            // at a time makes sense, but having too many in the pipe results in a hang
            // (see https://github.com/nodejs/node/issues/7657).
            // It would be preferable to base our limit on the amount of space left in the
            // buffer, but we have yet to find a way to retrieve that value.
            NodeTypingsInstaller.maxActiveRequestCount = 10;
            NodeTypingsInstaller.requestDelayMillis = 100;
            return NodeTypingsInstaller;
        }());
        var IOSession = /** @class */ (function (_super) {
            __extends(IOSession, _super);
            function IOSession() {
                var _this = this;
                var event = function (body, eventName) {
                    if (_this.constructed) {
                        _this.event(body, eventName);
                    }
                    else {
                        // It is unsafe to dereference `this` before initialization completes,
                        // so we defer until the next tick.
                        //
                        // Construction should finish before the next tick fires, so we do not need to do this recursively.
                        setImmediate(function () { return _this.event(body, eventName); });
                    }
                };
                var host = sys;
                var typingsInstaller = disableAutomaticTypingAcquisition
                    ? undefined
                    : new NodeTypingsInstaller(telemetryEnabled, logger, host, getGlobalTypingsCacheLocation(), typingSafeListLocation, typesMapLocation, npmLocation, validateDefaultNpmLocation, event);
                _this = _super.call(this, {
                    host: host,
                    cancellationToken: cancellationToken,
                    useSingleInferredProject: useSingleInferredProject,
                    useInferredProjectPerProjectRoot: useInferredProjectPerProjectRoot,
                    typingsInstaller: typingsInstaller || server.nullTypingsInstaller,
                    byteLength: Buffer.byteLength,
                    hrtime: process.hrtime,
                    logger: logger,
                    canUseEvents: true,
                    suppressDiagnosticEvents: suppressDiagnosticEvents,
                    syntaxOnly: syntaxOnly,
                    noGetErrOnBackgroundUpdate: noGetErrOnBackgroundUpdate,
                    globalPlugins: globalPlugins,
                    pluginProbeLocations: pluginProbeLocations,
                    allowLocalPluginLoads: allowLocalPluginLoads,
                    typesMapLocation: typesMapLocation,
                }) || this;
                _this.eventPort = eventPort;
                if (_this.canUseEvents && _this.eventPort) {
                    var s_1 = net.connect({ port: _this.eventPort }, function () {
                        _this.eventSocket = s_1;
                        if (_this.socketEventQueue) {
                            // flush queue.
                            for (var _i = 0, _a = _this.socketEventQueue; _i < _a.length; _i++) {
                                var event_1 = _a[_i];
                                _this.writeToEventSocket(event_1.body, event_1.eventName);
                            }
                            _this.socketEventQueue = undefined;
                        }
                    });
                }
                _this.constructed = true;
                return _this;
            }
            IOSession.prototype.event = function (body, eventName) {
                ts.Debug.assert(!!this.constructed, "Should only call `IOSession.prototype.event` on an initialized IOSession");
                if (this.canUseEvents && this.eventPort) {
                    if (!this.eventSocket) {
                        if (this.logger.hasLevel(server.LogLevel.verbose)) {
                            this.logger.info("eventPort: event \"" + eventName + "\" queued, but socket not yet initialized");
                        }
                        (this.socketEventQueue || (this.socketEventQueue = [])).push({ body: body, eventName: eventName });
                        return;
                    }
                    else {
                        ts.Debug.assert(this.socketEventQueue === undefined);
                        this.writeToEventSocket(body, eventName);
                    }
                }
                else {
                    _super.prototype.event.call(this, body, eventName);
                }
            };
            IOSession.prototype.writeToEventSocket = function (body, eventName) {
                this.eventSocket.write(server.formatMessage(server.toEvent(eventName, body), this.logger, this.byteLength, this.host.newLine), "utf8");
            };
            IOSession.prototype.exit = function () {
                this.logger.info("Exiting...");
                this.projectService.closeLog();
                process.exit(0);
            };
            IOSession.prototype.listen = function () {
                var _this = this;
                rl.on("line", function (input) {
                    var message = input.trim();
                    _this.onMessage(message);
                });
                rl.on("close", function () {
                    _this.exit();
                });
            };
            return IOSession;
        }(server.Session));
        function parseLoggingEnvironmentString(logEnvStr) {
            if (!logEnvStr) {
                return {};
            }
            var logEnv = { logToFile: true };
            var args = logEnvStr.split(" ");
            var len = args.length - 1;
            for (var i = 0; i < len; i += 2) {
                var option = args[i];
                var _a = getEntireValue(i + 1), value = _a.value, extraPartCounter = _a.extraPartCounter;
                i += extraPartCounter;
                if (option && value) {
                    switch (option) {
                        case "-file":
                            logEnv.file = value;
                            break;
                        case "-level":
                            var level = getLogLevel(value);
                            logEnv.detailLevel = level !== undefined ? level : server.LogLevel.normal;
                            break;
                        case "-traceToConsole":
                            logEnv.traceToConsole = value.toLowerCase() === "true";
                            break;
                        case "-logToFile":
                            logEnv.logToFile = value.toLowerCase() === "true";
                            break;
                    }
                }
            }
            return logEnv;
            function getEntireValue(initialIndex) {
                var pathStart = args[initialIndex];
                var extraPartCounter = 0;
                if (pathStart.charCodeAt(0) === 34 /* doubleQuote */ &&
                    pathStart.charCodeAt(pathStart.length - 1) !== 34 /* doubleQuote */) {
                    for (var i = initialIndex + 1; i < args.length; i++) {
                        pathStart += " ";
                        pathStart += args[i];
                        extraPartCounter++;
                        if (pathStart.charCodeAt(pathStart.length - 1) === 34 /* doubleQuote */)
                            break;
                    }
                }
                return { value: ts.stripQuotes(pathStart), extraPartCounter: extraPartCounter };
            }
        }
        function getLogLevel(level) {
            if (level) {
                var l = level.toLowerCase();
                for (var name in server.LogLevel) {
                    if (isNaN(+name) && l === name.toLowerCase()) {
                        return server.LogLevel[name];
                    }
                }
            }
            return undefined;
        }
        // TSS_LOG "{ level: "normal | verbose | terse", file?: string}"
        function createLogger() {
            var cmdLineLogFileName = server.findArgument("--logFile");
            var cmdLineVerbosity = getLogLevel(server.findArgument("--logVerbosity"));
            var envLogOptions = parseLoggingEnvironmentString(process.env.TSS_LOG);
            var unsubstitutedLogFileName = cmdLineLogFileName
                ? ts.stripQuotes(cmdLineLogFileName)
                : envLogOptions.logToFile
                    ? envLogOptions.file || (__dirname + "/.log" + process.pid.toString())
                    : undefined;
            var substitutedLogFileName = unsubstitutedLogFileName
                ? unsubstitutedLogFileName.replace("PID", process.pid.toString())
                : undefined;
            var logVerbosity = cmdLineVerbosity || envLogOptions.detailLevel;
            return new Logger(substitutedLogFileName, envLogOptions.traceToConsole, logVerbosity); // TODO: GH#18217
        }
        // This places log file in the directory containing editorServices.js
        // TODO: check that this location is writable
        // average async stat takes about 30 microseconds
        // set chunk size to do 30 files in < 1 millisecond
        function createPollingWatchedFileSet(interval, chunkSize) {
            if (interval === void 0) { interval = 2500; }
            if (chunkSize === void 0) { chunkSize = 30; }
            var watchedFiles = [];
            var nextFileToCheck = 0;
            return { getModifiedTime: getModifiedTime, poll: poll, startWatchTimer: startWatchTimer, addFile: addFile, removeFile: removeFile };
            function getModifiedTime(fileName) {
                return fs.statSync(fileName).mtime;
            }
            function poll(checkedIndex) {
                var watchedFile = watchedFiles[checkedIndex];
                if (!watchedFile) {
                    return;
                }
                fs.stat(watchedFile.fileName, function (err, stats) {
                    if (err) {
                        if (err.code === "ENOENT") {
                            if (watchedFile.mtime.getTime() !== 0) {
                                watchedFile.mtime = ts.missingFileModifiedTime;
                                watchedFile.callback(watchedFile.fileName, ts.FileWatcherEventKind.Deleted);
                            }
                        }
                        else {
                            watchedFile.callback(watchedFile.fileName, ts.FileWatcherEventKind.Changed);
                        }
                    }
                    else {
                        ts.onWatchedFileStat(watchedFile, stats.mtime);
                    }
                });
            }
            // this implementation uses polling and
            // stat due to inconsistencies of fs.watch
            // and efficiency of stat on modern filesystems
            function startWatchTimer() {
                // tslint:disable-next-line:ban
                setInterval(function () {
                    var count = 0;
                    var nextToCheck = nextFileToCheck;
                    var firstCheck = -1;
                    while ((count < chunkSize) && (nextToCheck !== firstCheck)) {
                        poll(nextToCheck);
                        if (firstCheck < 0) {
                            firstCheck = nextToCheck;
                        }
                        nextToCheck++;
                        if (nextToCheck === watchedFiles.length) {
                            nextToCheck = 0;
                        }
                        count++;
                    }
                    nextFileToCheck = nextToCheck;
                }, interval);
            }
            function addFile(fileName, callback) {
                var file = {
                    fileName: fileName,
                    callback: callback,
                    mtime: sys.fileExists(fileName)
                        ? getModifiedTime(fileName)
                        : ts.missingFileModifiedTime // Any subsequent modification will occur after this time
                };
                watchedFiles.push(file);
                if (watchedFiles.length === 1) {
                    startWatchTimer();
                }
                return file;
            }
            function removeFile(file) {
                ts.unorderedRemoveItem(watchedFiles, file);
            }
        }
        // REVIEW: for now this implementation uses polling.
        // The advantage of polling is that it works reliably
        // on all os and with network mounted files.
        // For 90 referenced files, the average time to detect
        // changes is 2*msInterval (by default 5 seconds).
        // The overhead of this is .04 percent (1/2500) with
        // average pause of < 1 millisecond (and max
        // pause less than 1.5 milliseconds); question is
        // do we anticipate reference sets in the 100s and
        // do we care about waiting 10-20 seconds to detect
        // changes for large reference sets? If so, do we want
        // to increase the chunk size or decrease the interval
        // time dynamically to match the large reference set?
        var pollingWatchedFileSet = createPollingWatchedFileSet();
        var pending = [];
        var canWrite = true;
        function writeMessage(buf) {
            if (!canWrite) {
                pending.push(buf);
            }
            else {
                canWrite = false;
                process.stdout.write(buf, setCanWriteFlagAndWriteMessageIfNecessary);
            }
        }
        function setCanWriteFlagAndWriteMessageIfNecessary() {
            canWrite = true;
            if (pending.length) {
                writeMessage(pending.shift());
            }
        }
        function extractWatchDirectoryCacheKey(path, currentDriveKey) {
            path = ts.normalizeSlashes(path);
            if (isUNCPath(path)) {
                // UNC path: extract server name
                // //server/location
                //         ^ <- from 0 to this position
                var firstSlash = path.indexOf(ts.directorySeparator, 2);
                return firstSlash !== -1 ? path.substring(0, firstSlash).toLowerCase() : path;
            }
            var rootLength = ts.getRootLength(path);
            if (rootLength === 0) {
                // relative path - assume file is on the current drive
                return currentDriveKey;
            }
            if (path.charCodeAt(1) === 58 /* colon */ && path.charCodeAt(2) === 47 /* slash */) {
                // rooted path that starts with c:/... - extract drive letter
                return path.charAt(0).toLowerCase();
            }
            if (path.charCodeAt(0) === 47 /* slash */ && path.charCodeAt(1) !== 47 /* slash */) {
                // rooted path that starts with slash - /somename - use key for current drive
                return currentDriveKey;
            }
            // do not cache any other cases
            return undefined;
        }
        function isUNCPath(s) {
            return s.length > 2 && s.charCodeAt(0) === 47 /* slash */ && s.charCodeAt(1) === 47 /* slash */;
        }
        var logger = createLogger();
        var sys = ts.sys;
        var nodeVersion = ts.getNodeMajorVersion();
        // use watchGuard process on Windows when node version is 4 or later
        var useWatchGuard = process.platform === "win32" && nodeVersion >= 4;
        var originalWatchDirectory = sys.watchDirectory.bind(sys);
        var noopWatcher = { close: ts.noop };
        // This is the function that catches the exceptions when watching directory, and yet lets project service continue to function
        // 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 watchDirectorySwallowingException(path, callback, recursive) {
            try {
                return originalWatchDirectory(path, callback, recursive);
            }
            catch (e) {
                logger.info("Exception when creating directory watcher: " + e.message);
                return noopWatcher;
            }
        }
        if (useWatchGuard) {
            var currentDrive_1 = extractWatchDirectoryCacheKey(sys.resolvePath(sys.getCurrentDirectory()), /*currentDriveKey*/ undefined);
            var statusCache_1 = ts.createMap();
            sys.watchDirectory = function (path, callback, recursive) {
                var cacheKey = extractWatchDirectoryCacheKey(path, currentDrive_1);
                var status = cacheKey && statusCache_1.get(cacheKey);
                if (status === undefined) {
                    if (logger.hasLevel(server.LogLevel.verbose)) {
                        logger.info(cacheKey + " for path " + path + " not found in cache...");
                    }
                    try {
                        var args = [ts.combinePaths(__dirname, "watchGuard.js"), path];
                        if (logger.hasLevel(server.LogLevel.verbose)) {
                            logger.info("Starting " + process.execPath + " with args:" + server.stringifyIndented(args));
                        }
                        childProcess.execFileSync(process.execPath, args, { stdio: "ignore", env: { ELECTRON_RUN_AS_NODE: "1" } });
                        status = true;
                        if (logger.hasLevel(server.LogLevel.verbose)) {
                            logger.info("WatchGuard for path " + path + " returned: OK");
                        }
                    }
                    catch (e) {
                        status = false;
                        if (logger.hasLevel(server.LogLevel.verbose)) {
                            logger.info("WatchGuard for path " + path + " returned: " + e.message);
                        }
                    }
                    if (cacheKey) {
                        statusCache_1.set(cacheKey, status);
                    }
                }
                else if (logger.hasLevel(server.LogLevel.verbose)) {
                    logger.info("watchDirectory for " + path + " uses cached drive information.");
                }
                if (status) {
                    // this drive is safe to use - call real 'watchDirectory'
                    return watchDirectorySwallowingException(path, callback, recursive);
                }
                else {
                    // this drive is unsafe - return no-op watcher
                    return noopWatcher;
                }
            };
        }
        else {
            sys.watchDirectory = watchDirectorySwallowingException;
        }
        // Override sys.write because fs.writeSync is not reliable on Node 4
        sys.write = function (s) { return writeMessage(sys.bufferFrom(s, "utf8")); };
        sys.watchFile = function (fileName, callback) {
            var watchedFile = pollingWatchedFileSet.addFile(fileName, callback);
            return {
                close: function () { return pollingWatchedFileSet.removeFile(watchedFile); }
            };
        };
        sys.setTimeout = setTimeout;
        sys.clearTimeout = clearTimeout;
        sys.setImmediate = setImmediate;
        sys.clearImmediate = clearImmediate;
        if (typeof global !== "undefined" && global.gc) {
            sys.gc = function () { return global.gc(); };
        }
        sys.require = function (initialDir, moduleName) {
            try {
                return { module: require(ts.resolveJSModule(moduleName, initialDir, sys)), error: undefined };
            }
            catch (error) {
                return { module: undefined, error: error };
            }
        };
        var cancellationToken;
        try {
            var factory = require("./cancellationToken");
            cancellationToken = factory(sys.args);
        }
        catch (e) {
            cancellationToken = server.nullCancellationToken;
        }
        var eventPort;
        {
            var str = server.findArgument("--eventPort");
            var v = str === undefined ? undefined : parseInt(str);
            if (v !== undefined && !isNaN(v)) {
                eventPort = v;
            }
        }
        var localeStr = server.findArgument("--locale");
        if (localeStr) {
            ts.validateLocaleAndSetLanguage(localeStr, sys);
        }
        ts.setStackTraceLimit();
        var typingSafeListLocation = server.findArgument(server.Arguments.TypingSafeListLocation); // TODO: GH#18217
        var typesMapLocation = server.findArgument(server.Arguments.TypesMapLocation) || ts.combinePaths(ts.getDirectoryPath(sys.getExecutingFilePath()), "typesMap.json");
        var npmLocation = server.findArgument(server.Arguments.NpmLocation);
        var validateDefaultNpmLocation = server.hasArgument(server.Arguments.ValidateDefaultNpmLocation);
        function parseStringArray(argName) {
            var arg = server.findArgument(argName);
            if (arg === undefined) {
                return server.emptyArray;
            }
            return arg.split(",").filter(function (name) { return name !== ""; });
        }
        var globalPlugins = parseStringArray("--globalPlugins");
        var pluginProbeLocations = parseStringArray("--pluginProbeLocations");
        var allowLocalPluginLoads = server.hasArgument("--allowLocalPluginLoads");
        var useSingleInferredProject = server.hasArgument("--useSingleInferredProject");
        var useInferredProjectPerProjectRoot = server.hasArgument("--useInferredProjectPerProjectRoot");
        var disableAutomaticTypingAcquisition = server.hasArgument("--disableAutomaticTypingAcquisition");
        var suppressDiagnosticEvents = server.hasArgument("--suppressDiagnosticEvents");
        var syntaxOnly = server.hasArgument("--syntaxOnly");
        var telemetryEnabled = server.hasArgument(server.Arguments.EnableTelemetry);
        var noGetErrOnBackgroundUpdate = server.hasArgument("--noGetErrOnBackgroundUpdate");
        logger.info("Starting TS Server");
        logger.info("Version: " + ts.version);
        logger.info("Arguments: " + process.argv.join(" "));
        logger.info("Platform: " + os.platform() + " NodeVersion: " + nodeVersion + " CaseSensitive: " + sys.useCaseSensitiveFileNames);
        var ioSession = new IOSession();
        process.on("uncaughtException", function (err) {
            ioSession.logError(err, "unknown");
        });
        // See https://github.com/Microsoft/TypeScript/issues/11348
        // tslint:disable-next-line no-unnecessary-type-assertion-2
        process.noAsar = true;
        // Start listening
        ioSession.listen();
        if (ts.Debug.isDebugging) {
            ts.Debug.enableDebugInfo();
        }
        if (ts.sys.tryEnableSourceMapsForHost && /^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV"))) {
            ts.sys.tryEnableSourceMapsForHost();
        }
    })(server = ts.server || (ts.server = {}));
})(ts || (ts = {}));
//# sourceMappingURL=tsserver.js.map