[Pkg-javascript-commits] [node-typescript] 09/13: New upstream version 2.5.2

Julien Puydt julien.puydt at laposte.net
Wed Sep 6 15:55:51 UTC 2017


This is an automated email from the git hooks/post-receive script.

jpuydt-guest pushed a commit to branch master
in repository node-typescript.

commit 6ac08db9b09cb88b634848507e90d931d13f9bec
Author: Julien Puydt <julien.puydt at laposte.net>
Date:   Fri Sep 1 08:58:44 2017 +0200

    New upstream version 2.5.2
---
 .travis.yml                                        |   1 +
 lib/protocol.d.ts                                  |  81 +++++-
 lib/tsc.js                                         | 233 ++++++++-------
 lib/tsserver.js                                    | 283 +++++++++---------
 lib/tsserverlibrary.d.ts                           |   6 +
 lib/tsserverlibrary.js                             | 283 +++++++++---------
 lib/typescript.d.ts                                |   2 +
 lib/typescript.js                                  | 322 ++++++++++++---------
 lib/typescriptServices.d.ts                        |   2 +
 lib/typescriptServices.js                          | 322 ++++++++++++---------
 lib/typingsInstaller.js                            |  17 +-
 package.json                                       |   2 +-
 scripts/buildProtocol.ts                           |  14 +-
 src/compiler/checker.ts                            |  55 +++-
 src/compiler/core.ts                               |   2 +-
 src/compiler/diagnosticMessages.json               |   2 +-
 src/compiler/factory.ts                            |  43 ++-
 src/compiler/transformers/es2015.ts                |  59 +---
 src/compiler/transformers/esnext.ts                |   6 +-
 src/compiler/transformers/generators.ts            |  76 ++---
 src/compiler/transformers/module/module.ts         |  48 +--
 src/compiler/transformers/ts.ts                    |   7 +-
 src/compiler/transformers/utilities.ts             |   2 +-
 src/compiler/types.ts                              |   1 +
 src/compiler/utilities.ts                          |   6 +-
 src/harness/fourslash.ts                           |  47 ++-
 src/harness/tsconfig.json                          |   1 +
 src/harness/unittests/customTransforms.ts          |  23 +-
 src/harness/unittests/tsserverProjectSystem.ts     |  28 +-
 src/server/editorServices.ts                       |   2 +-
 src/server/protocol.ts                             |   4 +
 .../typingsInstaller/nodeTypingsInstaller.ts       |   4 +-
 src/server/typingsInstaller/typingsInstaller.ts    |   2 +-
 src/services/documentRegistry.ts                   |  20 +-
 src/services/refactors/extractMethod.ts            |  44 +--
 tests/baselines/reference/asyncArrowInClassES5.js  |  21 ++
 .../reference/asyncArrowInClassES5.symbols         |  12 +
 .../baselines/reference/asyncArrowInClassES5.types |  13 +
 .../reference/circularContextualReturnType.js      |  18 ++
 .../reference/circularContextualReturnType.symbols |  19 ++
 .../reference/circularContextualReturnType.types   |  23 ++
 .../reference/constructorFunctions2.symbols        |  41 +++
 .../reference/constructorFunctions2.types          |  55 ++++
 .../before+decorators.js}                          |  54 ++--
 .../reference/decoratorOnClassMethod11.js          |   1 +
 .../reference/decoratorOnClassMethod12.js          |   1 +
 .../exportAssignmentOfGenericType1.errors.txt      |  17 --
 .../reference/exportClassWithoutName.errors.txt    |   8 +
 .../baselines/reference/exportClassWithoutName.js  |  10 +
 tests/baselines/reference/exportImport.errors.txt  |  21 --
 .../reference/extractMethod/extractMethod1.js      |   8 +-
 .../reference/extractMethod/extractMethod10.js     |   6 +-
 .../reference/extractMethod/extractMethod11.js     |   6 +-
 .../reference/extractMethod/extractMethod12.js     |   2 +-
 .../reference/extractMethod/extractMethod2.js      |   8 +-
 .../reference/extractMethod/extractMethod3.js      |   8 +-
 .../reference/extractMethod/extractMethod4.js      |   8 +-
 .../reference/extractMethod/extractMethod5.js      |   8 +-
 .../reference/extractMethod/extractMethod6.js      |   8 +-
 .../reference/extractMethod/extractMethod7.js      |   8 +-
 .../reference/extractMethod/extractMethod8.js      |   8 +-
 .../reference/extractMethod/extractMethod9.js      |   8 +-
 .../importCallExpressionInExportEqualsAMD.js       |  22 ++
 .../importCallExpressionInExportEqualsAMD.symbols  |  10 +
 .../importCallExpressionInExportEqualsAMD.types    |  14 +
 .../importCallExpressionInExportEqualsCJS.js       |  18 ++
 .../importCallExpressionInExportEqualsCJS.symbols  |  10 +
 .../importCallExpressionInExportEqualsCJS.types    |  14 +
 .../importCallExpressionInExportEqualsUMD.js       |  39 +++
 .../importCallExpressionInExportEqualsUMD.symbols  |  10 +
 .../importCallExpressionInExportEqualsUMD.types    |  14 +
 .../inferringClassMembersFromAssignments.js        |   1 +
 .../invalidContinueInDownlevelAsync.errors.txt     |  17 ++
 .../reference/invalidContinueInDownlevelAsync.js   |  63 ++++
 .../reference/noCrashOnImportShadowing.errors.txt  |  33 +++
 .../reference/noCrashOnImportShadowing.js          |  46 +++
 ...jectSpreadWithinMethodWithinObjectWithSpread.js |  26 ++
 ...preadWithinMethodWithinObjectWithSpread.symbols |  24 ++
 ...tSpreadWithinMethodWithinObjectWithSpread.types |  29 ++
 ...ModuleExportAssignmentOfGenericClass.errors.txt |  20 --
 tests/baselines/reference/superAccess2.js          |   1 +
 .../thisInArrowFunctionInStaticInitializer1.js     |   1 +
 .../reference/thisInConstructorParameter2.js       |   1 +
 tests/baselines/reference/thisInInvalidContexts.js |   1 +
 .../thisInInvalidContextsExternalModule.js         |   1 +
 tests/baselines/reference/thisInOuterClassBody.js  |   1 +
 .../reference/typeOfThisInStaticMembers2.js        |   1 +
 tests/cases/compiler/asyncArrowInClassES5.ts       |   9 +
 .../cases/compiler/circularContextualReturnType.ts |   9 +
 tests/cases/compiler/exportClassWithoutName.ts     |   4 +
 .../compiler/invalidContinueInDownlevelAsync.ts    |   8 +
 tests/cases/compiler/noCrashOnImportShadowing.ts   |  25 ++
 ...jectSpreadWithinMethodWithinObjectWithSpread.ts |  10 +
 .../importCallExpressionInExportEqualsAMD.ts       |   9 +
 .../importCallExpressionInExportEqualsCJS.ts       |   9 +
 .../importCallExpressionInExportEqualsUMD.ts       |   9 +
 .../conformance/salsa/constructorFunctions2.ts     |  18 ++
 .../fourslash/extract-method-not-for-import.ts     |  10 +
 tests/cases/fourslash/extract-method1.ts           |   7 +-
 tests/cases/fourslash/extract-method10.ts          |   9 +-
 tests/cases/fourslash/extract-method13.ts          |  12 +-
 tests/cases/fourslash/extract-method14.ts          |   6 +-
 tests/cases/fourslash/extract-method15.ts          |   6 +-
 tests/cases/fourslash/extract-method18.ts          |   7 +-
 tests/cases/fourslash/extract-method19.ts          |   9 +-
 tests/cases/fourslash/extract-method2.ts           |   7 +-
 tests/cases/fourslash/extract-method21.ts          |   6 +-
 tests/cases/fourslash/extract-method24.ts          |   6 +-
 tests/cases/fourslash/extract-method25.ts          |   6 +-
 tests/cases/fourslash/extract-method3.ts           |   2 +-
 tests/cases/fourslash/extract-method5.ts           |   6 +-
 tests/cases/fourslash/extract-method7.ts           |   6 +-
 tests/cases/fourslash/fourslash.ts                 |   4 +-
 113 files changed, 2076 insertions(+), 1010 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 4a99aaf..27b1473 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,6 +16,7 @@ matrix:
 branches:
   only:
   - master
+  - release-2.5
 
 install:
   - npm uninstall typescript --no-save
diff --git a/lib/protocol.d.ts b/lib/protocol.d.ts
index 2f76e5f..e260845 100644
--- a/lib/protocol.d.ts
+++ b/lib/protocol.d.ts
@@ -1963,6 +1963,7 @@ declare namespace ts.server.protocol {
         System = "System",
         ES6 = "ES6",
         ES2015 = "ES2015",
+        ESNext = "ESNext",
     }
     const enum ModuleResolutionKind {
         Classic = "Classic",
@@ -1977,6 +1978,9 @@ declare namespace ts.server.protocol {
         ES5 = "ES5",
         ES6 = "ES6",
         ES2015 = "ES2015",
+        ES2016 = "ES2016",
+        ES2017 = "ES2017",
+        ESNext = "ESNext",
     }
 }
 declare namespace ts.server.protocol {
@@ -1998,6 +2002,81 @@ declare namespace ts.server.protocol {
         position: number;
     }
 
+    enum HighlightSpanKind {
+        none = "none",
+        definition = "definition",
+        reference = "reference",
+        writtenReference = "writtenReference",
+    }
+
+    enum ScriptElementKind {
+        unknown = "",
+        warning = "warning",
+        /** predefined type (void) or keyword (class) */
+        keyword = "keyword",
+        /** top level script node */
+        scriptElement = "script",
+        /** module foo {} */
+        moduleElement = "module",
+        /** class X {} */
+        classElement = "class",
+        /** var x = class X {} */
+        localClassElement = "local class",
+        /** interface Y {} */
+        interfaceElement = "interface",
+        /** type T = ... */
+        typeElement = "type",
+        /** enum E */
+        enumElement = "enum",
+        enumMemberElement = "enum member",
+        /**
+         * Inside module and script only
+         * const v = ..
+         */
+        variableElement = "var",
+        /** Inside function */
+        localVariableElement = "local var",
+        /**
+         * Inside module and script only
+         * function f() { }
+         */
+        functionElement = "function",
+        /** Inside function */
+        localFunctionElement = "local function",
+        /** class X { [public|private]* foo() {} } */
+        memberFunctionElement = "method",
+        /** class X { [public|private]* [get|set] foo:number; } */
+        memberGetAccessorElement = "getter",
+        memberSetAccessorElement = "setter",
+        /**
+         * class X { [public|private]* foo:number; }
+         * interface Y { foo:number; }
+         */
+        memberVariableElement = "property",
+        /** class X { constructor() { } } */
+        constructorImplementationElement = "constructor",
+        /** interface Y { ():number; } */
+        callSignatureElement = "call",
+        /** interface Y { []:number; } */
+        indexSignatureElement = "index",
+        /** interface Y { new():Y; } */
+        constructSignatureElement = "construct",
+        /** function foo(*Y*: string) */
+        parameterElement = "parameter",
+        typeParameterElement = "type parameter",
+        primitiveType = "primitive type",
+        label = "label",
+        alias = "alias",
+        constElement = "const",
+        letElement = "let",
+        directory = "directory",
+        externalModuleName = "external module name",
+        /**
+         * <JsxTagName attribute1 attribute2={0} />
+         */
+        jsxAttribute = "JSX attribute",
+    }
+
     interface TypeAcquisition {
         enableAutoDiscovery?: boolean;
         enable?: boolean;
@@ -2033,8 +2112,6 @@ declare namespace ts.server.protocol {
 }
 declare namespace ts {
     // these types are empty stubs for types from services and should not be used directly
-    export type HighlightSpanKind = never;
-    export type ScriptElementKind = never;
     export type ScriptKind = never;
     export type IndentStyle = never;
     export type JsxEmit = never;
diff --git a/lib/tsc.js b/lib/tsc.js
index 76af89c..f5d3a50 100644
--- a/lib/tsc.js
+++ b/lib/tsc.js
@@ -152,7 +152,7 @@ var ts;
 var ts;
 (function (ts) {
     ts.versionMajorMinor = "2.5";
-    ts.version = ts.versionMajorMinor + ".1";
+    ts.version = ts.versionMajorMinor + ".2";
 })(ts || (ts = {}));
 (function (ts) {
     ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined;
@@ -3521,7 +3521,7 @@ var ts;
         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_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"),
-        Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"),
+        Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into {0}"),
     };
 })(ts || (ts = {}));
 var ts;
@@ -6876,9 +6876,9 @@ var ts;
             || kind === 265;
     }
     ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment;
-    function nodeIsSynthesized(node) {
-        return ts.positionIsSynthesized(node.pos)
-            || ts.positionIsSynthesized(node.end);
+    function nodeIsSynthesized(range) {
+        return ts.positionIsSynthesized(range.pos)
+            || ts.positionIsSynthesized(range.end);
     }
     ts.nodeIsSynthesized = nodeIsSynthesized;
     function getOriginalSourceFile(sourceFile) {
@@ -18801,7 +18801,10 @@ var ts;
                 }
                 return true;
             }
-            if (usage.parent.kind === 246) {
+            if (usage.parent.kind === 246 || (usage.parent.kind === 243 && usage.parent.isExportEquals)) {
+                return true;
+            }
+            if (usage.kind === 243 && usage.isExportEquals) {
                 return true;
             }
             var container = ts.getEnclosingBlockScopeContainer(declaration);
@@ -23469,6 +23472,9 @@ var ts;
             }
             return signature.resolvedReturnType;
         }
+        function isResolvingReturnTypeOfSignature(signature) {
+            return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3) >= 0;
+        }
         function getRestTypeOfSignature(signature) {
             if (signature.hasRestParameter) {
                 var type = getTypeOfSymbol(ts.lastOrUndefined(signature.parameters));
@@ -28576,7 +28582,7 @@ var ts;
                 return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl));
             }
             var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl);
-            if (signature) {
+            if (signature && !isResolvingReturnTypeOfSignature(signature)) {
                 return getReturnTypeOfSignature(signature);
             }
             return undefined;
@@ -30866,7 +30872,7 @@ var ts;
             return result;
         }
         function isJavaScriptConstructor(node) {
-            if (ts.isInJavaScriptFile(node)) {
+            if (node && ts.isInJavaScriptFile(node)) {
                 if (ts.getJSDocClassTag(node))
                     return true;
                 var symbol = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) ? getSymbolOfNode(node) :
@@ -30876,6 +30882,20 @@ var ts;
             }
             return false;
         }
+        function getJavaScriptClassType(symbol) {
+            if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) {
+                symbol = getSymbolOfNode(symbol.valueDeclaration.initializer);
+            }
+            if (isJavaScriptConstructor(symbol.valueDeclaration)) {
+                return getInferredClassType(symbol);
+            }
+            if (symbol.flags & 3) {
+                var valueType = getTypeOfSymbol(symbol);
+                if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) {
+                    return getInferredClassType(valueType.symbol);
+                }
+            }
+        }
         function getInferredClassType(symbol) {
             var links = getSymbolLinks(symbol);
             if (!links.inferredClassType) {
@@ -30904,13 +30924,11 @@ var ts;
                     var funcSymbol = node.expression.kind === 71 ?
                         getResolvedSymbol(node.expression) :
                         checkExpression(node.expression).symbol;
-                    if (funcSymbol && ts.isDeclarationOfFunctionOrClassExpression(funcSymbol)) {
-                        funcSymbol = getSymbolOfNode(funcSymbol.valueDeclaration.initializer);
-                    }
-                    if (funcSymbol && funcSymbol.flags & 16 && (funcSymbol.members || ts.getJSDocClassTag(funcSymbol.valueDeclaration))) {
-                        return getInferredClassType(funcSymbol);
+                    var type = funcSymbol && getJavaScriptClassType(funcSymbol);
+                    if (type) {
+                        return type;
                     }
-                    else if (noImplicitAny) {
+                    if (noImplicitAny) {
                         error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
                     }
                     return anyType;
@@ -33057,6 +33075,7 @@ var ts;
                             : 4;
                     case 229:
                     case 232:
+                    case 240:
                         return 2 | 1;
                     case 237:
                         var result_3 = 0;
@@ -36229,6 +36248,14 @@ var ts;
             return type.flags & 32768 && getSignaturesOfType(type, 0).length > 0;
         }
         function getTypeReferenceSerializationKind(typeName, location) {
+            typeName = ts.getParseTreeNode(typeName, ts.isEntityName);
+            if (!typeName)
+                return ts.TypeReferenceSerializationKind.Unknown;
+            if (location) {
+                location = ts.getParseTreeNode(location);
+                if (!location)
+                    return ts.TypeReferenceSerializationKind.Unknown;
+            }
             var valueSymbol = resolveEntityName(typeName, 107455, true, false, location);
             var typeSymbol = resolveEntityName(typeName, 793064, true, false, location);
             if (valueSymbol && valueSymbol === typeSymbol) {
@@ -39686,6 +39713,10 @@ var ts;
         return createCall(createFunctionExpression(undefined, undefined, undefined, undefined, param ? [param] : [], undefined, createBlock(statements, true)), undefined, paramValue ? [paramValue] : []);
     }
     ts.createImmediatelyInvokedFunctionExpression = createImmediatelyInvokedFunctionExpression;
+    function createImmediatelyInvokedArrowFunction(statements, param, paramValue) {
+        return createCall(createArrowFunction(undefined, undefined, param ? [param] : [], undefined, undefined, createBlock(statements, true)), undefined, paramValue ? [paramValue] : []);
+    }
+    ts.createImmediatelyInvokedArrowFunction = createImmediatelyInvokedArrowFunction;
     function createComma(left, right) {
         return createBinary(left, 26, right);
     }
@@ -40769,9 +40800,17 @@ var ts;
             case 288: return ts.updatePartiallyEmittedExpression(outerExpression, expression);
         }
     }
+    function isIgnorableParen(node) {
+        return node.kind === 185
+            && 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; }
-        if (outerExpression && isOuterExpression(outerExpression, kinds)) {
+        if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) {
             return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression));
         }
         return innerExpression;
@@ -41997,7 +42036,7 @@ var ts;
                         }
                         else {
                             var name = node.name;
-                            if (!uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) {
+                            if (name && !uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) {
                                 multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
                                 uniqueExports.set(ts.unescapeLeadingUnderscores(name.escapedText), true);
                                 exportedNames = ts.append(exportedNames, name);
@@ -42670,8 +42709,10 @@ var ts;
                 ts.setEmitFlags(statement, 1536 | 384);
                 statements.push(statement);
                 ts.addRange(statements, context.endLexicalEnvironment());
+                var iife = ts.createImmediatelyInvokedArrowFunction(statements);
+                ts.setEmitFlags(iife, 33554432);
                 var varStatement = ts.createVariableStatement(undefined, ts.createVariableDeclarationList([
-                    ts.createVariableDeclaration(ts.getLocalName(node, false, false), undefined, ts.createImmediatelyInvokedFunctionExpression(statements))
+                    ts.createVariableDeclaration(ts.getLocalName(node, false, false), undefined, iife)
                 ]));
                 ts.setOriginalNode(varStatement, node);
                 ts.setCommentRange(varStatement, node);
@@ -43277,7 +43318,7 @@ var ts;
                     var name = ts.getMutableClone(node);
                     name.flags &= ~8;
                     name.original = undefined;
-                    name.parent = currentScope;
+                    name.parent = ts.getParseTreeNode(currentScope);
                     if (useFallback) {
                         return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(name), ts.createLiteral("undefined")), name);
                     }
@@ -44361,7 +44402,7 @@ var ts;
                         chunkObject.push(ts.createPropertyAssignment(p.name, ts.visitNode(p.initializer, visitor, ts.isExpression)));
                     }
                     else {
-                        chunkObject.push(e);
+                        chunkObject.push(ts.visitNode(e, visitor, ts.isObjectLiteralElementLike));
                     }
                 }
             }
@@ -45307,58 +45348,12 @@ var ts;
                 && node.kind === 219
                 && !node.expression;
         }
-        function isClassLikeVariableStatement(node) {
-            if (!ts.isVariableStatement(node))
-                return false;
-            var variable = ts.singleOrUndefined(node.declarationList.declarations);
-            return variable
-                && variable.initializer
-                && ts.isIdentifier(variable.name)
-                && (ts.isClassLike(variable.initializer)
-                    || (ts.isAssignmentExpression(variable.initializer)
-                        && ts.isIdentifier(variable.initializer.left)
-                        && ts.isClassLike(variable.initializer.right)));
-        }
-        function isTypeScriptClassWrapper(node) {
-            var call = ts.tryCast(node, ts.isCallExpression);
-            if (!call || ts.isParseTreeNode(call) ||
-                ts.some(call.typeArguments) ||
-                ts.some(call.arguments)) {
-                return false;
-            }
-            var func = ts.tryCast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression);
-            if (!func || ts.isParseTreeNode(func) ||
-                ts.some(func.typeParameters) ||
-                ts.some(func.parameters) ||
-                func.type ||
-                !func.body) {
-                return false;
-            }
-            var statements = func.body.statements;
-            if (statements.length < 2) {
-                return false;
-            }
-            var firstStatement = statements[0];
-            if (ts.isParseTreeNode(firstStatement) ||
-                !ts.isClassLike(firstStatement) &&
-                    !isClassLikeVariableStatement(firstStatement)) {
-                return false;
-            }
-            var lastStatement = ts.elementAt(statements, -1);
-            var returnStatement = ts.tryCast(ts.isVariableStatement(lastStatement) ? ts.elementAt(statements, -2) : lastStatement, ts.isReturnStatement);
-            if (!returnStatement ||
-                !returnStatement.expression ||
-                !ts.isIdentifier(ts.skipOuterExpressions(returnStatement.expression))) {
-                return false;
-            }
-            return true;
-        }
         function shouldVisitNode(node) {
             return (node.transformFlags & 128) !== 0
                 || convertedLoopState !== undefined
                 || (hierarchyFacts & 4096 && (ts.isStatement(node) || (node.kind === 207)))
                 || (ts.isIterationStatement(node, false) && shouldConvertIterationStatementBody(node))
-                || isTypeScriptClassWrapper(node);
+                || (ts.getEmitFlags(node) & 33554432) !== 0;
         }
         function visitor(node) {
             if (shouldVisitNode(node)) {
@@ -46838,7 +46833,7 @@ var ts;
             return ts.visitEachChild(node, visitor, context);
         }
         function visitCallExpression(node) {
-            if (isTypeScriptClassWrapper(node)) {
+            if (ts.getEmitFlags(node) & 33554432) {
                 return visitTypeScriptClassWrapper(node);
             }
             if (node.transformFlags & 64) {
@@ -46847,7 +46842,7 @@ var ts;
             return ts.updateCall(node, ts.visitNode(node.expression, callExpressionVisitor, ts.isExpression), undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
         }
         function visitTypeScriptClassWrapper(node) {
-            var body = ts.cast(ts.skipOuterExpressions(node.expression), ts.isFunctionExpression).body;
+            var body = ts.cast(ts.cast(ts.skipOuterExpressions(node.expression), ts.isArrowFunction).body, ts.isBlock);
             var classStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 0, 1);
             var remainingStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 1, body.statements.length - 1);
             var varStatement = ts.cast(ts.firstOrUndefined(classStatements), ts.isVariableStatement);
@@ -48042,8 +48037,12 @@ var ts;
         }
         function transformAndEmitContinueStatement(node) {
             var label = findContinueTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined);
-            ts.Debug.assert(label > 0, "Expected continue statment to point to a valid Label.");
-            emitBreak(label, node);
+            if (label > 0) {
+                emitBreak(label, node);
+            }
+            else {
+                emitStatement(node);
+            }
         }
         function visitContinueStatement(node) {
             if (inStatementContainingYield) {
@@ -48056,8 +48055,12 @@ var ts;
         }
         function transformAndEmitBreakStatement(node) {
             var label = findBreakTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined);
-            ts.Debug.assert(label > 0, "Expected break statment to point to a valid Label.");
-            emitBreak(label, node);
+            if (label > 0) {
+                emitBreak(label, node);
+            }
+            else {
+                emitStatement(node);
+            }
         }
         function visitBreakStatement(node) {
             if (inStatementContainingYield) {
@@ -48481,43 +48484,45 @@ var ts;
             return false;
         }
         function findBreakTarget(labelText) {
-            ts.Debug.assert(blocks !== undefined);
-            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;
+            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;
+                else {
+                    for (var i = blockStack.length - 1; i >= 0; i--) {
+                        var block = blockStack[i];
+                        if (supportsUnlabeledBreak(block)) {
+                            return block.breakLabel;
+                        }
                     }
                 }
             }
             return 0;
         }
         function findContinueTarget(labelText) {
-            ts.Debug.assert(blocks !== undefined);
-            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;
+            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;
+                else {
+                    for (var i = blockStack.length - 1; i >= 0; i--) {
+                        var block = blockStack[i];
+                        if (supportsUnlabeledContinue(block)) {
+                            return block.continueLabel;
+                        }
                     }
                 }
             }
@@ -49071,17 +49076,23 @@ var ts;
         }
         function addExportEqualsIfNeeded(statements, emitAsReturn) {
             if (currentModuleInfo.exportEquals) {
-                if (emitAsReturn) {
-                    var statement = ts.createReturn(currentModuleInfo.exportEquals.expression);
-                    ts.setTextRange(statement, currentModuleInfo.exportEquals);
-                    ts.setEmitFlags(statement, 384 | 1536);
-                    statements.push(statement);
-                }
-                else {
-                    var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), currentModuleInfo.exportEquals.expression));
-                    ts.setTextRange(statement, currentModuleInfo.exportEquals);
-                    ts.setEmitFlags(statement, 1536);
-                    statements.push(statement);
+                var expressionResult = importCallExpressionVisitor(currentModuleInfo.exportEquals.expression);
+                if (expressionResult) {
+                    if (expressionResult instanceof Array) {
+                        return ts.Debug.fail("export= expression should never be replaced with multiple expressions!");
+                    }
+                    if (emitAsReturn) {
+                        var statement = ts.createReturn(expressionResult);
+                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
+                        ts.setEmitFlags(statement, 384 | 1536);
+                        statements.push(statement);
+                    }
+                    else {
+                        var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult));
+                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
+                        ts.setEmitFlags(statement, 1536);
+                        statements.push(statement);
+                    }
                 }
             }
         }
