mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 01:39:28 -06:00
Dont allow namespace reexport symbols when looking up valid local names (#43969)
This commit is contained in:
parent
233f28ca27
commit
a5607a4eab
@ -3935,12 +3935,12 @@ namespace ts {
|
||||
return typeCopy;
|
||||
}
|
||||
|
||||
function forEachSymbolTableInScope<T>(enclosingDeclaration: Node | undefined, callback: (symbolTable: SymbolTable) => T): T {
|
||||
function forEachSymbolTableInScope<T>(enclosingDeclaration: Node | undefined, callback: (symbolTable: SymbolTable, ignoreQualification?: boolean, isLocalNameLookup?: boolean) => T): T {
|
||||
let result: T;
|
||||
for (let location = enclosingDeclaration; location; location = location.parent) {
|
||||
// Locals of a source file are not in scope (because they get merged into the global symbol table)
|
||||
if (location.locals && !isGlobalSourceFile(location)) {
|
||||
if (result = callback(location.locals)) {
|
||||
if (result = callback(location.locals, /*ignoreQualification*/ undefined, /*isLocalNameLookup*/ true)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -3955,7 +3955,7 @@ namespace ts {
|
||||
// `sym` may not have exports if this module declaration is backed by the symbol for a `const` that's being rewritten
|
||||
// into a namespace - in such cases, it's best to just let the namespace appear empty (the const members couldn't have referred
|
||||
// to one another anyway)
|
||||
if (result = callback(sym?.exports || emptySymbols)) {
|
||||
if (result = callback(sym?.exports || emptySymbols, /*ignoreQualification*/ undefined, /*isLocalNameLookup*/ true)) {
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
@ -3983,7 +3983,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
return callback(globals);
|
||||
return callback(globals, /*ignoreQualification*/ undefined, /*isLocalNameLookup*/ true);
|
||||
}
|
||||
|
||||
function getQualifiedLeftMeaning(rightMeaning: SymbolFlags) {
|
||||
@ -4006,12 +4006,12 @@ namespace ts {
|
||||
/**
|
||||
* @param {ignoreQualification} boolean Set when a symbol is being looked for through the exports of another symbol (meaning we have a route to qualify it already)
|
||||
*/
|
||||
function getAccessibleSymbolChainFromSymbolTable(symbols: SymbolTable, ignoreQualification?: boolean): Symbol[] | undefined {
|
||||
function getAccessibleSymbolChainFromSymbolTable(symbols: SymbolTable, ignoreQualification?: boolean, isLocalNameLookup?: boolean): Symbol[] | undefined {
|
||||
if (!pushIfUnique(visitedSymbolTables!, symbols)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const result = trySymbolTable(symbols, ignoreQualification);
|
||||
const result = trySymbolTable(symbols, ignoreQualification, isLocalNameLookup);
|
||||
visitedSymbolTables!.pop();
|
||||
return result;
|
||||
}
|
||||
@ -4032,7 +4032,7 @@ namespace ts {
|
||||
(ignoreQualification || canQualifySymbol(getMergedSymbol(symbolFromSymbolTable), meaning));
|
||||
}
|
||||
|
||||
function trySymbolTable(symbols: SymbolTable, ignoreQualification: boolean | undefined): Symbol[] | undefined {
|
||||
function trySymbolTable(symbols: SymbolTable, ignoreQualification: boolean | undefined, isLocalNameLookup: boolean | undefined): Symbol[] | undefined {
|
||||
// If symbol is directly available by its name in the symbol table
|
||||
if (isAccessible(symbols.get(symbol!.escapedName)!, /*resolvedAliasSymbol*/ undefined, ignoreQualification)) {
|
||||
return [symbol!];
|
||||
@ -4046,6 +4046,8 @@ namespace ts {
|
||||
&& !(isUMDExportSymbol(symbolFromSymbolTable) && enclosingDeclaration && isExternalModule(getSourceFileOfNode(enclosingDeclaration)))
|
||||
// If `!useOnlyExternalAliasing`, we can use any type of alias to get the name
|
||||
&& (!useOnlyExternalAliasing || some(symbolFromSymbolTable.declarations, isExternalModuleImportEqualsDeclaration))
|
||||
// If we're looking up a local name to reference directly, omit namespace reexports, otherwise when we're trawling through an export list to make a dotted name, we can keep it
|
||||
&& (isLocalNameLookup ? !some(symbolFromSymbolTable.declarations, isNamespaceReexportDeclaration) : true)
|
||||
// While exports are generally considered to be in scope, export-specifier declared symbols are _not_
|
||||
// See similar comment in `resolveName` for details
|
||||
&& (ignoreQualification || !getDeclarationOfKind(symbolFromSymbolTable, SyntaxKind.ExportSpecifier))
|
||||
@ -4160,7 +4162,7 @@ namespace ts {
|
||||
return hasAccessibleDeclarations;
|
||||
}
|
||||
}
|
||||
else if (allowModules) {
|
||||
if (allowModules) {
|
||||
if (some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
|
||||
if (shouldComputeAliasesToMakeVisible) {
|
||||
earlyModuleBail = true;
|
||||
|
||||
@ -1971,6 +1971,10 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.TypeQuery;
|
||||
}
|
||||
|
||||
export function isNamespaceReexportDeclaration(node: Node): boolean {
|
||||
return isNamespaceExport(node) && !!node.parent.moduleSpecifier;
|
||||
}
|
||||
|
||||
export function isExternalModuleImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration & { moduleReference: ExternalModuleReference } {
|
||||
return node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference;
|
||||
}
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
//// [tests/cases/compiler/declarationEmitDoesNotUseReexportedNamespaceAsLocal.ts] ////
|
||||
|
||||
//// [sub.ts]
|
||||
export function a() {}
|
||||
//// [index.ts]
|
||||
export const x = add(import("./sub"));
|
||||
export * as Q from "./sub";
|
||||
declare function add<T>(x: Promise<T>): T;
|
||||
|
||||
//// [sub.js]
|
||||
export function a() { }
|
||||
//// [index.js]
|
||||
export const x = add(import("./sub"));
|
||||
export * as Q from "./sub";
|
||||
|
||||
|
||||
//// [sub.d.ts]
|
||||
export declare function a(): void;
|
||||
//// [index.d.ts]
|
||||
export declare const x: typeof import("./sub");
|
||||
export * as Q from "./sub";
|
||||
@ -0,0 +1,21 @@
|
||||
=== tests/cases/compiler/sub.ts ===
|
||||
export function a() {}
|
||||
>a : Symbol(a, Decl(sub.ts, 0, 0))
|
||||
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
export const x = add(import("./sub"));
|
||||
>x : Symbol(x, Decl(index.ts, 0, 12))
|
||||
>add : Symbol(add, Decl(index.ts, 1, 27))
|
||||
>"./sub" : Symbol("tests/cases/compiler/sub", Decl(sub.ts, 0, 0))
|
||||
|
||||
export * as Q from "./sub";
|
||||
>Q : Symbol(Q, Decl(index.ts, 1, 6))
|
||||
|
||||
declare function add<T>(x: Promise<T>): T;
|
||||
>add : Symbol(add, Decl(index.ts, 1, 27))
|
||||
>T : Symbol(T, Decl(index.ts, 2, 21))
|
||||
>x : Symbol(x, Decl(index.ts, 2, 24))
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(index.ts, 2, 21))
|
||||
>T : Symbol(T, Decl(index.ts, 2, 21))
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
=== tests/cases/compiler/sub.ts ===
|
||||
export function a() {}
|
||||
>a : () => void
|
||||
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
export const x = add(import("./sub"));
|
||||
>x : typeof import("tests/cases/compiler/sub")
|
||||
>add(import("./sub")) : typeof import("tests/cases/compiler/sub")
|
||||
>add : <T>(x: Promise<T>) => T
|
||||
>import("./sub") : Promise<typeof import("tests/cases/compiler/sub")>
|
||||
>"./sub" : "./sub"
|
||||
|
||||
export * as Q from "./sub";
|
||||
>Q : typeof import("tests/cases/compiler/sub")
|
||||
|
||||
declare function add<T>(x: Promise<T>): T;
|
||||
>add : <T>(x: Promise<T>) => T
|
||||
>x : Promise<T>
|
||||
|
||||
@ -9,7 +9,7 @@ export const b = 2;
|
||||
|
||||
=== tests/cases/conformance/es2020/modules/1.ts ===
|
||||
export * as ns from './0';
|
||||
>ns : typeof ns
|
||||
>ns : typeof import("tests/cases/conformance/es2020/modules/0")
|
||||
|
||||
ns.a;
|
||||
>ns.a : any
|
||||
|
||||
@ -9,7 +9,7 @@ export const b = 2;
|
||||
|
||||
=== tests/cases/conformance/es2020/modules/1.ts ===
|
||||
export * as ns from './0';
|
||||
>ns : typeof ns
|
||||
>ns : typeof import("tests/cases/conformance/es2020/modules/0")
|
||||
|
||||
ns.a;
|
||||
>ns.a : any
|
||||
|
||||
@ -9,7 +9,7 @@ export const b = 2;
|
||||
|
||||
=== tests/cases/conformance/es2020/modules/1.ts ===
|
||||
export * as ns from './0';
|
||||
>ns : typeof ns
|
||||
>ns : typeof import("tests/cases/conformance/es2020/modules/0")
|
||||
|
||||
ns.a;
|
||||
>ns.a : any
|
||||
|
||||
@ -9,7 +9,7 @@ export const b = 2;
|
||||
|
||||
=== tests/cases/conformance/es2020/modules/1.ts ===
|
||||
export * as ns from './0';
|
||||
>ns : typeof ns
|
||||
>ns : typeof import("tests/cases/conformance/es2020/modules/0")
|
||||
|
||||
ns.a;
|
||||
>ns.a : any
|
||||
|
||||
@ -9,7 +9,7 @@ export const b = 2;
|
||||
|
||||
=== tests/cases/conformance/es2020/modules/1.ts ===
|
||||
export * as ns from './0';
|
||||
>ns : typeof ns
|
||||
>ns : typeof import("tests/cases/conformance/es2020/modules/0")
|
||||
|
||||
ns.a;
|
||||
>ns.a : any
|
||||
|
||||
@ -9,7 +9,7 @@ export const b = 2;
|
||||
|
||||
=== tests/cases/conformance/es2020/modules/1.ts ===
|
||||
export * as ns from './0';
|
||||
>ns : typeof ns
|
||||
>ns : typeof import("tests/cases/conformance/es2020/modules/0")
|
||||
|
||||
ns.a;
|
||||
>ns.a : any
|
||||
|
||||
@ -9,7 +9,7 @@ export const b = 2;
|
||||
|
||||
=== tests/cases/conformance/es2020/modules/1.ts ===
|
||||
export * as ns from './0';
|
||||
>ns : typeof ns
|
||||
>ns : typeof import("tests/cases/conformance/es2020/modules/0")
|
||||
|
||||
ns.a;
|
||||
>ns.a : any
|
||||
|
||||
@ -9,7 +9,7 @@ export const b = 2;
|
||||
|
||||
=== tests/cases/conformance/es2020/modules/1.ts ===
|
||||
export * as ns from './0';
|
||||
>ns : typeof ns
|
||||
>ns : typeof import("tests/cases/conformance/es2020/modules/0")
|
||||
|
||||
ns.a;
|
||||
>ns.a : any
|
||||
|
||||
@ -9,7 +9,7 @@ export const b = 2;
|
||||
|
||||
=== tests/cases/conformance/es2020/modules/1.ts ===
|
||||
export * as ns from './0';
|
||||
>ns : typeof ns
|
||||
>ns : typeof import("tests/cases/conformance/es2020/modules/0")
|
||||
|
||||
ns.a;
|
||||
>ns.a : any
|
||||
|
||||
@ -9,7 +9,7 @@ export const b = 2;
|
||||
|
||||
=== tests/cases/conformance/es2020/modules/1.ts ===
|
||||
export * as ns from './0';
|
||||
>ns : typeof ns
|
||||
>ns : typeof import("tests/cases/conformance/es2020/modules/0")
|
||||
|
||||
ns.a;
|
||||
>ns.a : any
|
||||
|
||||
@ -9,7 +9,7 @@ export const b = 2;
|
||||
|
||||
=== tests/cases/conformance/es2020/modules/1.ts ===
|
||||
export * as ns from './0';
|
||||
>ns : typeof ns
|
||||
>ns : typeof import("tests/cases/conformance/es2020/modules/0")
|
||||
|
||||
ns.a;
|
||||
>ns.a : any
|
||||
|
||||
@ -9,7 +9,7 @@ export const b = 2;
|
||||
|
||||
=== tests/cases/conformance/es2020/modules/1.ts ===
|
||||
export * as ns from './0';
|
||||
>ns : typeof ns
|
||||
>ns : typeof import("tests/cases/conformance/es2020/modules/0")
|
||||
|
||||
ns.a;
|
||||
>ns.a : any
|
||||
|
||||
@ -4,7 +4,7 @@ export class A {}
|
||||
|
||||
=== tests/cases/conformance/externalModules/typeOnly/b.ts ===
|
||||
export * as a from './a';
|
||||
>a : typeof a
|
||||
>a : typeof import("tests/cases/conformance/externalModules/typeOnly/a")
|
||||
|
||||
=== tests/cases/conformance/externalModules/typeOnly/c.ts ===
|
||||
import type { a } from './b';
|
||||
|
||||
@ -8,7 +8,7 @@ export type { A } from './a';
|
||||
|
||||
=== tests/cases/conformance/externalModules/typeOnly/c.ts ===
|
||||
export * as a from './b';
|
||||
>a : typeof a
|
||||
>a : typeof import("tests/cases/conformance/externalModules/typeOnly/b")
|
||||
|
||||
=== tests/cases/conformance/externalModules/typeOnly/d.ts ===
|
||||
import { a } from './c';
|
||||
|
||||
@ -7,7 +7,7 @@ export type * from './a'; // Grammar error
|
||||
No type information for this code.
|
||||
No type information for this code.=== tests/cases/conformance/externalModules/typeOnly/c.ts ===
|
||||
export type * as ns from './a'; // Grammar error
|
||||
>ns : typeof ns
|
||||
>ns : typeof import("tests/cases/conformance/externalModules/typeOnly/a")
|
||||
|
||||
=== tests/cases/conformance/externalModules/typeOnly/d.ts ===
|
||||
import { A } from './b';
|
||||
|
||||
@ -27,5 +27,5 @@ register("ok");
|
||||
export * from "./register";
|
||||
export * from "./data1";
|
||||
export * as aliased from "./data1";
|
||||
>aliased : typeof aliased
|
||||
>aliased : typeof import("tests/cases/compiler/data1")
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ export class A { }
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
export * as a from "./a";
|
||||
>a : typeof a
|
||||
>a : typeof import("tests/cases/compiler/a")
|
||||
|
||||
=== tests/cases/compiler/tslib.d.ts ===
|
||||
declare module "tslib" {
|
||||
|
||||
@ -4,7 +4,7 @@ export class A { }
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
export * as a from "./a";
|
||||
>a : typeof a
|
||||
>a : typeof import("tests/cases/compiler/a")
|
||||
|
||||
=== tests/cases/compiler/tslib.d.ts ===
|
||||
declare module "tslib" {
|
||||
|
||||
@ -4,7 +4,7 @@ export class A { }
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
export * as a from "./a";
|
||||
>a : typeof a
|
||||
>a : typeof import("tests/cases/compiler/a")
|
||||
|
||||
=== tests/cases/compiler/tslib.d.ts ===
|
||||
declare module "tslib" {
|
||||
|
||||
@ -4,7 +4,7 @@ export class A { }
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
export * as a from "./a";
|
||||
>a : typeof a
|
||||
>a : typeof import("tests/cases/compiler/a")
|
||||
|
||||
=== tests/cases/compiler/tslib.d.ts ===
|
||||
declare module "tslib" {
|
||||
|
||||
@ -4,7 +4,7 @@ export class A { }
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
export * as a from "./a";
|
||||
>a : typeof a
|
||||
>a : typeof import("tests/cases/compiler/a")
|
||||
|
||||
=== tests/cases/compiler/tslib.d.ts ===
|
||||
declare module "tslib" {
|
||||
|
||||
@ -4,7 +4,7 @@ export class A { }
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
export * as a from "./a";
|
||||
>a : typeof a
|
||||
>a : typeof import("tests/cases/compiler/a")
|
||||
|
||||
=== tests/cases/compiler/tslib.d.ts ===
|
||||
declare module "tslib" {
|
||||
|
||||
@ -4,7 +4,7 @@ export class A { }
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
export * as a from "./a";
|
||||
>a : typeof a
|
||||
>a : typeof import("tests/cases/compiler/a")
|
||||
|
||||
=== tests/cases/compiler/tslib.d.ts ===
|
||||
declare module "tslib" {
|
||||
|
||||
@ -4,7 +4,7 @@ export class A { }
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
export * as a from "./a";
|
||||
>a : typeof a
|
||||
>a : typeof import("tests/cases/compiler/a")
|
||||
|
||||
=== tests/cases/compiler/tslib.d.ts ===
|
||||
declare module "tslib" {
|
||||
|
||||
@ -4,7 +4,7 @@ export class A { }
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
export * as a from "./a";
|
||||
>a : typeof a
|
||||
>a : typeof import("tests/cases/compiler/a")
|
||||
|
||||
=== tests/cases/compiler/tslib.d.ts ===
|
||||
declare module "tslib" {
|
||||
|
||||
@ -4,7 +4,7 @@ export class A { }
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
export * as a from "./a";
|
||||
>a : typeof a
|
||||
>a : typeof import("tests/cases/compiler/a")
|
||||
|
||||
=== tests/cases/compiler/tslib.d.ts ===
|
||||
declare module "tslib" {
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
// @target: esnext
|
||||
// @module: esnext
|
||||
// @declaration: true
|
||||
// @filename: sub.ts
|
||||
export function a() {}
|
||||
// @filename: index.ts
|
||||
export const x = add(import("./sub"));
|
||||
export * as Q from "./sub";
|
||||
declare function add<T>(x: Promise<T>): T;
|
||||
Loading…
x
Reference in New Issue
Block a user