Merge pull request #5588 from Microsoft/reexport-default-export
Reexport default export
This commit is contained in:
commit
c1ea85fa72
|
@ -486,9 +486,19 @@ namespace ts {
|
|||
if (location.kind === SyntaxKind.SourceFile ||
|
||||
(location.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>location).name.kind === SyntaxKind.StringLiteral)) {
|
||||
|
||||
// It's an external module. Because of module/namespace merging, a module's exports are in scope,
|
||||
// yet we never want to treat an export specifier as putting a member in scope. Therefore,
|
||||
// if the name we find is purely an export specifier, it is not actually considered in scope.
|
||||
// It's an external module. First see if the module has an export default and if the local
|
||||
// name of that export default matches.
|
||||
if (result = moduleExports["default"]) {
|
||||
const localSymbol = getLocalSymbolForExportDefault(result);
|
||||
if (localSymbol && (result.flags & meaning) && localSymbol.name === name) {
|
||||
break loop;
|
||||
}
|
||||
result = undefined;
|
||||
}
|
||||
|
||||
// Because of module/namespace merging, a module's exports are in scope,
|
||||
// yet we never want to treat an export specifier as putting a member in scope.
|
||||
// Therefore, if the name we find is purely an export specifier, it is not actually considered in scope.
|
||||
// Two things to note about this:
|
||||
// 1. We have to check this without calling getSymbol. The problem with calling getSymbol
|
||||
// on an export specifier is that it might find the export specifier itself, and try to
|
||||
|
@ -502,13 +512,6 @@ namespace ts {
|
|||
getDeclarationOfKind(moduleExports[name], SyntaxKind.ExportSpecifier)) {
|
||||
break;
|
||||
}
|
||||
|
||||
result = moduleExports["default"];
|
||||
const localSymbol = getLocalSymbolForExportDefault(result);
|
||||
if (result && localSymbol && (result.flags & meaning) && localSymbol.name === name) {
|
||||
break loop;
|
||||
}
|
||||
result = undefined;
|
||||
}
|
||||
|
||||
if (result = getSymbol(moduleExports, name, meaning & SymbolFlags.ModuleMember)) {
|
||||
|
@ -4201,12 +4204,12 @@ namespace ts {
|
|||
// We only support expressions that are simple qualified names. For other expressions this produces undefined.
|
||||
const typeNameOrExpression = node.kind === SyntaxKind.TypeReference ? (<TypeReferenceNode>node).typeName :
|
||||
isSupportedExpressionWithTypeArguments(<ExpressionWithTypeArguments>node) ? (<ExpressionWithTypeArguments>node).expression :
|
||||
undefined;
|
||||
undefined;
|
||||
const symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, SymbolFlags.Type) || unknownSymbol;
|
||||
const type = symbol === unknownSymbol ? unknownType :
|
||||
symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) ? getTypeFromClassOrInterfaceReference(node, symbol) :
|
||||
symbol.flags & SymbolFlags.TypeAlias ? getTypeFromTypeAliasReference(node, symbol) :
|
||||
getTypeFromNonGenericTypeReference(node, symbol);
|
||||
symbol.flags & SymbolFlags.TypeAlias ? getTypeFromTypeAliasReference(node, symbol) :
|
||||
getTypeFromNonGenericTypeReference(node, symbol);
|
||||
// Cache both the resolved symbol and the resolved type. The resolved symbol is needed in when we check the
|
||||
// type reference in checkTypeReferenceOrExpressionWithTypeArguments.
|
||||
links.resolvedSymbol = symbol;
|
||||
|
@ -11446,7 +11449,7 @@ namespace ts {
|
|||
|
||||
// Abstract methods can't have an implementation -- in particular, they don't need one.
|
||||
if (!isExportSymbolInsideModule && lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
|
||||
!(lastSeenNonAmbientDeclaration.flags & NodeFlags.Abstract) ) {
|
||||
!(lastSeenNonAmbientDeclaration.flags & NodeFlags.Abstract)) {
|
||||
reportImplementationExpectedError(lastSeenNonAmbientDeclaration);
|
||||
}
|
||||
|
||||
|
@ -14380,8 +14383,8 @@ namespace ts {
|
|||
if (className) {
|
||||
copySymbol(location.symbol, meaning);
|
||||
}
|
||||
// fall through; this fall-through is necessary because we would like to handle
|
||||
// type parameter inside class expression similar to how we handle it in classDeclaration and interface Declaration
|
||||
// fall through; this fall-through is necessary because we would like to handle
|
||||
// type parameter inside class expression similar to how we handle it in classDeclaration and interface Declaration
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
// If we didn't come from static member of class or interface,
|
||||
|
@ -14537,8 +14540,8 @@ namespace ts {
|
|||
return resolveEntityName(<EntityName>entityName, meaning);
|
||||
}
|
||||
else if ((entityName.parent.kind === SyntaxKind.JsxOpeningElement) ||
|
||||
(entityName.parent.kind === SyntaxKind.JsxSelfClosingElement) ||
|
||||
(entityName.parent.kind === SyntaxKind.JsxClosingElement)) {
|
||||
(entityName.parent.kind === SyntaxKind.JsxSelfClosingElement) ||
|
||||
(entityName.parent.kind === SyntaxKind.JsxClosingElement)) {
|
||||
return getJsxElementTagSymbol(<JsxOpeningLikeElement>entityName.parent);
|
||||
}
|
||||
else if (isExpression(entityName)) {
|
||||
|
@ -14605,8 +14608,8 @@ namespace ts {
|
|||
: getSymbolOfPartOfRightHandSideOfImportEquals(<Identifier>node);
|
||||
}
|
||||
else if (node.parent.kind === SyntaxKind.BindingElement &&
|
||||
node.parent.parent.kind === SyntaxKind.ObjectBindingPattern &&
|
||||
node === (<BindingElement>node.parent).propertyName) {
|
||||
node.parent.parent.kind === SyntaxKind.ObjectBindingPattern &&
|
||||
node === (<BindingElement>node.parent).propertyName) {
|
||||
const typeOfPattern = getTypeOfNode(node.parent.parent);
|
||||
const propertyDeclaration = typeOfPattern && getPropertyOfType(typeOfPattern, (<Identifier>node).text);
|
||||
|
||||
|
@ -14643,7 +14646,7 @@ namespace ts {
|
|||
(<ImportDeclaration>node.parent).moduleSpecifier === node)) {
|
||||
return resolveExternalModuleName(node, <LiteralExpression>node);
|
||||
}
|
||||
// Fall through
|
||||
// Fall through
|
||||
|
||||
case SyntaxKind.NumericLiteral:
|
||||
// index access
|
||||
|
@ -14839,7 +14842,7 @@ namespace ts {
|
|||
if (links.isNestedRedeclaration === undefined) {
|
||||
const container = getEnclosingBlockScopeContainer(symbol.valueDeclaration);
|
||||
links.isNestedRedeclaration = isStatementWithLocals(container) &&
|
||||
!!resolveName(container.parent, symbol.name, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
|
||||
!!resolveName(container.parent, symbol.name, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
|
||||
}
|
||||
return links.isNestedRedeclaration;
|
||||
}
|
||||
|
|
27
tests/baselines/reference/reExportDefaultExport.js
Normal file
27
tests/baselines/reference/reExportDefaultExport.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
//// [tests/cases/conformance/es6/modules/reExportDefaultExport.ts] ////
|
||||
|
||||
//// [m1.ts]
|
||||
|
||||
export default function f() {
|
||||
}
|
||||
export {f};
|
||||
|
||||
|
||||
//// [m2.ts]
|
||||
import foo from "./m1";
|
||||
import {f} from "./m1";
|
||||
|
||||
f();
|
||||
foo();
|
||||
|
||||
//// [m1.js]
|
||||
function f() {
|
||||
}
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.default = f;
|
||||
exports.f = f;
|
||||
//// [m2.js]
|
||||
var m1_1 = require("./m1");
|
||||
var m1_2 = require("./m1");
|
||||
m1_2.f();
|
||||
m1_1.default();
|
22
tests/baselines/reference/reExportDefaultExport.symbols
Normal file
22
tests/baselines/reference/reExportDefaultExport.symbols
Normal file
|
@ -0,0 +1,22 @@
|
|||
=== tests/cases/conformance/es6/modules/m1.ts ===
|
||||
|
||||
export default function f() {
|
||||
>f : Symbol(f, Decl(m1.ts, 0, 0))
|
||||
}
|
||||
export {f};
|
||||
>f : Symbol(f, Decl(m1.ts, 3, 8))
|
||||
|
||||
|
||||
=== tests/cases/conformance/es6/modules/m2.ts ===
|
||||
import foo from "./m1";
|
||||
>foo : Symbol(foo, Decl(m2.ts, 0, 6))
|
||||
|
||||
import {f} from "./m1";
|
||||
>f : Symbol(f, Decl(m2.ts, 1, 8))
|
||||
|
||||
f();
|
||||
>f : Symbol(f, Decl(m2.ts, 1, 8))
|
||||
|
||||
foo();
|
||||
>foo : Symbol(foo, Decl(m2.ts, 0, 6))
|
||||
|
24
tests/baselines/reference/reExportDefaultExport.types
Normal file
24
tests/baselines/reference/reExportDefaultExport.types
Normal file
|
@ -0,0 +1,24 @@
|
|||
=== tests/cases/conformance/es6/modules/m1.ts ===
|
||||
|
||||
export default function f() {
|
||||
>f : () => void
|
||||
}
|
||||
export {f};
|
||||
>f : () => void
|
||||
|
||||
|
||||
=== tests/cases/conformance/es6/modules/m2.ts ===
|
||||
import foo from "./m1";
|
||||
>foo : () => void
|
||||
|
||||
import {f} from "./m1";
|
||||
>f : () => void
|
||||
|
||||
f();
|
||||
>f() : void
|
||||
>f : () => void
|
||||
|
||||
foo();
|
||||
>foo() : void
|
||||
>foo : () => void
|
||||
|
15
tests/cases/conformance/es6/modules/reExportDefaultExport.ts
Normal file
15
tests/cases/conformance/es6/modules/reExportDefaultExport.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
// @module: commonjs
|
||||
// @target: ES5
|
||||
|
||||
// @filename: m1.ts
|
||||
export default function f() {
|
||||
}
|
||||
export {f};
|
||||
|
||||
|
||||
// @filename: m2.ts
|
||||
import foo from "./m1";
|
||||
import {f} from "./m1";
|
||||
|
||||
f();
|
||||
foo();
|
Loading…
Reference in a new issue