Goal: I'm trying to run JSLint in JavaScriptCore.
Older JSLint releases exposed a global function named JSLINT
like this:
var JSLINT = (function () {
...
}
This was easy to retrieve and execute in JavaScriptCore:
// Assume 'ctx' is a JSGlobalContextRef
// Assume we have already called JSEvaluateScript()
JSStringRef jsFunctionName = JSStringCreateWithUTF8CString("JSLINT");
JSValueRef jsLintFunctionValue = JSObjectGetProperty(ctx, JSContextGetGlobalObject(ctx), jsFunctionName, NULL);
JSStringRelease(jsFunctionName);
JSObjectRef jsLintFunction = JSValueToObject(ctx, jsLintFunctionValue, &exception);
With that reference, I could then use JSObjectCallAsFunction()
to execute the function. Worked perfectly.
Now, JSLint has moved to this:
export default Object.freeze(function jslint(
source = "",
option_object = empty(),
global_array = []
) {
...
});
The documentation for JavaScriptCore is poor. I have tried many things but am clearly missing something obvious. How can I retrieve and execute the jslint
function now?
If @kaizhu's answer didn't give you want you wanted, another option to get to a state closer to what you had before is to...
jslint
Here are the two lines you need to comment out with today's version of JSLint.
// export default Object.freeze(jslint_export);
// jslint_import_meta_url = import.meta.url;
If you include that now-edited file in a project, the function jslint
is in your global scope.
console.log(JSON.stringify(jslint("var a = 5").warnings, null, " "))
Results:
[
{
"a": ";",
"b": "(end)",
"code": "expected_a_b",
"column": 9,
"line": 1,
"line_source": "var a = 5",
"name": "JSLintError",
"message": "Expected ';' and instead saw '(end)'.",
"formatted_message": " 1. \u001b[31mExpected ';' and instead saw '(end)'.\u001b[39m \u001b[90m// line 1, column 9\u001b[39m\n var a = 5"
}
]
I think the only change you'd make to your code is to lower-case jslint
:
JSStringRef jsFunctionName = JSStringCreateWithUTF8CString("jslint");
Note that it's probably "even righter" to use jslint_export
, which is a frozen copy of jslint
.
JSStringRef jsFunctionName = JSStringCreateWithUTF8CString("jslint_export");
If you really wanted to, you could replace the jslint_export
variable with JSLINT
and not change your JavaScriptCore code at all.
// let jslint_export; // The jslint object to be exported.
let JSLINT; // The jslint object to be exported.
// lots of stuff skipped
// jslint_export = Object.freeze(Object.assign(jslint, {
JSLINT = Object.freeze(Object.assign(jslint, {
cli: Object.freeze(jslint_cli),
edition: jslint_edition,
jslint: Object.freeze(jslint.bind(undefined))
}));
I'd have to double-check the old code to see if this acts the same, but note that the actual linting function would be on JSLINT.jslint
in that construction.
I'm not sure why there's so much global scope pollution in the current version of JSLint, however. Why this doesn't all live in an IIFE is confusing; I think it used to? Anyhow, this should solve your issue.