From 61ebcb49c7808030b78b01e0c85039a79290cf4b Mon Sep 17 00:00:00 2001 From: "Diogo Franco (Kovensky)" Date: Fri, 17 Mar 2017 10:25:37 +0900 Subject: [PATCH] Allow exporting a binding before its declaration --- src/compiler/checker.ts | 7 +++++++ tests/baselines/reference/exportBinding.js | 19 +++++++++++++++++++ .../baselines/reference/exportBinding.symbols | 14 ++++++++++++++ tests/baselines/reference/exportBinding.types | 15 +++++++++++++++ .../conformance/es6/modules/exportBinding.ts | 5 +++++ 5 files changed, 60 insertions(+) create mode 100644 tests/baselines/reference/exportBinding.js create mode 100644 tests/baselines/reference/exportBinding.symbols create mode 100644 tests/baselines/reference/exportBinding.types create mode 100644 tests/cases/conformance/es6/modules/exportBinding.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 00498191f287a..736b3154fbc03 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -742,6 +742,13 @@ namespace ts { // declaration is after usage, but it can still be legal if usage is deferred: // 1. inside a function // 2. inside an instance property initializer, a reference to a non-instance property + // 3. inside an export specifier + + if (usage.parent.kind === SyntaxKind.ExportSpecifier) { + // export specifiers do not use the variable, they only make it available for use + return true; + } + const container = getEnclosingBlockScopeContainer(declaration); const isInstanceProperty = declaration.kind === SyntaxKind.PropertyDeclaration && !(getModifierFlags(declaration) & ModifierFlags.Static); return isUsedInFunctionOrInstanceProperty(usage, isInstanceProperty, container); diff --git a/tests/baselines/reference/exportBinding.js b/tests/baselines/reference/exportBinding.js new file mode 100644 index 0000000000000..5059c5356a376 --- /dev/null +++ b/tests/baselines/reference/exportBinding.js @@ -0,0 +1,19 @@ +//// [exportBinding.ts] +export { x } +const x = 'x' + +export { Y as Z } +class Y {} + + +//// [exportBinding.js] +"use strict"; +exports.__esModule = true; +var x = 'x'; +exports.x = x; +var Y = (function () { + function Y() { + } + return Y; +}()); +exports.Z = Y; diff --git a/tests/baselines/reference/exportBinding.symbols b/tests/baselines/reference/exportBinding.symbols new file mode 100644 index 0000000000000..cb3b58a5776a2 --- /dev/null +++ b/tests/baselines/reference/exportBinding.symbols @@ -0,0 +1,14 @@ +=== tests/cases/conformance/es6/modules/exportBinding.ts === +export { x } +>x : Symbol(x, Decl(exportBinding.ts, 0, 8)) + +const x = 'x' +>x : Symbol(x, Decl(exportBinding.ts, 1, 5)) + +export { Y as Z } +>Y : Symbol(Z, Decl(exportBinding.ts, 3, 8)) +>Z : Symbol(Z, Decl(exportBinding.ts, 3, 8)) + +class Y {} +>Y : Symbol(Y, Decl(exportBinding.ts, 3, 17)) + diff --git a/tests/baselines/reference/exportBinding.types b/tests/baselines/reference/exportBinding.types new file mode 100644 index 0000000000000..e2553ba1eaa58 --- /dev/null +++ b/tests/baselines/reference/exportBinding.types @@ -0,0 +1,15 @@ +=== tests/cases/conformance/es6/modules/exportBinding.ts === +export { x } +>x : "x" + +const x = 'x' +>x : "x" +>'x' : "x" + +export { Y as Z } +>Y : typeof Y +>Z : typeof Y + +class Y {} +>Y : Y + diff --git a/tests/cases/conformance/es6/modules/exportBinding.ts b/tests/cases/conformance/es6/modules/exportBinding.ts new file mode 100644 index 0000000000000..1e6b0314f0bd0 --- /dev/null +++ b/tests/cases/conformance/es6/modules/exportBinding.ts @@ -0,0 +1,5 @@ +export { x } +const x = 'x' + +export { Y as Z } +class Y {}