简体   繁体   English

ScalaJS fullLinkJS 错误

[英]ScalaJS fullLinkJS errors

I upgraded my Play+ScalaJS project from ScalaJS 0.6.32 to 1.4.0 several weeks ago.几周前,我将我的 Play+ScalaJS 项目从 ScalaJS 0.6.32 升级到了 1.4.0。 All has been working fine in development.一切都在开发中运行良好。 Today I tried to deploy it and thus executed fullLinkJS for the first time.今天我尝试部署它,因此第一次执行了fullLinkJS It generated a number of errors:它产生了许多错误:

sbt:browser> fullLinkJS
[info] Full optimizing /Users/bwbecker/oat/src/oat3/_browser/target/scala-2.12/browser-opt
[error] c91662c1ae832d6a8493/oat/browser/views/bulkmail/BMailCreateView.scala(125:43:Apply): scala.Dynamic expected but any found for tree of type org.scalajs.ir.Trees$JSSelect
[error] c91662c1ae832d6a8493/oat/browser/views/components/filteredTable/FilteredBMailTable.scala(81:53:Apply): scala.Dynamic expected but any found for tree of type org.scalajs.ir.Trees$JSSelect
[error] c91662c1ae832d6a8493/oat/browser/models/Autocomplete.scala(156:18:Apply): scala.Dynamic expected but any found for tree of type org.scalajs.ir.Trees$JSSelect
[error] c91662c1ae832d6a8493/oat/browser/views/virtualq/QueueAddEditView.scala(90:52:Apply): scala.Dynamic expected but any found for tree of type org.scalajs.ir.Trees$JSSelect
[error] c91662c1ae832d6a8493/oat/browser/views/bulkmail/edit/BMailSendView.scala(273:62:Apply): scala.Dynamic expected but any found for tree of type org.scalajs.ir.Trees$JSSelect
[error] c91662c1ae832d6a8493/oat/browser/views/bulkmail/TemplateListView.scala(42:64:Apply): scala.Dynamic expected but any found for tree of type org.scalajs.ir.Trees$JSSelect
...

I've looked at about a dozen of the referenced lines in the source code.我查看了源代码中大约十几个引用的行。 Most of them refer to either a Play route or invoke the url method.它们中的大多数都指的是播放路线或调用url方法。 The rest of them involve a call to jQuery.其中的 rest 涉及对 jQuery 的调用。

The project has a cross-platform subproject.该项目有一个跨平台的子项目。 That one does the fullLinkJS just fine.那个做fullLinkJS就好了。 There's also a client-specific ScalaJS project.还有一个特定于客户端的 ScalaJS 项目。 That's where the errors are happening.这就是错误发生的地方。

I'm using ScalaJS 1.4.0 and Play 2.6.25.我正在使用 ScalaJS 1.4.0 和 Play 2.6.25。

Suggestions on how to procede?关于如何进行的建议?

Later, after reading reply from @sjrd后来,在阅读了@sjrd 的回复后

A sample of the offending code:有问题的代码示例:

private val wapp = routes.oat.wapp.controllers.BMailCtrl
...
window.location.href = wapp.edit(emailId).url // this is the line flagged with the error

window is defined in org.scalajs.dom as a js.Dynamic . windoworg.scalajs.dom中定义为js.Dynamic

routes is defined in my code as val routes: js.Dynamic = global.jsRoutes . routes在我的代码中定义为val routes: js.Dynamic = global.jsRoutes The js.Dynamic type annotation is what is inferred by IntelliJ. js.Dynamic类型注释是 IntelliJ 推断的。

Aha!啊哈! global is defined in scala.scalajs.js as extending scala.Dynamic . globalscala.scalajs.js中定义为扩展scala.Dynamic But I believe the jsRoutes should be interpreted as a js.Dynamic .但我相信jsRoutes应该被解释为js.Dynamic It's the routes produced by the Play server.它是 Play 服务器生成的路由。

It looks like I need to change how I access those guys.看来我需要改变访问这些人的方式。 Researching, particularly,Scala.js GlobalScope .特别是研究Scala.js GlobalScope

Still Later -- the fix再后来——修复

I'm recording what I did here so I can mark sjrd's answer as "the answer".我正在记录我在这里所做的事情,以便我可以将 sjrd 的答案标记为“答案”。

As noted, most of my IR validation errors were on lines of the form如前所述,我的大部分 IR 验证错误都在表格的行上

window.location.href = wapp.edit(emailId).url

