blob: 99c274fda6a3ad0267ca60762c75a59349e86933 (
plain) (
tree)
|
|
package scala.scalajs.compiler.test
import scala.scalajs.compiler.test.util._
import org.junit.Test
import org.junit.Ignore
class JSInteropTest extends DirectTest with TestHelpers {
override def preamble =
"""import scala.scalajs.js
"""
@Test
def noInnerClassTraitObject: Unit = {
val objs = List("class", "trait", "object")
for {
outer <- objs
inner <- objs
} yield {
s"""
$outer A extends js.Object {
$inner A
}
""" hasErrors
s"""
|newSource1.scala:4: error: Traits, classes and objects extending js.Any may not have inner traits, classes or objects
| $inner A
| ${" " * inner.length}^
"""
}
}
@Test
def noBadSetters = {
"""
class A extends js.Object {
def foo_=(x: Int): Int = js.native
}
""" hasErrors
"""
|newSource1.scala:4: error: Setters that do not return Unit are not allowed in types extending js.Any
| def foo_=(x: Int): Int = js.native
| ^
"""
}
@Test
def onlyJSRawTraits = {
"""
trait A
class B extends js.Object with A
""" hasErrors
"""
|newSource1.scala:4: error: B extends A which does not extend js.Any.
| class B extends js.Object with A
| ^
"""
"""
trait A
class B extends js.Object with Serializable
""" hasErrors
"""
|newSource1.scala:4: error: B extends scala.Serializable which does not extend js.Any.
| class B extends js.Object with Serializable
| ^
"""
}
@Test
def noAnonymousClass = {
"""
class A {
val x = new js.Object {
def a: Int = js.native
}
}
""" hasErrors
"""
|newSource1.scala:4: error: Anonymous classes may not extend js.Any
| val x = new js.Object {
| ^
"""
}
@Test
def noCaseClassObject = {
"""
case class A(x: Int) extends js.Object
""" hasErrors
"""
|newSource1.scala:3: error: Classes and objects extending js.Any may not have a case modifier
| case class A(x: Int) extends js.Object
| ^
"""
"""
case object B extends js.Object
""" hasErrors
"""
|newSource1.scala:3: error: Classes and objects extending js.Any may not have a case modifier
| case object B extends js.Object
| ^
"""
}
@Test
def notNested: Unit = {
val outers = List("class", "trait")
val inners = List("trait", "class", "object")
for {
outer <- outers
inner <- inners
} yield {
val errTrg = if (inner == "object") "Objects" else "Classes"
s"""
$outer A {
$inner Inner extends js.Object
}
""" hasErrors
s"""
|newSource1.scala:4: error: $errTrg extending js.Any may not be defined inside a class or trait
| $inner Inner extends js.Object
| ${" " * inner.length}^
"""
}
}
@Test
def noGlobalScopeClass = {
"""
class A extends js.GlobalScope
""" hasErrors
"""
|newSource1.scala:3: error: Only objects may extend js.GlobalScope
| class A extends js.GlobalScope
| ^
"""
"""
trait A extends js.GlobalScope
""" hasErrors
"""
|newSource1.scala:3: error: Only objects may extend js.GlobalScope
| trait A extends js.GlobalScope
| ^
"""
}
@Test
def noLocalClass = {
"""
object A {
def a = {
class B extends js.Object
}
}
""" hasErrors
"""
|newSource1.scala:5: error: Local classes and objects may not extend js.Any
| class B extends js.Object
| ^
"""
}
@Test
def noLocalObject = {
"""
object A {
def a = {
object B extends js.Object
}
}
""" hasErrors
"""
|newSource1.scala:5: error: Local classes and objects may not extend js.Any
| object B extends js.Object
| ^
"""
}
@Test
def noExtendJSAny = {
"""
class A extends js.Any
""" hasErrors
"""
|newSource1.scala:3: error: illegal inheritance from sealed trait Any
| class A extends js.Any
| ^
"""
}
@Test
def noNativeInJSAny = {
"""
class A extends js.Object {
@native
def value: Int = js.native
}
""" hasErrors
"""
|newSource1.scala:5: error: Methods in a js.Any may not be @native
| def value: Int = js.native
| ^
"""
}
@Test
def warnJSAnyBody = {
"""
class A extends js.Object {
def value: Int = ???
val x: Int = ???
}
""" hasWarns
"""
|newSource1.scala:4: warning: Members of traits, classes and objects extending js.Any may only contain members that call js.native. This will be enforced in 1.0.
| def value: Int = ???
| ^
|newSource1.scala:5: warning: Members of traits, classes and objects extending js.Any may only contain members that call js.native. This will be enforced in 1.0.
| val x: Int = ???
| ^
"""
"""
trait A extends js.Object {
def value: Int
val x: Int
}
""" hasWarns
"""
|newSource1.scala:4: warning: Members of traits, classes and objects extending js.Any may only contain members that call js.native. This will be enforced in 1.0.
| def value: Int
| ^
|newSource1.scala:5: warning: Members of traits, classes and objects extending js.Any may only contain members that call js.native. This will be enforced in 1.0.
| val x: Int
| ^
"""
}
@Test
def noCallSecondaryCtor = {
"""
class A(x: Int, y: Int) extends js.Object {
def this(x: Int) = this(x, 5)
def this() = this(7)
}
""" hasErrors
"""
|newSource1.scala:5: error: A secondary constructor of a class extending js.Any may only call the primary constructor
| def this() = this(7)
| ^
"""
}
@Test
def noUseJsNative = {
"""
class A {
def foo = js.native
}
""" hasErrors
"""
|newSource1.scala:4: error: js.native may only be used as stub implementation in facade types
| def foo = js.native
| ^
"""
}
@Test
def warnNothingRaw = {
"""
class A extends js.Object {
def foo = js.native
val bar = js.native
}
""" hasWarns
"""
|newSource1.scala:4: warning: The type of foo got inferred as Nothing. To suppress this warning, explicitly ascribe the type.
| def foo = js.native
| ^
|newSource1.scala:5: warning: The type of bar got inferred as Nothing. To suppress this warning, explicitly ascribe the type.
| val bar = js.native
| ^
"""
}
@Test
def noNonLiteralJSName = {
"""
import js.annotation.JSName
object A {
val a = "Hello"
final val b = "World"
}
class B extends js.Object {
@JSName(A.a)
def foo: Int = js.native
@JSName(A.b)
def bar: Int = js.native
}
""" hasErrors
"""
|newSource1.scala:11: error: The argument to JSName must be a literal string
| @JSName(A.a)
| ^
"""
}
}
|