@@ -49415,7 +49426,7 @@ var ts;
                 return statements;
             }
             if (ts.hasModifier(decl, 1)) {
-                var exportName = ts.hasModifier(decl, 512) ? ts.createIdentifier("default") : decl.name;
+                var exportName = ts.hasModifier(decl, 512) ? ts.createIdentifier("default") : ts.getDeclarationName(decl);
                 statements = appendExportStatement(statements, exportName, ts.getLocalName(decl), decl);
             }
             if (decl.name) {
diff --git a/lib/tsserver.js b/lib/tsserver.js
index b9bdd21..ddbefc7 100644
--- a/lib/tsserver.js
+++ b/lib/tsserver.js
@@ -1066,6 +1066,7 @@ var ts;
         EmitFlags[EmitFlags["HasEndOfDeclarationMarker"] = 4194304] = "HasEndOfDeclarationMarker";
         EmitFlags[EmitFlags["Iterator"] = 8388608] = "Iterator";
         EmitFlags[EmitFlags["NoAsciiEscaping"] = 16777216] = "NoAsciiEscaping";
+        EmitFlags[EmitFlags["TypeScriptClassWrapper"] = 33554432] = "TypeScriptClassWrapper";
     })(EmitFlags = ts.EmitFlags || (ts.EmitFlags = {}));
     var ExternalEmitHelpers;
     (function (ExternalEmitHelpers) {
@@ -1163,7 +1164,7 @@ var ts;
 var ts;
 (function (ts) {
     ts.versionMajorMinor = "2.5";
-    ts.version = ts.versionMajorMinor + ".1";
+    ts.version = ts.versionMajorMinor + ".2";
 })(ts || (ts = {}));
 (function (ts) {
     ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined;
@@ -4557,7 +4558,7 @@ var ts;
         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_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"),
-        Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"),
+        Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into {0}"),
     };
 })(ts || (ts = {}));
 var ts;
@@ -7133,9 +7134,9 @@ var ts;
             || kind === 265;
     }
     ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment;
-    function nodeIsSynthesized(node) {
-        return ts.positionIsSynthesized(node.pos)
-            || ts.positionIsSynthesized(node.end);
+    function nodeIsSynthesized(range) {
+        return ts.positionIsSynthesized(range.pos)
+            || ts.positionIsSynthesized(range.end);
     }
     ts.nodeIsSynthesized = nodeIsSynthesized;
     function getOriginalSourceFile(sourceFile) {
@@ -20010,7 +20011,10 @@ var ts;
                 }
                 return true;
             }
-            if (usage.parent.kind === 246) {
+            if (usage.parent.kind === 246 || (usage.parent.kind === 243 && usage.parent.isExportEquals)) {
+                return true;
+            }
+            if (usage.kind === 243 && usage.isExportEquals) {
                 return true;
             }
             var container = ts.getEnclosingBlockScopeContainer(declaration);
@@ -24678,6 +24682,9 @@ var ts;
             }
             return signature.resolvedReturnType;
         }
+        function isResolvingReturnTypeOfSignature(signature) {
+            return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3) >= 0;
+        }
         function getRestTypeOfSignature(signature) {
             if (signature.hasRestParameter) {
                 var type = getTypeOfSymbol(ts.lastOrUndefined(signature.parameters));
@@ -29785,7 +29792,7 @@ var ts;
                 return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl));
             }
             var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl);
-            if (signature) {
+            if (signature && !isResolvingReturnTypeOfSignature(signature)) {
                 return getReturnTypeOfSignature(signature);
             }
             return undefined;
@@ -32075,7 +32082,7 @@ var ts;
             return result;
         }
         function isJavaScriptConstructor(node) {
-            if (ts.isInJavaScriptFile(node)) {
+            if (node && ts.isInJavaScriptFile(node)) {
                 if (ts.getJSDocClassTag(node))
                     return true;
                 var symbol = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) ? getSymbolOfNode(node) :
@@ -32085,6 +32092,20 @@ var ts;
             }
             return false;
         }
+        function getJavaScriptClassType(symbol) {
+            if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) {
+                symbol = getSymbolOfNode(symbol.valueDeclaration.initializer);
+            }
+            if (isJavaScriptConstructor(symbol.valueDeclaration)) {
+                return getInferredClassType(symbol);
+            }
+            if (symbol.flags & 3) {
+                var valueType = getTypeOfSymbol(symbol);
+                if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) {
+                    return getInferredClassType(valueType.symbol);
+                }
+            }
+        }
         function getInferredClassType(symbol) {
             var links = getSymbolLinks(symbol);
             if (!links.inferredClassType) {
@@ -32113,13 +32134,11 @@ var ts;
                     var funcSymbol = node.expression.kind === 71 ?
                         getResolvedSymbol(node.expression) :
                         checkExpression(node.expression).symbol;
-                    if (funcSymbol && ts.isDeclarationOfFunctionOrClassExpression(funcSymbol)) {
-                        funcSymbol = getSymbolOfNode(funcSymbol.valueDeclaration.initializer);
-                    }
-                    if (funcSymbol && funcSymbol.flags & 16 && (funcSymbol.members || ts.getJSDocClassTag(funcSymbol.valueDeclaration))) {
-                        return getInferredClassType(funcSymbol);
+                    var type = funcSymbol && getJavaScriptClassType(funcSymbol);
+                    if (type) {
+                        return type;
                     }
-                    else if (noImplicitAny) {
+                    if (noImplicitAny) {
                         error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
                     }
                     return anyType;
@@ -34280,6 +34299,7 @@ var ts;
                             : 4;
                     case 229:
                     case 232:
+                    case 240:
                         return 2 | 1;
                     case 237:
                         var result_3 = 0;
@@ -37452,6 +37472,14 @@ var ts;
             return type.flags & 32768 && getSignaturesOfType(type, 0).length > 0;
         }
         function getTypeReferenceSerializationKind(typeName, location) {
+            typeName = ts.getParseTreeNode(typeName, ts.isEntityName);
+            if (!typeName)
+                return ts.TypeReferenceSerializationKind.Unknown;
+            if (location) {
+                location = ts.getParseTreeNode(location);
+                if (!location)
+                    return ts.TypeReferenceSerializationKind.Unknown;
+            }
             var valueSymbol = resolveEntityName(typeName, 107455, true, false, location);
             var typeSymbol = resolveEntityName(typeName, 793064, true, false, location);
             if (valueSymbol && valueSymbol === typeSymbol) {
@@ -40909,6 +40937,10 @@ var ts;
         return createCall(createFunctionExpression(undefined, undefined, undefined, undefined, param ? [param] : [], undefined, createBlock(statements, true)), undefined, paramValue ? [paramValue] : []);
     }
     ts.createImmediatelyInvokedFunctionExpression = createImmediatelyInvokedFunctionExpression;
+    function createImmediatelyInvokedArrowFunction(statements, param, paramValue) {
+        return createCall(createArrowFunction(undefined, undefined, param ? [param] : [], undefined, undefined, createBlock(statements, true)), undefined, paramValue ? [paramValue] : []);
+    }
+    ts.createImmediatelyInvokedArrowFunction = createImmediatelyInvokedArrowFunction;
     function createComma(left, right) {
         return createBinary(left, 26, right);
     }
@@ -41999,9 +42031,17 @@ var ts;
             case 288: return ts.updatePartiallyEmittedExpression(outerExpression, expression);
         }
     }
+    function isIgnorableParen(node) {
+        return node.kind === 185
+            && 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; }
-        if (outerExpression && isOuterExpression(outerExpression, kinds)) {
+        if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) {
             return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression));
         }
         return innerExpression;
@@ -43227,7 +43267,7 @@ var ts;
                         }
                         else {
                             var name = node.name;
-                            if (!uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) {
+                            if (name && !uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) {
                                 multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
                                 uniqueExports.set(ts.unescapeLeadingUnderscores(name.escapedText), true);
                                 exportedNames = ts.append(exportedNames, name);
@@ -43927,8 +43967,10 @@ var ts;
                 ts.setEmitFlags(statement, 1536 | 384);
                 statements.push(statement);
                 ts.addRange(statements, context.endLexicalEnvironment());
+                var iife = ts.createImmediatelyInvokedArrowFunction(statements);
+                ts.setEmitFlags(iife, 33554432);
                 var varStatement = ts.createVariableStatement(undefined, ts.createVariableDeclarationList([
-                    ts.createVariableDeclaration(ts.getLocalName(node, false, false), undefined, ts.createImmediatelyInvokedFunctionExpression(statements))
+                    ts.createVariableDeclaration(ts.getLocalName(node, false, false), undefined, iife)
                 ]));
                 ts.setOriginalNode(varStatement, node);
                 ts.setCommentRange(varStatement, node);
@@ -44534,7 +44576,7 @@ var ts;
                     var name = ts.getMutableClone(node);
                     name.flags &= ~8;
                     name.original = undefined;
-                    name.parent = currentScope;
+                    name.parent = ts.getParseTreeNode(currentScope);
                     if (useFallback) {
                         return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(name), ts.createLiteral("undefined")), name);
                     }
@@ -45626,7 +45668,7 @@ var ts;
                         chunkObject.push(ts.createPropertyAssignment(p.name, ts.visitNode(p.initializer, visitor, ts.isExpression)));
                     }
                     else {
-                        chunkObject.push(e);
+                        chunkObject.push(ts.visitNode(e, visitor, ts.isObjectLiteralElementLike));
                     }
                 }
             }
@@ -46641,58 +46683,12 @@ var ts;
                 && node.kind === 219
                 && !node.expression;
         }
-        function isClassLikeVariableStatement(node) {
-            if (!ts.isVariableStatement(node))
-                return false;
-            var variable = ts.singleOrUndefined(node.declarationList.declarations);
-            return variable
-                && variable.initializer
-                && ts.isIdentifier(variable.name)
-                && (ts.isClassLike(variable.initializer)
-                    || (ts.isAssignmentExpression(variable.initializer)
-                        && ts.isIdentifier(variable.initializer.left)
-                        && ts.isClassLike(variable.initializer.right)));
-        }
-        function isTypeScriptClassWrapper(node) {
-            var call = ts.tryCast(node, ts.isCallExpression);
-            if (!call || ts.isParseTreeNode(call) ||
-                ts.some(call.typeArguments) ||
-                ts.some(call.arguments)) {
-                return false;
-            }
-            var func = ts.tryCast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression);
-            if (!func || ts.isParseTreeNode(func) ||
-                ts.some(func.typeParameters) ||
-                ts.some(func.parameters) ||
-                func.type ||
-                !func.body) {
-                return false;
-            }
-            var statements = func.body.statements;
-            if (statements.length < 2) {
-                return false;
-            }
-            var firstStatement = statements[0];
-            if (ts.isParseTreeNode(firstStatement) ||
-                !ts.isClassLike(firstStatement) &&
-                    !isClassLikeVariableStatement(firstStatement)) {
-                return false;
-            }
-            var lastStatement = ts.elementAt(statements, -1);
-            var returnStatement = ts.tryCast(ts.isVariableStatement(lastStatement) ? ts.elementAt(statements, -2) : lastStatement, ts.isReturnStatement);
-            if (!returnStatement ||
-                !returnStatement.expression ||
-                !ts.isIdentifier(ts.skipOuterExpressions(returnStatement.expression))) {
-                return false;
-            }
-            return true;
-        }
         function shouldVisitNode(node) {
             return (node.transformFlags & 128) !== 0
                 || convertedLoopState !== undefined
                 || (hierarchyFacts & 4096 && (ts.isStatement(node) || (node.kind === 207)))
                 || (ts.isIterationStatement(node, false) && shouldConvertIterationStatementBody(node))
-                || isTypeScriptClassWrapper(node);
+                || (ts.getEmitFlags(node) & 33554432) !== 0;
         }
         function visitor(node) {
             if (shouldVisitNode(node)) {
@@ -48172,7 +48168,7 @@ var ts;
             return ts.visitEachChild(node, visitor, context);
         }
         function visitCallExpression(node) {
-            if (isTypeScriptClassWrapper(node)) {
+            if (ts.getEmitFlags(node) & 33554432) {
                 return visitTypeScriptClassWrapper(node);
             }
             if (node.transformFlags & 64) {
@@ -48181,7 +48177,7 @@ var ts;
             return ts.updateCall(node, ts.visitNode(node.expression, callExpressionVisitor, ts.isExpression), undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
         }
         function visitTypeScriptClassWrapper(node) {
-            var body = ts.cast(ts.skipOuterExpressions(node.expression), ts.isFunctionExpression).body;
+            var body = ts.cast(ts.cast(ts.skipOuterExpressions(node.expression), ts.isArrowFunction).body, ts.isBlock);
             var classStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 0, 1);
             var remainingStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 1, body.statements.length - 1);
             var varStatement = ts.cast(ts.firstOrUndefined(classStatements), ts.isVariableStatement);
@@ -49351,8 +49347,12 @@ var ts;
         }
         function transformAndEmitContinueStatement(node) {
             var label = findContinueTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined);
-            ts.Debug.assert(label > 0, "Expected continue statment to point to a valid Label.");
-            emitBreak(label, node);
+            if (label > 0) {
+                emitBreak(label, node);
+            }
+            else {
+                emitStatement(node);
+            }
         }
         function visitContinueStatement(node) {
             if (inStatementContainingYield) {
@@ -49365,8 +49365,12 @@ var ts;
         }
         function transformAndEmitBreakStatement(node) {
             var label = findBreakTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined);
-            ts.Debug.assert(label > 0, "Expected break statment to point to a valid Label.");
-            emitBreak(label, node);
+            if (label > 0) {
+                emitBreak(label, node);
+            }
+            else {
+                emitStatement(node);
+            }
         }
         function visitBreakStatement(node) {
             if (inStatementContainingYield) {
@@ -49790,43 +49794,45 @@ var ts;
             return false;
         }
         function findBreakTarget(labelText) {
-            ts.Debug.assert(blocks !== undefined);
-            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;
+            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;
+                else {
+                    for (var i = blockStack.length - 1; i >= 0; i--) {
+                        var block = blockStack[i];
+                        if (supportsUnlabeledBreak(block)) {
+                            return block.breakLabel;
+                        }
                     }
                 }
             }
             return 0;
         }
         function findContinueTarget(labelText) {
-            ts.Debug.assert(blocks !== undefined);
-            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;
+            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;
+                else {
+                    for (var i = blockStack.length - 1; i >= 0; i--) {
+                        var block = blockStack[i];
+                        if (supportsUnlabeledContinue(block)) {
+                            return block.continueLabel;
+                        }
                     }
                 }
             }
@@ -50450,17 +50456,23 @@ var ts;
         }
         function addExportEqualsIfNeeded(statements, emitAsReturn) {
             if (currentModuleInfo.exportEquals) {
-                if (emitAsReturn) {
-                    var statement = ts.createReturn(currentModuleInfo.exportEquals.expression);
-                    ts.setTextRange(statement, currentModuleInfo.exportEquals);
-                    ts.setEmitFlags(statement, 384 | 1536);
-                    statements.push(statement);
-                }
-                else {
-                    var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), currentModuleInfo.exportEquals.expression));
-                    ts.setTextRange(statement, currentModuleInfo.exportEquals);
-                    ts.setEmitFlags(statement, 1536);
-                    statements.push(statement);
+                var expressionResult = importCallExpressionVisitor(currentModuleInfo.exportEquals.expression);
+                if (expressionResult) {
+                    if (expressionResult instanceof Array) {
+                        return ts.Debug.fail("export= expression should never be replaced with multiple expressions!");
+                    }
+                    if (emitAsReturn) {
+                        var statement = ts.createReturn(expressionResult);
+                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
+                        ts.setEmitFlags(statement, 384 | 1536);
+                        statements.push(statement);
+                    }
+                    else {
+                        var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult));
+                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
+                        ts.setEmitFlags(statement, 1536);
+                        statements.push(statement);
+                    }
                 }
             }
         }
@@ -50794,7 +50806,7 @@ var ts;
                 return statements;
             }
             if (ts.hasModifier(decl, 1)) {
-                var exportName = ts.hasModifier(decl, 512) ? ts.createIdentifier("default") : decl.name;
+                var exportName = ts.hasModifier(decl, 512) ? ts.createIdentifier("default") : ts.getDeclarationName(decl);
                 statements = appendExportStatement(statements, exportName, ts.getLocalName(decl), decl);
             }
             if (decl.name) {
@@ -64875,11 +64887,10 @@ var ts;
             var bucket = getBucketForCompilationSettings(key, true);
             var entry = bucket.get(path);
             if (!entry) {
-                ts.Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?");
                 var sourceFile = ts.createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, false, scriptKind);
                 entry = {
                     sourceFile: sourceFile,
-                    languageServiceRefCount: 0,
+                    languageServiceRefCount: 1,
                     owners: []
                 };
                 bucket.set(path, entry);
@@ -64888,9 +64899,9 @@ var ts;
                 if (entry.sourceFile.version !== version) {
                     entry.sourceFile = ts.updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot));
                 }
-            }
-            if (acquiring) {
-                entry.languageServiceRefCount++;
+                if (acquiring) {
+                    entry.languageServiceRefCount++;
+                }
             }
             return entry.sourceFile;
         }
@@ -74613,12 +74624,7 @@ var ts;
                     if (errors) {
                         return { errors: errors };
                     }
-                    var range = ts.isStatement(start)
-                        ? [start]
-                        : start.parent && start.parent.kind === 210
-                            ? [start.parent]
-                            : start;
-                    return { targetRange: { range: range, facts: rangeFacts, declarations: declarations } };
+                    return { targetRange: { range: getStatementOrExpressionRange(start), facts: rangeFacts, declarations: declarations } };
                 }
                 function createErrorResult(sourceFile, start, length, message) {
                     return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] };
@@ -74803,6 +74809,15 @@ var ts;
                 }
             }
             extractMethod_1.getRangeToExtract = getRangeToExtract;
+            function getStatementOrExpressionRange(node) {
+                if (ts.isStatement(node)) {
+                    return [node];
+                }
+                else if (ts.isPartOfExpression(node)) {
+                    return ts.isExpressionStatement(node.parent) ? [node.parent] : node;
+                }
+                return undefined;
+            }
             function isValidExtractionTarget(node) {
                 return (node.kind === 228) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node);
             }
@@ -74871,32 +74886,32 @@ var ts;
                             return "constructor";
                         case 186:
                             return scope.name
-                                ? "function expression " + scope.name.getText()
+                                ? "function expression " + scope.name.text
                                 : "anonymous function expression";
                         case 228:
-                            return "function " + scope.name.getText();
+                            return "function '" + scope.name.text + "'";
                         case 187:
                             return "arrow function";
                         case 151:
-                            return "method " + scope.name.getText();
+                            return "method '" + scope.name.getText();
                         case 153:
-                            return "get " + scope.name.getText();
+                            return "'get " + scope.name.getText() + "'";
                         case 154:
-                            return "set " + scope.name.getText();
+                            return "'set " + scope.name.getText() + "'";
                     }
                 }
                 else if (isModuleBlock(scope)) {
-                    return "namespace " + scope.parent.name.getText();
+                    return "namespace '" + scope.parent.name.getText() + "'";
                 }
                 else if (ts.isClassLike(scope)) {
                     return scope.kind === 229
-                        ? "class " + scope.name.text
+                        ? "class '" + scope.name.text + "'"
                         : scope.name.text
-                            ? "class expression " + scope.name.text
+                            ? "class expression '" + scope.name.text + "'"
                             : "anonymous class expression";
                 }
                 else if (ts.isSourceFile(scope)) {
-                    return "file '" + scope.fileName + "'";
+                    return scope.externalModuleIndicator ? "module scope" : "global scope";
                 }
                 else {
                     return "unknown";
@@ -77866,6 +77881,7 @@ var ts;
                 ModuleKind["System"] = "System";
                 ModuleKind["ES6"] = "ES6";
                 ModuleKind["ES2015"] = "ES2015";
+                ModuleKind["ESNext"] = "ESNext";
             })(ModuleKind = protocol.ModuleKind || (protocol.ModuleKind = {}));
             var ModuleResolutionKind;
             (function (ModuleResolutionKind) {
@@ -77883,6 +77899,9 @@ var ts;
                 ScriptTarget["ES5"] = "ES5";
                 ScriptTarget["ES6"] = "ES6";
                 ScriptTarget["ES2015"] = "ES2015";
+                ScriptTarget["ES2016"] = "ES2016";
+                ScriptTarget["ES2017"] = "ES2017";
+                ScriptTarget["ESNext"] = "ESNext";
             })(ScriptTarget = protocol.ScriptTarget || (protocol.ScriptTarget = {}));
         })(protocol = server.protocol || (server.protocol = {}));
     })(server = ts.server || (ts.server = {}));
@@ -80803,7 +80822,7 @@ var ts;
                     for (var _i = 0, openFiles_1 = openFiles; _i < openFiles_1.length; _i++) {
                         var file = openFiles_1[_i];
                         var scriptInfo = this.getScriptInfo(file.fileName);
-                        ts.Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen());
+                        ts.Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen(), "Script should not exist and not be open already");
                         var normalizedPath = scriptInfo ? scriptInfo.fileName : server.toNormalizedPath(file.fileName);
                         this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent);
                     }
diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts
index d43f0e0..4c27618 100644
--- a/lib/tsserverlibrary.d.ts
+++ b/lib/tsserverlibrary.d.ts
@@ -2996,6 +2996,8 @@ declare namespace ts {
     function updateBundle(node: Bundle, sourceFiles: SourceFile[]): Bundle;
     function createImmediatelyInvokedFunctionExpression(statements: Statement[]): CallExpression;
     function createImmediatelyInvokedFunctionExpression(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression;
+    function createImmediatelyInvokedArrowFunction(statements: Statement[]): CallExpression;
+    function createImmediatelyInvokedArrowFunction(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression;
     function createComma(left: Expression, right: Expression): Expression;
     function createLessThan(left: Expression, right: Expression): Expression;
     function createAssignment(left: ObjectLiteralExpression | ArrayLiteralExpression, right: Expression): DestructuringAssignment;
@@ -4730,6 +4732,7 @@ declare namespace ts.server.protocol {
         System = "System",
         ES6 = "ES6",
         ES2015 = "ES2015",
+        ESNext = "ESNext",
     }
     enum ModuleResolutionKind {
         Classic = "Classic",
@@ -4744,6 +4747,9 @@ declare namespace ts.server.protocol {
         ES5 = "ES5",
         ES6 = "ES6",
         ES2015 = "ES2015",
+        ES2016 = "ES2016",
+        ES2017 = "ES2017",
+        ESNext = "ESNext",
     }
 }
 declare namespace ts.server {
diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js
index 9e95700..60d8bc0 100644
--- a/lib/tsserverlibrary.js
+++ b/lib/tsserverlibrary.js
@@ -1066,6 +1066,7 @@ var ts;
         EmitFlags[EmitFlags["HasEndOfDeclarationMarker"] = 4194304] = "HasEndOfDeclarationMarker";
         EmitFlags[EmitFlags["Iterator"] = 8388608] = "Iterator";
         EmitFlags[EmitFlags["NoAsciiEscaping"] = 16777216] = "NoAsciiEscaping";
+        EmitFlags[EmitFlags["TypeScriptClassWrapper"] = 33554432] = "TypeScriptClassWrapper";
     })(EmitFlags = ts.EmitFlags || (ts.EmitFlags = {}));
     var ExternalEmitHelpers;
     (function (ExternalEmitHelpers) {
@@ -1163,7 +1164,7 @@ var ts;
 var ts;
 (function (ts) {
     ts.versionMajorMinor = "2.5";
-    ts.version = ts.versionMajorMinor + ".1";
+    ts.version = ts.versionMajorMinor + ".2";
 })(ts || (ts = {}));
 (function (ts) {
     ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined;
@@ -4557,7 +4558,7 @@ var ts;
         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_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"),
-        Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"),
+        Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into {0}"),
     };
 })(ts || (ts = {}));
 var ts;
@@ -6330,9 +6331,9 @@ var ts;
             || kind === 265;
     }
     ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment;
-    function nodeIsSynthesized(node) {
-        return ts.positionIsSynthesized(node.pos)
-            || ts.positionIsSynthesized(node.end);
+    function nodeIsSynthesized(range) {
+        return ts.positionIsSynthesized(range.pos)
+            || ts.positionIsSynthesized(range.end);
     }
     ts.nodeIsSynthesized = nodeIsSynthesized;
     function getOriginalSourceFile(sourceFile) {
@@ -21716,7 +21717,10 @@ var ts;
                 }
                 return true;
             }
-            if (usage.parent.kind === 246) {
+            if (usage.parent.kind === 246 || (usage.parent.kind === 243 && usage.parent.isExportEquals)) {
+                return true;
+            }
+            if (usage.kind === 243 && usage.isExportEquals) {
                 return true;
             }
             var container = ts.getEnclosingBlockScopeContainer(declaration);
@@ -26384,6 +26388,9 @@ var ts;
             }
             return signature.resolvedReturnType;
         }
+        function isResolvingReturnTypeOfSignature(signature) {
+            return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3) >= 0;
+        }
         function getRestTypeOfSignature(signature) {
             if (signature.hasRestParameter) {
                 var type = getTypeOfSymbol(ts.lastOrUndefined(signature.parameters));
@@ -31491,7 +31498,7 @@ var ts;
                 return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl));
             }
             var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl);
-            if (signature) {
+            if (signature && !isResolvingReturnTypeOfSignature(signature)) {
                 return getReturnTypeOfSignature(signature);
             }
             return undefined;
@@ -33781,7 +33788,7 @@ var ts;
             return result;
         }
         function isJavaScriptConstructor(node) {
-            if (ts.isInJavaScriptFile(node)) {
+            if (node && ts.isInJavaScriptFile(node)) {
                 if (ts.getJSDocClassTag(node))
                     return true;
                 var symbol = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) ? getSymbolOfNode(node) :
@@ -33791,6 +33798,20 @@ var ts;
             }
             return false;
         }
