Skip to content
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

[scala.js] Dotty does not produce null/undefined property on anonymous class #14168

Closed
exoego opened this issue Dec 24, 2021 · 7 comments
Closed

Comments

@exoego
Copy link

exoego commented Dec 24, 2021

Compiler version

3.1.0

Minimized code

  • With Scala.js 1.8.0
trait Foo extends js.Object {
  var extra: js.UndefOr[String]
}

val anon1 = new js.Object() {
  var extra = "a"
}
val anon2 = new js.Object() {
  var extra = js.undefined
}
val anon3 = new js.Object() {
  var extra = null
}
val foo1 = new Foo {
   var extra = "a"
}
val foo2 = new Foo {
  var extra: js.UndefOr[String] = js.undefined
}
val foo3 = new Foo {
  var extra: js.UndefOr[String] = null
}
println(js.Object.hasProperty(anon1, "extra"))
println(js.Object.hasProperty(anon2, "extra"))
println(js.Object.hasProperty(anon3, "extra"))
println(js.Object.hasProperty(foo1, "extra"))
println(js.Object.hasProperty(foo2, "extra"))
println(js.Object.hasProperty(foo3, "extra"))

Output

On Scala 2.13.7 and 2.12.15,

true
true
true
true
true
true

However on Scala 3.1.0,

true
false
false
true
true
true

which means null or undefined property on anonymous class is missing.

val foo2 = new Foo {
  var extra: js.UndefOr[String] = js.undefined
}
val foo3 = new Foo {
  var extra: js.UndefOr[String] = null
}

Expectation

All properties should exist even if its value is null or undefined.

@sjrd
Copy link
Member

sjrd commented Dec 24, 2021

Thanks for the report. I'm starting my vacation today, so I won't be able to look at it in the next two weeks.

I think you forgot the definition of Foo in your reproduction.

@exoego
Copy link
Author

exoego commented Dec 24, 2021

Added Foo definition

@sjrd
Copy link
Member

sjrd commented Jan 21, 2022

This appears to happen only when the type of the var is Unit or Null (whether inferred, or explicitly written). It does not seem to be related to having a supertrait, since I can also reproduce the issue when the trait declares the member but the class implements it with a more specific type that is explicitly Null or Unit.

Also, I can reproduce this with a named class, local or top-level. So it's also not related to anonymous classes.

The situations where this issue pops up are therefore summarized as:

  • A field of type Unit or Null in a non-native JS class.

@sjrd
Copy link
Member

sjrd commented Jan 21, 2022

Related: constant-value fields are also lost:

class Bar extends Foo {
  final val extra = "foo"
}

@sjrd
Copy link
Member

sjrd commented Jan 21, 2022

Both cases are also problematic for @JSExportTopLevel vals and vars.

@xerial
Copy link
Contributor

xerial commented Sep 19, 2022

@sjrd I also hit this issue when trying to implement an object comparison method like deepEquals(jsObjectA, jsObjectB) in Scala 3 + Scala.js.

sjrd added a commit to dotty-staging/dotty that referenced this issue Oct 14, 2022
sjrd added a commit to dotty-staging/dotty that referenced this issue Oct 14, 2022
sjrd added a commit to dotty-staging/dotty that referenced this issue Oct 14, 2022
sjrd added a commit to dotty-staging/dotty that referenced this issue Oct 14, 2022
@sjrd sjrd closed this as completed in 49b7cda Oct 18, 2022
szymon-rd pushed a commit to dotty-staging/dotty that referenced this issue Oct 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants