[HtmlUnit] [htmlunit:bugs] #1980 [corejs] Quirky handling of named function expression

RBRi via HtmlUnit-develop <[email protected]> Fri, 10 Aug 2018 06:11:21 -0000
Newsgroups gmane.comp.java.htmlunit.devel
Message-ID </p/htmlunit/bugs/1980/c4e940bd32b2e93647a71af5a330a012c7e0dcff.bugs@htmlunit.p.sourceforge.net>
BTW: will inform on twitter if a new SNASPHOT build is available


---

** [bugs:#1980] [corejs] Quirky handling of named function expression**

**Status:** closed
**Group:** Latest SVN
**Created:** Sun Aug 05, 2018 12:28 PM UTC by Atsushi Nakagawa
**Last Updated:** Fri Aug 10, 2018 06:10 AM UTC
**Owner:** RBRi
**Attachments:**

- [test1.html](https://sourceforge.net/p/htmlunit/bugs/1980/attachment/test1.html) (194 Bytes; text/html)
- [test2.html](https://sourceforge.net/p/htmlunit/bugs/1980/attachment/test2.html) (275 Bytes; text/html)
- [test3.html](https://sourceforge.net/p/htmlunit/bugs/1980/attachment/test3.html) (227 Bytes; text/html)
- [test4.html](https://sourceforge.net/p/htmlunit/bugs/1980/attachment/test4.html) (182 Bytes; text/html)
- [test5.html](https://sourceforge.net/p/htmlunit/bugs/1980/attachment/test5.html) (1.2 kB; text/html)


Attached are five tests for testing various aspects of **[named function expressions](https://stackoverflow.com/questions/15336347)** in htmlunit.

As at 2.32, support for them are *quirky*, leading to subtly misinterpreted JS that are hard to debug.

For example, the following code from `test1.html` incorrectly throws a `ScriptException: ReferenceError: Assignment to undefined "abc" in strict mode` on the second line.

```javascript
'use strict';
var abc = 1;
var foo = function abc() {}
```

This code from `test2.html` should print `a` followed by `b`.  Instead `b` is printed twice.  (Unfortunatley, code like this is all too common for minimized scripts.)

```javascript
var a = function () {
	var x = (function x () { console.log("a") })
	return function () { x() }
}()

var b = function () {
	var x = (function x () { console.log("b") })
	return function () { x() }
}()

a()
b()
```

### Test cases

Five tests `test1.html` to `test5.html` are attached.  Expectations are as follows:

`test1.html`:
```java
final String[] expected = {
		"INFO: outer abc =  1.0",
		"INFO: inner abc =  (function abc() { console.log(\"inner abc = \", abc); })",
};
```

`test2.html`:
```java
final String[] expected = {
		"INFO: a",
		"INFO: b",
};
```

`test3.html`:
```java
final String[] expected = {
		"INFO: a",
};
```

`test4.html`:
```java
final String[] expected = {
		"INFO: (function func() { console.log(func); })",
		"INFO: outer",
};
```

`test5.html`:
```java
final String[] expected = {
		"INFO: f1",
		"INFO: f2",
		"INFO: f3",
		"INFO: !f4",
		"INFO: f5",
		"INFO: !f6",
		"INFO: !f7",
		"INFO: !f8",
		"INFO: f10",
		"INFO: f11",
		"INFO: f12",
		"INFO: f10", // Chrome/FF: !f10
		"INFO: f11",
		"INFO: f12",
		"INFO: f13",
};
```

### Possible fix

While rhino far surpasses  my coding ability, asashour [seems to have](https://github.com/HtmlUnit/htmlunit-rhino-fork/commit/afadfd48770eace84c70f503efef66c5767c9a3b) already added the [necessary building block](https://github.com/HtmlUnit/htmlunit-rhino-fork/blob/e7ce0f761305d876f99a323a27214f064c5fb4f3/src/org/mozilla/javascript/InterpreterData.java#L98) for this.

The following is the code I'm using to further this for a fix:

```diff
--- a/src/main/java/net/sourceforge/htmlunit/corejs/javascript/CodeGenerator.java
+++ b/src/main/java/net/sourceforge/htmlunit/corejs/javascript/CodeGenerator.java
@@ -6,12 +6,12 @@

 package net.sourceforge.htmlunit.corejs.javascript;

-import net.sourceforge.htmlunit.corejs.javascript.ast.AstNode;
-import net.sourceforge.htmlunit.corejs.javascript.ast.FunctionCall;
+import net.sourceforge.htmlunit.corejs.javascript.ast.AstRoot;
+import net.sourceforge.htmlunit.corejs.javascript.ast.Block;
 import net.sourceforge.htmlunit.corejs.javascript.ast.FunctionNode;
 import net.sourceforge.htmlunit.corejs.javascript.ast.Jump;
+import net.sourceforge.htmlunit.corejs.javascript.ast.Scope;
 import net.sourceforge.htmlunit.corejs.javascript.ast.ScriptNode;
-import net.sourceforge.htmlunit.corejs.javascript.ast.UnaryExpression;
 import net.sourceforge.htmlunit.corejs.javascript.ast.VariableInitializer;

 /**
@@ -197,11 +197,10 @@ private void generateNestedFunctions()
             gen.itsData = new InterpreterData(itsData);
             gen.generateFunctionICode();
             array[i] = gen.itsData;
-            if (fn.getParent() instanceof FunctionCall) {
-                AstNode grandParent = fn.getParent().getParent();
-                if (grandParent instanceof UnaryExpression && grandParent.getType() == Token.NOT) {
-                    gen.itsData.declaredAsFunctionExpression = true;
-                }
+            if (!(fn.getParent() instanceof AstRoot ||
+                    fn.getParent() instanceof Scope ||
+                    fn.getParent() instanceof Block)) {
+                gen.itsData.declaredAsFunctionExpression = true;
             }
         }
         itsData.itsNestedFunctions = array;
```



---

Sent from sourceforge.net because [email protected] is subscribed to https://sourceforge.net/p/htmlunit/bugs/

To unsubscribe from further messages, a project admin can change settings at https://sourceforge.net/p/htmlunit/admin/bugs/options.  Or, if this is a mailing list, you can unsubscribe from the mailing list.

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot

_______________________________________________
HtmlUnit-develop mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/htmlunit-develop