+        function getJavaScriptClassType(symbol) {
+            if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) {
+                symbol = getSymbolOfNode(symbol.valueDeclaration.initializer);
+            }
+            if (isJavaScriptConstructor(symbol.valueDeclaration)) {
+                return getInferredClassType(symbol);
+            }
+            if (symbol.flags & 3) {
+                var valueType = getTypeOfSymbol(symbol);
+                if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) {
+                    return getInferredClassType(valueType.symbol);
+                }
+            }
+        }
         function getInferredClassType(symbol) {
             var links = getSymbolLinks(symbol);
             if (!links.inferredClassType) {
@@ -33819,13 +33840,11 @@ var ts;
                     var funcSymbol = node.expression.kind === 71 ?
                         getResolvedSymbol(node.expression) :
                         checkExpression(node.expression).symbol;
-                    if (funcSymbol && ts.isDeclarationOfFunctionOrClassExpression(funcSymbol)) {
-                        funcSymbol = getSymbolOfNode(funcSymbol.valueDeclaration.initializer);
-                    }
-                    if (funcSymbol && funcSymbol.flags & 16 && (funcSymbol.members || ts.getJSDocClassTag(funcSymbol.valueDeclaration))) {
-                        return getInferredClassType(funcSymbol);
+                    var type = funcSymbol && getJavaScriptClassType(funcSymbol);
+                    if (type) {
+                        return type;
                     }
-                    else if (noImplicitAny) {
+                    if (noImplicitAny) {
                         error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
                     }
                     return anyType;
@@ -35986,6 +36005,7 @@ var ts;
                             : 4;
                     case 229:
                     case 232:
+                    case 240:
                         return 2 | 1;
                     case 237:
                         var result_3 = 0;
@@ -39158,6 +39178,14 @@ var ts;
             return type.flags & 32768 && getSignaturesOfType(type, 0).length > 0;
         }
         function getTypeReferenceSerializationKind(typeName, location) {
+            typeName = ts.getParseTreeNode(typeName, ts.isEntityName);
+            if (!typeName)
+                return ts.TypeReferenceSerializationKind.Unknown;
+            if (location) {
+                location = ts.getParseTreeNode(location);
+                if (!location)
+                    return ts.TypeReferenceSerializationKind.Unknown;
+            }
             var valueSymbol = resolveEntityName(typeName, 107455, true, false, location);
             var typeSymbol = resolveEntityName(typeName, 793064, true, false, location);
             if (valueSymbol && valueSymbol === typeSymbol) {
@@ -42615,6 +42643,10 @@ var ts;
         return createCall(createFunctionExpression(undefined, undefined, undefined, undefined, param ? [param] : [], undefined, createBlock(statements, true)), undefined, paramValue ? [paramValue] : []);
     }
     ts.createImmediatelyInvokedFunctionExpression = createImmediatelyInvokedFunctionExpression;
+    function createImmediatelyInvokedArrowFunction(statements, param, paramValue) {
+        return createCall(createArrowFunction(undefined, undefined, param ? [param] : [], undefined, undefined, createBlock(statements, true)), undefined, paramValue ? [paramValue] : []);
+    }
+    ts.createImmediatelyInvokedArrowFunction = createImmediatelyInvokedArrowFunction;
     function createComma(left, right) {
         return createBinary(left, 26, right);
     }
@@ -43705,9 +43737,17 @@ var ts;
             case 288: return ts.updatePartiallyEmittedExpression(outerExpression, expression);
         }
     }
+    function isIgnorableParen(node) {
+        return node.kind === 185
+            && 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; }
-        if (outerExpression && isOuterExpression(outerExpression, kinds)) {
+        if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) {
             return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression));
         }
         return innerExpression;
@@ -44933,7 +44973,7 @@ var ts;
                         }
                         else {
                             var name = node.name;
-                            if (!uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) {
+                            if (name && !uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) {
                                 multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
                                 uniqueExports.set(ts.unescapeLeadingUnderscores(name.escapedText), true);
                                 exportedNames = ts.append(exportedNames, name);
@@ -45633,8 +45673,10 @@ var ts;
                 ts.setEmitFlags(statement, 1536 | 384);
                 statements.push(statement);
                 ts.addRange(statements, context.endLexicalEnvironment());
+                var iife = ts.createImmediatelyInvokedArrowFunction(statements);
+                ts.setEmitFlags(iife, 33554432);
                 var varStatement = ts.createVariableStatement(undefined, ts.createVariableDeclarationList([
-                    ts.createVariableDeclaration(ts.getLocalName(node, false, false), undefined, ts.createImmediatelyInvokedFunctionExpression(statements))
+                    ts.createVariableDeclaration(ts.getLocalName(node, false, false), undefined, iife)
                 ]));
                 ts.setOriginalNode(varStatement, node);
                 ts.setCommentRange(varStatement, node);
@@ -46240,7 +46282,7 @@ var ts;
                     var name = ts.getMutableClone(node);
                     name.flags &= ~8;
                     name.original = undefined;
-                    name.parent = currentScope;
+                    name.parent = ts.getParseTreeNode(currentScope);
                     if (useFallback) {
                         return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(name), ts.createLiteral("undefined")), name);
                     }
@@ -47332,7 +47374,7 @@ var ts;
                         chunkObject.push(ts.createPropertyAssignment(p.name, ts.visitNode(p.initializer, visitor, ts.isExpression)));
                     }
                     else {
-                        chunkObject.push(e);
+                        chunkObject.push(ts.visitNode(e, visitor, ts.isObjectLiteralElementLike));
                     }
                 }
             }
@@ -48347,58 +48389,12 @@ var ts;
                 && node.kind === 219
                 && !node.expression;
         }
-        function isClassLikeVariableStatement(node) {
-            if (!ts.isVariableStatement(node))
-                return false;
-            var variable = ts.singleOrUndefined(node.declarationList.declarations);
-            return variable
-                && variable.initializer
-                && ts.isIdentifier(variable.name)
-                && (ts.isClassLike(variable.initializer)
-                    || (ts.isAssignmentExpression(variable.initializer)
-                        && ts.isIdentifier(variable.initializer.left)
-                        && ts.isClassLike(variable.initializer.right)));
-        }
-        function isTypeScriptClassWrapper(node) {
-            var call = ts.tryCast(node, ts.isCallExpression);
-            if (!call || ts.isParseTreeNode(call) ||
-                ts.some(call.typeArguments) ||
-                ts.some(call.arguments)) {
-                return false;
-            }
-            var func = ts.tryCast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression);
-            if (!func || ts.isParseTreeNode(func) ||
-                ts.some(func.typeParameters) ||
-                ts.some(func.parameters) ||
-                func.type ||
-                !func.body) {
-                return false;
-            }
-            var statements = func.body.statements;
-            if (statements.length < 2) {
-                return false;
-            }
-            var firstStatement = statements[0];
-            if (ts.isParseTreeNode(firstStatement) ||
-                !ts.isClassLike(firstStatement) &&
-                    !isClassLikeVariableStatement(firstStatement)) {
-                return false;
-            }
-            var lastStatement = ts.elementAt(statements, -1);
-            var returnStatement = ts.tryCast(ts.isVariableStatement(lastStatement) ? ts.elementAt(statements, -2) : lastStatement, ts.isReturnStatement);
-            if (!returnStatement ||
-                !returnStatement.expression ||
-                !ts.isIdentifier(ts.skipOuterExpressions(returnStatement.expression))) {
-                return false;
-            }
-            return true;
-        }
         function shouldVisitNode(node) {
             return (node.transformFlags & 128) !== 0
                 || convertedLoopState !== undefined
                 || (hierarchyFacts & 4096 && (ts.isStatement(node) || (node.kind === 207)))
                 || (ts.isIterationStatement(node, false) && shouldConvertIterationStatementBody(node))
-                || isTypeScriptClassWrapper(node);
+                || (ts.getEmitFlags(node) & 33554432) !== 0;
         }
         function visitor(node) {
             if (shouldVisitNode(node)) {
@@ -49878,7 +49874,7 @@ var ts;
             return ts.visitEachChild(node, visitor, context);
         }
         function visitCallExpression(node) {
-            if (isTypeScriptClassWrapper(node)) {
+            if (ts.getEmitFlags(node) & 33554432) {
                 return visitTypeScriptClassWrapper(node);
             }
             if (node.transformFlags & 64) {
@@ -49887,7 +49883,7 @@ var ts;
             return ts.updateCall(node, ts.visitNode(node.expression, callExpressionVisitor, ts.isExpression), undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
         }
         function visitTypeScriptClassWrapper(node) {
-            var body = ts.cast(ts.skipOuterExpressions(node.expression), ts.isFunctionExpression).body;
+            var body = ts.cast(ts.cast(ts.skipOuterExpressions(node.expression), ts.isArrowFunction).body, ts.isBlock);
             var classStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 0, 1);
             var remainingStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 1, body.statements.length - 1);
             var varStatement = ts.cast(ts.firstOrUndefined(classStatements), ts.isVariableStatement);
@@ -51057,8 +51053,12 @@ var ts;
         }
         function transformAndEmitContinueStatement(node) {
             var label = findContinueTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined);
-            ts.Debug.assert(label > 0, "Expected continue statment to point to a valid Label.");
-            emitBreak(label, node);
+            if (label > 0) {
+                emitBreak(label, node);
+            }
+            else {
+                emitStatement(node);
+            }
         }
         function visitContinueStatement(node) {
             if (inStatementContainingYield) {
@@ -51071,8 +51071,12 @@ var ts;
         }
         function transformAndEmitBreakStatement(node) {
             var label = findBreakTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined);
-            ts.Debug.assert(label > 0, "Expected break statment to point to a valid Label.");
-            emitBreak(label, node);
+            if (label > 0) {
+                emitBreak(label, node);
+            }
+            else {
+                emitStatement(node);
+            }
         }
         function visitBreakStatement(node) {
             if (inStatementContainingYield) {
@@ -51496,43 +51500,45 @@ var ts;
             return false;
         }
         function findBreakTarget(labelText) {
-            ts.Debug.assert(blocks !== undefined);
-            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;
+            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;
+                else {
+                    for (var i = blockStack.length - 1; i >= 0; i--) {
+                        var block = blockStack[i];
+                        if (supportsUnlabeledBreak(block)) {
+                            return block.breakLabel;
+                        }
                     }
                 }
             }
             return 0;
         }
         function findContinueTarget(labelText) {
-            ts.Debug.assert(blocks !== undefined);
-            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;
+            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;
+                else {
+                    for (var i = blockStack.length - 1; i >= 0; i--) {
+                        var block = blockStack[i];
+                        if (supportsUnlabeledContinue(block)) {
+                            return block.continueLabel;
+                        }
                     }
                 }
             }
@@ -52156,17 +52162,23 @@ var ts;
         }
         function addExportEqualsIfNeeded(statements, emitAsReturn) {
             if (currentModuleInfo.exportEquals) {
-                if (emitAsReturn) {
-                    var statement = ts.createReturn(currentModuleInfo.exportEquals.expression);
-                    ts.setTextRange(statement, currentModuleInfo.exportEquals);
-                    ts.setEmitFlags(statement, 384 | 1536);
-                    statements.push(statement);
-                }
-                else {
-                    var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), currentModuleInfo.exportEquals.expression));
-                    ts.setTextRange(statement, currentModuleInfo.exportEquals);
-                    ts.setEmitFlags(statement, 1536);
-                    statements.push(statement);
+                var expressionResult = importCallExpressionVisitor(currentModuleInfo.exportEquals.expression);
+                if (expressionResult) {
+                    if (expressionResult instanceof Array) {
+                        return ts.Debug.fail("export= expression should never be replaced with multiple expressions!");
+                    }
+                    if (emitAsReturn) {
+                        var statement = ts.createReturn(expressionResult);
+                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
+                        ts.setEmitFlags(statement, 384 | 1536);
+                        statements.push(statement);
+                    }
+                    else {
+                        var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult));
+                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
+                        ts.setEmitFlags(statement, 1536);
+                        statements.push(statement);
+                    }
                 }
             }
         }
@@ -52500,7 +52512,7 @@ var ts;
                 return statements;
             }
             if (ts.hasModifier(decl, 1)) {
-                var exportName = ts.hasModifier(decl, 512) ? ts.createIdentifier("default") : decl.name;
+                var exportName = ts.hasModifier(decl, 512) ? ts.createIdentifier("default") : ts.getDeclarationName(decl);
                 statements = appendExportStatement(statements, exportName, ts.getLocalName(decl), decl);
             }
             if (decl.name) {
@@ -64875,11 +64887,10 @@ var ts;
             var bucket = getBucketForCompilationSettings(key, true);
             var entry = bucket.get(path);
             if (!entry) {
-                ts.Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?");
                 var sourceFile = ts.createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, false, scriptKind);
                 entry = {
                     sourceFile: sourceFile,
-                    languageServiceRefCount: 0,
+                    languageServiceRefCount: 1,
                     owners: []
                 };
                 bucket.set(path, entry);
@@ -64888,9 +64899,9 @@ var ts;
                 if (entry.sourceFile.version !== version) {
                     entry.sourceFile = ts.updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot));
                 }
-            }
-            if (acquiring) {
-                entry.languageServiceRefCount++;
+                if (acquiring) {
+                    entry.languageServiceRefCount++;
+                }
             }
             return entry.sourceFile;
         }
@@ -74613,12 +74624,7 @@ var ts;
                     if (errors) {
                         return { errors: errors };
                     }
-                    var range = ts.isStatement(start)
-                        ? [start]
-                        : start.parent && start.parent.kind === 210
-                            ? [start.parent]
-                            : start;
-                    return { targetRange: { range: range, facts: rangeFacts, declarations: declarations } };
+                    return { targetRange: { range: getStatementOrExpressionRange(start), facts: rangeFacts, declarations: declarations } };
                 }
                 function createErrorResult(sourceFile, start, length, message) {
                     return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] };
@@ -74803,6 +74809,15 @@ var ts;
                 }
             }
             extractMethod_1.getRangeToExtract = getRangeToExtract;
+            function getStatementOrExpressionRange(node) {
+                if (ts.isStatement(node)) {
+                    return [node];
+                }
+                else if (ts.isPartOfExpression(node)) {
+                    return ts.isExpressionStatement(node.parent) ? [node.parent] : node;
+                }
+                return undefined;
+            }
             function isValidExtractionTarget(node) {
                 return (node.kind === 228) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node);
             }
@@ -74871,32 +74886,32 @@ var ts;
                             return "constructor";
                         case 186:
                             return scope.name
-                                ? "function expression " + scope.name.getText()
+                                ? "function expression " + scope.name.text
                                 : "anonymous function expression";
                         case 228:
-                            return "function " + scope.name.getText();
+                            return "function '" + scope.name.text + "'";
                         case 187:
                             return "arrow function";
                         case 151:
-                            return "method " + scope.name.getText();
+                            return "method '" + scope.name.getText();
                         case 153:
-                            return "get " + scope.name.getText();
+                            return "'get " + scope.name.getText() + "'";
                         case 154:
-                            return "set " + scope.name.getText();
+                            return "'set " + scope.name.getText() + "'";
                     }
                 }
                 else if (isModuleBlock(scope)) {
-                    return "namespace " + scope.parent.name.getText();
+                    return "namespace '" + scope.parent.name.getText() + "'";
                 }
                 else if (ts.isClassLike(scope)) {
                     return scope.kind === 229
-                        ? "class " + scope.name.text
+                        ? "class '" + scope.name.text + "'"
                         : scope.name.text
-                            ? "class expression " + scope.name.text
+                            ? "class expression '" + scope.name.text + "'"
                             : "anonymous class expression";
                 }
                 else if (ts.isSourceFile(scope)) {
-                    return "file '" + scope.fileName + "'";
+                    return scope.externalModuleIndicator ? "module scope" : "global scope";
                 }
                 else {
                     return "unknown";
@@ -77209,6 +77224,7 @@ var ts;
                 ModuleKind["System"] = "System";
                 ModuleKind["ES6"] = "ES6";
                 ModuleKind["ES2015"] = "ES2015";
+                ModuleKind["ESNext"] = "ESNext";
             })(ModuleKind = protocol.ModuleKind || (protocol.ModuleKind = {}));
             var ModuleResolutionKind;
             (function (ModuleResolutionKind) {
@@ -77226,6 +77242,9 @@ var ts;
                 ScriptTarget["ES5"] = "ES5";
                 ScriptTarget["ES6"] = "ES6";
                 ScriptTarget["ES2015"] = "ES2015";
+                ScriptTarget["ES2016"] = "ES2016";
+                ScriptTarget["ES2017"] = "ES2017";
+                ScriptTarget["ESNext"] = "ESNext";
             })(ScriptTarget = protocol.ScriptTarget || (protocol.ScriptTarget = {}));
         })(protocol = server.protocol || (server.protocol = {}));
     })(server = ts.server || (ts.server = {}));
@@ -82541,7 +82560,7 @@ var ts;
                     for (var _i = 0, openFiles_1 = openFiles; _i < openFiles_1.length; _i++) {
                         var file = openFiles_1[_i];
                         var scriptInfo = this.getScriptInfo(file.fileName);
-                        ts.Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen());
+                        ts.Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen(), "Script should not exist and not be open already");
                         var normalizedPath = scriptInfo ? scriptInfo.fileName : server.toNormalizedPath(file.fileName);
                         this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent);
                     }
diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts
index bec9e86..2ebd420 100644
--- a/lib/typescript.d.ts
+++ b/lib/typescript.d.ts
@@ -3388,6 +3388,8 @@ declare namespace ts {
     function updateBundle(node: Bundle, sourceFiles: SourceFile[]): Bundle;
     function createImmediatelyInvokedFunctionExpression(statements: Statement[]): CallExpression;
     function createImmediatelyInvokedFunctionExpression(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression;
+    function createImmediatelyInvokedArrowFunction(statements: Statement[]): CallExpression;
+    function createImmediatelyInvokedArrowFunction(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression;
     function createComma(left: Expression, right: Expression): Expression;
     function createLessThan(left: Expression, right: Expression): Expression;
     function createAssignment(left: ObjectLiteralExpression | ArrayLiteralExpression, right: Expression): DestructuringAssignment;
diff --git a/lib/typescript.js b/lib/typescript.js
index 3b497d4..d8b7626 100644
--- a/lib/typescript.js
+++ b/lib/typescript.js
@@ -1201,6 +1201,7 @@ var ts;
         EmitFlags[EmitFlags["HasEndOfDeclarationMarker"] = 4194304] = "HasEndOfDeclarationMarker";
         EmitFlags[EmitFlags["Iterator"] = 8388608] = "Iterator";
         EmitFlags[EmitFlags["NoAsciiEscaping"] = 16777216] = "NoAsciiEscaping";
+        /*@internal*/ EmitFlags[EmitFlags["TypeScriptClassWrapper"] = 33554432] = "TypeScriptClassWrapper";
     })(EmitFlags = ts.EmitFlags || (ts.EmitFlags = {}));
     /**
      * Used by the checker, this enum keeps track of external emit helpers that should be type
@@ -1348,7 +1349,7 @@ var ts;
     // If changing the text in this section, be sure to test `configureNightly` too.
     ts.versionMajorMinor = "2.5";
     /** The version of the TypeScript compiler release */
-    ts.version = ts.versionMajorMinor + ".1";
+    ts.version = ts.versionMajorMinor + ".2";
 })(ts || (ts = {}));
 /* @internal */
 (function (ts) {
@@ -5080,7 +5081,7 @@ var ts;
         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_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"),
-        Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"),
+        Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into {0}"),
     };
 })(ts || (ts = {}));
 /// <reference path="core.ts"/>
@@ -8844,9 +8845,9 @@ var ts;
             || kind === 265 /* SourceFile */;
     }
     ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment;
-    function nodeIsSynthesized(node) {
-        return ts.positionIsSynthesized(node.pos)
-            || ts.positionIsSynthesized(node.end);
+    function nodeIsSynthesized(range) {
+        return ts.positionIsSynthesized(range.pos)
+            || ts.positionIsSynthesized(range.end);
     }
     ts.nodeIsSynthesized = nodeIsSynthesized;
     function getOriginalSourceFile(sourceFile) {
@@ -23319,12 +23320,17 @@ var ts;
             // 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)
-            if (usage.parent.kind === 246 /* ExportSpecifier */) {
+            if (usage.parent.kind === 246 /* ExportSpecifier */ || (usage.parent.kind === 243 /* 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 === 243 /* ExportAssignment */ && usage.isExportEquals) {
+                return true;
+            }
             var container = ts.getEnclosingBlockScopeContainer(declaration);
             return isInTypeQuery(usage) || isUsedInFunctionOrInstanceProperty(usage, declaration, container);
             function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage) {
@@ -28615,6 +28621,9 @@ var ts;
             }
             return signature.resolvedReturnType;
         }
+        function isResolvingReturnTypeOfSignature(signature) {
+            return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3 /* ResolvedReturnType */) >= 0;
+        }
         function getRestTypeOfSignature(signature) {
             if (signature.hasRestParameter) {
                 var type = getTypeOfSymbol(ts.lastOrUndefined(signature.parameters));
@@ -34496,7 +34505,7 @@ var ts;
             // 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) {
+            if (signature && !isResolvingReturnTypeOfSignature(signature)) {
                 return getReturnTypeOfSignature(signature);
             }
             return undefined;
@@ -37549,7 +37558,7 @@ var ts;
          * file.
          */
         function isJavaScriptConstructor(node) {
-            if (ts.isInJavaScriptFile(node)) {
+            if (node && ts.isInJavaScriptFile(node)) {
                 // If the node has a @class tag, treat it like a constructor.
                 if (ts.getJSDocClassTag(node))
                     return true;
@@ -37561,6 +37570,20 @@ var ts;
             }
             return false;
         }
+        function getJavaScriptClassType(symbol) {
+            if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) {
+                symbol = getSymbolOfNode(symbol.valueDeclaration.initializer);
+            }
+            if (isJavaScriptConstructor(symbol.valueDeclaration)) {
+                return getInferredClassType(symbol);
+            }
+            if (symbol.flags & 3 /* Variable */) {
+                var valueType = getTypeOfSymbol(symbol);
+                if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) {
+                    return getInferredClassType(valueType.symbol);
+                }
+            }
+        }
         function getInferredClassType(symbol) {
             var links = getSymbolLinks(symbol);
             if (!links.inferredClassType) {
@@ -37600,13 +37623,11 @@ var ts;
                     var funcSymbol = node.expression.kind === 71 /* Identifier */ ?
                         getResolvedSymbol(node.expression) :
                         checkExpression(node.expression).symbol;
-                    if (funcSymbol && ts.isDeclarationOfFunctionOrClassExpression(funcSymbol)) {
-                        funcSymbol = getSymbolOfNode(funcSymbol.valueDeclaration.initializer);
-                    }
-                    if (funcSymbol && funcSymbol.flags & 16 /* Function */ && (funcSymbol.members || ts.getJSDocClassTag(funcSymbol.valueDeclaration))) {
-                        return getInferredClassType(funcSymbol);
+                    var type = funcSymbol && getJavaScriptClassType(funcSymbol);
+                    if (type) {
+                        return type;
                     }
-                    else if (noImplicitAny) {
+                    if (noImplicitAny) {
                         error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
                     }
                     return anyType;
@@ -40064,6 +40085,8 @@ var ts;
                             : 4 /* ExportNamespace */;
                     case 229 /* ClassDeclaration */:
                     case 232 /* EnumDeclaration */:
+                    // A NamespaceImport declares an Alias, which is allowed to merge with other values within the module
+                    case 240 /* NamespaceImport */:
                         return 2 /* ExportType */ | 1 /* ExportValue */;
                     case 237 /* ImportEqualsDeclaration */:
                         var result_3 = 0 /* None */;
@@ -43921,6 +43944,15 @@ var ts;
             return type.flags & 32768 /* Object */ && getSignaturesOfType(type, 0 /* Call */).length > 0;
         }
         function getTypeReferenceSerializationKind(typeName, location) {
+            // ensure both `typeName` and `location` are parse tree nodes.
+            typeName = ts.getParseTreeNode(typeName, 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, 107455 /* 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.
@@ -47563,6 +47595,17 @@ var ts;
         /*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, 26 /* CommaToken */, right);
     }
@@ -48963,9 +49006,31 @@ var ts;
             case 288 /* 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 === 185 /* 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)) {
+        if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) {
             return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression));
         }
         return innerExpression;
@@ -50417,7 +50482,7 @@ var ts;
                         else {
                             // export class x { }
                             var name = node.name;
-                            if (!uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) {
+                            if (name && !uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) {
                                 multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
                                 uniqueExports.set(ts.unescapeLeadingUnderscores(name.escapedText), true);
                                 exportedNames = ts.append(exportedNames, name);
@@ -51435,10 +51500,12 @@ var ts;
                 ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */);
                 statements.push(statement);
                 ts.addRange(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, ts.createImmediatelyInvokedFunctionExpression(statements))
+                    /*type*/ undefined, iife)
                 ]));
                 ts.setOriginalNode(varStatement, node);
                 ts.setCommentRange(varStatement, node);
@@ -52541,7 +52608,7 @@ var ts;
                     var name = ts.getMutableClone(node);
                     name.flags &= ~8 /* Synthesized */;
                     name.original = undefined;
-                    name.parent = currentScope;
+                    name.parent = ts.getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node.
                     if (useFallback) {
                         return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(name), ts.createLiteral("undefined")), name);
                     }
@@ -54222,7 +54289,7 @@ var ts;
                         chunkObject.push(ts.createPropertyAssignment(p.name, ts.visitNode(p.initializer, visitor, ts.isExpression)));
                     }
                     else {
-                        chunkObject.push(e);
+                        chunkObject.push(ts.visitNode(e, visitor, ts.isObjectLiteralElementLike));
                     }
                 }
             }
@@ -55457,58 +55524,12 @@ var ts;
                 && node.kind === 219 /* ReturnStatement */
                 && !node.expression;
         }
