Create import helpers for named imports if they contain default imports (#21550) (#21561)

This commit is contained in:
Wesley Wigham
2018-02-01 19:52:02 -08:00
committed by GitHub
parent 2916c9c57e
commit 9e0d8c3aa0
5 changed files with 152 additions and 2 deletions
+22 -2
View File
@@ -690,16 +690,36 @@ namespace ts {
return createCall(createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]);
}
function getNamedImportCount(node: ImportDeclaration) {
if (!(node.importClause && node.importClause.namedBindings)) return 0;
const names = node.importClause.namedBindings;
if (!names) return 0;
if (!isNamedImports(names)) return 0;
return names.elements.length;
}
function containsDefaultReference(node: NamedImportBindings) {
if (!node) return false;
if (!isNamedImports(node)) return false;
return some(node.elements, isNamedDefaultReference);
}
function isNamedDefaultReference(e: ImportSpecifier) {
return e.propertyName && e.propertyName.escapedText === InternalSymbolName.Default;
}
function getHelperExpressionForImport(node: ImportDeclaration, innerExpr: Expression) {
if (!compilerOptions.esModuleInterop || getEmitFlags(node) & EmitFlags.NeverApplyImportHelper) {
return innerExpr;
}
if (getNamespaceDeclarationNode(node)) {
const nameCount = getNamedImportCount(node);
const hasDefault = nameCount > 0 ? containsDefaultReference(node.importClause.namedBindings) : undefined;
if (getNamespaceDeclarationNode(node) || (nameCount > 1 && hasDefault)) {
context.requestEmitHelper(importStarHelper);
return createCall(getHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]);
}
if (isDefaultImport(node)) {
if (isDefaultImport(node) || (nameCount === 1 && hasDefault)) {
context.requestEmitHelper(importDefaultHelper);
return createCall(getHelperName("__importDefault"), /*typeArguments*/ undefined, [innerExpr]);
}
@@ -0,0 +1,49 @@
//// [tests/cases/compiler/esModuleInteropNamedDefaultImports.ts] ////
//// [mod.ts]
export default class Foo {}
export class Bar {}
//// [idx.ts]
import Foo from "./mod";
import { default as Foo2 } from "./mod";
import { Bar, default as Foo3 } from "./mod";
new Foo();
new Foo2();
new Bar();
new Foo3();
//// [mod.js]
"use strict";
exports.__esModule = true;
var Foo = /** @class */ (function () {
function Foo() {
}
return Foo;
}());
exports["default"] = Foo;
var Bar = /** @class */ (function () {
function Bar() {
}
return Bar;
}());
exports.Bar = Bar;
//// [idx.js]
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
}
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
}
exports.__esModule = true;
var mod_1 = __importDefault(require("./mod"));
var mod_2 = __importDefault(require("./mod"));
var mod_3 = __importStar(require("./mod"));
new mod_1["default"]();
new mod_2["default"]();
new mod_3.Bar();
new mod_3["default"]();
@@ -0,0 +1,32 @@
=== tests/cases/compiler/mod.ts ===
export default class Foo {}
>Foo : Symbol(Foo, Decl(mod.ts, 0, 0))
export class Bar {}
>Bar : Symbol(Bar, Decl(mod.ts, 0, 27))
=== tests/cases/compiler/idx.ts ===
import Foo from "./mod";
>Foo : Symbol(Foo, Decl(idx.ts, 0, 6))
import { default as Foo2 } from "./mod";
>default : Symbol(Foo2, Decl(idx.ts, 1, 8))
>Foo2 : Symbol(Foo2, Decl(idx.ts, 1, 8))
import { Bar, default as Foo3 } from "./mod";
>Bar : Symbol(Bar, Decl(idx.ts, 2, 8))
>default : Symbol(Foo3, Decl(idx.ts, 2, 13))
>Foo3 : Symbol(Foo3, Decl(idx.ts, 2, 13))
new Foo();
>Foo : Symbol(Foo, Decl(idx.ts, 0, 6))
new Foo2();
>Foo2 : Symbol(Foo2, Decl(idx.ts, 1, 8))
new Bar();
>Bar : Symbol(Bar, Decl(idx.ts, 2, 8))
new Foo3();
>Foo3 : Symbol(Foo3, Decl(idx.ts, 2, 13))
@@ -0,0 +1,36 @@
=== tests/cases/compiler/mod.ts ===
export default class Foo {}
>Foo : Foo
export class Bar {}
>Bar : Bar
=== tests/cases/compiler/idx.ts ===
import Foo from "./mod";
>Foo : typeof Foo
import { default as Foo2 } from "./mod";
>default : typeof Foo
>Foo2 : typeof Foo
import { Bar, default as Foo3 } from "./mod";
>Bar : typeof Bar
>default : typeof Foo
>Foo3 : typeof Foo
new Foo();
>new Foo() : Foo
>Foo : typeof Foo
new Foo2();
>new Foo2() : Foo
>Foo2 : typeof Foo
new Bar();
>new Bar() : Bar
>Bar : typeof Bar
new Foo3();
>new Foo3() : Foo
>Foo3 : typeof Foo
@@ -0,0 +1,13 @@
// @module: commonjs
// @esModuleInterop: true
// @filename: mod.ts
export default class Foo {}
export class Bar {}
// @filename: idx.ts
import Foo from "./mod";
import { default as Foo2 } from "./mod";
import { Bar, default as Foo3 } from "./mod";
new Foo();
new Foo2();
new Bar();
new Foo3();