Skip to content

Commit

Permalink
Fix CJS export of typedef and class w/latebound names (microsoft#55053)
Browse files Browse the repository at this point in the history
  • Loading branch information
sandersn authored and snovader committed Sep 23, 2023
1 parent 1eea215 commit 89caf30
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 1 deletion.
19 changes: 18 additions & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12822,7 +12822,24 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}

links[resolutionKind] = combineSymbolTables(earlySymbols, lateSymbols) || emptySymbols;
let resolved = combineSymbolTables(earlySymbols, lateSymbols);
if (symbol.flags & SymbolFlags.Transient && links.cjsExportMerged && symbol.declarations) {
for (const decl of symbol.declarations) {
const original = getSymbolLinks(decl.symbol)[resolutionKind];
if (!resolved) {
resolved = original;
continue;
}
if (!original) continue;
original.forEach((s, name) => {
const existing = resolved!.get(name);
if (!existing) resolved!.set(name, s);
else if (existing === s) return;
else resolved!.set(name, mergeSymbol(existing, s));
});
}
}
links[resolutionKind] = resolved || emptySymbols;
}

return links[resolutionKind]!;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//// [tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypedefAndLatebound.ts] ////

=== index.js ===
// from #53967, based on webpack/webpack#16957

const LazySet = require("./LazySet");
>LazySet : Symbol(LazySet, Decl(index.js, 2, 5))
>require : Symbol(require)
>"./LazySet" : Symbol("LazySet", Decl(LazySet.js, 0, 0))

/** @type {LazySet} */
const stringSet = undefined;
>stringSet : Symbol(stringSet, Decl(index.js, 5, 5))
>undefined : Symbol(undefined)

stringSet.addAll(stringSet);
>stringSet.addAll : Symbol(LazySet.addAll, Decl(LazySet.js, 4, 15))
>stringSet : Symbol(stringSet, Decl(index.js, 5, 5))
>addAll : Symbol(LazySet.addAll, Decl(LazySet.js, 4, 15))
>stringSet : Symbol(stringSet, Decl(index.js, 5, 5))


=== LazySet.js ===
// Comment out this JSDoc, and note that the errors index.js go away.
/**
* @typedef {Object} SomeObject
*/
class LazySet {
>LazySet : Symbol(LazySet, Decl(LazySet.js, 0, 0))

/**
* @param {LazySet} iterable
*/
addAll(iterable) {}
>addAll : Symbol(LazySet.addAll, Decl(LazySet.js, 4, 15))
>iterable : Symbol(iterable, Decl(LazySet.js, 8, 11))

[Symbol.iterator]() {}
>[Symbol.iterator] : Symbol(LazySet[Symbol.iterator], Decl(LazySet.js, 8, 23))
>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --))
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --))
}

module.exports = LazySet;
>module.exports : Symbol(module.exports, Decl(LazySet.js, 0, 0))
>module : Symbol(export=, Decl(LazySet.js, 10, 1))
>exports : Symbol(export=, Decl(LazySet.js, 10, 1))
>LazySet : Symbol(LazySet, Decl(LazySet.js, 0, 0))

53 changes: 53 additions & 0 deletions tests/baselines/reference/jsDeclarationsTypedefAndLatebound.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//// [tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypedefAndLatebound.ts] ////

=== index.js ===
// from #53967, based on webpack/webpack#16957

const LazySet = require("./LazySet");
>LazySet : typeof LazySet
>require("./LazySet") : typeof LazySet
>require : any
>"./LazySet" : "./LazySet"

/** @type {LazySet} */
const stringSet = undefined;
>stringSet : LazySet
>undefined : undefined

stringSet.addAll(stringSet);
>stringSet.addAll(stringSet) : void
>stringSet.addAll : (iterable: LazySet) => void
>stringSet : LazySet
>addAll : (iterable: LazySet) => void
>stringSet : LazySet


=== LazySet.js ===
// Comment out this JSDoc, and note that the errors index.js go away.
/**
* @typedef {Object} SomeObject
*/
class LazySet {
>LazySet : LazySet

/**
* @param {LazySet} iterable
*/
addAll(iterable) {}
>addAll : (iterable: LazySet) => void
>iterable : import("LazySet")

[Symbol.iterator]() {}
>[Symbol.iterator] : () => void
>Symbol.iterator : unique symbol
>Symbol : SymbolConstructor
>iterator : unique symbol
}

module.exports = LazySet;
>module.exports = LazySet : typeof LazySet
>module.exports : typeof LazySet
>module : { exports: typeof LazySet; }
>exports : typeof LazySet
>LazySet : typeof LazySet

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// @lib: es2017
// @allowJs: true
// @checkJs: true
// @noEmit: true
// from #53967, based on webpack/webpack#16957

// @filename: index.js
const LazySet = require("./LazySet");

/** @type {LazySet} */
const stringSet = undefined;
stringSet.addAll(stringSet);


// @filename: LazySet.js
// Comment out this JSDoc, and note that the errors index.js go away.
/**
* @typedef {Object} SomeObject
*/
class LazySet {
/**
* @param {LazySet} iterable
*/
addAll(iterable) {}
[Symbol.iterator]() {}
}

module.exports = LazySet;

0 comments on commit 89caf30

Please sign in to comment.