Skip to content

Make all of our JS libraries closure-warning free. #16199

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 2 additions & 102 deletions src/closure-externs/closure-externs.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,125 +70,28 @@ Atomics.store = function() {};
var WebAssembly = {};
/**
* @constructor
* @param {!BufferSource} bytes
*/
WebAssembly.Module = function(bytes) {};
/**
* @constructor
* @param {!WebAssembly.Module} moduleObject
* @param {Object=} importObject
*/
WebAssembly.Instance = function(moduleObject, importObject) {};
/**
* @constructor
* @param {MemoryDescriptor} memoryDescriptor
*/
WebAssembly.Memory = function(memoryDescriptor) {};
/**
* @constructor
* @param {TableDescriptor} tableDescriptor
*/
WebAssembly.Table = function(tableDescriptor) {};
/**
* @constructor
* @param {GlobalDescriptotr} globalDescriptor
* @param {Object} globalDescriptor
*/
WebAssembly.Global = function(globalDescriptor) {};
/**
* @constructor
* @param {TagDescriptotr} tagDescriptor
* @param {Object} tagDescriptor
*/
WebAssembly.Tag = function(tagDescriptor) {};
/**
* @constructor
* @extends {Error}
*/
WebAssembly.CompileError = function() {};
/**
* @constructor
* @extends {Error}
*/
WebAssembly.LinkError = function() {};
/**
* @constructor
* @param {string=} message
* @param {string=} fileName
* @param {number=} lineNumber
* @extends {Error}
*/
WebAssembly.RuntimeError = function(message, fileName, lineNumber) {};
/**
* Note: Closure compiler does not support function overloading, omit this overload for now.
* {function(!WebAssembly.Module, Object=):!Promise<!WebAssembly.Instance>}
*/
/**
* @param {!BufferSource} moduleObject
* @param {Object=} importObject
* @return {!Promise<{module:WebAssembly.Module, instance:WebAssembly.Instance}>}
*/
WebAssembly.instantiate = function(moduleObject, importObject) {};
/**
* @param {!Promise<!Response>|!Response} source
* @param {Object=} importObject
* @return {!Promise<{module:WebAssembly.Module, instance:WebAssembly.Instance}>}
*/
WebAssembly.instantiateStreaming = function(source, importObject) {};
/**
* @param {!BufferSource} bytes
* @return {!Promise<!WebAssembly.Module>}
*/
WebAssembly.compile = function(bytes) {};
/**
* @param {!BufferSource} bytes
* @return {boolean}
*/
WebAssembly.validate = function(bytes) {};
/**
* @param {!WebAssembly.Module} moduleObject
* @return {!Array<{name:string, kind:string}>}
*/
WebAssembly.Module.exports = function(moduleObject) {};
/**
* @param {!WebAssembly.Module} moduleObject
* @return {!Array<{module:string, name:string, kind:string}>}
*/
WebAssembly.Module.imports = function(moduleObject) {};
/**
* @param {!WebAssembly.Module} moduleObject
* @param {string} sectionName
* @return {!Array<!ArrayBuffer>}
*/
WebAssembly.Module.customSections = function(moduleObject, sectionName) {};
/** @dict */
WebAssembly.Instance.prototype.exports;
/**
* @param {number} delta
* @return {number}
*/
WebAssembly.Memory.prototype.grow = function(delta) {};
/**
* @type {!ArrayBuffer}
*/
WebAssembly.Memory.prototype.buffer;
/**
* @param {number} delta
* @return {number}
*/
WebAssembly.Table.prototype.grow = function(delta) {};
/**
* @type {number}
*/
WebAssembly.Table.prototype.length;
/**
* @param {number} index
* @return {function(...)}
*/
WebAssembly.Table.prototype.get = function(index) {};
/**
* @param {number} index
* @param {?function(...)} value
*/
WebAssembly.Table.prototype.set = function(index, value) {};

/**
* @suppress {undefinedVars}
Expand Down Expand Up @@ -287,9 +190,6 @@ var devicePixelRatio;
/** @suppress {duplicate} */
var noExitRuntime;

/** @type {?AudioWorklet} */
BaseAudioContext.prototype.audioWorklet;

/*
* AudioWorkletGlobalScope globals
*/
Expand Down
24 changes: 24 additions & 0 deletions src/closure-externs/node-externs.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,27 @@ var Buffer = function(var_args) {};
* @nosideeffects
*/
Buffer.from = function(arrayBuffer, byteOffset, length) {};

/**
* @param {number} size
* @param {(string|!Buffer|number)=} fill
* @param {string=} encoding
* @return {!Buffer}
*/
Buffer.alloc = function(size, fill, encoding) {};

/**
* @param {number=} start
* @param {number=} end
* @return {Buffer}
* @nosideeffects
*/
Buffer.prototype.slice = function(start, end) {};

