diff --git a/src/closure_externs.js b/src/closure_externs.js index afa464ac0..52d97158f 100644 --- a/src/closure_externs.js +++ b/src/closure_externs.js @@ -52,9 +52,6 @@ var NodeListOf; */ var RegExpExecArray; -/** @typedef {!Map} */ -var ReadonlyMap; - /** @typedef {!Set} */ var ReadonlySet; diff --git a/src/externs.ts b/src/externs.ts index 2ed92c645..5f30fe362 100644 --- a/src/externs.ts +++ b/src/externs.ts @@ -456,6 +456,16 @@ export function generateExterns( reportDiagnostic(diagnostics, decl, 'anonymous type in externs'); return; } + + // gbigint, as defined in + // google3/third_party/java_src/clutz/src/resources/closure.lib.d.ts, is + // defined separately in TypeScript and JavaScript. + if (name.escapedText === 'gbigint' + // Just the terminal filename so we can test this. + && decl.getSourceFile().fileName.endsWith('closure.lib.d.ts')) { + return; + } + const typeName = namespace.concat([name.getText()]).join('.'); if (PREDECLARED_CLOSURE_EXTERNS_LIST.indexOf(typeName) >= 0) return; diff --git a/src/ts_migration_exports_shim.ts b/src/ts_migration_exports_shim.ts index d68dea67d..962bc4616 100644 --- a/src/ts_migration_exports_shim.ts +++ b/src/ts_migration_exports_shim.ts @@ -58,6 +58,12 @@ export function createTsMigrationExportsShimTransformerFactory( src, srcIds, typeChecker, host, manifest, tsickleDiagnostics); const tsmesFile = srcIds.google3PathWithoutExtension() + '.tsmes.js'; const dtsFile = srcIds.google3PathWithoutExtension() + '.tsmes.d.ts'; + if (!host.generateTsMigrationExportsShim) { + // we need to create the Generator to make sure there aren't any shim + // related function calls if generateTsMigrationExportsShim isn't true, + // but we don't want to actually write any files, so return + return src; + } if (!generator.foundMigrationExportsShim()) { // If there is no export shims calls, we still need to generate empty // files, so that we always produce a predictable set of files. diff --git a/src/type_translator.ts b/src/type_translator.ts index 8ae3db406..6dd15cec6 100644 --- a/src/type_translator.ts +++ b/src/type_translator.ts @@ -592,6 +592,13 @@ export class TypeTranslator { } return innerSymbol ?? '?'; } + // gbigint, as defined in + // google3/third_party/java_src/clutz/src/resources/closure.lib.d.ts, is + // defined separately in TypeScript and JavaScript. + // In JS, gbigint is treated as an object so needs !. + if (type.aliasSymbol?.escapedName === 'gbigint') { + return '!gbigint'; + } this.warn(`unhandled type flags: ${ts.TypeFlags[type.flags]}`); return '?'; case ts.TypeFlags.Index: diff --git a/test/e2e_closure_test.ts b/test/e2e_closure_test.ts index 0255531d1..f1d85b300 100644 --- a/test/e2e_closure_test.ts +++ b/test/e2e_closure_test.ts @@ -31,6 +31,7 @@ describe('golden file tests', () => { 'third_party/tslib/externs.js', 'third_party/tslib/tslib.js', 'test/googbase_fake.js', + 'test_files/temp_externs.js', 'test_files/augment/shim.js', 'test_files/clutz_type_value.no_externs/type_value.js', 'test_files/clutz.no_externs/default_export.js', diff --git a/test_files/gbigint/closure.lib.d.ts b/test_files/gbigint/closure.lib.d.ts new file mode 100644 index 000000000..e4f33ce61 --- /dev/null +++ b/test_files/gbigint/closure.lib.d.ts @@ -0,0 +1,9 @@ +/** + * Opaque value type that represents big integer values regardless of native + * platform support for `bigint`. See go/gbigint for more info. + */ +interface gbigint { + readonly __doNotManuallySet: unique symbol; + + valueOf(): gbigint; +} diff --git a/test_files/gbigint/exports_gbigint.js b/test_files/gbigint/exports_gbigint.js new file mode 100644 index 000000000..28657b28b --- /dev/null +++ b/test_files/gbigint/exports_gbigint.js @@ -0,0 +1,28 @@ +/** + * @fileoverview added by tsickle + * Generated from: test_files/gbigint/exports_gbigint.ts + */ +goog.module('test_files.gbigint.exports_gbigint'); +var module = module || { id: 'test_files/gbigint/exports_gbigint.ts' }; +goog.require('tslib'); +/** + * @param {string} val + * @return {!gbigint} + */ +function toGbigint(val) { + return (/** @type {!gbigint} */ ((/** @type {*} */ (val)))); +} +/** + * A `gbigint` value on an exported variable. + * @type {!gbigint} + */ +exports.myGbigint = toGbigint('0'); +/** + * A `gbigint` value on a param type. + * @param {!gbigint} val + * @return {void} + */ +function takeGbigint(val) { + console.log(val); +} +exports.takeGbigint = takeGbigint; diff --git a/test_files/gbigint/exports_gbigint.ts b/test_files/gbigint/exports_gbigint.ts new file mode 100644 index 000000000..53ee0d0d0 --- /dev/null +++ b/test_files/gbigint/exports_gbigint.ts @@ -0,0 +1,11 @@ +function toGbigint(val: string): gbigint { + return val as unknown as gbigint; +} + +/** A `gbigint` value on an exported variable. */ +export const myGbigint: gbigint = toGbigint('0'); + +/** A `gbigint` value on a param type. */ +export function takeGbigint(val: gbigint): void { + console.log(val); +} diff --git a/test_files/temp_externs.js b/test_files/temp_externs.js new file mode 100644 index 000000000..382502623 --- /dev/null +++ b/test_files/temp_externs.js @@ -0,0 +1,21 @@ +/** + * When gbigint is made globally available, this file will be + * deleted as the typings here will move to a global location. At this moment, + * the proposed location is: + * google3/javascript/externs/google_legacy.js + * @externs + */ + +/** + * See go/gbigint. + * + * Opaque value type that represents `bigint` values regardless of native + * platform support for `bigint`. As value types, they have a guaranteed + * consistent runtime representation compatible with `===`, ES6 `Map` keys and + * `Set` values. + * @interface + */ +function gbigint() {} + +/** @const {symbol} */ +gbigint.prototype.__doNotManuallySet;