-        function isClassLikeVariableStatement(node) {
-            if (!ts.isVariableStatement(node))
-                return false;
-            var variable = ts.singleOrUndefined(node.declarationList.declarations);
-            return variable
-                && variable.initializer
-                && ts.isIdentifier(variable.name)
-                && (ts.isClassLike(variable.initializer)
-                    || (ts.isAssignmentExpression(variable.initializer)
-                        && ts.isIdentifier(variable.initializer.left)
-                        && ts.isClassLike(variable.initializer.right)));
-        }
-        function isTypeScriptClassWrapper(node) {
-            var call = ts.tryCast(node, ts.isCallExpression);
-            if (!call || ts.isParseTreeNode(call) ||
-                ts.some(call.typeArguments) ||
-                ts.some(call.arguments)) {
-                return false;
-            }
-            var func = ts.tryCast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression);
-            if (!func || ts.isParseTreeNode(func) ||
-                ts.some(func.typeParameters) ||
-                ts.some(func.parameters) ||
-                func.type ||
-                !func.body) {
-                return false;
-            }
-            var statements = func.body.statements;
-            if (statements.length < 2) {
-                return false;
-            }
-            var firstStatement = statements[0];
-            if (ts.isParseTreeNode(firstStatement) ||
-                !ts.isClassLike(firstStatement) &&
-                    !isClassLikeVariableStatement(firstStatement)) {
-                return false;
-            }
-            var lastStatement = ts.elementAt(statements, -1);
-            var returnStatement = ts.tryCast(ts.isVariableStatement(lastStatement) ? ts.elementAt(statements, -2) : lastStatement, ts.isReturnStatement);
-            if (!returnStatement ||
-                !returnStatement.expression ||
-                !ts.isIdentifier(ts.skipOuterExpressions(returnStatement.expression))) {
-                return false;
-            }
-            return true;
-        }
         function shouldVisitNode(node) {
             return (node.transformFlags & 128 /* ContainsES2015 */) !== 0
                 || convertedLoopState !== undefined
                 || (hierarchyFacts & 4096 /* ConstructorWithCapturedSuper */ && (ts.isStatement(node) || (node.kind === 207 /* Block */)))
                 || (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node))
-                || isTypeScriptClassWrapper(node);
+                || (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) !== 0;
         }
         function visitor(node) {
             if (shouldVisitNode(node)) {
@@ -57643,7 +57664,7 @@ var ts;
          * @param node a CallExpression.
          */
         function visitCallExpression(node) {
-            if (isTypeScriptClassWrapper(node)) {
+            if (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) {
                 return visitTypeScriptClassWrapper(node);
             }
             if (node.transformFlags & 64 /* ES2015 */) {
@@ -57685,7 +57706,7 @@ var ts;
             //  }())
             // 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.skipOuterExpressions(node.expression), ts.isFunctionExpression).body;
+            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 of the
             // body (1), while all other statements are added to remainingStatements (2)
             var classStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 0, 1);
@@ -59725,8 +59746,13 @@ var ts;
         }
         function transformAndEmitContinueStatement(node) {
             var label = findContinueTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined);
-            ts.Debug.assert(label > 0, "Expected continue statment to point to a valid Label.");
-            emitBreak(label, /*location*/ node);
+            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) {
@@ -59739,8 +59765,13 @@ var ts;
         }
         function transformAndEmitBreakStatement(node) {
             var label = findBreakTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined);
-            ts.Debug.assert(label > 0, "Expected break statment to point to a valid Label.");
-            emitBreak(label, /*location*/ node);
+            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) {
@@ -60344,23 +60375,24 @@ var ts;
          * @param labelText An optional name of a containing labeled statement.
          */
         function findBreakTarget(labelText) {
-            ts.Debug.assert(blocks !== undefined);
-            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;
+            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;
+                else {
+                    for (var i = blockStack.length - 1; i >= 0; i--) {
+                        var block = blockStack[i];
+                        if (supportsUnlabeledBreak(block)) {
+                            return block.breakLabel;
+                        }
                     }
                 }
             }
@@ -60372,20 +60404,21 @@ var ts;
          * @param labelText An optional name of a containing labeled statement.
          */
         function findContinueTarget(labelText) {
-            ts.Debug.assert(blocks !== undefined);
-            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;
+            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;
+                else {
+                    for (var i = blockStack.length - 1; i >= 0; i--) {
+                        var block = blockStack[i];
+                        if (supportsUnlabeledContinue(block)) {
+                            return block.continueLabel;
+                        }
                     }
                 }
             }
@@ -61344,17 +61377,23 @@ var ts;
          */
         function addExportEqualsIfNeeded(statements, emitAsReturn) {
             if (currentModuleInfo.exportEquals) {
-                if (emitAsReturn) {
-                    var statement = ts.createReturn(currentModuleInfo.exportEquals.expression);
-                    ts.setTextRange(statement, currentModuleInfo.exportEquals);
-                    ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */);
-                    statements.push(statement);
-                }
-                else {
-                    var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), currentModuleInfo.exportEquals.expression));
-                    ts.setTextRange(statement, currentModuleInfo.exportEquals);
-                    ts.setEmitFlags(statement, 1536 /* NoComments */);
-                    statements.push(statement);
+                var expressionResult = importCallExpressionVisitor(currentModuleInfo.exportEquals.expression);
+                if (expressionResult) {
+                    if (expressionResult instanceof Array) {
+                        return ts.Debug.fail("export= expression should never be replaced with multiple expressions!");
+                    }
+                    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.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult));
+                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
+                        ts.setEmitFlags(statement, 1536 /* NoComments */);
+                        statements.push(statement);
+                    }
                 }
             }
         }
@@ -61899,7 +61938,7 @@ var ts;
                 return statements;
             }
             if (ts.hasModifier(decl, 1 /* Export */)) {
-                var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createIdentifier("default") : decl.name;
+                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) {
@@ -78138,12 +78177,11 @@ var ts;
             var bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true);
             var entry = bucket.get(path);
             if (!entry) {
-                ts.Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?");
                 // Have never seen this file with these settings.  Create a new source file for it.
                 var sourceFile = ts.createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false, scriptKind);
                 entry = {
                     sourceFile: sourceFile,
-                    languageServiceRefCount: 0,
+                    languageServiceRefCount: 1,
                     owners: []
                 };
                 bucket.set(path, entry);
@@ -78155,14 +78193,14 @@ var ts;
                 if (entry.sourceFile.version !== version) {
                     entry.sourceFile = ts.updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot));
                 }
-            }
-            // 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++;
+                // 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++;
+                }
             }
             return entry.sourceFile;
         }
@@ -89591,16 +89629,7 @@ var ts;
                     if (errors) {
                         return { errors: errors };
                     }
-                    // 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)
-                    var range = ts.isStatement(start)
-                        ? [start]
-                        : start.parent && start.parent.kind === 210 /* ExpressionStatement */
-                            ? [start.parent]
-                            : start;
-                    return { targetRange: { range: range, facts: rangeFacts, declarations: declarations } };
+                    return { targetRange: { range: getStatementOrExpressionRange(start), facts: rangeFacts, declarations: declarations } };
                 }
                 function createErrorResult(sourceFile, start, length, message) {
                     return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] };
@@ -89802,6 +89831,19 @@ var ts;
                 }
             }
             extractMethod_1.getRangeToExtract = getRangeToExtract;
+            function getStatementOrExpressionRange(node) {
+                if (ts.isStatement(node)) {
+                    return [node];
+                }
+                else if (ts.isPartOfExpression(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 isValidExtractionTarget(node) {
                 // Note that we don't use isFunctionLike because we don't want to put the extracted closure *inside* a method
                 return (node.kind === 228 /* FunctionDeclaration */) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node);
@@ -89889,32 +89931,32 @@ var ts;
                             return "constructor";
                         case 186 /* FunctionExpression */:
                             return scope.name
-                                ? "function expression " + scope.name.getText()
+                                ? "function expression " + scope.name.text
                                 : "anonymous function expression";
                         case 228 /* FunctionDeclaration */:
-                            return "function " + scope.name.getText();
+                            return "function '" + scope.name.text + "'";
                         case 187 /* ArrowFunction */:
                             return "arrow function";
                         case 151 /* MethodDeclaration */:
-                            return "method " + scope.name.getText();
+                            return "method '" + scope.name.getText();
                         case 153 /* GetAccessor */:
-                            return "get " + scope.name.getText();
+                            return "'get " + scope.name.getText() + "'";
                         case 154 /* SetAccessor */:
-                            return "set " + scope.name.getText();
+                            return "'set " + scope.name.getText() + "'";
                     }
                 }
                 else if (isModuleBlock(scope)) {
-                    return "namespace " + scope.parent.name.getText();
+                    return "namespace '" + scope.parent.name.getText() + "'";
                 }
                 else if (ts.isClassLike(scope)) {
                     return scope.kind === 229 /* ClassDeclaration */
-                        ? "class " + scope.name.text
+                        ? "class '" + scope.name.text + "'"
                         : scope.name.text
-                            ? "class expression " + scope.name.text
+                            ? "class expression '" + scope.name.text + "'"
                             : "anonymous class expression";
                 }
                 else if (ts.isSourceFile(scope)) {
-                    return "file '" + scope.fileName + "'";
+                    return scope.externalModuleIndicator ? "module scope" : "global scope";
                 }
                 else {
                     return "unknown";
diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts
index c41b2e6..7051b32 100644
--- a/lib/typescriptServices.d.ts
+++ b/lib/typescriptServices.d.ts
@@ -3388,6 +3388,8 @@ declare namespace ts {
     function updateBundle(node: Bundle, sourceFiles: SourceFile[]): Bundle;
     function createImmediatelyInvokedFunctionExpression(statements: Statement[]): CallExpression;
     function createImmediatelyInvokedFunctionExpression(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression;
+    function createImmediatelyInvokedArrowFunction(statements: Statement[]): CallExpression;
+    function createImmediatelyInvokedArrowFunction(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression;
     function createComma(left: Expression, right: Expression): Expression;
     function createLessThan(left: Expression, right: Expression): Expression;
     function createAssignment(left: ObjectLiteralExpression | ArrayLiteralExpression, right: Expression): DestructuringAssignment;
diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js
index 3b497d4..d8b7626 100644
--- a/lib/typescriptServices.js
+++ b/lib/typescriptServices.js
@@ -1201,6 +1201,7 @@ var ts;
         EmitFlags[EmitFlags["HasEndOfDeclarationMarker"] = 4194304] = "HasEndOfDeclarationMarker";
         EmitFlags[EmitFlags["Iterator"] = 8388608] = "Iterator";
         EmitFlags[EmitFlags["NoAsciiEscaping"] = 16777216] = "NoAsciiEscaping";
+        /*@internal*/ EmitFlags[EmitFlags["TypeScriptClassWrapper"] = 33554432] = "TypeScriptClassWrapper";
     })(EmitFlags = ts.EmitFlags || (ts.EmitFlags = {}));
     /**
      * Used by the checker, this enum keeps track of external emit helpers that should be type
@@ -1348,7 +1349,7 @@ var ts;
     // If changing the text in this section, be sure to test `configureNightly` too.
     ts.versionMajorMinor = "2.5";
     /** The version of the TypeScript compiler release */
-    ts.version = ts.versionMajorMinor + ".1";
+    ts.version = ts.versionMajorMinor + ".2";
 })(ts || (ts = {}));
 /* @internal */
 (function (ts) {
@@ -5080,7 +5081,7 @@ var ts;
         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_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"),
-        Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"),
+        Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into {0}"),
     };
 })(ts || (ts = {}));
 /// <reference path="core.ts"/>
@@ -8844,9 +8845,9 @@ var ts;
             || kind === 265 /* SourceFile */;
     }
     ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment;
-    function nodeIsSynthesized(node) {
-        return ts.positionIsSynthesized(node.pos)
-            || ts.positionIsSynthesized(node.end);
+    function nodeIsSynthesized(range) {
+        return ts.positionIsSynthesized(range.pos)
+            || ts.positionIsSynthesized(range.end);
     }
     ts.nodeIsSynthesized = nodeIsSynthesized;
     function getOriginalSourceFile(sourceFile) {
@@ -23319,12 +23320,17 @@ var ts;
             // 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)
-            if (usage.parent.kind === 246 /* ExportSpecifier */) {
+            if (usage.parent.kind === 246 /* ExportSpecifier */ || (usage.parent.kind === 243 /* 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 === 243 /* ExportAssignment */ && usage.isExportEquals) {
+                return true;
+            }
             var container = ts.getEnclosingBlockScopeContainer(declaration);
             return isInTypeQuery(usage) || isUsedInFunctionOrInstanceProperty(usage, declaration, container);
             function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage) {
@@ -28615,6 +28621,9 @@ var ts;
             }
             return signature.resolvedReturnType;
         }
+        function isResolvingReturnTypeOfSignature(signature) {
+            return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3 /* ResolvedReturnType */) >= 0;
+        }
         function getRestTypeOfSignature(signature) {
             if (signature.hasRestParameter) {
                 var type = getTypeOfSymbol(ts.lastOrUndefined(signature.parameters));
@@ -34496,7 +34505,7 @@ var ts;
             // 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) {
+            if (signature && !isResolvingReturnTypeOfSignature(signature)) {
                 return getReturnTypeOfSignature(signature);
             }
             return undefined;
@@ -37549,7 +37558,7 @@ var ts;
          * file.
          */
         function isJavaScriptConstructor(node) {
-            if (ts.isInJavaScriptFile(node)) {
+            if (node && ts.isInJavaScriptFile(node)) {
                 // If the node has a @class tag, treat it like a constructor.
                 if (ts.getJSDocClassTag(node))
                     return true;
@@ -37561,6 +37570,20 @@ var ts;
             }
             return false;
         }
+        function getJavaScriptClassType(symbol) {
+            if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) {
+                symbol = getSymbolOfNode(symbol.valueDeclaration.initializer);
+            }
+            if (isJavaScriptConstructor(symbol.valueDeclaration)) {
+                return getInferredClassType(symbol);
+            }
+            if (symbol.flags & 3 /* Variable */) {
+                var valueType = getTypeOfSymbol(symbol);
+                if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) {
+                    return getInferredClassType(valueType.symbol);
+                }
+            }
+        }
         function getInferredClassType(symbol) {
             var links = getSymbolLinks(symbol);
             if (!links.inferredClassType) {
@@ -37600,13 +37623,11 @@ var ts;
                     var funcSymbol = node.expression.kind === 71 /* Identifier */ ?
                         getResolvedSymbol(node.expression) :
                         checkExpression(node.expression).symbol;
-                    if (funcSymbol && ts.isDeclarationOfFunctionOrClassExpression(funcSymbol)) {
-                        funcSymbol = getSymbolOfNode(funcSymbol.valueDeclaration.initializer);
-                    }
-                    if (funcSymbol && funcSymbol.flags & 16 /* Function */ && (funcSymbol.members || ts.getJSDocClassTag(funcSymbol.valueDeclaration))) {
-                        return getInferredClassType(funcSymbol);
+                    var type = funcSymbol && getJavaScriptClassType(funcSymbol);
+                    if (type) {
+                        return type;
                     }
-                    else if (noImplicitAny) {
+                    if (noImplicitAny) {
                         error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
                     }
                     return anyType;
@@ -40064,6 +40085,8 @@ var ts;
                             : 4 /* ExportNamespace */;
                     case 229 /* ClassDeclaration */:
                     case 232 /* EnumDeclaration */:
+                    // A NamespaceImport declares an Alias, which is allowed to merge with other values within the module
+                    case 240 /* NamespaceImport */:
                         return 2 /* ExportType */ | 1 /* ExportValue */;
                     case 237 /* ImportEqualsDeclaration */:
                         var result_3 = 0 /* None */;
@@ -43921,6 +43944,15 @@ var ts;
             return type.flags & 32768 /* Object */ && getSignaturesOfType(type, 0 /* Call */).length > 0;
         }
         function getTypeReferenceSerializationKind(typeName, location) {
+            // ensure both `typeName` and `location` are parse tree nodes.
+            typeName = ts.getParseTreeNode(typeName, 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, 107455 /* 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.
@@ -47563,6 +47595,17 @@ var ts;
         /*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, 26 /* CommaToken */, right);
     }
@@ -48963,9 +49006,31 @@ var ts;
             case 288 /* 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 === 185 /* 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)) {
+        if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) {
             return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression));
         }
         return innerExpression;
@@ -50417,7 +50482,7 @@ var ts;
                         else {
                             // export class x { }
                             var name = node.name;
-                            if (!uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) {
+                            if (name && !uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) {
                                 multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
                                 uniqueExports.set(ts.unescapeLeadingUnderscores(name.escapedText), true);
                                 exportedNames = ts.append(exportedNames, name);
@@ -51435,10 +51500,12 @@ var ts;
                 ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */);
                 statements.push(statement);
                 ts.addRange(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, ts.createImmediatelyInvokedFunctionExpression(statements))
+                    /*type*/ undefined, iife)
                 ]));
                 ts.setOriginalNode(varStatement, node);
                 ts.setCommentRange(varStatement, node);
@@ -52541,7 +52608,7 @@ var ts;
                     var name = ts.getMutableClone(node);
                     name.flags &= ~8 /* Synthesized */;
                     name.original = undefined;
-                    name.parent = currentScope;
+                    name.parent = ts.getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node.
                     if (useFallback) {
                         return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(name), ts.createLiteral("undefined")), name);
                     }
@@ -54222,7 +54289,7 @@ var ts;
                         chunkObject.push(ts.createPropertyAssignment(p.name, ts.visitNode(p.initializer, visitor, ts.isExpression)));
                     }
                     else {
-                        chunkObject.push(e);
+                        chunkObject.push(ts.visitNode(e, visitor, ts.isObjectLiteralElementLike));
                     }
                 }
             }
@@ -55457,58 +55524,12 @@ var ts;
                 && node.kind === 219 /* ReturnStatement */
                 && !node.expression;
         }
-        function isClassLikeVariableStatement(node) {
-            if (!ts.isVariableStatement(node))
-                return false;
-            var variable = ts.singleOrUndefined(node.declarationList.declarations);
-            return variable
-                && variable.initializer
-                && ts.isIdentifier(variable.name)
-                && (ts.isClassLike(variable.initializer)
-                    || (ts.isAssignmentExpression(variable.initializer)
-                        && ts.isIdentifier(variable.initializer.left)
-                        && ts.isClassLike(variable.initializer.right)));
-        }
-        function isTypeScriptClassWrapper(node) {
-            var call = ts.tryCast(node, ts.isCallExpression);
-            if (!call || ts.isParseTreeNode(call) ||
-                ts.some(call.typeArguments) ||
-                ts.some(call.arguments)) {
-                return false;
-            }
-            var func = ts.tryCast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression);
-            if (!func || ts.isParseTreeNode(func) ||
-                ts.some(func.typeParameters) ||
-                ts.some(func.parameters) ||
-                func.type ||
-                !func.body) {
-                return false;
-            }
-            var statements = func.body.statements;
-            if (statements.length < 2) {
-                return false;
-            }
-            var firstStatement = statements[0];
-            if (ts.isParseTreeNode(firstStatement) ||
-                !ts.isClassLike(firstStatement) &&
-                    !isClassLikeVariableStatement(firstStatement)) {
-                return false;
-            }
-            var lastStatement = ts.elementAt(statements, -1);
-            var returnStatement = ts.tryCast(ts.isVariableStatement(lastStatement) ? ts.elementAt(statements, -2) : lastStatement, ts.isReturnStatement);
-            if (!returnStatement ||
-                !returnStatement.expression ||
-                !ts.isIdentifier(ts.skipOuterExpressions(returnStatement.expression))) {
-                return false;
-            }
-            return true;
-        }
         function shouldVisitNode(node) {
             return (node.transformFlags & 128 /* ContainsES2015 */) !== 0
                 || convertedLoopState !== undefined
                 || (hierarchyFacts & 4096 /* ConstructorWithCapturedSuper */ && (ts.isStatement(node) || (node.kind === 207 /* Block */)))
                 || (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node))
-                || isTypeScriptClassWrapper(node);
+                || (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) !== 0;
         }
         function visitor(node) {
             if (shouldVisitNode(node)) {
@@ -57643,7 +57664,7 @@ var ts;
          * @param node a CallExpression.
          */
         function visitCallExpression(node) {
-            if (isTypeScriptClassWrapper(node)) {
+            if (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) {
                 return visitTypeScriptClassWrapper(node);
             }
             if (node.transformFlags & 64 /* ES2015 */) {
@@ -57685,7 +57706,7 @@ var ts;
             //  }())
             // 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.skipOuterExpressions(node.expression), ts.isFunctionExpression).body;
+            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 of the
             // body (1), while all other statements are added to remainingStatements (2)
             var classStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 0, 1);
@@ -59725,8 +59746,13 @@ var ts;
         }
         function transformAndEmitContinueStatement(node) {
             var label = findContinueTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined);
-            ts.Debug.assert(label > 0, "Expected continue statment to point to a valid Label.");
-            emitBreak(label, /*location*/ node);
+            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) {
@@ -59739,8 +59765,13 @@ var ts;
         }
         function transformAndEmitBreakStatement(node) {
             var label = findBreakTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined);
-            ts.Debug.assert(label > 0, "Expected break statment to point to a valid Label.");
-            emitBreak(label, /*location*/ node);
+            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) {
@@ -60344,23 +60375,24 @@ var ts;
          * @param labelText An optional name of a containing labeled statement.
          */
         function findBreakTarget(labelText) {
-            ts.Debug.assert(blocks !== undefined);
-            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;
+            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;
+                else {
+                    for (var i = blockStack.length - 1; i >= 0; i--) {
+                        var block = blockStack[i];
+                        if (supportsUnlabeledBreak(block)) {
+                            return block.breakLabel;
+                        }
                     }
                 }
             }
@@ -60372,20 +60404,21 @@ var ts;
          * @param labelText An optional name of a containing labeled statement.
          */
         function findContinueTarget(labelText) {
-            ts.Debug.assert(blocks !== undefined);
-            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;
+            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;
+                else {
+                    for (var i = blockStack.length - 1; i >= 0; i--) {
+                        var block = blockStack[i];
+                        if (supportsUnlabeledContinue(block)) {
+                            return block.continueLabel;
+                        }
                     }
                 }
             }
@@ -61344,17 +61377,23 @@ var ts;
          */
         function addExportEqualsIfNeeded(statements, emitAsReturn) {
             if (currentModuleInfo.exportEquals) {
-                if (emitAsReturn) {
-                    var statement = ts.createReturn(currentModuleInfo.exportEquals.expression);
-                    ts.setTextRange(statement, currentModuleInfo.exportEquals);
-                    ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */);
-                    statements.push(statement);
-                }
-                else {
-                    var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), currentModuleInfo.exportEquals.expression));
-                    ts.setTextRange(statement, currentModuleInfo.exportEquals);
-                    ts.setEmitFlags(statement, 1536 /* NoComments */);
-                    statements.push(statement);
+                var expressionResult = importCallExpressionVisitor(currentModuleInfo.exportEquals.expression);
+                if (expressionResult) {
+                    if (expressionResult instanceof Array) {
+                        return ts.Debug.fail("export= expression should never be replaced with multiple expressions!");
+                    }
+                    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.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult));
+                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
+                        ts.setEmitFlags(statement, 1536 /* NoComments */);
+                        statements.push(statement);
+                    }
                 }
             }
         }
@@ -61899,7 +61938,7 @@ var ts;
                 return statements;
             }
             if (ts.hasModifier(decl, 1 /* Export */)) {
-                var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createIdentifier("default") : decl.name;
+                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) {
@@ -78138,12 +78177,11 @@ var ts;
             var bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true);
             var entry = bucket.get(path);
             if (!entry) {
-                ts.Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?");
                 // Have never seen this file with these settings.  Create a new source file for it.
                 var sourceFile = ts.createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false, scriptKind);
                 entry = {
                     sourceFile: sourceFile,
-                    languageServiceRefCount: 0,
+                    languageServiceRefCount: 1,
                     owners: []
                 };
                 bucket.set(path, entry);
@@ -78155,14 +78193,14 @@ var ts;
                 if (entry.sourceFile.version !== version) {
                     entry.sourceFile = ts.updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot));
                 }
-            }
-            // 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++;
+                // 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++;
+                }
             }
             return entry.sourceFile;
         }
@@ -89591,16 +89629,7 @@ var ts;
                     if (errors) {
                         return { errors: errors };
                     }
-                    // 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)
-                    var range = ts.isStatement(start)
-                        ? [start]
-                        : start.parent && start.parent.kind === 210 /* ExpressionStatement */
-                            ? [start.parent]
-                            : start;
-                    return { targetRange: { range: range, facts: rangeFacts, declarations: declarations } };
+                    return { targetRange: { range: getStatementOrExpressionRange(start), facts: rangeFacts, declarations: declarations } };
                 }
                 function createErrorResult(sourceFile, start, length, message) {
                     return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] };
@@ -89802,6 +89831,19 @@ var ts;
                 }
             }
             extractMethod_1.getRangeToExtract = getRangeToExtract;
+            function getStatementOrExpressionRange(node) {
+                if (ts.isStatement(node)) {
+                    return [node];
+                }
+                else if (ts.isPartOfExpression(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 isValidExtractionTarget(node) {
                 // Note that we don't use isFunctionLike because we don't want to put the extracted closure *inside* a method
                 return (node.kind === 228 /* FunctionDeclaration */) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node);
@@ -89889,32 +89931,32 @@ var ts;
                             return "constructor";
                         case 186 /* FunctionExpression */:
                             return scope.name
-                                ? "function expression " + scope.name.getText()
+                                ? "function expression " + scope.name.text
                                 : "anonymous function expression";
                         case 228 /* FunctionDeclaration */:
-                            return "function " + scope.name.getText();
+                            return "function '" + scope.name.text + "'";
                         case 187 /* ArrowFunction */:
                             return "arrow function";
                         case 151 /* MethodDeclaration */:
-                            return "method " + scope.name.getText();
+                            return "method '" + scope.name.getText();
                         case 153 /* GetAccessor */:
-                            return "get " + scope.name.getText();
+                            return "'get " + scope.name.getText() + "'";
                         case 154 /* SetAccessor */:
-                            return "set " + scope.name.getText();
+                            return "'set " + scope.name.getText() + "'";
                     }
                 }
                 else if (isModuleBlock(scope)) {
-                    return "namespace " + scope.parent.name.getText();
+                    return "namespace '" + scope.parent.name.getText() + "'";
                 }
                 else if (ts.isClassLike(scope)) {
                     return scope.kind === 229 /* ClassDeclaration */
-                        ? "class " + scope.name.text
+                        ? "class '" + scope.name.text + "'"
                         : scope.name.text
-                            ? "class expression " + scope.name.text
+                            ? "class expression '" + scope.name.text + "'"
                             : "anonymous class expression";
                 }
                 else if (ts.isSourceFile(scope)) {
-                    return "file '" + scope.fileName + "'";
+                    return scope.externalModuleIndicator ? "module scope" : "global scope";
                 }
                 else {
                     return "unknown";
diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js
index 9f38426..f92f5af 100644
--- a/lib/typingsInstaller.js
+++ b/lib/typingsInstaller.js
@@ -162,7 +162,7 @@ var ts;
 var ts;
 (function (ts) {
     ts.versionMajorMinor = "2.5";
-    ts.version = ts.versionMajorMinor + ".1";
+    ts.version = ts.versionMajorMinor + ".2";
 })(ts || (ts = {}));
 (function (ts) {
     ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined;
@@ -3531,7 +3531,7 @@ var ts;
         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_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"),
-        Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"),
+        Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into {0}"),
     };
 })(ts || (ts = {}));
 var ts;
@@ -5290,9 +5290,9 @@ var ts;
             || kind === 265;
     }
     ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment;