/**
* @param {string=} encoding
* @param {number=} start
* @param {number=} end
* @nosideeffects
*/
Buffer.prototype.toString = function(encoding, start, end) {};
14 changes: 11 additions & 3 deletions src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -1875,6 +1875,7 @@ LibraryManager.library = {

return { family: family, addr: addr, port: port };
},
$writeSockaddr__docs: '/** @param {number=} addrlen */',
$writeSockaddr__deps: ['$Sockets', '$inetPton4', '$inetPton6', '$zeroMemory'],
$writeSockaddr: function (sa, family, addr, port, addrlen) {
switch (family) {
Expand Down Expand Up @@ -2795,6 +2796,7 @@ LibraryManager.library = {
// Generates a representation of the program counter from a line of stack trace.
// The exact return value depends in whether we are running WASM or JS, and whether
// the engine supports offsets into WASM. See the function body for details.
$convertFrameToPC__docs: '/** @returns {number} */',
$convertFrameToPC__internal: true,
$convertFrameToPC: function(frame) {
#if !USE_OFFSET_CONVERTER
Expand All @@ -2818,11 +2820,10 @@ LibraryManager.library = {
// This should work for wasm2js. We tag the high bit to distinguish this
// from wasm addresses.
return 0x80000000 | +match[1];
} else {
// return 0 if we can't find any
return 0;
}
#endif
// return 0 if we can't find any
return 0;
},

// Returns a representation of a call site of the caller of this function, in a manner
Expand Down Expand Up @@ -3285,6 +3286,8 @@ LibraryManager.library = {
// without user interaction.
// If @elements is not provided, we default to the document and canvas
// elements, which handle common use cases.
// TODO(sbc): Remove seemingly unused elements argument
$autoResumeAudioContext__docs: '/** @param {Object=} elements */',
$autoResumeAudioContext__deps: ['$listenOnce'],
$autoResumeAudioContext: function(ctx, elements) {
if (!elements) {
Expand Down Expand Up @@ -3343,6 +3346,7 @@ LibraryManager.library = {
},
#endif

$dynCall__docs: '/** @param {Object=} args */',
$dynCall: function(sig, ptr, args) {
#if DYNCALLS
return dynCallLegacy(sig, ptr, args);
Expand Down Expand Up @@ -3566,6 +3570,7 @@ LibraryManager.library = {
'$maybeExit',
#endif
],
$callUserCallback__docs: '/** @param {boolean=} synchronous */',
$callUserCallback: function(func, synchronous) {
if (runtimeExited || ABORT) {
#if ASSERTIONS
Expand Down Expand Up @@ -3628,6 +3633,7 @@ LibraryManager.library = {
'$runtimeKeepalivePop',
#endif
],
$safeSetTimeout__docs: '/** @param {number=} timeout */',
$safeSetTimeout: function(func, timeout) {
{{{ runtimeKeepalivePush() }}}
return setTimeout(function() {
Expand All @@ -3641,6 +3647,8 @@ LibraryManager.library = {
return x.indexOf('dynCall_') == 0 || unmangledSymbols.includes(x) ? x : '_' + x;
},


$asyncLoad__docs: '/** @param {boolean=} noRunDep */',
$asyncLoad: function(url, onload, onerror, noRunDep) {
var dep = !noRunDep ? getUniqueRunDependency('al ' + url) : '';
readAsync(url, function(arrayBuffer) {
Expand Down
5 changes: 5 additions & 0 deletions src/library_browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,11 @@ var LibraryBrowser = {
'$maybeExit',
#endif
],
$setMainLoop__docs: `
/**
* @param {number=} arg
* @param {boolean=} noSetTiming
*/`,
$setMainLoop: function(browserIterationFunc, fps, simulateInfiniteLoop, arg, noSetTiming) {
assert(!Browser.mainLoop.func, 'emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.');

Expand Down
6 changes: 6 additions & 0 deletions src/library_exceptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var LibraryExceptions = {
// purpose, it references the primary exception.
//
// excPtr - Thrown object pointer to wrap. Metadata pointer is calculated from it.
$ExceptionInfo__docs: '/** @constructor */',
$ExceptionInfo: function(excPtr) {
this.excPtr = excPtr;
this.ptr = excPtr - {{{ C_STRUCTS.__cxa_exception.__size__ }}};
Expand Down Expand Up @@ -96,6 +97,11 @@ var LibraryExceptions = {
};
},

$CatchInfo__docs: `
/**
* @constructor
* @param {number=} ptr
*/`,
$CatchInfo__deps: ['$ExceptionInfo', '__cxa_is_pointer_type'],
// This native structure is returned from __cxa_find_matching_catch, and serves as catching
// context, i.e. stores information required to proceed with a specific selected catch. It stores
Expand Down
4 changes: 2 additions & 2 deletions src/library_formatString.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,9 @@ mergeInto(LibraryManager.library, {
var currAbsArg = Math.abs(currArg);
var prefix = '';
if (next == {{{ charCode('d') }}} || next == {{{ charCode('i') }}}) {
argText = reSign(currArg, 8 * argSize, 1).toString(10);
argText = reSign(currArg, 8 * argSize).toString(10);
} else if (next == {{{ charCode('u') }}}) {
argText = unSign(currArg, 8 * argSize, 1).toString(10);
argText = unSign(currArg, 8 * argSize).toString(10);
currArg = Math.abs(currArg);
} else if (next == {{{ charCode('o') }}}) {
argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8);
Expand Down
4 changes: 2 additions & 2 deletions src/library_math.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ mergeInto(LibraryManager.library, {
emscripten_math_pow: function(x, y) {
return Math.pow(x, y);
},
emscripten_math_random: function(x) {
return Math.random(x);
emscripten_math_random: function() {
return Math.random();
},
emscripten_math_sign: function(x) {
return Math.sign(x);
Expand Down
1 change: 1 addition & 0 deletions src/library_syscall.js
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ var SyscallsLibrary = {
},
/** @param {boolean=} allowNull */
$getSocketAddress__deps: ['$readSockaddr', '$FS', '$DNS'],
$getSocketAddress__docs: '/** @param {boolean=} allowNull */',
$getSocketAddress: function(addrp, addrlen, allowNull) {
if (allowNull && addrp === 0) return null;
var info = readSockaddr(addrp, addrlen);
Expand Down
2 changes: 1 addition & 1 deletion src/library_tty.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ mergeInto(LibraryManager.library, {
var bytesRead = 0;

try {
bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE, null);
bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE, -1);
} catch(e) {
// Cross-platform differences: on Windows, reading EOF throws an exception, but on other OSes,
// reading EOF returns 0. Uniformize behavior by treating the EOF exception to return 0.
Expand Down
2 changes: 1 addition & 1 deletion src/node_shell_read.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ read_ = function shell_read(filename, binary) {
#endif
requireNodeFS();
filename = nodePath['normalize'](filename);
return fs.readFileSync(filename, binary ? null : 'utf8');
return fs.readFileSync(filename, binary ? undefined : 'utf8');
};

readBinary = (filename) => {
Expand Down
12 changes: 12 additions & 0 deletions src/preamble.js
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,13 @@ function abort(what) {
// Use a wasm runtime error, because a JS error might be seen as a foreign
// exception, which means we'd run destructors on it. We need the error to
// simply make the program stop.

// Suppress closure compiler warning here. Closure compiler's builtin extern
// defintion for WebAssembly.RuntimeError claims it takes no arguments even
// though it can.
// TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.

/** @suppress {checkTypes} */
var e = new WebAssembly.RuntimeError(what);

#if MODULARIZE
Expand Down Expand Up @@ -1209,6 +1216,11 @@ function createWasm() {
#endif
typeof fetch === 'function') {
return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function (response) {
// Suppress closure warning here since the upstream definition for
// instantiateStreaming only allows Promise<Repsponse> rather than
// an actual Response.
// TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed.
/** @suppress {checkTypes} */
var result = WebAssembly.instantiateStreaming(response, info);

#if USE_OFFSET_CONVERTER
Expand Down
18 changes: 14 additions & 4 deletions tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -7917,14 +7917,24 @@ def test_full_js_library_minimal_runtime(self):
self.run_process([EMCC, test_file('hello_world.c'), '-sSTRICT_JS', '-sINCLUDE_FULL_LIBRARY', '-sMINIMAL_RUNTIME'])

def test_closure_full_js_library(self):
# test for closure errors in the entire JS library
# Test for closure errors and warnings in the entire JS library.
# We must ignore various types of errors that are expected in this situation, as we
# are including a lot of JS without corresponding compiled code for it. This still
# lets us catch all other errors.

# USE_WEBGPU is specified here to make sure that it's closure-safe.
# It can be removed if USE_WEBGPU is later included in INCLUDE_FULL_LIBRARY.
self.run_process([EMCC, test_file('hello_world.c'), '-O1', '--closure=1', '-g1', '-sINCLUDE_FULL_LIBRARY', '-sUSE_WEBGPU', '-sERROR_ON_UNDEFINED_SYMBOLS=0'])
self.run_process([EMCC, test_file('hello_world.c'), '-O1', '-g1',
'--closure=1',
'-sCLOSURE_WARNINGS=error',
'-sINCLUDE_FULL_LIBRARY',
'-sERROR_ON_UNDEFINED_SYMBOLS=0'])

def test_closure_webgpu(self):
# This test can be removed if USE_WEBGPU is later included in INCLUDE_FULL_LIBRARY.
self.run_process([EMCC, test_file('hello_world.c'), '-O1', '-g1',
'--closure=1',
'-sINCLUDE_FULL_LIBRARY',
'-sUSE_WEBGPU',
'-sERROR_ON_UNDEFINED_SYMBOLS=0'])

# Tests --closure-args command line flag
def test_closure_externs(self):
Expand Down
14 changes: 0 additions & 14 deletions third_party/closure-compiler/node-externs/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -375,20 +375,6 @@ nodeBuffer.SlowBuffer.prototype.slice = function(start, end) {};
*/
nodeBuffer.SlowBuffer.prototype.toString = function() {};

/**
* @param {number} size
* @param {(string|!Buffer|number)=} fill
* @param {string=} encoding
* @return {!Buffer}
*/
nodeBuffer.Buffer.alloc;

/**
* @param {Array} aray
* @return {!Buffer}
*/
nodeBuffer.Buffer.from;

//
// Legacy
//
Expand Down