google / google/closure-compiler

Deterministic test fails when using classes/function prototypes, but not otherwise

Open
#3,981 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
7.7k
Forks
1.2k
Avg merge
2d 12h
Merged PRs (30d)
6

Description

The contents of `test.js`:

```js
let a = null;

function b() {
if(a != null) {
console.log("not null");
}
a = 0;
}

b();
document.getElementById("id").onclick = b;
```

Compiled with `closure-compiler -O ADVANCED --js test.js --js_output_file test.min.js`

Output: none. No warnings, no errors. Compiled successfully.

Now, the new contents of `test.js`:

```js
class A {
constructor() {
this.a = null;
}
b() {
if(this.a != null) {
console.log("not null");
}
this.a = 0;
}
}

const a = new A();
a.b();
document.getElementById("id").onclick = a.b.bind(a);
```

The same compilation step as before.

Output:
```
test.js:6:5: WARNING - [JSC_DETERMINISTIC_TEST] condition always evaluates to false
left : null
right: null
6| if(this.a != null) {
^^^^^^^^^^^^^^

0 error(s), 1 warning(s), 100.0% typed
```

I suspect that's not intended. The condition does not always evaluate to false if the user clicks the `"id"` element.

```
$> closure-compiler --version
Closure Compiler (http://github.com/google/closure-compiler)
Version: v20220601
```

---

To provide a fuller bug submission, I've also tested the following 2 scripts, both of which work as expected (maybe will prove to be helpful):

```js
let a = {
a: null
};
function b() {
if(this.a != null) {
console.log("not null");
}
this.a = 0;
}
b.call(a);
document.getElementById("id").onclick = b.bind(a);
```
and
```js
function a() {
this.a = null;
}
a.prototype.b = function() {
if(this.a != null) {
console.log("not null");
}
this.a = 0;
};

const A = new a();
A.b();
document.getElementById("id").onclick = A.b.bind(A);
```

However, the script above throws the following warnings:
```
test.js:2:1: WARNING - [JSC_USED_GLOBAL_THIS] dangerous use of the global this object
2| this.a = null;
^^^^

test.js:11:10: WARNING - [JSC_NOT_A_CONSTRUCTOR] cannot instantiate non-constructor
11| const A = new a();
^^^^^^^

0 error(s), 2 warning(s), 57.1% typed
```

So I figured I will add `/** @constructor */` to help it in some way, and there goes the `class` symptoms again, with the deterministic test failing to figure it out:

```js
/** @constructor */
function a() {
this.a = null;
}
a.prototype.b = function() {
if(this.a != null) {
console.log("not null");
}
this.a = 0;
};

const A = new a();
A.b();
document.getElementById("id").onclick = A.b.bind(A);
```

```
test.js:6:4: WARNING - [JSC_DETERMINISTIC_TEST] condition always evaluates to false
left : null
right: null
6| if(this.a != null) {
^^^^^^^^^^^^^^

0 error(s), 1 warning(s), 100.0% typed
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.