Merge multiple symbols even when re-exported (#49987)

* Merge multiple symbols even when re-exported

As far as I remember, the target of `mergeSymbol` needs to be a merged
symbol, not a symbol with a mergeId that points to mergedSymbol.
However, mergeSymbolTable didn't check for this.

I can't remember if symbol tables may contain
symbols-with-mergeId. If they can, then mergeSymbolTable needs to call
getMergedSymbol on the individual targets of the merge. That's what I
did in this PR.

* Call getMergeSymbol eagerly

On the source, not target, of mergeSymbolTable's contents
This commit is contained in:
Nathan Shively-Sanders 2022-08-09 16:36:53 -07:00 committed by GitHub
parent abc2a350e6
commit dd98c17b10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 191 additions and 3 deletions

View File

@ -1426,7 +1426,7 @@ namespace ts {
function mergeSymbolTable(target: SymbolTable, source: SymbolTable, unidirectional = false) {
source.forEach((sourceSymbol, id) => {
const targetSymbol = target.get(id);
target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol, unidirectional) : sourceSymbol);
target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol, unidirectional) : getMergedSymbol(sourceSymbol));
});
}

View File

@ -0,0 +1,65 @@
//// [tests/cases/compiler/mergeMultipleInterfacesReexported.ts] ////
//// [index.ts]
export * from './eventList';
//// [test.ts]
import { EventList } from "./eventList";
declare const p012: "p0" | "p1" | "p2"
const t: keyof EventList = p012
//// [eventList.ts]
export interface EventList {
p0: [];
}
//// [foo.ts]
declare module './index' {
interface EventList {
p1: []
}
}
export {};
//// [bar.ts]
declare module './index' {
interface EventList {
p2: []
}
}
export {};
//// [eventList.js]
"use strict";
exports.__esModule = true;
//// [index.js]
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
exports.__esModule = true;
__exportStar(require("./eventList"), exports);
//// [test.js]
"use strict";
exports.__esModule = true;
var t = p012;
//// [foo.js]
"use strict";
exports.__esModule = true;
//// [bar.js]
"use strict";
exports.__esModule = true;

View File

@ -0,0 +1,50 @@
=== tests/cases/compiler/index.ts ===
export * from './eventList';
No type information for this code.
No type information for this code.=== tests/cases/compiler/test.ts ===
import { EventList } from "./eventList";
>EventList : Symbol(EventList, Decl(test.ts, 0, 8))
declare const p012: "p0" | "p1" | "p2"
>p012 : Symbol(p012, Decl(test.ts, 2, 13))
const t: keyof EventList = p012
>t : Symbol(t, Decl(test.ts, 3, 5))
>EventList : Symbol(EventList, Decl(test.ts, 0, 8))
>p012 : Symbol(p012, Decl(test.ts, 2, 13))
=== tests/cases/compiler/eventList.ts ===
export interface EventList {
>EventList : Symbol(EventList, Decl(eventList.ts, 0, 0), Decl(foo.ts, 0, 26), Decl(bar.ts, 0, 26))
p0: [];
>p0 : Symbol(EventList.p0, Decl(eventList.ts, 0, 28))
}
=== tests/cases/compiler/foo.ts ===
declare module './index' {
>'./index' : Symbol("tests/cases/compiler/index", Decl(index.ts, 0, 0), Decl(foo.ts, 0, 0), Decl(bar.ts, 0, 0))
interface EventList {
>EventList : Symbol(EventList, Decl(eventList.ts, 0, 0), Decl(foo.ts, 0, 26), Decl(bar.ts, 0, 26))
p1: []
>p1 : Symbol(EventList.p1, Decl(foo.ts, 1, 25))
}
}
export {};
=== tests/cases/compiler/bar.ts ===
declare module './index' {
>'./index' : Symbol("tests/cases/compiler/index", Decl(index.ts, 0, 0), Decl(foo.ts, 0, 0), Decl(bar.ts, 0, 0))
interface EventList {
>EventList : Symbol(EventList, Decl(eventList.ts, 0, 0), Decl(foo.ts, 0, 26), Decl(bar.ts, 0, 26))
p2: []
>p2 : Symbol(EventList.p2, Decl(bar.ts, 1, 25))
}
}
export {};

View File

@ -0,0 +1,43 @@
=== tests/cases/compiler/index.ts ===
export * from './eventList';
No type information for this code.
No type information for this code.=== tests/cases/compiler/test.ts ===
import { EventList } from "./eventList";
>EventList : any
declare const p012: "p0" | "p1" | "p2"
>p012 : "p0" | "p1" | "p2"
const t: keyof EventList = p012
>t : keyof EventList
>p012 : "p0" | "p1" | "p2"
=== tests/cases/compiler/eventList.ts ===
export interface EventList {
p0: [];
>p0 : []
}
=== tests/cases/compiler/foo.ts ===
declare module './index' {
>'./index' : typeof import("tests/cases/compiler/index")
interface EventList {
p1: []
>p1 : []
}
}
export {};
=== tests/cases/compiler/bar.ts ===
declare module './index' {
>'./index' : typeof import("tests/cases/compiler/index")
interface EventList {
p2: []
>p2 : []
}
}
export {};

View File

@ -45,9 +45,9 @@ const g: ns.Root = ns.Root.A;
>ns : Symbol(ns, Decl(augment.ts, 0, 6))
>Root : Symbol(ns.Root, Decl(file.ts, 0, 0), Decl(augment.ts, 2, 29))
>ns.Root.A : Symbol(ns.Root.A, Decl(augment.ts, 4, 22))
>ns.Root : Symbol(ns.Root, Decl(augment.ts, 2, 29))
>ns.Root : Symbol(ns.Root, Decl(file.ts, 0, 0), Decl(augment.ts, 2, 29))
>ns : Symbol(ns, Decl(augment.ts, 0, 6))
>Root : Symbol(ns.Root, Decl(augment.ts, 2, 29))
>Root : Symbol(ns.Root, Decl(file.ts, 0, 0), Decl(augment.ts, 2, 29))
>A : Symbol(ns.Root.A, Decl(augment.ts, 4, 22))
f.x;

View File

@ -0,0 +1,30 @@
// @filename: index.ts
export * from './eventList';
// @filename: test.ts
import { EventList } from "./eventList";
declare const p012: "p0" | "p1" | "p2"
const t: keyof EventList = p012
// @filename: eventList.ts
export interface EventList {
p0: [];
}
// @filename: foo.ts
declare module './index' {
interface EventList {
p1: []
}
}
export {};
// @filename: bar.ts
declare module './index' {
interface EventList {
p2: []
}
}
export {};