-    function nodeIsSynthesized(node) {
-        return ts.positionIsSynthesized(node.pos)
-            || ts.positionIsSynthesized(node.end);
+    function nodeIsSynthesized(range) {
+        return ts.positionIsSynthesized(range.pos)
+            || ts.positionIsSynthesized(range.end);
     }
     ts.nodeIsSynthesized = nodeIsSynthesized;
     function getOriginalSourceFile(sourceFile) {
@@ -17565,6 +17565,7 @@ var ts;
                     }
                 };
                 TypingsInstaller.prototype.install = function (req) {
+                    var _this = this;
                     if (this.log.isEnabled()) {
                         this.log.writeLine("Got install request " + JSON.stringify(req));
                     }
@@ -17577,7 +17578,7 @@ var ts;
                     if (this.safeList === undefined) {
                         this.safeList = ts.JsTyping.loadSafeList(this.installTypingHost, this.safeListPath);
                     }
-                    var discoverTypingsResult = ts.JsTyping.discoverTypings(this.installTypingHost, this.log.isEnabled() ? this.log.writeLine : undefined, req.fileNames, req.projectRootPath, this.safeList, this.packageNameToTypingLocation, req.typeAcquisition, req.unresolvedImports);
+                    var discoverTypingsResult = ts.JsTyping.discoverTypings(this.installTypingHost, this.log.isEnabled() ? (function (s) { return _this.log.writeLine(s); }) : undefined, req.fileNames, req.projectRootPath, this.safeList, this.packageNameToTypingLocation, req.typeAcquisition, req.unresolvedImports);
                     if (this.log.isEnabled()) {
                         this.log.writeLine("Finished typings discovery: " + JSON.stringify(discoverTypingsResult));
                     }
@@ -17919,7 +17920,7 @@ var ts;
                         if (_this.log.isEnabled()) {
                             _this.log.writeLine("Updating " + TypesRegistryPackageName + " npm package...");
                         }
-                        _this.execSync(_this.npmPath + " install " + TypesRegistryPackageName, { cwd: globalTypingsCacheLocation, stdio: "ignore" });
+                        _this.execSync(_this.npmPath + " install --ignore-scripts " + TypesRegistryPackageName, { cwd: globalTypingsCacheLocation, stdio: "ignore" });
                         if (_this.log.isEnabled()) {
                             _this.log.writeLine("Updated " + TypesRegistryPackageName + " npm package");
                         }
@@ -17965,7 +17966,7 @@ var ts;
                     if (this.log.isEnabled()) {
                         this.log.writeLine("#" + requestId + " with arguments'" + JSON.stringify(args) + "'.");
                     }
-                    var command = this.npmPath + " install " + args.join(" ") + " --save-dev --user-agent=\"typesInstaller/" + ts.version + "\"";
+                    var command = this.npmPath + " install --ignore-scripts " + args.join(" ") + " --save-dev --user-agent=\"typesInstaller/" + ts.version + "\"";
                     var start = Date.now();
                     var stdout;
                     var stderr;
diff --git a/package.json b/package.json
index 845c371..f9424a1 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
     "name": "typescript",
     "author": "Microsoft Corp.",
     "homepage": "http://typescriptlang.org/",
-    "version": "2.5.1",
+    "version": "2.5.2",
     "license": "Apache-2.0",
     "description": "TypeScript is a language for application scale JavaScript development",
     "keywords": [
diff --git a/scripts/buildProtocol.ts b/scripts/buildProtocol.ts
index e03338b..c2ac33c 100644
--- a/scripts/buildProtocol.ts
+++ b/scripts/buildProtocol.ts
@@ -7,11 +7,15 @@ function endsWith(s: string, suffix: string) {
     return s.lastIndexOf(suffix, s.length - suffix.length) !== -1;
 }
 
+function isStringEnum(declaration: ts.EnumDeclaration) {
+    return declaration.members.length && declaration.members.every(m => m.initializer && m.initializer.kind === ts.SyntaxKind.StringLiteral);
+}
+
 class DeclarationsWalker {
     private visitedTypes: ts.Type[] = [];
     private text = "";
     private removedTypes: ts.Type[] = [];
-    
+
     private constructor(private typeChecker: ts.TypeChecker, private protocolFile: ts.SourceFile) {
     }
 
@@ -19,7 +23,7 @@ class DeclarationsWalker {
         let text = "declare namespace ts.server.protocol {\n";
         var walker = new DeclarationsWalker(typeChecker, protocolFile);
         walker.visitTypeNodes(protocolFile);
-        text = walker.text 
+        text = walker.text
             ? `declare namespace ts.server.protocol {\n${walker.text}}`
             : "";
         if (walker.removedTypes) {
@@ -52,7 +56,7 @@ class DeclarationsWalker {
                 if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") {
                     return;
                 }
-                if (decl.kind === ts.SyntaxKind.EnumDeclaration) {
+                if (decl.kind === ts.SyntaxKind.EnumDeclaration && !isStringEnum(decl as ts.EnumDeclaration)) {
                     this.removedTypes.push(type);
                     return;
                 }
@@ -91,7 +95,7 @@ class DeclarationsWalker {
                         for (const type of heritageClauses[0].types) {
                             this.processTypeOfNode(type);
                         }
-                    } 
+                    }
                     break;
             }
         }
@@ -110,7 +114,7 @@ class DeclarationsWalker {
                 this.processType(type);
             }
         }
-    } 
+    }
 }
 
 function writeProtocolFile(outputFile: string, protocolTs: string, typeScriptServicesDts: string) {
diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 15fd97c..1c650a3 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -791,12 +791,17 @@ namespace ts {
             // 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)
-            if (usage.parent.kind === SyntaxKind.ExportSpecifier) {
+            if (usage.parent.kind === SyntaxKind.ExportSpecifier || (usage.parent.kind === SyntaxKind.ExportAssignment && (usage.parent as ExportAssignment).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 === SyntaxKind.ExportAssignment && (usage as ExportAssignment).isExportEquals) {
+                return true;
+            }
 
             const container = getEnclosingBlockScopeContainer(declaration);
             return isInTypeQuery(usage) || isUsedInFunctionOrInstanceProperty(usage, declaration, container);
@@ -6579,6 +6584,10 @@ namespace ts {
             return signature.resolvedReturnType;
         }
 
+        function isResolvingReturnTypeOfSignature(signature: Signature) {
+            return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, TypeSystemPropertyName.ResolvedReturnType) >= 0;
+        }
+
         function getRestTypeOfSignature(signature: Signature): Type {
             if (signature.hasRestParameter) {
                 const type = getTypeOfSymbol(lastOrUndefined(signature.parameters));
@@ -12952,7 +12961,7 @@ namespace ts {
             // 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
             const signature = getContextualSignatureForFunctionLikeDeclaration(<FunctionExpression>functionDecl);
-            if (signature) {
+            if (signature && !isResolvingReturnTypeOfSignature(signature)) {
                 return getReturnTypeOfSignature(signature);
             }
 
@@ -16318,8 +16327,8 @@ namespace ts {
          * Indicates whether a declaration can be treated as a constructor in a JavaScript
          * file.
          */
-        function isJavaScriptConstructor(node: Declaration): boolean {
-            if (isInJavaScriptFile(node)) {
+        function isJavaScriptConstructor(node: Declaration | undefined): boolean {
+            if (node && isInJavaScriptFile(node)) {
                 // If the node has a @class tag, treat it like a constructor.
                 if (getJSDocClassTag(node)) return true;
 
@@ -16334,6 +16343,21 @@ namespace ts {
             return false;
         }
 
+        function getJavaScriptClassType(symbol: Symbol): Type | undefined {
+            if (isDeclarationOfFunctionOrClassExpression(symbol)) {
+                symbol = getSymbolOfNode((<VariableDeclaration>symbol.valueDeclaration).initializer);
+            }
+            if (isJavaScriptConstructor(symbol.valueDeclaration)) {
+                return getInferredClassType(symbol);
+            }
+            if (symbol.flags & SymbolFlags.Variable) {
+                const valueType = getTypeOfSymbol(symbol);
+                if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) {
+                    return getInferredClassType(valueType.symbol);
+                }
+            }
+        }
+
         function getInferredClassType(symbol: Symbol) {
             const links = getSymbolLinks(symbol);
             if (!links.inferredClassType) {
@@ -16377,16 +16401,14 @@ namespace ts {
                     // in a JS file
                     // Note:JS inferred classes might come from a variable declaration instead of a function declaration.
                     // In this case, using getResolvedSymbol directly is required to avoid losing the members from the declaration.
-                    let funcSymbol = node.expression.kind === SyntaxKind.Identifier ?
+                    const funcSymbol = node.expression.kind === SyntaxKind.Identifier ?
                         getResolvedSymbol(node.expression as Identifier) :
                         checkExpression(node.expression).symbol;
-                    if (funcSymbol && isDeclarationOfFunctionOrClassExpression(funcSymbol)) {
-                        funcSymbol = getSymbolOfNode((<VariableDeclaration>funcSymbol.valueDeclaration).initializer);
-                    }
-                    if (funcSymbol && funcSymbol.flags & SymbolFlags.Function && (funcSymbol.members || getJSDocClassTag(funcSymbol.valueDeclaration))) {
-                        return getInferredClassType(funcSymbol);
+                    const type = funcSymbol && getJavaScriptClassType(funcSymbol);
+                    if (type) {
+                        return type;
                     }
-                    else if (noImplicitAny) {
+                    if (noImplicitAny) {
                         error(node, Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
                     }
                     return anyType;
@@ -19104,6 +19126,8 @@ namespace ts {
                             : DeclarationSpaces.ExportNamespace;
                     case SyntaxKind.ClassDeclaration:
                     case SyntaxKind.EnumDeclaration:
+                    // A NamespaceImport declares an Alias, which is allowed to merge with other values within the module
+                    case SyntaxKind.NamespaceImport:
                         return DeclarationSpaces.ExportType | DeclarationSpaces.ExportValue;
                     case SyntaxKind.ImportEqualsDeclaration:
                         let result = DeclarationSpaces.None;
@@ -23430,6 +23454,15 @@ namespace ts {
         }
 
         function getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind {
+            // ensure both `typeName` and `location` are parse tree nodes.
+            typeName = getParseTreeNode(typeName, isEntityName);
+            if (!typeName) return TypeReferenceSerializationKind.Unknown;
+
+            if (location) {
+                location = getParseTreeNode(location);
+                if (!location) return TypeReferenceSerializationKind.Unknown;
+            }
+
             // Resolve the symbol as a value to ensure the type can be reached at runtime during emit.
             const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
 
diff --git a/src/compiler/core.ts b/src/compiler/core.ts
index eea8793..8e2ef6e 100644
--- a/src/compiler/core.ts
+++ b/src/compiler/core.ts
@@ -6,7 +6,7 @@ namespace ts {
     // If changing the text in this section, be sure to test `configureNightly` too.
     export const versionMajorMinor = "2.5";
     /** The version of the TypeScript compiler release */
-    export const version = `${versionMajorMinor}.1`;
+    export const version = `${versionMajorMinor}.2`;
 }
 
 /* @internal */
diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json
index 77e7f7e..974224e 100644
--- a/src/compiler/diagnosticMessages.json
+++ b/src/compiler/diagnosticMessages.json
@@ -3688,7 +3688,7 @@
         "code": 95003
     },
 
-    "Extract function into '{0}'": {
+    "Extract function into {0}": {
         "category": "Message",
         "code": 95004
     }
diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts
index daec1bc..04e6b55 100644
--- a/src/compiler/factory.ts
+++ b/src/compiler/factory.ts
@@ -2372,6 +2372,24 @@ namespace ts {
         );
     }
 
+    export function createImmediatelyInvokedArrowFunction(statements: Statement[]): CallExpression;
+    export function createImmediatelyInvokedArrowFunction(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression;
+    export function createImmediatelyInvokedArrowFunction(statements: Statement[], param?: ParameterDeclaration, paramValue?: Expression) {
+        return createCall(
+            createArrowFunction(
+                /*modifiers*/ undefined,
+                /*typeParameters*/ undefined,
+                /*parameters*/ param ? [param] : [],
+                /*type*/ undefined,
+                /*equalsGreaterThanToken*/ undefined,
+                createBlock(statements, /*multiLine*/ true)
+            ),
+            /*typeArguments*/ undefined,
+            /*argumentsArray*/ paramValue ? [paramValue] : []
+        );
+    }
+
+
     export function createComma(left: Expression, right: Expression) {
         return <Expression>createBinary(left, SyntaxKind.CommaToken, right);
     }
@@ -4040,8 +4058,31 @@ namespace ts {
         }
     }
 
+    /**
+     * 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: Expression) {
+        return node.kind === SyntaxKind.ParenthesizedExpression
+            && nodeIsSynthesized(node)
+            && nodeIsSynthesized(getSourceMapRange(node))
+            && nodeIsSynthesized(getCommentRange(node))
+            && !some(getSyntheticLeadingComments(node))
+            && !some(getSyntheticTrailingComments(node));
+    }
+
     export function recreateOuterExpressions(outerExpression: Expression | undefined, innerExpression: Expression, kinds = OuterExpressionKinds.All): Expression {
-        if (outerExpression && isOuterExpression(outerExpression, kinds)) {
+        if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) {
             return updateOuterExpression(
                 outerExpression,
                 recreateOuterExpressions(outerExpression.expression, innerExpression)
diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts
index ce907d4..e9c84be 100644
--- a/src/compiler/transformers/es2015.ts
+++ b/src/compiler/transformers/es2015.ts
@@ -339,64 +339,12 @@ namespace ts {
                 && !(<ReturnStatement>node).expression;
         }
 
-        function isClassLikeVariableStatement(node: Node) {
-            if (!isVariableStatement(node)) return false;
-            const variable = singleOrUndefined((<VariableStatement>node).declarationList.declarations);
-            return variable
-                && variable.initializer
-                && isIdentifier(variable.name)
-                && (isClassLike(variable.initializer)
-                    || (isAssignmentExpression(variable.initializer)
-                        && isIdentifier(variable.initializer.left)
-                        && isClassLike(variable.initializer.right)));
-        }
-
-        function isTypeScriptClassWrapper(node: Node) {
-            const call = tryCast(node, isCallExpression);
-            if (!call || isParseTreeNode(call) ||
-                some(call.typeArguments) ||
-                some(call.arguments)) {
-                return false;
-            }
-
-            const func = tryCast(skipOuterExpressions(call.expression), isFunctionExpression);
-            if (!func || isParseTreeNode(func) ||
-                some(func.typeParameters) ||
-                some(func.parameters) ||
-                func.type ||
-                !func.body) {
-                return false;
-            }
-
-            const statements = func.body.statements;
-            if (statements.length < 2) {
-                return false;
-            }
-
-            const firstStatement = statements[0];
-            if (isParseTreeNode(firstStatement) ||
-                !isClassLike(firstStatement) &&
-                !isClassLikeVariableStatement(firstStatement)) {
-                return false;
-            }
-
-            const lastStatement = elementAt(statements, -1);
-            const returnStatement = tryCast(isVariableStatement(lastStatement) ? elementAt(statements, -2) : lastStatement, isReturnStatement);
-            if (!returnStatement ||
-                !returnStatement.expression ||
-                !isIdentifier(skipOuterExpressions(returnStatement.expression))) {
-                return false;
-            }
-
-            return true;
-        }
-
         function shouldVisitNode(node: Node): boolean {
             return (node.transformFlags & TransformFlags.ContainsES2015) !== 0
                 || convertedLoopState !== undefined
                 || (hierarchyFacts & HierarchyFacts.ConstructorWithCapturedSuper && (isStatement(node) || (node.kind === SyntaxKind.Block)))
                 || (isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node))
-                || isTypeScriptClassWrapper(node);
+                || (getEmitFlags(node) & EmitFlags.TypeScriptClassWrapper) !== 0;
         }
 
         function visitor(node: Node): VisitResult<Node> {
@@ -3308,13 +3256,14 @@ namespace ts {
          * @param node a CallExpression.
          */
         function visitCallExpression(node: CallExpression) {
-            if (isTypeScriptClassWrapper(node)) {
+            if (getEmitFlags(node) & EmitFlags.TypeScriptClassWrapper) {
                 return visitTypeScriptClassWrapper(node);
             }
 
             if (node.transformFlags & TransformFlags.ES2015) {
                 return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ true);
             }
+
             return updateCall(
                 node,
                 visitNode(node.expression, callExpressionVisitor, isExpression),
@@ -3357,7 +3306,7 @@ namespace ts {
 
             // 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.
-            const body = cast(skipOuterExpressions(node.expression), isFunctionExpression).body;
+            const body = cast(cast(skipOuterExpressions(node.expression), isArrowFunction).body, isBlock);
 
             // The class statements are the statements generated by visiting the first statement of the
             // body (1), while all other statements are added to remainingStatements (2)
diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts
index 8d71016..3bdcc9e 100644
--- a/src/compiler/transformers/esnext.ts
+++ b/src/compiler/transformers/esnext.ts
@@ -158,8 +158,8 @@ namespace ts {
             return visitEachChild(node, visitor, context);
         }
 
-        function chunkObjectLiteralElements(elements: ReadonlyArray<ObjectLiteralElement>): Expression[] {
-            let chunkObject: (ShorthandPropertyAssignment | PropertyAssignment)[];
+        function chunkObjectLiteralElements(elements: ReadonlyArray<ObjectLiteralElementLike>): Expression[] {
+            let chunkObject: ObjectLiteralElementLike[];
             const objects: Expression[] = [];
             for (const e of elements) {
                 if (e.kind === SyntaxKind.SpreadAssignment) {
@@ -179,7 +179,7 @@ namespace ts {
                         chunkObject.push(createPropertyAssignment(p.name, visitNode(p.initializer, visitor, isExpression)));
                     }
                     else {
-                        chunkObject.push(e as ShorthandPropertyAssignment);
+                        chunkObject.push(visitNode(e, visitor, isObjectLiteralElementLike));
                     }
                 }
             }
diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts
index f45147b..20195ad 100644
--- a/src/compiler/transformers/generators.ts
+++ b/src/compiler/transformers/generators.ts
@@ -1639,8 +1639,13 @@ namespace ts {
 
         function transformAndEmitContinueStatement(node: ContinueStatement): void {
             const label = findContinueTarget(node.label ? unescapeLeadingUnderscores(node.label.escapedText) : undefined);
-            Debug.assert(label > 0, "Expected continue statment to point to a valid Label.");
-            emitBreak(label, /*location*/ node);
+            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: ContinueStatement): Statement {
@@ -1656,8 +1661,13 @@ namespace ts {
 
         function transformAndEmitBreakStatement(node: BreakStatement): void {
             const label = findBreakTarget(node.label ? unescapeLeadingUnderscores(node.label.escapedText) : undefined);
-            Debug.assert(label > 0, "Expected break statment to point to a valid Label.");
-            emitBreak(label, /*location*/ node);
+            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: BreakStatement): Statement {
@@ -2351,27 +2361,27 @@ namespace ts {
          * @param labelText An optional name of a containing labeled statement.
          */
         function findBreakTarget(labelText?: string): Label {
-            Debug.assert(blocks !== undefined);
-            if (labelText) {
-                for (let i = blockStack.length - 1; i >= 0; i--) {
-                    const block = blockStack[i];
-                    if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) {
-                        return block.breakLabel;
-                    }
-                    else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
-                        return block.breakLabel;
+            if (blockStack) {
+                if (labelText) {
+                    for (let i = blockStack.length - 1; i >= 0; i--) {
+                        const 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 (let i = blockStack.length - 1; i >= 0; i--) {
-                    const block = blockStack[i];
-                    if (supportsUnlabeledBreak(block)) {
-                        return block.breakLabel;
+                else {
+                    for (let i = blockStack.length - 1; i >= 0; i--) {
+                        const block = blockStack[i];
+                        if (supportsUnlabeledBreak(block)) {
+                            return block.breakLabel;
+                        }
                     }
                 }
             }
-
             return 0;
         }
 
@@ -2381,24 +2391,24 @@ namespace ts {
          * @param labelText An optional name of a containing labeled statement.
          */
         function findContinueTarget(labelText?: string): Label {
-            Debug.assert(blocks !== undefined);
-            if (labelText) {
-                for (let i = blockStack.length - 1; i >= 0; i--) {
-                    const block = blockStack[i];
-                    if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
-                        return block.continueLabel;
+            if (blockStack) {
+                if (labelText) {
+                    for (let i = blockStack.length - 1; i >= 0; i--) {
+                        const block = blockStack[i];
+                        if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
+                            return block.continueLabel;
+                        }
                     }
                 }
-            }
-            else {
-                for (let i = blockStack.length - 1; i >= 0; i--) {
-                    const block = blockStack[i];
-                    if (supportsUnlabeledContinue(block)) {
-                        return block.continueLabel;
+                else {
+                    for (let i = blockStack.length - 1; i >= 0; i--) {
+                        const block = blockStack[i];
+                        if (supportsUnlabeledContinue(block)) {
+                            return block.continueLabel;
+                        }
                     }
                 }
             }
-
             return 0;
         }
 
diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts
index 2c3133d..23bae87 100644
--- a/src/compiler/transformers/module/module.ts
+++ b/src/compiler/transformers/module/module.ts
@@ -430,26 +430,32 @@ namespace ts {
          */
         function addExportEqualsIfNeeded(statements: Statement[], emitAsReturn: boolean) {
             if (currentModuleInfo.exportEquals) {
-                if (emitAsReturn) {
-                    const statement = createReturn(currentModuleInfo.exportEquals.expression);
-                    setTextRange(statement, currentModuleInfo.exportEquals);
-                    setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments);
-                    statements.push(statement);
-                }
-                else {
-                    const statement = createStatement(
-                        createAssignment(
-                            createPropertyAccess(
-                                createIdentifier("module"),
-                                "exports"
-                            ),
-                            currentModuleInfo.exportEquals.expression
-                        )
-                    );
+                const expressionResult = importCallExpressionVisitor(currentModuleInfo.exportEquals.expression);
+                if (expressionResult) {
+                    if (expressionResult instanceof Array) {
+                        return Debug.fail("export= expression should never be replaced with multiple expressions!");
+                    }
+                    if (emitAsReturn) {
+                        const statement = createReturn(expressionResult);
+                        setTextRange(statement, currentModuleInfo.exportEquals);
+                        setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments);
+                        statements.push(statement);
+                    }
+                    else {
+                        const statement = createStatement(
+                            createAssignment(
+                                createPropertyAccess(
+                                    createIdentifier("module"),
+                                    "exports"
+                                ),
+                                expressionResult
+                            )
+                        );
 
-                    setTextRange(statement, currentModuleInfo.exportEquals);
-                    setEmitFlags(statement, EmitFlags.NoComments);
-                    statements.push(statement);
+                        setTextRange(statement, currentModuleInfo.exportEquals);
+                        setEmitFlags(statement, EmitFlags.NoComments);
+                        statements.push(statement);
+                    }
                 }
             }
         }
@@ -497,7 +503,7 @@ namespace ts {
             }
         }
 
-        function importCallExpressionVisitor(node: Node): VisitResult<Node> {
+        function importCallExpressionVisitor(node: Expression): VisitResult<Expression> {
             // This visitor does not need to descend into the tree if there is no dynamic import,
             // as export/import statements are only transformed at the top level of a file.
             if (!(node.transformFlags & TransformFlags.ContainsDynamicImport)) {
@@ -1204,7 +1210,7 @@ namespace ts {
             }
 
             if (hasModifier(decl, ModifierFlags.Export)) {
-                const exportName = hasModifier(decl, ModifierFlags.Default) ? createIdentifier("default") : decl.name;
+                const exportName = hasModifier(decl, ModifierFlags.Default) ? createIdentifier("default") : getDeclarationName(decl);
                 statements = appendExportStatement(statements, exportName, getLocalName(decl), /*location*/ decl);
             }
 
diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts
index 4c679ea..692c758 100644
--- a/src/compiler/transformers/ts.ts
+++ b/src/compiler/transformers/ts.ts
@@ -613,13 +613,16 @@ namespace ts {
 
                 addRange(statements, context.endLexicalEnvironment());
 
+                const iife = createImmediatelyInvokedArrowFunction(statements);
+                setEmitFlags(iife, EmitFlags.TypeScriptClassWrapper);
+
                 const varStatement = createVariableStatement(
                     /*modifiers*/ undefined,
                     createVariableDeclarationList([
                         createVariableDeclaration(
                             getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ false),
                             /*type*/ undefined,
-                            createImmediatelyInvokedFunctionExpression(statements)
+                            iife
                         )
                     ])
                 );
@@ -1944,7 +1947,7 @@ namespace ts {
                     const name = getMutableClone(<Identifier>node);
                     name.flags &= ~NodeFlags.Synthesized;
                     name.original = undefined;
-                    name.parent = currentScope;
+                    name.parent = getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node.
                     if (useFallback) {
                         return createLogicalAnd(
                             createStrictInequality(
diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts
index be99df6..f641ee4 100644
--- a/src/compiler/transformers/utilities.ts
+++ b/src/compiler/transformers/utilities.ts
@@ -124,7 +124,7 @@ namespace ts {
                         else {
                             // export class x { }
                             const name = (<ClassDeclaration>node).name;
-                            if (!uniqueExports.get(unescapeLeadingUnderscores(name.escapedText))) {
+                            if (name && !uniqueExports.get(unescapeLeadingUnderscores(name.escapedText))) {
                                 multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
                                 uniqueExports.set(unescapeLeadingUnderscores(name.escapedText), true);
                                 exportedNames = append(exportedNames, name);
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index e74529e..5a57245 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -4170,6 +4170,7 @@ namespace ts {
         HasEndOfDeclarationMarker = 1 << 22,    // Declaration has an associated NotEmittedStatement to mark the end of the declaration
         Iterator = 1 << 23,                     // The expression to a `yield*` should be treated as an Iterator when down-leveling, not an Iterable.
         NoAsciiEscaping = 1 << 24,              // When synthesizing nodes that lack an original node or textSourceNode, we want to write the text on the node with ASCII escaping substitutions.
+        /*@internal*/ TypeScriptClassWrapper = 1 << 25, // The node is an IIFE class wrapper created by the ts transform.
     }
 
     export interface EmitHelper {
diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts
index c77d267..25ba99c 100644
--- a/src/compiler/utilities.ts
+++ b/src/compiler/utilities.ts
@@ -2068,9 +2068,9 @@ namespace ts {
             || kind === SyntaxKind.SourceFile;
     }
 
-    export function nodeIsSynthesized(node: TextRange): boolean {
-        return positionIsSynthesized(node.pos)
-            || positionIsSynthesized(node.end);
+    export function nodeIsSynthesized(range: TextRange): boolean {
+        return positionIsSynthesized(range.pos)
+            || positionIsSynthesized(range.end);
     }
 
     export function getOriginalSourceFile(sourceFile: SourceFile) {
diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts
index 2b28ecb..77639dc 100644
--- a/src/harness/fourslash.ts
+++ b/src/harness/fourslash.ts
@@ -2743,20 +2743,25 @@ namespace FourSlash {
             });
         }
 
-        public verifyRefactorAvailable(negative: boolean, name?: string, subName?: string) {
+        public verifyRefactorAvailable(negative: boolean, name: string, actionName?: string) {
             const selection = this.getSelection();
 
             let refactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, selection) || [];
-            if (name) {
-                refactors = refactors.filter(r => r.name === name && (subName === undefined || r.actions.some(a => a.name === subName)));
-            }
+            refactors = refactors.filter(r => r.name === name && (actionName === undefined || r.actions.some(a => a.name === actionName)));
             const isAvailable = refactors.length > 0;
 
-            if (negative && isAvailable) {
-                this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected no refactor but found some: ${refactors.map(r => r.name).join(", ")}`);
+            if (negative) {
+                if (isAvailable) {
+                    this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected no refactor but found: ${refactors.map(r => r.name).join(", ")}`);
+                }
             }
-            else if (!negative && !isAvailable) {
-                this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected a refactor but found none.`);
+            else {
+                if (!isAvailable) {
+                    this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected a refactor but found none.`);
+                }
+                if (refactors.length > 1) {
+                    this.raiseError(`${refactors.length} available refactors both have name ${name} and action ${actionName}`);
+                }
             }
         }
 
@@ -2776,14 +2781,22 @@ namespace FourSlash {
             }
         }
 
-        public applyRefactor(refactorName: string, actionName: string) {
+        public applyRefactor({ refactorName, actionName, actionDescription }: FourSlashInterface.ApplyRefactorOptions) {
             const range = this.getSelection();
             const refactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, range);
-            const refactor = ts.find(refactors, r => r.name === refactorName);
+            const refactor = refactors.find(r => r.name === refactorName);
             if (!refactor) {
                 this.raiseError(`The expected refactor: ${refactorName} is not available at the marker location.`);
             }
 
+            const action = refactor.actions.find(a => a.name === actionName);
+            if (!action) {
+                this.raiseError(`The expected action: ${action} is not included in: ${refactor.actions.map(a => a.name)}`);
+            }
+            if (action.description !== actionDescription) {
+                this.raiseError(`Expected action description to be ${JSON.stringify(actionDescription)}, got: ${JSON.stringify(action.description)}`);
+            }
+
             const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, this.formatCodeSettings, range, refactorName, actionName);
             for (const edit of editInfo.edits) {
                 this.applyEdits(edit.fileName, edit.textChanges, /*isFormattingEdit*/ false);
@@ -3660,8 +3673,8 @@ namespace FourSlashInterface {
             this.state.verifyApplicableRefactorAvailableForRange(this.negative);
         }
 
-        public refactorAvailable(name?: string, subName?: string) {
-            this.state.verifyRefactorAvailable(this.negative, name, subName);
+        public refactorAvailable(name: string, actionName?: string) {
+            this.state.verifyRefactorAvailable(this.negative, name, actionName);
         }
     }
 
@@ -4059,8 +4072,8 @@ namespace FourSlashInterface {
             this.state.enableFormatting = false;
         }
 
-        public applyRefactor(refactorName: string, actionName: string) {
-            this.state.applyRefactor(refactorName, actionName);
+        public applyRefactor(options: ApplyRefactorOptions) {
+            this.state.applyRefactor(options);
         }
     }
 
@@ -4273,4 +4286,10 @@ namespace FourSlashInterface {
             return { classificationType, text, textSpan };
         }
     }
+
+    export interface ApplyRefactorOptions {
+        refactorName: string;
+        actionName: string;
+        actionDescription: string;
+    }
 }
diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json
index 66ca2fc..f8ad5e6 100644
--- a/src/harness/tsconfig.json
+++ b/src/harness/tsconfig.json
@@ -123,6 +123,7 @@
         "./unittests/printer.ts",
         "./unittests/transform.ts",
         "./unittests/customTransforms.ts",
+        "./unittests/extractMethods.ts",
         "./unittests/textChanges.ts",
         "./unittests/telemetry.ts",
         "./unittests/programMissingFiles.ts"
diff --git a/src/harness/unittests/customTransforms.ts b/src/harness/unittests/customTransforms.ts
index 4b05ebb..f47bdad 100644
--- a/src/harness/unittests/customTransforms.ts
+++ b/src/harness/unittests/customTransforms.ts
@@ -3,12 +3,11 @@
 
 namespace ts {
     describe("customTransforms", () => {
-        function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers) {
+        function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers, options: CompilerOptions = {}) {
             it(name, () => {
                 const roots = sources.map(source => createSourceFile(source.file, source.text, ScriptTarget.ES2015));
                 const fileMap = arrayToMap(roots, file => file.fileName);
                 const outputs = createMap<string>();
-                const options: CompilerOptions = {};
                 const host: CompilerHost = {
                     getSourceFile: (fileName) => fileMap.get(fileName),
                     getDefaultLibFileName: () => "lib.d.ts",
@@ -82,5 +81,25 @@ namespace ts {
         emitsCorrectly("before", sources, { before: [before] });
         emitsCorrectly("after", sources, { after: [after] });
         emitsCorrectly("both", sources, { before: [before], after: [after] });
+
+        emitsCorrectly("before+decorators", [{
+            file: "source.ts",
+            text: `
+                declare const dec: any;
+                class B {}
+                @dec export class C { constructor(b: B) { } }
+                'change'
+            `
+        }], {before: [
+            context => node => visitNode(node, function visitor(node: Node): Node {
+                if (isStringLiteral(node) && node.text === "change") return createLiteral("changed");
+                return visitEachChild(node, visitor, context);
+            })
+        ]}, {
+            target: ScriptTarget.ES5,
+            module: ModuleKind.ES2015,
+            emitDecoratorMetadata: true,
+            experimentalDecorators: true
+         });
     });
 }
\ No newline at end of file
diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts
index 6e54823..96d278f 100644
--- a/src/harness/unittests/tsserverProjectSystem.ts
+++ b/src/harness/unittests/tsserverProjectSystem.ts
@@ -1760,6 +1760,28 @@ namespace ts.projectSystem {
             checkProjectActualFiles(projectService.externalProjects[0], [file1.path, file2.path, file3.path]);
         });
 
+        it("regression test for crash in acquireOrUpdateDocument", () => {
+            const tsFile = {
+                fileName: "/a/b/file1.ts",
+                path: "/a/b/file1.ts",
+                content: ""
+            };
+            const jsFile = {
+                path: "/a/b/file1.js",
+                content: "var x = 10;",
+                fileName: "/a/b/file1.js",
+                scriptKind: "JS" as "JS"
+            };
+
+            const host = createServerHost([]);
+            const projectService = createProjectService(host);
+            projectService.applyChangesInOpenFiles([tsFile], [], []);
+            const projs = projectService.synchronizeProjectList([]);
+            projectService.findProject(projs[0].info.projectName).getLanguageService().getNavigationBarItems(tsFile.fileName);
+            projectService.synchronizeProjectList([projs[0].info]);
+            projectService.applyChangesInOpenFiles([jsFile], [], []);
+        });
+
         it("config file is deleted", () => {
             const file1 = {
                 path: "/a/b/f1.ts",
@@ -1860,7 +1882,7 @@ namespace ts.projectSystem {
 
             // Open HTML file
             projectService.applyChangesInOpenFiles(
-                /*openFiles*/ [{ fileName: file2.path, hasMixedContent: true, scriptKind: ScriptKind.JS, content: `var hello = "hello";` }],
+                /*openFiles*/[{ fileName: file2.path, hasMixedContent: true, scriptKind: ScriptKind.JS, content: `var hello = "hello";` }],
                 /*changedFiles*/ undefined,
                 /*closedFiles*/ undefined);
 
@@ -1877,7 +1899,7 @@ namespace ts.projectSystem {
             projectService.applyChangesInOpenFiles(
                 /*openFiles*/ undefined,
                 /*changedFiles*/ undefined,
-                /*closedFiles*/ [file2.path]);
+                /*closedFiles*/[file2.path]);
 
             // HTML file is still included in project
             checkNumberOfProjects(projectService, { configuredProjects: 1 });
@@ -3308,7 +3330,7 @@ namespace ts.projectSystem {
             const error1Result = <protocol.Diagnostic[]>session.executeCommand(dTsFile1GetErrRequest).response;
             assert.isTrue(error1Result.length === 0);
 
-             const dTsFile2GetErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
+            const dTsFile2GetErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
                 CommandNames.SemanticDiagnosticsSync,
                 { file: dTsFile2.path }
             );
diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts
index cb497ff..1843504 100644
--- a/src/server/editorServices.ts
+++ b/src/server/editorServices.ts
@@ -1609,7 +1609,7 @@ namespace ts.server {
             if (openFiles) {
                 for (const file of openFiles) {
                     const scriptInfo = this.getScriptInfo(file.fileName);
-                    Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen());
+                    Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen(), "Script should not exist and not be open already");
                     const normalizedPath = scriptInfo ? scriptInfo.fileName : toNormalizedPath(file.fileName);
                     this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent);
                 }
diff --git a/src/server/protocol.ts b/src/server/protocol.ts
index 0b7405c..214091f 100644
--- a/src/server/protocol.ts
+++ b/src/server/protocol.ts
@@ -2473,6 +2473,7 @@ namespace ts.server.protocol {
         System = "System",
         ES6 = "ES6",
         ES2015 = "ES2015",
+        ESNext = "ESNext"
     }
 
     export const enum ModuleResolutionKind {
@@ -2490,5 +2491,8 @@ namespace ts.server.protocol {
         ES5 = "ES5",
         ES6 = "ES6",
         ES2015 = "ES2015",
+        ES2016 = "ES2016",
+        ES2017 = "ES2017",
+        ESNext = "ESNext"
     }
 }
diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts
index de23b26..f80b7a7 100644
--- a/src/server/typingsInstaller/nodeTypingsInstaller.ts
+++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts
@@ -102,7 +102,7 @@ namespace ts.server.typingsInstaller {
                 if (this.log.isEnabled()) {
                     this.log.writeLine(`Updating ${TypesRegistryPackageName} npm package...`);
                 }
-                this.execSync(`${this.npmPath} install ${TypesRegistryPackageName}`, { cwd: globalTypingsCacheLocation, stdio: "ignore" });
+                this.execSync(`${this.npmPath} install --ignore-scripts ${TypesRegistryPackageName}`, { cwd: globalTypingsCacheLocation, stdio: "ignore" });
                 if (this.log.isEnabled()) {
                     this.log.writeLine(`Updated ${TypesRegistryPackageName} npm package`);
                 }
@@ -152,7 +152,7 @@ namespace ts.server.typingsInstaller {
             if (this.log.isEnabled()) {
                 this.log.writeLine(`#${requestId} with arguments'${JSON.stringify(args)}'.`);
             }
-            const command = `${this.npmPath} install ${args.join(" ")} --save-dev --user-agent="typesInstaller/${version}"`;
+            const command = `${this.npmPath} install --ignore-scripts ${args.join(" ")} --save-dev --user-agent="typesInstaller/${version}"`;
             const start = Date.now();
             let stdout: Buffer;
             let stderr: Buffer;
diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts
index df2b691..f005ec7 100644
--- a/src/server/typingsInstaller/typingsInstaller.ts
+++ b/src/server/typingsInstaller/typingsInstaller.ts
@@ -149,7 +149,7 @@ namespace ts.server.typingsInstaller {
             }
             const discoverTypingsResult = JsTyping.discoverTypings(
                 this.installTypingHost,
-                this.log.isEnabled() ? this.log.writeLine : undefined,
+                this.log.isEnabled() ? (s => this.log.writeLine(s)) : undefined,
                 req.fileNames,
                 req.projectRootPath,
                 this.safeList,
diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts
index bc01f2a..0c3d4d1 100644
--- a/src/services/documentRegistry.ts
+++ b/src/services/documentRegistry.ts
@@ -173,14 +173,12 @@ namespace ts {
             const bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true);
             let entry = bucket.get(path);
             if (!entry) {
-                Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?");
-
                 // Have never seen this file with these settings.  Create a new source file for it.
                 const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false, scriptKind);
 
                 entry = {
                     sourceFile,
-                    languageServiceRefCount: 0,
+                    languageServiceRefCount: 1,
                     owners: []
                 };
                 bucket.set(path, entry);
@@ -193,15 +191,15 @@ namespace ts {
                     entry.sourceFile = updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version,
                         scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot));
                 }
-            }
 
-            // 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++;
+                // 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++;
+                }
             }
 
             return entry.sourceFile;
diff --git a/src/services/refactors/extractMethod.ts b/src/services/refactors/extractMethod.ts
index f0f85ee..9634b9c 100644
--- a/src/services/refactors/extractMethod.ts
+++ b/src/services/refactors/extractMethod.ts
@@ -232,17 +232,7 @@ namespace ts.refactor.extractMethod {
                 return { errors };
             }
 
-            // 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)
-            const range = isStatement(start)
-                ? [start]
-                : start.parent && start.parent.kind === SyntaxKind.ExpressionStatement
-                    ? [start.parent as Statement]
-                    : start as Expression;
-
-            return { targetRange: { range, facts: rangeFacts, declarations } };
+            return { targetRange: { range: getStatementOrExpressionRange(start), facts: rangeFacts, declarations } };
         }
 
         function createErrorResult(sourceFile: SourceFile, start: number, length: number, message: DiagnosticMessage): RangeToExtract {
@@ -459,6 +449,20 @@ namespace ts.refactor.extractMethod {
         }
     }
 
+    function getStatementOrExpressionRange(node: Node): Statement[] | Expression {
+        if (isStatement(node)) {
+            return [node];
+        }
+        else if (isPartOfExpression(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 isExpressionStatement(node.parent) ? [node.parent] : node as Expression;
+        }
+        return undefined;
+    }
+
     function isValidExtractionTarget(node: Node): node is Scope {
         // Note that we don't use isFunctionLike because we don't want to put the extracted closure *inside* a method
         return (node.kind === SyntaxKind.FunctionDeclaration) || isSourceFile(node) || isModuleBlock(node) || isClassLike(node);
@@ -560,32 +564,32 @@ namespace ts.refactor.extractMethod {
                     return "constructor";
                 case SyntaxKind.FunctionExpression:
                     return scope.name
-                        ? `function expression ${scope.name.getText()}`
+                        ? `function expression ${scope.name.text}`
                         : "anonymous function expression";
                 case SyntaxKind.FunctionDeclaration:
-                    return `function ${scope.name.getText()}`;
+                    return `function '${scope.name.text}'`;
                 case SyntaxKind.ArrowFunction:
                     return "arrow function";
                 case SyntaxKind.MethodDeclaration:
-                    return `method ${scope.name.getText()}`;
+                    return `method '${scope.name.getText()}`;
                 case SyntaxKind.GetAccessor:
-                    return `get ${scope.name.getText()}`;
+                    return `'get ${scope.name.getText()}'`;
                 case SyntaxKind.SetAccessor:
-                    return `set ${scope.name.getText()}`;
+                    return `'set ${scope.name.getText()}'`;
             }
         }
         else if (isModuleBlock(scope)) {
-            return `namespace ${scope.parent.name.getText()}`;
+            return `namespace '${scope.parent.name.getText()}'`;
         }
         else if (isClassLike(scope)) {
             return scope.kind === SyntaxKind.ClassDeclaration
-                ? `class ${scope.name.text}`
+                ? `class '${scope.name.text}'`
                 : scope.name.text
-                    ? `class expression ${scope.name.text}`
+                    ? `class expression '${scope.name.text}'`
                     : "anonymous class expression";
         }
         else if (isSourceFile(scope)) {
-            return `file '${scope.fileName}'`;
+            return scope.externalModuleIndicator ? "module scope" : "global scope";
         }
         else {
             return "unknown";
diff --git a/tests/baselines/reference/asyncArrowInClassES5.js b/tests/baselines/reference/asyncArrowInClassES5.js
new file mode 100644
index 0000000..f0204f7
--- /dev/null
+++ b/tests/baselines/reference/asyncArrowInClassES5.js
@@ -0,0 +1,21 @@
+//// [asyncArrowInClassES5.ts]
+// https://github.com/Microsoft/TypeScript/issues/16924
+// Should capture `this`
+
+class Test {
+    static member = async (x: string) => { };
+}
+
+
+//// [asyncArrowInClassES5.js]
+// https://github.com/Microsoft/TypeScript/issues/16924
+// Should capture `this`
+var _this = this;
+var Test = /** @class */ (function () {
+    function Test() {
+    }
+    Test.member = function (x) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
+        return [2 /*return*/];
+    }); }); };
+    return Test;
+}());
diff --git a/tests/baselines/reference/asyncArrowInClassES5.symbols b/tests/baselines/reference/asyncArrowInClassES5.symbols
new file mode 100644
index 0000000..a6cc9f7
--- /dev/null
+++ b/tests/baselines/reference/asyncArrowInClassES5.symbols
@@ -0,0 +1,12 @@
+=== tests/cases/compiler/asyncArrowInClassES5.ts ===
+// https://github.com/Microsoft/TypeScript/issues/16924
+// Should capture `this`
+
+class Test {
+>Test : Symbol(Test, Decl(asyncArrowInClassES5.ts, 0, 0))
+
+    static member = async (x: string) => { };
+>member : Symbol(Test.member, Decl(asyncArrowInClassES5.ts, 3, 12))
+>x : Symbol(x, Decl(asyncArrowInClassES5.ts, 4, 27))
+}
+
diff --git a/tests/baselines/reference/asyncArrowInClassES5.types b/tests/baselines/reference/asyncArrowInClassES5.types
new file mode 100644
index 0000000..8da6d5d
--- /dev/null
+++ b/tests/baselines/reference/asyncArrowInClassES5.types
@@ -0,0 +1,13 @@
+=== tests/cases/compiler/asyncArrowInClassES5.ts ===
+// https://github.com/Microsoft/TypeScript/issues/16924
+// Should capture `this`
+
+class Test {
+>Test : Test
+
+    static member = async (x: string) => { };
+>member : (x: string) => Promise<void>
+>async (x: string) => { } : (x: string) => Promise<void>
+>x : string
+}
+
diff --git a/tests/baselines/reference/circularContextualReturnType.js b/tests/baselines/reference/circularContextualReturnType.js
new file mode 100644
index 0000000..d68f254
--- /dev/null
+++ b/tests/baselines/reference/circularContextualReturnType.js
@@ -0,0 +1,18 @@
+//// [circularContextualReturnType.ts]
+// Repro from #17711
+
+Object.freeze({
+    foo() {
+        return Object.freeze('a');
+    },
+});
+
+
+//// [circularContextualReturnType.js]
+"use strict";
+// Repro from #17711
+Object.freeze({
+    foo: function () {
+        return Object.freeze('a');
+    }
+});
diff --git a/tests/baselines/reference/circularContextualReturnType.symbols b/tests/baselines/reference/circularContextualReturnType.symbols
new file mode 100644
index 0000000..d0e81a6
--- /dev/null
+++ b/tests/baselines/reference/circularContextualReturnType.symbols
@@ -0,0 +1,19 @@
+=== tests/cases/compiler/circularContextualReturnType.ts ===
+// Repro from #17711
+
+Object.freeze({
+>Object.freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
+>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
+>freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
+
+    foo() {
+>foo : Symbol(foo, Decl(circularContextualReturnType.ts, 2, 15))
+
+        return Object.freeze('a');
+>Object.freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
+>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
+>freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
+
+    },
+});
+
diff --git a/tests/baselines/reference/circularContextualReturnType.types b/tests/baselines/reference/circularContextualReturnType.types
new file mode 100644
index 0000000..d32640d
--- /dev/null
+++ b/tests/baselines/reference/circularContextualReturnType.types
@@ -0,0 +1,23 @@
+=== tests/cases/compiler/circularContextualReturnType.ts ===
+// Repro from #17711
+
+Object.freeze({
+>Object.freeze({    foo() {        return Object.freeze('a');    },}) : Readonly<{ foo(): string; }>
+>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
+>Object : ObjectConstructor
+>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
+>{    foo() {        return Object.freeze('a');    },} : { foo(): string; }
+
+    foo() {
+>foo : () => string
+
+        return Object.freeze('a');
+>Object.freeze('a') : string
+>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
+>Object : ObjectConstructor
+>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
+>'a' : "a"
+
+    },
+});
+
diff --git a/tests/baselines/reference/constructorFunctions2.symbols b/tests/baselines/reference/constructorFunctions2.symbols
new file mode 100644
index 0000000..1046aa3
--- /dev/null
+++ b/tests/baselines/reference/constructorFunctions2.symbols
@@ -0,0 +1,41 @@
+=== tests/cases/conformance/salsa/node.d.ts ===
+declare function require(id: string): any;
+>require : Symbol(require, Decl(node.d.ts, 0, 0))
+>id : Symbol(id, Decl(node.d.ts, 0, 25))
+
+declare var module: any, exports: any;
+>module : Symbol(module, Decl(node.d.ts, 1, 11))
+>exports : Symbol(exports, Decl(node.d.ts, 1, 24))
+
+=== tests/cases/conformance/salsa/index.js ===
+const A = require("./other");
+>A : Symbol(A, Decl(index.js, 0, 5))
+>require : Symbol(require, Decl(node.d.ts, 0, 0))
+>"./other" : Symbol("tests/cases/conformance/salsa/other", Decl(other.js, 0, 0))
+
+const a = new A().id;
+>a : Symbol(a, Decl(index.js, 1, 5))
+>new A().id : Symbol(A.id, Decl(other.js, 0, 14))
+>A : Symbol(A, Decl(index.js, 0, 5))
+>id : Symbol(A.id, Decl(other.js, 0, 14))
+
+const B = function() { this.id = 1; }
+>B : Symbol(B, Decl(index.js, 3, 5))
+>id : Symbol(B.id, Decl(index.js, 3, 22))
+
+const b = new B().id;
+>b : Symbol(b, Decl(index.js, 4, 5))
+>new B().id : Symbol(B.id, Decl(index.js, 3, 22))
+>B : Symbol(B, Decl(index.js, 3, 5))
+>id : Symbol(B.id, Decl(index.js, 3, 22))
+
+=== tests/cases/conformance/salsa/other.js ===
+function A() { this.id = 1; }
+>A : Symbol(A, Decl(other.js, 0, 0))
+>id : Symbol(A.id, Decl(other.js, 0, 14))
+
+module.exports = A;
+>module : Symbol(export=, Decl(other.js, 0, 29))
+>exports : Symbol(export=, Decl(other.js, 0, 29))
+>A : Symbol(A, Decl(other.js, 0, 0))
+
diff --git a/tests/baselines/reference/constructorFunctions2.types b/tests/baselines/reference/constructorFunctions2.types
new file mode 100644
index 0000000..e96053b
--- /dev/null
+++ b/tests/baselines/reference/constructorFunctions2.types
@@ -0,0 +1,55 @@
+=== tests/cases/conformance/salsa/node.d.ts ===
+declare function require(id: string): any;
+>require : (id: string) => any
+>id : string
+
+declare var module: any, exports: any;
+>module : any
+>exports : any
+
+=== tests/cases/conformance/salsa/index.js ===
+const A = require("./other");
+>A : () => void
+>require("./other") : () => void
+>require : (id: string) => any
+>"./other" : "./other"
+
+const a = new A().id;
+>a : number
+>new A().id : number
+>new A() : { id: number; }
+>A : () => void
+>id : number
+
+const B = function() { this.id = 1; }
+>B : () => void
+>function() { this.id = 1; } : () => void
+>this.id = 1 : 1
+>this.id : any
+>this : any
+>id : any
+>1 : 1
+
+const b = new B().id;
+>b : number
+>new B().id : number
+>new B() : { id: number; }
+>B : () => void
+>id : number
+
+=== tests/cases/conformance/salsa/other.js ===
+function A() { this.id = 1; }
+>A : () => void
+>this.id = 1 : 1
+>this.id : any
+>this : any
+>id : any
+>1 : 1
+
+module.exports = A;
+>module.exports = A : () => void
+>module.exports : any
+>module : any
+>exports : any
+>A : () => void
+
diff --git a/tests/baselines/reference/decoratorOnClassMethod11.js b/tests/baselines/reference/customTransforms/before+decorators.js
similarity index 50%
copy from tests/baselines/reference/decoratorOnClassMethod11.js
copy to tests/baselines/reference/customTransforms/before+decorators.js
index 2600681..ef705f0 100644
--- a/tests/baselines/reference/decoratorOnClassMethod11.js
+++ b/tests/baselines/reference/customTransforms/before+decorators.js
@@ -1,30 +1,26 @@
-//// [decoratorOnClassMethod11.ts]
-module M {
-    class C {
-        decorator(target: Object, key: string): void { }
-
-        @this.decorator
-        method() { }
+// [source.js]
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    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;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var __metadata = (this && this.__metadata) || function (k, v) {
+    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
+};
+var B = /** @class */ (function () {
+    function B() {
     }
-}
-
-//// [decoratorOnClassMethod11.js]
-var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
-    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
-    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
-    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;
-    return c > 3 && r && Object.defineProperty(target, key, r), r;
-};
-var M;
-(function (M) {
-    var C = /** @class */ (function () {
-        function C() {
-        }
-        C.prototype.decorator = function (target, key) { };
-        C.prototype.method = function () { };
-        __decorate([
-            this.decorator
-        ], C.prototype, "method", null);
-        return C;
-    }());
-})(M || (M = {}));
+    return B;
+}());
+var C = /** @class */ (function () {
+    function C(b) {
+    }
+    C = __decorate([
+        dec,
+        __metadata("design:paramtypes", [B])
+    ], C);
+    return C;
+}());
+export { C };
+"changed";
diff --git a/tests/baselines/reference/decoratorOnClassMethod11.js b/tests/baselines/reference/decoratorOnClassMethod11.js
index 2600681..e29c407 100644
--- a/tests/baselines/reference/decoratorOnClassMethod11.js
+++ b/tests/baselines/reference/decoratorOnClassMethod11.js
@@ -17,6 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 var M;
 (function (M) {
+    var _this = this;
     var C = /** @class */ (function () {
         function C() {
         }
diff --git a/tests/baselines/reference/decoratorOnClassMethod12.js b/tests/baselines/reference/decoratorOnClassMethod12.js
index 494cb08..0063e02 100644
--- a/tests/baselines/reference/decoratorOnClassMethod12.js
+++ b/tests/baselines/reference/decoratorOnClassMethod12.js
@@ -28,6 +28,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 var M;
 (function (M) {
+    var _this = this;
     var S = /** @class */ (function () {
         function S() {
         }
diff --git a/tests/baselines/reference/exportAssignmentOfGenericType1.errors.txt b/tests/baselines/reference/exportAssignmentOfGenericType1.errors.txt
deleted file mode 100644
index e484d40..0000000
--- a/tests/baselines/reference/exportAssignmentOfGenericType1.errors.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-tests/cases/compiler/exportAssignmentOfGenericType1_0.ts(1,10): error TS2449: Class 'T' used before its declaration.
-
-
-==== tests/cases/compiler/exportAssignmentOfGenericType1_1.ts (0 errors) ====
-    ///<reference path='exportAssignmentOfGenericType1_0.ts'/>
-    import q = require("exportAssignmentOfGenericType1_0");
-    
-    class M extends q<string> { }
-    var m: M;
-    var r: string = m.foo;
-    
-==== tests/cases/compiler/exportAssignmentOfGenericType1_0.ts (1 errors) ====
-    export = T;
-             ~
-!!! error TS2449: Class 'T' used before its declaration.
-    class T<X> { foo: X; }
-    
\ No newline at end of file
diff --git a/tests/baselines/reference/exportClassWithoutName.errors.txt b/tests/baselines/reference/exportClassWithoutName.errors.txt
new file mode 100644
index 0000000..448a1b2
--- /dev/null
+++ b/tests/baselines/reference/exportClassWithoutName.errors.txt
@@ -0,0 +1,8 @@
+tests/cases/compiler/exportClassWithoutName.ts(1,1): error TS1211: A class declaration without the 'default' modifier must have a name.
+
+
+==== tests/cases/compiler/exportClassWithoutName.ts (1 errors) ====
+    export class {
+    ~~~~~~
+!!! error TS1211: A class declaration without the 'default' modifier must have a name.
+    }
\ No newline at end of file
diff --git a/tests/baselines/reference/exportClassWithoutName.js b/tests/baselines/reference/exportClassWithoutName.js
new file mode 100644
index 0000000..45b4301
--- /dev/null
+++ b/tests/baselines/reference/exportClassWithoutName.js
@@ -0,0 +1,10 @@
+//// [exportClassWithoutName.ts]
+export class {
+}
+
+//// [exportClassWithoutName.js]
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+class default_1 {
+}
+exports.default_1 = default_1;
diff --git a/tests/baselines/reference/exportImport.errors.txt b/tests/baselines/reference/exportImport.errors.txt
deleted file mode 100644
index 4f397d5..0000000
--- a/tests/baselines/reference/exportImport.errors.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-tests/cases/compiler/w1.ts(1,1): error TS2449: Class 'Widget1' used before its declaration.
-tests/cases/compiler/w1.ts(1,10): error TS2449: Class 'Widget1' used before its declaration.
-
-
-==== tests/cases/compiler/consumer.ts (0 errors) ====
-    import e = require('./exporter');
-    
-    export function w(): e.w { // Should be OK
-        return new e.w();
-    }
-==== tests/cases/compiler/w1.ts (2 errors) ====
-    export = Widget1
-    ~~~~~~~~~~~~~~~~
-!!! error TS2449: Class 'Widget1' used before its declaration.
-             ~~~~~~~
-!!! error TS2449: Class 'Widget1' used before its declaration.
-    class Widget1 { name = 'one'; }
-    
-==== tests/cases/compiler/exporter.ts (0 errors) ====
-    export import w = require('./w1');
-    
\ No newline at end of file
diff --git a/tests/baselines/reference/extractMethod/extractMethod1.js b/tests/baselines/reference/extractMethod/extractMethod1.js
index 60c7e30..10bf264 100644
--- a/tests/baselines/reference/extractMethod/extractMethod1.js
+++ b/tests/baselines/reference/extractMethod/extractMethod1.js
@@ -14,7 +14,7 @@ namespace A {
         }
     }
 }
-==SCOPE::function a==
+==SCOPE::function 'a'==
 namespace A {
     let x = 1;
     function foo() {
@@ -34,7 +34,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace B==
+==SCOPE::namespace 'B'==
 namespace A {
     let x = 1;
     function foo() {
@@ -55,7 +55,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace A==
+==SCOPE::namespace 'A'==
 namespace A {
     let x = 1;
     function foo() {
@@ -76,7 +76,7 @@ namespace A {
         return a;
     }
 }
-==SCOPE::file '/a.ts'==
+==SCOPE::global scope==
 namespace A {
     let x = 1;
     function foo() {
diff --git a/tests/baselines/reference/extractMethod/extractMethod10.js b/tests/baselines/reference/extractMethod/extractMethod10.js
index 02923b7..b239774 100644
--- a/tests/baselines/reference/extractMethod/extractMethod10.js
+++ b/tests/baselines/reference/extractMethod/extractMethod10.js
@@ -9,7 +9,7 @@ namespace A {
         }
     }
 }
-==SCOPE::class C==
+==SCOPE::class 'C'==
 namespace A {
     export interface I { x: number };
     class C {
@@ -24,7 +24,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace A==
+==SCOPE::namespace 'A'==
 namespace A {
     export interface I { x: number };
     class C {
@@ -39,7 +39,7 @@ namespace A {
         return a1.x + 10;
     }
 }
-==SCOPE::file '/a.ts'==
+==SCOPE::global scope==
 namespace A {
     export interface I { x: number };
     class C {
diff --git a/tests/baselines/reference/extractMethod/extractMethod11.js b/tests/baselines/reference/extractMethod/extractMethod11.js
index 77565e7..21392a0 100644
--- a/tests/baselines/reference/extractMethod/extractMethod11.js
+++ b/tests/baselines/reference/extractMethod/extractMethod11.js
@@ -11,7 +11,7 @@ namespace A {
         }
     }
 }
-==SCOPE::class C==
+==SCOPE::class 'C'==
 namespace A {
     let y = 1;
     class C {
@@ -30,7 +30,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace A==
+==SCOPE::namespace 'A'==
 namespace A {
     let y = 1;
     class C {
@@ -49,7 +49,7 @@ namespace A {
         return { __return: a1.x + 10, z };
     }
 }
-==SCOPE::file '/a.ts'==
+==SCOPE::global scope==
 namespace A {
     let y = 1;
     class C {
diff --git a/tests/baselines/reference/extractMethod/extractMethod12.js b/tests/baselines/reference/extractMethod/extractMethod12.js
index 8ff6e13..7cebab5 100644
--- a/tests/baselines/reference/extractMethod/extractMethod12.js
+++ b/tests/baselines/reference/extractMethod/extractMethod12.js
@@ -13,7 +13,7 @@ namespace A {
         }
     }
 }
-==SCOPE::class C==
+==SCOPE::class 'C'==
 namespace A {
     let y = 1;
     class C {
diff --git a/tests/baselines/reference/extractMethod/extractMethod2.js b/tests/baselines/reference/extractMethod/extractMethod2.js
index 28c2799..3c0d2e7 100644
--- a/tests/baselines/reference/extractMethod/extractMethod2.js
+++ b/tests/baselines/reference/extractMethod/extractMethod2.js
@@ -12,7 +12,7 @@ namespace A {
         }
     }
 }
-==SCOPE::function a==
+==SCOPE::function 'a'==
 namespace A {
     let x = 1;
     function foo() {
@@ -30,7 +30,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace B==
+==SCOPE::namespace 'B'==
 namespace A {
     let x = 1;
     function foo() {
@@ -48,7 +48,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace A==
+==SCOPE::namespace 'A'==
 namespace A {
     let x = 1;
     function foo() {
@@ -66,7 +66,7 @@ namespace A {
         return foo();
     }
 }
-==SCOPE::file '/a.ts'==
+==SCOPE::global scope==
 namespace A {
     let x = 1;
     function foo() {
diff --git a/tests/baselines/reference/extractMethod/extractMethod3.js b/tests/baselines/reference/extractMethod/extractMethod3.js
index e5903ea..cb28e27 100644
--- a/tests/baselines/reference/extractMethod/extractMethod3.js
+++ b/tests/baselines/reference/extractMethod/extractMethod3.js
@@ -11,7 +11,7 @@ namespace A {
         }
     }
 }
-==SCOPE::function a==
+==SCOPE::function 'a'==
 namespace A {
     function foo() {
     }
@@ -28,7 +28,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace B==
+==SCOPE::namespace 'B'==
 namespace A {
     function foo() {
     }
@@ -45,7 +45,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace A==
+==SCOPE::namespace 'A'==
 namespace A {
     function foo() {
     }
@@ -62,7 +62,7 @@ namespace A {
         return foo();
     }
 }
-==SCOPE::file '/a.ts'==
+==SCOPE::global scope==
 namespace A {
     function foo() {
     }
diff --git a/tests/baselines/reference/extractMethod/extractMethod4.js b/tests/baselines/reference/extractMethod/extractMethod4.js
index 6b9e2ee..07029b2 100644
--- a/tests/baselines/reference/extractMethod/extractMethod4.js
+++ b/tests/baselines/reference/extractMethod/extractMethod4.js
@@ -13,7 +13,7 @@ namespace A {
         }
     }
 }
-==SCOPE::function a==
+==SCOPE::function 'a'==
 namespace A {
     function foo() {
     }
@@ -32,7 +32,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace B==
+==SCOPE::namespace 'B'==
 namespace A {
     function foo() {
     }
@@ -51,7 +51,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace A==
+==SCOPE::namespace 'A'==
 namespace A {
     function foo() {
     }
@@ -70,7 +70,7 @@ namespace A {
         return foo();
     }
 }
-==SCOPE::file '/a.ts'==
+==SCOPE::global scope==
 namespace A {
     function foo() {
     }
diff --git a/tests/baselines/reference/extractMethod/extractMethod5.js b/tests/baselines/reference/extractMethod/extractMethod5.js
index cf63cb2..96a76e4 100644
--- a/tests/baselines/reference/extractMethod/extractMethod5.js
+++ b/tests/baselines/reference/extractMethod/extractMethod5.js
@@ -14,7 +14,7 @@ namespace A {
         }
     }
 }
-==SCOPE::function a==
+==SCOPE::function 'a'==
 namespace A {
     let x = 1;
     export function foo() {
@@ -34,7 +34,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace B==
+==SCOPE::namespace 'B'==
 namespace A {
     let x = 1;
     export function foo() {
@@ -55,7 +55,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace A==
+==SCOPE::namespace 'A'==
 namespace A {
     let x = 1;
     export function foo() {
@@ -76,7 +76,7 @@ namespace A {
         return a;
     }
 }
-==SCOPE::file '/a.ts'==
+==SCOPE::global scope==
 namespace A {
     let x = 1;
     export function foo() {
diff --git a/tests/baselines/reference/extractMethod/extractMethod6.js b/tests/baselines/reference/extractMethod/extractMethod6.js
index 99f52e9..d1244ac 100644
--- a/tests/baselines/reference/extractMethod/extractMethod6.js
+++ b/tests/baselines/reference/extractMethod/extractMethod6.js
@@ -14,7 +14,7 @@ namespace A {
         }
     }
 }
-==SCOPE::function a==
+==SCOPE::function 'a'==
 namespace A {
     let x = 1;
     export function foo() {
@@ -34,7 +34,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace B==
+==SCOPE::namespace 'B'==
 namespace A {
     let x = 1;
     export function foo() {
@@ -56,7 +56,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace A==
+==SCOPE::namespace 'A'==
 namespace A {
     let x = 1;
     export function foo() {
@@ -78,7 +78,7 @@ namespace A {
         return { __return: foo(), a };
     }
 }
-==SCOPE::file '/a.ts'==
+==SCOPE::global scope==
 namespace A {
     let x = 1;
     export function foo() {
diff --git a/tests/baselines/reference/extractMethod/extractMethod7.js b/tests/baselines/reference/extractMethod/extractMethod7.js
index 09d5eda..da400d8 100644
--- a/tests/baselines/reference/extractMethod/extractMethod7.js
+++ b/tests/baselines/reference/extractMethod/extractMethod7.js
@@ -16,7 +16,7 @@ namespace A {
         }
     }
 }
-==SCOPE::function a==
+==SCOPE::function 'a'==
 namespace A {
     let x = 1;
     export namespace C {
@@ -38,7 +38,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace B==
+==SCOPE::namespace 'B'==
 namespace A {
     let x = 1;
     export namespace C {
@@ -62,7 +62,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace A==
+==SCOPE::namespace 'A'==
 namespace A {
     let x = 1;
     export namespace C {
@@ -86,7 +86,7 @@ namespace A {
         return { __return: C.foo(), a };
     }
 }
-==SCOPE::file '/a.ts'==
+==SCOPE::global scope==
 namespace A {
     let x = 1;
     export namespace C {
diff --git a/tests/baselines/reference/extractMethod/extractMethod8.js b/tests/baselines/reference/extractMethod/extractMethod8.js
index fe9cf2a..d298387 100644
--- a/tests/baselines/reference/extractMethod/extractMethod8.js
+++ b/tests/baselines/reference/extractMethod/extractMethod8.js
@@ -8,7 +8,7 @@ namespace A {
         }
     }
 }
-==SCOPE::function a==
+==SCOPE::function 'a'==
 namespace A {
     let x = 1;
     namespace B {
@@ -22,7 +22,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace B==
+==SCOPE::namespace 'B'==
 namespace A {
     let x = 1;
     namespace B {
@@ -36,7 +36,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace A==
+==SCOPE::namespace 'A'==
 namespace A {
     let x = 1;
     namespace B {
@@ -50,7 +50,7 @@ namespace A {
         return 1 + a1 + x;
     }
 }
-==SCOPE::file '/a.ts'==
+==SCOPE::global scope==
 namespace A {
     let x = 1;
     namespace B {
diff --git a/tests/baselines/reference/extractMethod/extractMethod9.js b/tests/baselines/reference/extractMethod/extractMethod9.js
index fcc5dcd..609e353 100644
--- a/tests/baselines/reference/extractMethod/extractMethod9.js
+++ b/tests/baselines/reference/extractMethod/extractMethod9.js
@@ -8,7 +8,7 @@ namespace A {
         }
     }
 }
-==SCOPE::function a==
+==SCOPE::function 'a'==
 namespace A {
     export interface I { x: number };
     namespace B {
@@ -22,7 +22,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace B==
+==SCOPE::namespace 'B'==
 namespace A {
     export interface I { x: number };
     namespace B {
@@ -36,7 +36,7 @@ namespace A {
         }
     }
 }
-==SCOPE::namespace A==
+==SCOPE::namespace 'A'==
 namespace A {
     export interface I { x: number };
     namespace B {
@@ -50,7 +50,7 @@ namespace A {
         return a1.x + 10;
     }
 }
-==SCOPE::file '/a.ts'==
+==SCOPE::global scope==
 namespace A {
     export interface I { x: number };
     namespace B {
diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsAMD.js b/tests/baselines/reference/importCallExpressionInExportEqualsAMD.js
new file mode 100644
index 0000000..f2fda1f
--- /dev/null
+++ b/tests/baselines/reference/importCallExpressionInExportEqualsAMD.js
@@ -0,0 +1,22 @@
+//// [tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsAMD.ts] ////
+
+//// [something.ts]
+export = 42;
+
+//// [index.ts]
+export = async function() {
+    const something = await import("./something");
+};
+
+//// [something.js]
+define(["require", "exports"], function (require, exports) {
+    "use strict";
+    return 42;
+});
+//// [index.js]
+define(["require", "exports"], function (require, exports) {
+    "use strict";
+    return async function () {
+        const something = await new Promise(function (resolve_1, reject_1) { require(["./something"], resolve_1, reject_1); });
+    };
+});
diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsAMD.symbols b/tests/baselines/reference/importCallExpressionInExportEqualsAMD.symbols
new file mode 100644
index 0000000..cd8d7d3
--- /dev/null
+++ b/tests/baselines/reference/importCallExpressionInExportEqualsAMD.symbols
@@ -0,0 +1,10 @@
+=== tests/cases/conformance/dynamicImport/something.ts ===
+export = 42;
+No type information for this code.
+No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
+export = async function() {
+    const something = await import("./something");
+>something : Symbol(something, Decl(index.ts, 1, 9))
+>"./something" : Symbol("tests/cases/conformance/dynamicImport/something", Decl(something.ts, 0, 0))
+
+};
diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsAMD.types b/tests/baselines/reference/importCallExpressionInExportEqualsAMD.types
new file mode 100644
index 0000000..b590130
--- /dev/null
+++ b/tests/baselines/reference/importCallExpressionInExportEqualsAMD.types
@@ -0,0 +1,14 @@
+=== tests/cases/conformance/dynamicImport/something.ts ===
+export = 42;
+No type information for this code.
+No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
+export = async function() {
+>async function() {    const something = await import("./something");} : () => Promise<void>
+
+    const something = await import("./something");
+>something : 42
+>await import("./something") : 42
+>import("./something") : Promise<42>
+>"./something" : "./something"
+
+};
diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsCJS.js b/tests/baselines/reference/importCallExpressionInExportEqualsCJS.js
new file mode 100644
index 0000000..5d7e281
--- /dev/null
+++ b/tests/baselines/reference/importCallExpressionInExportEqualsCJS.js
@@ -0,0 +1,18 @@
+//// [tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsCJS.ts] ////
+
+//// [something.ts]
+export = 42;
+
+//// [index.ts]
+export = async function() {
+    const something = await import("./something");
+};
+
+//// [something.js]
+"use strict";
+module.exports = 42;
+//// [index.js]
+"use strict";
+module.exports = async function () {
+    const something = await Promise.resolve().then(function () { return require("./something"); });
+};
diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsCJS.symbols b/tests/baselines/reference/importCallExpressionInExportEqualsCJS.symbols
new file mode 100644
index 0000000..cd8d7d3
--- /dev/null
+++ b/tests/baselines/reference/importCallExpressionInExportEqualsCJS.symbols
@@ -0,0 +1,10 @@
+=== tests/cases/conformance/dynamicImport/something.ts ===
+export = 42;
+No type information for this code.
+No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
+export = async function() {
+    const something = await import("./something");
+>something : Symbol(something, Decl(index.ts, 1, 9))
+>"./something" : Symbol("tests/cases/conformance/dynamicImport/something", Decl(something.ts, 0, 0))
+
+};
diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsCJS.types b/tests/baselines/reference/importCallExpressionInExportEqualsCJS.types
new file mode 100644
index 0000000..b590130
--- /dev/null
+++ b/tests/baselines/reference/importCallExpressionInExportEqualsCJS.types
@@ -0,0 +1,14 @@
+=== tests/cases/conformance/dynamicImport/something.ts ===
+export = 42;
+No type information for this code.
+No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
+export = async function() {
+>async function() {    const something = await import("./something");} : () => Promise<void>
+
+    const something = await import("./something");
+>something : 42
+>await import("./something") : 42
+>import("./something") : Promise<42>
+>"./something" : "./something"
+
+};
diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsUMD.js b/tests/baselines/reference/importCallExpressionInExportEqualsUMD.js
new file mode 100644
index 0000000..e0c6e2a
--- /dev/null
+++ b/tests/baselines/reference/importCallExpressionInExportEqualsUMD.js
@@ -0,0 +1,39 @@
+//// [tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsUMD.ts] ////
+
+//// [something.ts]
+export = 42;
+
+//// [index.ts]
+export = async function() {
+    const something = await import("./something");
+};
+
+//// [something.js]
+(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 (require, exports) {
+    "use strict";
+    return 42;
+});
+//// [index.js]
+(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 (require, exports) {
+    "use strict";
+    var __syncRequire = typeof module === "object" && typeof module.exports === "object";
+    return async function () {
+        const something = await (__syncRequire ? Promise.resolve().then(function () { return require("./something"); }) : new Promise(function (resolve_1, reject_1) { require(["./something"], resolve_1, reject_1); }));
+    };
+});
diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsUMD.symbols b/tests/baselines/reference/importCallExpressionInExportEqualsUMD.symbols
new file mode 100644
index 0000000..cd8d7d3
--- /dev/null
+++ b/tests/baselines/reference/importCallExpressionInExportEqualsUMD.symbols
@@ -0,0 +1,10 @@
+=== tests/cases/conformance/dynamicImport/something.ts ===
+export = 42;
+No type information for this code.
+No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
+export = async function() {
+    const something = await import("./something");
+>something : Symbol(something, Decl(index.ts, 1, 9))
+>"./something" : Symbol("tests/cases/conformance/dynamicImport/something", Decl(something.ts, 0, 0))
+
+};
diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsUMD.types b/tests/baselines/reference/importCallExpressionInExportEqualsUMD.types
new file mode 100644
index 0000000..b590130
--- /dev/null
+++ b/tests/baselines/reference/importCallExpressionInExportEqualsUMD.types
@@ -0,0 +1,14 @@
+=== tests/cases/conformance/dynamicImport/something.ts ===
+export = 42;
+No type information for this code.
+No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
+export = async function() {
+>async function() {    const something = await import("./something");} : () => Promise<void>
+
+    const something = await import("./something");
+>something : 42
+>await import("./something") : 42
+>import("./something") : Promise<42>
+>"./something" : "./something"
+
+};
diff --git a/tests/baselines/reference/inferringClassMembersFromAssignments.js b/tests/baselines/reference/inferringClassMembersFromAssignments.js
index 3fa72bc..90f8773 100644
--- a/tests/baselines/reference/inferringClassMembersFromAssignments.js
+++ b/tests/baselines/reference/inferringClassMembersFromAssignments.js
@@ -124,6 +124,7 @@ var stringOrNumberOrUndefined = C.inStaticNestedArrowFunction;
 
 
 //// [output.js]
+var _this = this;
 var C = /** @class */ (function () {
     function C() {
         var _this = this;
diff --git a/tests/baselines/reference/invalidContinueInDownlevelAsync.errors.txt b/tests/baselines/reference/invalidContinueInDownlevelAsync.errors.txt
new file mode 100644
index 0000000..ffdfee2
--- /dev/null
+++ b/tests/baselines/reference/invalidContinueInDownlevelAsync.errors.txt
@@ -0,0 +1,17 @@
+tests/cases/compiler/invalidContinueInDownlevelAsync.ts(3,9): error TS1107: Jump target cannot cross function boundary.
+tests/cases/compiler/invalidContinueInDownlevelAsync.ts(6,9): error TS7027: Unreachable code detected.
+
+
+==== tests/cases/compiler/invalidContinueInDownlevelAsync.ts (2 errors) ====
+    async function func() {
+        if (true) {
+            continue;
+            ~~~~~~~~~
+!!! error TS1107: Jump target cannot cross function boundary.
+        }
+        else {
+            await 1;
+            ~~~~~
+!!! error TS7027: Unreachable code detected.
+        }
+    }
\ No newline at end of file
diff --git a/tests/baselines/reference/invalidContinueInDownlevelAsync.js b/tests/baselines/reference/invalidContinueInDownlevelAsync.js
new file mode 100644
index 0000000..69e5e76
--- /dev/null
+++ b/tests/baselines/reference/invalidContinueInDownlevelAsync.js
@@ -0,0 +1,63 @@
+//// [invalidContinueInDownlevelAsync.ts]
+async function func() {
+    if (true) {
+        continue;
+    }
+    else {
+        await 1;
+    }
+}
+
+//// [invalidContinueInDownlevelAsync.js]
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+    return new (P || (P = Promise))(function (resolve, reject) {
+        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
+        step((generator = generator.apply(thisArg, _arguments || [])).next());
+    });
+};
+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 = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
+            if (y = 0, t) op = [0, 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 };
+    }
+};
+function func() {
+    return __awaiter(this, void 0, void 0, function () {
+        return __generator(this, function (_a) {
+            switch (_a.label) {
+                case 0:
+                    if (!true) return [3 /*break*/, 1];
+                    continue;
+                    return [3 /*break*/, 3];
+                case 1: return [4 /*yield*/, 1];
+                case 2:
+                    _a.sent();
+                    _a.label = 3;
+                case 3: return [2 /*return*/];
+            }
+        });
+    });
+}
diff --git a/tests/baselines/reference/noCrashOnImportShadowing.errors.txt b/tests/baselines/reference/noCrashOnImportShadowing.errors.txt
new file mode 100644
index 0000000..c1d1dbc
--- /dev/null
+++ b/tests/baselines/reference/noCrashOnImportShadowing.errors.txt
@@ -0,0 +1,33 @@
+tests/cases/compiler/index.ts(4,1): error TS2693: 'B' only refers to a type, but is being used as a value here.
+tests/cases/compiler/index.ts(9,10): error TS2304: Cannot find name 'OriginalB'.
+
+
+==== tests/cases/compiler/b.ts (0 errors) ====
+    export const zzz = 123;
+    
+==== tests/cases/compiler/a.ts (0 errors) ====
+    import * as B from "./b";
+    
+    interface B {
+        x: string;
+    }
+    
+    const x: B = { x: "" };
+    B.zzz;
+    
+    export { B };
+    
+==== tests/cases/compiler/index.ts (2 errors) ====
+    import { B } from "./a";
+    
+    const x: B = { x: "" };
+    B.zzz;
+    ~
+!!! error TS2693: 'B' only refers to a type, but is being used as a value here.
+    
+    import * as OriginalB from "./b";
+    OriginalB.zzz;
+    
+    const y: OriginalB = x;
+             ~~~~~~~~~
+!!! error TS2304: Cannot find name 'OriginalB'.
\ No newline at end of file
diff --git a/tests/baselines/reference/noCrashOnImportShadowing.js b/tests/baselines/reference/noCrashOnImportShadowing.js
new file mode 100644
index 0000000..7ca2116
--- /dev/null
+++ b/tests/baselines/reference/noCrashOnImportShadowing.js
@@ -0,0 +1,46 @@
+//// [tests/cases/compiler/noCrashOnImportShadowing.ts] ////
+
+//// [b.ts]
+export const zzz = 123;
+
+//// [a.ts]
+import * as B from "./b";
+
+interface B {
+    x: string;
+}
+
+const x: B = { x: "" };
+B.zzz;
+
+export { B };
+
+//// [index.ts]
+import { B } from "./a";
+
+const x: B = { x: "" };
+B.zzz;
+
+import * as OriginalB from "./b";
+OriginalB.zzz;
+
+const y: OriginalB = x;
+
+//// [b.js]
+"use strict";
+exports.__esModule = true;
+exports.zzz = 123;
+//// [a.js]
+"use strict";
+exports.__esModule = true;
+var B = require("./b");
+var x = { x: "" };
+B.zzz;
+//// [index.js]
+"use strict";
+exports.__esModule = true;
+var x = { x: "" };
+B.zzz;
+var OriginalB = require("./b");
+OriginalB.zzz;
+var y = x;
diff --git a/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.js b/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.js
new file mode 100644
index 0000000..e16695b
--- /dev/null
+++ b/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.js
@@ -0,0 +1,26 @@
+//// [objectSpreadWithinMethodWithinObjectWithSpread.ts]
+const obj = {};
+const a = {
+    ...obj,
+    prop() {
+        return {
+            ...obj,
+            metadata: 213
+        };
+    }
+};
+
+
+//// [objectSpreadWithinMethodWithinObjectWithSpread.js]
+var __assign = (this && this.__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;
+};
+var obj = {};
+var a = __assign({}, obj, { prop: function () {
+        return __assign({}, obj, { metadata: 213 });
+    } });
diff --git a/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.symbols b/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.symbols
new file mode 100644
index 0000000..181cacd
--- /dev/null
+++ b/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.symbols
@@ -0,0 +1,24 @@
+=== tests/cases/compiler/objectSpreadWithinMethodWithinObjectWithSpread.ts ===
+const obj = {};
+>obj : Symbol(obj, Decl(objectSpreadWithinMethodWithinObjectWithSpread.ts, 0, 5))
+
+const a = {
+>a : Symbol(a, Decl(objectSpreadWithinMethodWithinObjectWithSpread.ts, 1, 5))
+
+    ...obj,
+>obj : Symbol(obj, Decl(objectSpreadWithinMethodWithinObjectWithSpread.ts, 0, 5))
+
+    prop() {
+>prop : Symbol(prop, Decl(objectSpreadWithinMethodWithinObjectWithSpread.ts, 2, 11))
+
+        return {
+            ...obj,
+>obj : Symbol(obj, Decl(objectSpreadWithinMethodWithinObjectWithSpread.ts, 0, 5))
+
+            metadata: 213
+>metadata : Symbol(metadata, Decl(objectSpreadWithinMethodWithinObjectWithSpread.ts, 5, 19))
+
+        };
+    }
+};
+
diff --git a/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.types b/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.types
new file mode 100644
index 0000000..351aa0c
--- /dev/null
+++ b/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.types
@@ -0,0 +1,29 @@
+=== tests/cases/compiler/objectSpreadWithinMethodWithinObjectWithSpread.ts ===
+const obj = {};
+>obj : {}
+>{} : {}
+
+const a = {
+>a : { prop(): { metadata: number; }; }
+>{    ...obj,    prop() {        return {            ...obj,            metadata: 213        };    }} : { prop(): { metadata: number; }; }
+
+    ...obj,
+>obj : {}
+
+    prop() {
+>prop : () => { metadata: number; }
+
+        return {
+>{            ...obj,            metadata: 213        } : { metadata: number; }
+
+            ...obj,
+>obj : {}
+
+            metadata: 213
+>metadata : number
+>213 : 213
+
+        };
+    }
+};
+
diff --git a/tests/baselines/reference/privacyCheckExternalModuleExportAssignmentOfGenericClass.errors.txt b/tests/baselines/reference/privacyCheckExternalModuleExportAssignmentOfGenericClass.errors.txt
deleted file mode 100644
index 2945950..0000000
--- a/tests/baselines/reference/privacyCheckExternalModuleExportAssignmentOfGenericClass.errors.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-tests/cases/compiler/privacyCheckExternalModuleExportAssignmentOfGenericClass_0.ts(1,1): error TS2449: Class 'Foo' used before its declaration.
-tests/cases/compiler/privacyCheckExternalModuleExportAssignmentOfGenericClass_0.ts(1,10): error TS2449: Class 'Foo' used before its declaration.
-
-
-==== tests/cases/compiler/privacyCheckExternalModuleExportAssignmentOfGenericClass_1.ts (0 errors) ====
-    import Foo = require("./privacyCheckExternalModuleExportAssignmentOfGenericClass_0");
-    export = Bar;
-    interface Bar {
-        foo: Foo<number>;
-    }
-==== tests/cases/compiler/privacyCheckExternalModuleExportAssignmentOfGenericClass_0.ts (2 errors) ====
-    export = Foo;
-    ~~~~~~~~~~~~~
-!!! error TS2449: Class 'Foo' used before its declaration.
-             ~~~
-!!! error TS2449: Class 'Foo' used before its declaration.
-    class Foo<A> {
-        constructor(public a: A) { }
-    }
-    
\ No newline at end of file
diff --git a/tests/baselines/reference/superAccess2.js b/tests/baselines/reference/superAccess2.js
index de75536..d3aac21 100644
--- a/tests/baselines/reference/superAccess2.js
+++ b/tests/baselines/reference/superAccess2.js
@@ -35,6 +35,7 @@ var __extends = (this && this.__extends) || (function () {
         d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
     };
 })();
+var _this = this;
 var P = /** @class */ (function () {
     function P() {
     }
diff --git a/tests/baselines/reference/thisInArrowFunctionInStaticInitializer1.js b/tests/baselines/reference/thisInArrowFunctionInStaticInitializer1.js
index 97e958a..2d58fd4 100644
--- a/tests/baselines/reference/thisInArrowFunctionInStaticInitializer1.js
+++ b/tests/baselines/reference/thisInArrowFunctionInStaticInitializer1.js
@@ -9,6 +9,7 @@ class Vector {
 }
 
 //// [thisInArrowFunctionInStaticInitializer1.js]
+var _this = this;
 function log(a) { }
 var Vector = /** @class */ (function () {
     function Vector() {
diff --git a/tests/baselines/reference/thisInConstructorParameter2.js b/tests/baselines/reference/thisInConstructorParameter2.js
index 6a27183..a5e4f4d 100644
--- a/tests/baselines/reference/thisInConstructorParameter2.js
+++ b/tests/baselines/reference/thisInConstructorParameter2.js
@@ -10,6 +10,7 @@ class P {
 }
 
 //// [thisInConstructorParameter2.js]
+var _this = this;
 var P = /** @class */ (function () {
     function P(z, zz) {
         if (z === void 0) { z = this; }
diff --git a/tests/baselines/reference/thisInInvalidContexts.js b/tests/baselines/reference/thisInInvalidContexts.js
index 635eff2..1e24cc4 100644
--- a/tests/baselines/reference/thisInInvalidContexts.js
+++ b/tests/baselines/reference/thisInInvalidContexts.js
@@ -59,6 +59,7 @@ var __extends = (this && this.__extends) || (function () {
         d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
     };
 })();
+var _this = this;
 //'this' in static member initializer
 var ErrClass1 = /** @class */ (function () {
     function ErrClass1() {
diff --git a/tests/baselines/reference/thisInInvalidContextsExternalModule.js b/tests/baselines/reference/thisInInvalidContextsExternalModule.js
index ea69a58..daadace 100644
--- a/tests/baselines/reference/thisInInvalidContextsExternalModule.js
+++ b/tests/baselines/reference/thisInInvalidContextsExternalModule.js
@@ -60,6 +60,7 @@ var __extends = (this && this.__extends) || (function () {
         d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
     };
 })();
+var _this = this;
 //'this' in static member initializer
 var ErrClass1 = /** @class */ (function () {
     function ErrClass1() {
diff --git a/tests/baselines/reference/thisInOuterClassBody.js b/tests/baselines/reference/thisInOuterClassBody.js
index 2b4e3a1..d5bf689 100644
--- a/tests/baselines/reference/thisInOuterClassBody.js
+++ b/tests/baselines/reference/thisInOuterClassBody.js
@@ -21,6 +21,7 @@ class Foo {
 }
 
 //// [thisInOuterClassBody.js]
+var _this = this;
 var Foo = /** @class */ (function () {
     function Foo() {
         this.x = this;
diff --git a/tests/baselines/reference/typeOfThisInStaticMembers2.js b/tests/baselines/reference/typeOfThisInStaticMembers2.js
index 72243cd..1cfec3a 100644
--- a/tests/baselines/reference/typeOfThisInStaticMembers2.js
+++ b/tests/baselines/reference/typeOfThisInStaticMembers2.js
@@ -8,6 +8,7 @@ class C2<T> {
 }
 
 //// [typeOfThisInStaticMembers2.js]
+var _this = this;
 var C = /** @class */ (function () {
     function C() {
     }
diff --git a/tests/cases/compiler/asyncArrowInClassES5.ts b/tests/cases/compiler/asyncArrowInClassES5.ts
new file mode 100644
index 0000000..2712372
--- /dev/null
+++ b/tests/cases/compiler/asyncArrowInClassES5.ts
@@ -0,0 +1,9 @@
+// @noEmitHelpers: true
+// @lib: es2015
+// @target: es5
+// https://github.com/Microsoft/TypeScript/issues/16924
+// Should capture `this`
+
+class Test {
+    static member = async (x: string) => { };
+}
diff --git a/tests/cases/compiler/circularContextualReturnType.ts b/tests/cases/compiler/circularContextualReturnType.ts
new file mode 100644
index 0000000..1b356af
--- /dev/null
+++ b/tests/cases/compiler/circularContextualReturnType.ts
@@ -0,0 +1,9 @@
+// @strict: true
+
+// Repro from #17711
+
+Object.freeze({
+    foo() {
+        return Object.freeze('a');
+    },
+});
diff --git a/tests/cases/compiler/exportClassWithoutName.ts b/tests/cases/compiler/exportClassWithoutName.ts
new file mode 100644
index 0000000..a83ca97
--- /dev/null
+++ b/tests/cases/compiler/exportClassWithoutName.ts
@@ -0,0 +1,4 @@
+//@module: commonjs
+//@target: es2015
+export class {
+}
\ No newline at end of file
diff --git a/tests/cases/compiler/invalidContinueInDownlevelAsync.ts b/tests/cases/compiler/invalidContinueInDownlevelAsync.ts
new file mode 100644
index 0000000..bdf476c
--- /dev/null
+++ b/tests/cases/compiler/invalidContinueInDownlevelAsync.ts
@@ -0,0 +1,8 @@
+async function func() {
+    if (true) {
+        continue;
+    }
+    else {
+        await 1;
+    }
+}
\ No newline at end of file
diff --git a/tests/cases/compiler/noCrashOnImportShadowing.ts b/tests/cases/compiler/noCrashOnImportShadowing.ts
new file mode 100644
index 0000000..69e8b6a
--- /dev/null
+++ b/tests/cases/compiler/noCrashOnImportShadowing.ts
@@ -0,0 +1,25 @@
+// @filename: b.ts
+export const zzz = 123;
+
+// @filename: a.ts
+import * as B from "./b";
+
+interface B {
+    x: string;
+}
+
+const x: B = { x: "" };
+B.zzz;
+
+export { B };
+
+// @filename: index.ts
+import { B } from "./a";
+
+const x: B = { x: "" };
+B.zzz;
+
+import * as OriginalB from "./b";
+OriginalB.zzz;
+
+const y: OriginalB = x;
\ No newline at end of file
diff --git a/tests/cases/compiler/objectSpreadWithinMethodWithinObjectWithSpread.ts b/tests/cases/compiler/objectSpreadWithinMethodWithinObjectWithSpread.ts
new file mode 100644
index 0000000..4d1663b
--- /dev/null
+++ b/tests/cases/compiler/objectSpreadWithinMethodWithinObjectWithSpread.ts
@@ -0,0 +1,10 @@
+const obj = {};
+const a = {
+    ...obj,
+    prop() {
+        return {
+            ...obj,
+            metadata: 213
+        };
+    }
+};
diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsAMD.ts b/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsAMD.ts
new file mode 100644
index 0000000..77f348b
--- /dev/null
+++ b/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsAMD.ts
@@ -0,0 +1,9 @@
+// @module: amd
+// @target: esnext
+// @filename: something.ts
+export = 42;
+
+// @filename: index.ts
+export = async function() {
+    const something = await import("./something");
+};
\ No newline at end of file
diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsCJS.ts b/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsCJS.ts
new file mode 100644
index 0000000..efda80d
--- /dev/null
+++ b/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsCJS.ts
@@ -0,0 +1,9 @@
+// @module: commonjs
+// @target: esnext
+// @filename: something.ts
+export = 42;
+
+// @filename: index.ts
+export = async function() {
+    const something = await import("./something");
+};
\ No newline at end of file
diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsUMD.ts b/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsUMD.ts
new file mode 100644
index 0000000..fc08659
--- /dev/null
+++ b/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsUMD.ts
@@ -0,0 +1,9 @@
+// @module: umd
+// @target: esnext
+// @filename: something.ts
+export = 42;
+
+// @filename: index.ts
+export = async function() {
+    const something = await import("./something");
+};
\ No newline at end of file
diff --git a/tests/cases/conformance/salsa/constructorFunctions2.ts b/tests/cases/conformance/salsa/constructorFunctions2.ts
new file mode 100644
index 0000000..13a6e7b
--- /dev/null
+++ b/tests/cases/conformance/salsa/constructorFunctions2.ts
@@ -0,0 +1,18 @@
+// @allowJs: true
+// @checkJs: true
+// @noEmit: true
+// @module: commonjs
+// @filename: node.d.ts
+declare function require(id: string): any;
+declare var module: any, exports: any;
+
+// @filename: index.js
+const A = require("./other");
+const a = new A().id;
+
+const B = function() { this.id = 1; }
+const b = new B().id;
+
+// @filename: other.js
+function A() { this.id = 1; }
+module.exports = A;
\ No newline at end of file
diff --git a/tests/cases/fourslash/extract-method-not-for-import.ts b/tests/cases/fourslash/extract-method-not-for-import.ts
new file mode 100644
index 0000000..a72d793
--- /dev/null
+++ b/tests/cases/fourslash/extract-method-not-for-import.ts
@@ -0,0 +1,10 @@
+/// <reference path='fourslash.ts' />
+
+// @Filename: /a.ts
+////i/**/mport _ from "./b";
+
+// @Filename: /b.ts
+////export default function f() {}
+
+goTo.marker("");
+verify.not.refactorAvailable('Extract Method');
diff --git a/tests/cases/fourslash/extract-method1.ts b/tests/cases/fourslash/extract-method1.ts
index 7f5c2ac..ff06129 100644
--- a/tests/cases/fourslash/extract-method1.ts
+++ b/tests/cases/fourslash/extract-method1.ts
@@ -13,8 +13,11 @@
 //// }
 
 goTo.select('start', 'end')
-verify.refactorAvailable('Extract Method');
-edit.applyRefactor('Extract Method', "scope_0");
+edit.applyRefactor({
+    refactorName: "Extract Method",
+    actionName: "scope_0",
+    actionDescription: "Extract function into class 'Foo'",
+});
 verify.currentFileContentIs(
 `class Foo {
     someMethod(m: number) {
diff --git a/tests/cases/fourslash/extract-method10.ts b/tests/cases/fourslash/extract-method10.ts
index 1a02bfa..ffbee73 100644
--- a/tests/cases/fourslash/extract-method10.ts
+++ b/tests/cases/fourslash/extract-method10.ts
@@ -1,6 +1,11 @@
 /// <reference path='fourslash.ts' />
 
-//// (x => x)(/*1*/x => x/*2*/)(1); 
+//// export {}; // Make this a module
+//// (x => x)(/*1*/x => x/*2*/)(1);
 
 goTo.select('1', '2');
-edit.applyRefactor('Extract Method', 'scope_0');
+edit.applyRefactor({
+    refactorName: "Extract Method",
+    actionName: 'scope_0',
+    actionDescription: "Extract function into module scope",
+});
diff --git a/tests/cases/fourslash/extract-method13.ts b/tests/cases/fourslash/extract-method13.ts
index b9b7c00..14a146a 100644
--- a/tests/cases/fourslash/extract-method13.ts
+++ b/tests/cases/fourslash/extract-method13.ts
@@ -10,10 +10,18 @@
 //// }
 
 goTo.select('a', 'b');
-edit.applyRefactor('Extract Method', 'scope_0');
+edit.applyRefactor({
+    refactorName: "Extract Method",
+    actionName: "scope_0",
+    actionDescription: "Extract function into class 'C'",
+});
 
 goTo.select('c', 'd');
-edit.applyRefactor('Extract Method', 'scope_0');
+edit.applyRefactor({
+    refactorName: "Extract Method",
+    actionName: "scope_0",
+    actionDescription: "Extract function into class 'C'",
+});
 
 verify.currentFileContentIs(`class C {
     static j = C.newFunction_1();
diff --git a/tests/cases/fourslash/extract-method14.ts b/tests/cases/fourslash/extract-method14.ts
index c8bab1b..696bb66 100644
--- a/tests/cases/fourslash/extract-method14.ts
+++ b/tests/cases/fourslash/extract-method14.ts
@@ -11,7 +11,11 @@
 //// }
 
 goTo.select('a', 'b');
-edit.applyRefactor('Extract Method', 'scope_1');
+edit.applyRefactor({
+    refactorName: "Extract Method",
+    actionName: "scope_1",
+    actionDescription: "Extract function into global scope",
+});
 verify.currentFileContentIs(`function foo() {
     var i = 10;
     var __return: any;
diff --git a/tests/cases/fourslash/extract-method15.ts b/tests/cases/fourslash/extract-method15.ts
index ef62bd3..93aa357 100644
--- a/tests/cases/fourslash/extract-method15.ts
+++ b/tests/cases/fourslash/extract-method15.ts
@@ -9,7 +9,11 @@
 //// }
 
 goTo.select('a', 'b');
-edit.applyRefactor('Extract Method', 'scope_1');
+edit.applyRefactor({
+    refactorName: "Extract Method",
+    actionName: "scope_1",
+    actionDescription: "Extract function into global scope",
+});
 
 verify.currentFileContentIs(`function foo() {
     var i = 10;
diff --git a/tests/cases/fourslash/extract-method18.ts b/tests/cases/fourslash/extract-method18.ts
index 9d87979..d99d14b 100644
--- a/tests/cases/fourslash/extract-method18.ts
+++ b/tests/cases/fourslash/extract-method18.ts
@@ -9,8 +9,11 @@
 //// }
 
 goTo.select('a', 'b')
-verify.refactorAvailable('Extract Method');
-edit.applyRefactor('Extract Method', "scope_1");
+edit.applyRefactor({
+    refactorName: "Extract Method",
+    actionName: "scope_1",
+    actionDescription: "Extract function into global scope",
+});
 verify.currentFileContentIs(`function fn() {
     const x = { m: 1 };
     newFunction(x);
diff --git a/tests/cases/fourslash/extract-method19.ts b/tests/cases/fourslash/extract-method19.ts
index 54f7931..e4fb3e6 100644
--- a/tests/cases/fourslash/extract-method19.ts
+++ b/tests/cases/fourslash/extract-method19.ts
@@ -5,12 +5,15 @@
 //// function fn() {
 ////     /*a*/console.log("hi");/*b*/
 //// }
-//// 
+////
 //// function newFunction() { }
 
 goTo.select('a', 'b')
-verify.refactorAvailable('Extract Method');
-edit.applyRefactor('Extract Method', "scope_0");
+edit.applyRefactor({
+    refactorName: "Extract Method",
+    actionName: "scope_0",
+    actionDescription: "Extract function into function 'fn'",
+});
 verify.currentFileContentIs(`function fn() {
     newFunction_1();
 
diff --git a/tests/cases/fourslash/extract-method2.ts b/tests/cases/fourslash/extract-method2.ts
index 0a4f346..508836c 100644
--- a/tests/cases/fourslash/extract-method2.ts
+++ b/tests/cases/fourslash/extract-method2.ts
@@ -10,8 +10,11 @@
 ////     }
 //// }
 goTo.select('start', 'end')
-verify.refactorAvailable('Extract Method');
-edit.applyRefactor('Extract Method', "scope_2");
+edit.applyRefactor({
+    refactorName: "Extract Method",
+    actionName: "scope_2",
+    actionDescription: "Extract function into global scope",
+});
 verify.currentFileContentIs(
 `namespace NS {
     class Q {
diff --git a/tests/cases/fourslash/extract-method21.ts b/tests/cases/fourslash/extract-method21.ts
index 0168daf..c32df5b 100644
--- a/tests/cases/fourslash/extract-method21.ts
+++ b/tests/cases/fourslash/extract-method21.ts
@@ -12,7 +12,11 @@ goTo.select('start', 'end')
 
 verify.refactorAvailable('Extract Method');
 
-edit.applyRefactor('Extract Method', "scope_0");
+edit.applyRefactor({
+    refactorName: "Extract Method",
+    actionName: "scope_0",
+    actionDescription: "Extract function into class 'Foo'",
+});
 
 verify.currentFileContentIs(`class Foo {
     static method() {
diff --git a/tests/cases/fourslash/extract-method24.ts b/tests/cases/fourslash/extract-method24.ts
index 9eebc00..615cb2a 100644
--- a/tests/cases/fourslash/extract-method24.ts
+++ b/tests/cases/fourslash/extract-method24.ts
@@ -7,7 +7,11 @@
 //// }
 
 goTo.select('a', 'b')
-edit.applyRefactor('Extract Method', 'scope_1');
+edit.applyRefactor({
+    refactorName: "Extract Method",
+    actionName: "scope_1",
+    actionDescription: "Extract function into global scope",
+});
 verify.currentFileContentIs(`function M() {
     let a = [1,2,3];
     let x = 0;
diff --git a/tests/cases/fourslash/extract-method25.ts b/tests/cases/fourslash/extract-method25.ts
index ac7e7a2..8585dd0 100644
--- a/tests/cases/fourslash/extract-method25.ts
+++ b/tests/cases/fourslash/extract-method25.ts
@@ -8,7 +8,11 @@
 //// }
 
 goTo.select('a', 'b')
-edit.applyRefactor('Extract Method', 'scope_0');
+edit.applyRefactor({
+    refactorName: "Extract Method",
+    actionName: "scope_0",
+    actionDescription: "Extract function into function 'fn'",
+});
 verify.currentFileContentIs(`function fn() {
     var q = newFunction()
     q[0]++
diff --git a/tests/cases/fourslash/extract-method3.ts b/tests/cases/fourslash/extract-method3.ts
index af54312..27a520d 100644
--- a/tests/cases/fourslash/extract-method3.ts
+++ b/tests/cases/fourslash/extract-method3.ts
@@ -10,7 +10,7 @@
 ////     }
 //// }
 
-// Don't offer to to 'extract method' a single identifier
+// Don't offer to 'extract method' a single identifier
 
 goTo.marker('a');
 verify.not.refactorAvailable('Extract Method');
diff --git a/tests/cases/fourslash/extract-method5.ts b/tests/cases/fourslash/extract-method5.ts
index ac09f92..1029429 100644
--- a/tests/cases/fourslash/extract-method5.ts
+++ b/tests/cases/fourslash/extract-method5.ts
@@ -9,7 +9,11 @@
 //// }
 
 goTo.select('start', 'end');
-edit.applyRefactor('Extract Method', 'scope_0');
+edit.applyRefactor({
+    refactorName: "Extract Method",
+    actionName: "scope_0",
+    actionDescription: "Extract function into function 'f'",
+});
 verify.currentFileContentIs(
 `function f() {
     var x: 1 | 2 | 3 = newFunction();
diff --git a/tests/cases/fourslash/extract-method7.ts b/tests/cases/fourslash/extract-method7.ts
index 4c95c6a..95c9cbe 100644
--- a/tests/cases/fourslash/extract-method7.ts
+++ b/tests/cases/fourslash/extract-method7.ts
@@ -7,7 +7,11 @@
 //// }
 
 goTo.select('a', 'b');
-edit.applyRefactor('Extract Method', 'scope_0');
+edit.applyRefactor({
+    refactorName: "Extract Method",
+    actionName: "scope_0",
+    actionDescription: "Extract function into global scope",
+});
 verify.currentFileContentIs(`function fn(x = newFunction()) {
 }
 function newFunction() {
diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts
index 5175b52..be84268 100644
--- a/tests/cases/fourslash/fourslash.ts
+++ b/tests/cases/fourslash/fourslash.ts
@@ -158,7 +158,7 @@ declare namespace FourSlashInterface {
         codeFixDiagnosticsAvailableAtMarkers(markerNames: string[], diagnosticCode?: number): void;
         applicableRefactorAvailableForRange(): void;
 
-        refactorAvailable(name?: string, subName?: string);
+        refactorAvailable(name: string, actionName?: string);
     }
     class verify extends verifyNegatable {
         assertHasRanges(ranges: Range[]): void;
@@ -309,7 +309,7 @@ declare namespace FourSlashInterface {
         enableFormatting(): void;
         disableFormatting(): void;
 
-        applyRefactor(refactorName: string, actionName: string): void;
+        applyRefactor(options: { refactorName: string, actionName: string, actionDescription: string }): void;
     }
     class debug {
         printCurrentParameterHelp(): void;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-typescript.git



More information about the Pkg-javascript-commits mailing list