href has a type of String and url is js.Dynamic but produces a string. href的类型为Stringurljs.Dynamic但会生成一个字符串。 I think therein lies the problem.我认为这就是问题所在。

The fix, however, was simple: add toString :然而,修复很简单:添加toString

window.location.href = wapp.edit(emailId).url.toString

All the other IR validation errors were variants of this with a similar fix.所有其他 IR 验证错误都是具有类似修复的变体。

The errors you see are "IR checking errors".您看到的错误是“IR 检查错误”。 They mean that there are inconsistencies in the .sjsir files that are produced by the compiler.它们意味着编译器生成的.sjsir文件中存在不一致。 By default, they are only checked for fullOpt tasks, which is why you have not seen them before.默认情况下,它们只检查fullOpt任务,这就是你以前没有见过它们的原因。 However, that does not mean the IR is any more valid for fastOpt (it's the same IR,), so the error was always there (latent).但是,这并不意味着 IR 对fastOpt更有效(它是相同的 IR),所以错误总是存在(潜在的)。 but only surfaces now, Having IR checking errors means that the optimizer, or simply the JavaScript code generator.但现在只是表面,有 IR 检查错误意味着优化器,或者只是 JavaScript 代码生成器。 can produce nonsensical results.可以产生无意义的结果。

(IR checking errors are also similar to VerifyError s on the JVM. (IR 检查错误也类似于 JVM 上的VerifyError

Broadly speaking, there are 3 sources of IR checking errors:一般来说,IR 检查错误有 3 个来源:

  • Using binary incompatible versions of transitive libraries can cause IR checking errors in some rare cases, even when no linking error arises.在极少数情况下,使用二进制不兼容版本的传递库可能会导致 IR 检查错误,即使没有出现链接错误
  • Bugs in the Scala.js core toolchain (compiler, linker) Scala.js 核心工具链(编译器、链接器)中的错误
  • A particular known (and somewhat intentional) unsoundness issue in the Scala.js type system: js.Dynamic <: scala.Dynamic causes unsoundness in the IR . Scala.js 类型系统中一个特定的已知(并且有些故意)不健全问题: js.Dynamic <: scala.Dynamic 导致 IR 不健全

What you are experiencing is the latter issue.您遇到的是后一个问题。 It is quite rare.这是相当罕见的。 Basically, it happens if you assign (through = or passing a function argument, etc.) a value of type js.Dynamic to a value of type scala.Dynamic .基本上,如果您将 js.Dynamic 类型的值分配给js.Dynamic类型的值(通过=或传递scala.Dynamic参数等),就会发生这种情况。 For example:例如:

val jsDyn = js.Dynamic.literal(foo = "bar")
val scalaDyn: scala.Dynamic = jsDyn

The type checker accepts that snippet because, at compile-time, js.Dynamic extends scala.Dynamic .类型检查器接受该片段,因为在编译时, js.Dynamic扩展scala.Dynamic This is necessary for js.Dynamic to expose its dynamism in the first place, so we cannot change that.这是js.Dynamic首先暴露其活力所必需的,因此我们无法更改它。 However, at link- and run-time, js.Dynamic is a JavaScript type (because it extends js.Any ) and scala.Dynamic is a Scala type, and JavaScript types are never subtypes of Scala types. However, at link- and run-time, js.Dynamic is a JavaScript type (because it extends js.Any ) and scala.Dynamic is a Scala type, and JavaScript types are never subtypes of Scala types.


So where does that leave you?那么,这让你何去何从?

Look at the code pointed by the error messages.查看错误消息指向的代码。 You will need to identify a place where a js.Dynamic (or any other JS type that extends scala.Dynamic , but js.Dynamic is typically the only one like that) is assigned to a scala.Dynamic .您需要确定一个js.Dynamic (或任何其他扩展scala.Dynamic的 JS 类型,但js.Dynamic通常是唯一这样的)分配给scala.Dynamic的位置。

It is extremely rare to write scala.Dynamic (or just Dynamic ) as a type by hand (and doing so is probably always a mistake), but it could be the case that it is inferred by the compiler, for example if you have two branches of an if/else that return two different subtypes of scala.Dynamic .手动编写scala.Dynamic (或只是Dynamic )作为一种类型是极其罕见的(这样做可能总是一个错误),但它可能是由编译器推断出来的,例如,如果你有两个if/else 的分支,返回scala.Dynamic的两个不同子类型。

This is all I can say without seeing the problematic code snippet.在没有看到有问题的代码片段的情况下,我只能这么说。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM