From ffd1e9d10c809cf60a0f1ff50b1413b704cbc969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 10 Nov 2022 20:19:56 +0100 Subject: [PATCH 1/2] Upgrade to Scala.js 1.11.0. Port of the compiler and build changes from the following commits: * https://github.com/scala-js/scala-js/commit/b7e7c56be51e993abc387f14f1006c4bd64d4a42 * https://github.com/scala-js/scala-js/commit/cb80afb9db6fa530c7c56d8f9e39cae15cb00718 * https://github.com/scala-js/scala-js/commit/994a59892f1c6d17e9bdb3f3bf81cd49a099660d * https://github.com/scala-js/scala-js/commit/d6fe1a868b7be50b65ef56380d4ecbdf20a7ce82 * https://github.com/scala-js/scala-js/commit/bcce3f2dd415fd133db45d75073c08a490ee6b1c * https://github.com/scala-js/scala-js/commit/b1137d5bc6aa94b6449c02839dd9d35ed5f5de56 * https://github.com/scala-js/scala-js/commit/874d9b95bf5fcf3accf6bd52e5e5332da2431775 * https://github.com/scala-js/scala-js/commit/3fb2b965472dbb0ecb0dfa7533138f2c0a2cba2e In addition, we have to update the compiler test infrastructure to include the new `scalajs-javalib` artifact. Unfortunately, there is an unchecked val extraction in the source code of scalajs-ir. We temporarily disable fatal warnings in the compiler, until we can upgrade to Scala.js 1.12.0. --- .../dotty/tools/backend/sjs/JSCodeGen.scala | 201 ++++++++++++------ .../tools/backend/sjs/JSDefinitions.scala | 12 +- .../tools/backend/sjs/JSExportsGen.scala | 6 +- .../tools/backend/sjs/JSPrimitives.scala | 20 +- compiler/test/dotty/Properties.scala | 3 + .../tools/vulpix/TestConfiguration.scala | 1 + project/Build.scala | 5 + project/plugins.sbt | 2 +- 8 files changed, 168 insertions(+), 82 deletions(-) diff --git a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala index 6714f664620b..ebd62801df1a 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala @@ -125,7 +125,14 @@ class JSCodeGen()(using genCtx: Context) { /** Implicitly materializes the current local name generator. */ implicit def implicitLocalNames: LocalNameGenerator = localNames.get - private def currentClassType = encodeClassType(currentClassSym) + def currentThisType: jstpe.Type = { + encodeClassType(currentClassSym) match { + case tpe @ jstpe.ClassType(cls) => + jstpe.BoxedClassToPrimType.getOrElse(cls, tpe) + case tpe => + tpe + } + } /** Returns a new fresh local identifier. */ private def freshLocalIdent()(implicit pos: Position): js.LocalIdent = @@ -1023,7 +1030,7 @@ class JSCodeGen()(using genCtx: Context) { // Constructor of a non-native JS class ------------------------------------ def genJSClassCapturesAndConstructor(constructorTrees: List[DefDef])( - implicit pos: SourcePosition): (List[js.ParamDef], js.JSMethodDef) = { + implicit pos: SourcePosition): (List[js.ParamDef], js.JSConstructorDef) = { /* We need to merge all Scala constructors into a single one because the * IR, like JavaScript, only allows a single one. * @@ -1095,20 +1102,21 @@ class JSCodeGen()(using genCtx: Context) { (exports.result(), jsClassCaptures.result()) } + // The name 'constructor' is used for error reporting here val (formalArgs, restParam, overloadDispatchBody) = jsExportsGen.genOverloadDispatch(JSName.Literal("constructor"), exports, jstpe.IntType) val overloadVar = js.VarDef(freshLocalIdent("overload"), NoOriginalName, jstpe.IntType, mutable = false, overloadDispatchBody) - val ctorStats = genJSClassCtorStats(overloadVar.ref, ctorTree) - - val constructorBody = js.Block( - paramVarDefs ::: List(overloadVar, ctorStats, js.Undefined())) + val constructorBody = wrapJSCtorBody( + paramVarDefs :+ overloadVar, + genJSClassCtorBody(overloadVar.ref, ctorTree), + js.Undefined() :: Nil + ) - val constructorDef = js.JSMethodDef( - js.MemberFlags.empty, - js.StringLiteral("constructor"), + val constructorDef = js.JSConstructorDef( + js.MemberFlags.empty.withNamespace(js.MemberNamespace.Constructor), formalArgs, restParam, constructorBody)(OptimizerHints.empty, None) (jsClassCaptures, constructorDef) @@ -1150,7 +1158,8 @@ class JSCodeGen()(using genCtx: Context) { assert(jsSuperCall.isDefined, s"Did not find Super call in primary JS construtor at ${dd.sourcePos}") - new PrimaryJSCtor(sym, genParamsAndInfo(sym, dd.paramss), jsSuperCall.get :: jsStats.result()) + new PrimaryJSCtor(sym, genParamsAndInfo(sym, dd.paramss), + js.JSConstructorBody(Nil, jsSuperCall.get, jsStats.result())(dd.span)) } private def genSecondaryJSClassCtor(dd: DefDef): SplitSecondaryJSCtor = { @@ -1251,9 +1260,9 @@ class JSCodeGen()(using genCtx: Context) { (jsExport, jsClassCaptures) } - /** generates a sequence of JS constructor statements based on a constructor tree. */ - private def genJSClassCtorStats(overloadVar: js.VarRef, - ctorTree: ConstructorTree[PrimaryJSCtor])(implicit pos: Position): js.Tree = { + /** Generates a JS constructor body based on a constructor tree. */ + private def genJSClassCtorBody(overloadVar: js.VarRef, + ctorTree: ConstructorTree[PrimaryJSCtor])(implicit pos: Position): js.JSConstructorBody = { /* generates a statement that conditionally executes body iff the chosen * overload is any of the descendants of `tree` (including itself). @@ -1348,13 +1357,19 @@ class JSCodeGen()(using genCtx: Context) { val primaryCtor = ctorTree.ctor val secondaryCtorTrees = ctorTree.subCtors - js.Block( - secondaryCtorTrees.map(preStats(_, primaryCtor.paramsAndInfo)) ++ - primaryCtor.body ++ + wrapJSCtorBody( + secondaryCtorTrees.map(preStats(_, primaryCtor.paramsAndInfo)), + primaryCtor.body, secondaryCtorTrees.map(postStats(_)) ) } + private def wrapJSCtorBody(before: List[js.Tree], body: js.JSConstructorBody, + after: List[js.Tree]): js.JSConstructorBody = { + js.JSConstructorBody(before ::: body.beforeSuper, body.superCall, + body.afterSuper ::: after)(body.pos) + } + private sealed trait JSCtor { val sym: Symbol val paramsAndInfo: List[(Symbol, JSParamInfo)] @@ -1362,7 +1377,7 @@ class JSCodeGen()(using genCtx: Context) { private class PrimaryJSCtor(val sym: Symbol, val paramsAndInfo: List[(Symbol, JSParamInfo)], - val body: List[js.Tree]) extends JSCtor + val body: js.JSConstructorBody) extends JSCtor private class SplitSecondaryJSCtor(val sym: Symbol, val paramsAndInfo: List[(Symbol, JSParamInfo)], @@ -1945,9 +1960,9 @@ class JSCodeGen()(using genCtx: Context) { }*/ thisLocalVarIdent.fold[js.Tree] { - js.This()(currentClassType) + js.This()(currentThisType) } { thisLocalIdent => - js.VarRef(thisLocalIdent)(currentClassType) + js.VarRef(thisLocalIdent)(currentThisType) } } @@ -2014,9 +2029,7 @@ class JSCodeGen()(using genCtx: Context) { val (exceptValDef, exceptVar) = if (mightCatchJavaScriptException) { val valDef = js.VarDef(freshLocalIdent("e"), NoOriginalName, - encodeClassType(defn.ThrowableClass), mutable = false, { - genModuleApplyMethod(jsdefn.Runtime_wrapJavaScriptException, origExceptVar :: Nil) - }) + encodeClassType(defn.ThrowableClass), mutable = false, js.WrapAsThrowable(origExceptVar)) (valDef, valDef.ref) } else { (js.Skip(), origExceptVar) @@ -2307,7 +2320,7 @@ class JSCodeGen()(using genCtx: Context) { val privateFieldDefs = mutable.ListBuffer.empty[js.FieldDef] val classDefMembers = mutable.ListBuffer.empty[js.MemberDef] val instanceMembers = mutable.ListBuffer.empty[js.MemberDef] - var constructor: Option[js.JSMethodDef] = None + var constructor: Option[js.JSConstructorDef] = None originalClassDef.memberDefs.foreach { case fdef: js.FieldDef => @@ -2321,17 +2334,13 @@ class JSCodeGen()(using genCtx: Context) { "Non-static, unexported method in non-native JS class") classDefMembers += mdef - case mdef: js.JSMethodDef => - mdef.name match { - case js.StringLiteral("constructor") => - assert(!mdef.flags.namespace.isStatic, "Exported static method") - assert(constructor.isEmpty, "two ctors in class") - constructor = Some(mdef) + case cdef: js.JSConstructorDef => + assert(constructor.isEmpty, "two ctors in class") + constructor = Some(cdef) - case _ => - assert(!mdef.flags.namespace.isStatic, "Exported static method") - instanceMembers += mdef - } + case mdef: js.JSMethodDef => + assert(!mdef.flags.namespace.isStatic, "Exported static method") + instanceMembers += mdef case property: js.JSPropertyDef => instanceMembers += property @@ -2361,7 +2370,7 @@ class JSCodeGen()(using genCtx: Context) { val jsClassCaptures = originalClassDef.jsClassCaptures.getOrElse { throw new AssertionError(s"no class captures for anonymous JS class at $pos") } - val js.JSMethodDef(_, _, ctorParams, ctorRestParam, ctorBody) = constructor.getOrElse { + val js.JSConstructorDef(_, ctorParams, ctorRestParam, ctorBody) = constructor.getOrElse { throw new AssertionError("No ctor found") } assert(ctorParams.isEmpty && ctorRestParam.isEmpty, @@ -2396,6 +2405,9 @@ class JSCodeGen()(using genCtx: Context) { case mdef: js.MethodDef => throw new AssertionError("unexpected MethodDef") + case cdef: js.JSConstructorDef => + throw new AssertionError("unexpected JSConstructorDef") + case mdef: js.JSMethodDef => implicit val pos = mdef.pos val impl = memberLambda(mdef.args, mdef.restParam, mdef.body) @@ -2468,36 +2480,43 @@ class JSCodeGen()(using genCtx: Context) { } // Transform the constructor body. - val inlinedCtorStats = new ir.Transformers.Transformer { - override def transform(tree: js.Tree, isStat: Boolean): js.Tree = tree match { - // The super constructor call. Transform this into a simple new call. - case js.JSSuperConstructorCall(args) => - implicit val pos = tree.pos - - val newTree = { - val ident = originalClassDef.superClass.getOrElse(throw new FatalError("No superclass")) - if (args.isEmpty && ident.name == JSObjectClassName) - js.JSObjectConstr(Nil) - else - js.JSNew(jsSuperClassRef, args) - } - - js.Block( - js.VarDef(selfName, thisOriginalName, jstpe.AnyType, mutable = false, newTree) :: - memberDefinitions) + val inlinedCtorStats: List[js.Tree] = { + val beforeSuper = ctorBody.beforeSuper - case js.This() => - selfRef(tree.pos) + val superCall = { + implicit val pos = ctorBody.superCall.pos + val js.JSSuperConstructorCall(args) = ctorBody.superCall - // Don't traverse closure boundaries - case closure: js.Closure => - val newCaptureValues = closure.captureValues.map(transformExpr) - closure.copy(captureValues = newCaptureValues)(closure.pos) + val newTree = { + val ident = originalClassDef.superClass.getOrElse(throw new FatalError("No superclass")) + if (args.isEmpty && ident.name == JSObjectClassName) + js.JSObjectConstr(Nil) + else + js.JSNew(jsSuperClassRef, args) + } - case tree => - super.transform(tree, isStat) + val selfVarDef = js.VarDef(selfName, thisOriginalName, jstpe.AnyType, mutable = false, newTree) + selfVarDef :: memberDefinitions } - }.transform(ctorBody, isStat = true) + + // After the super call, substitute `selfRef` for `This()` + val afterSuper = new ir.Transformers.Transformer { + override def transform(tree: js.Tree, isStat: Boolean): js.Tree = tree match { + case js.This() => + selfRef(tree.pos) + + // Don't traverse closure boundaries + case closure: js.Closure => + val newCaptureValues = closure.captureValues.map(transformExpr) + closure.copy(captureValues = newCaptureValues)(closure.pos) + + case tree => + super.transform(tree, isStat) + } + }.transformStats(ctorBody.afterSuper) + + beforeSuper ::: superCall ::: afterSuper + } val closure = js.Closure(arrow = true, jsClassCaptures, Nil, None, js.Block(inlinedCtorStats, selfRef), jsSuperClassValue :: args) @@ -2989,14 +3008,12 @@ class JSCodeGen()(using genCtx: Context) { implicit val pos: SourcePosition = tree.sourcePos val exception = args.head val genException = genExpr(exception) - js.Throw { - if (exception.tpe.typeSymbol.derivesFrom(jsdefn.JavaScriptExceptionClass)) { - genModuleApplyMethod( - jsdefn.Runtime_unwrapJavaScriptException, - List(genException)) - } else { - genException - } + genException match { + case js.New(cls, _, _) if cls != JavaScriptExceptionClassName => + // Common case where ex is neither null nor a js.JavaScriptException + js.Throw(genException) + case _ => + js.Throw(js.UnwrapFromThrowable(genException)) } } @@ -3982,6 +3999,53 @@ class JSCodeGen()(using genCtx: Context) { js.JSFunctionApply(fVarDef.ref, List(keyVarRef)) })) + case JS_THROW => + // js.special.throw(arg) + js.Throw(genArgs1) + + case JS_TRY_CATCH => + /* js.special.tryCatch(arg1, arg2) + * + * We must generate: + * + * val body = arg1 + * val handler = arg2 + * try { + * body() + * } catch (e) { + * handler(e) + * } + * + * with temporary vals, because `arg2` must be evaluated before + * `body` executes. Moreover, exceptions thrown while evaluating + * the function values `arg1` and `arg2` must not be caught. + */ + val (arg1, arg2) = genArgs2 + val bodyVarDef = js.VarDef(freshLocalIdent("body"), NoOriginalName, + jstpe.AnyType, mutable = false, arg1) + val handlerVarDef = js.VarDef(freshLocalIdent("handler"), NoOriginalName, + jstpe.AnyType, mutable = false, arg2) + val exceptionVarIdent = freshLocalIdent("e") + val exceptionVarRef = js.VarRef(exceptionVarIdent)(jstpe.AnyType) + js.Block( + bodyVarDef, + handlerVarDef, + js.TryCatch( + js.JSFunctionApply(bodyVarDef.ref, Nil), + exceptionVarIdent, + NoOriginalName, + js.JSFunctionApply(handlerVarDef.ref, List(exceptionVarRef)) + )(jstpe.AnyType) + ) + + case WRAP_AS_THROWABLE => + // js.special.wrapAsThrowable(arg) + js.WrapAsThrowable(genArgs1) + + case UNWRAP_FROM_THROWABLE => + // js.special.unwrapFromThrowable(arg) + js.UnwrapFromThrowable(genArgs1) + case UNION_FROM | UNION_FROM_TYPE_CONSTRUCTOR => /* js.|.from and js.|.fromTypeConstructor * We should not have to deal with those. They have a perfectly valid @@ -4764,6 +4828,7 @@ object JSCodeGen { private val NullPointerExceptionClass = ClassName("java.lang.NullPointerException") private val JSObjectClassName = ClassName("scala.scalajs.js.Object") + private val JavaScriptExceptionClassName = ClassName("scala.scalajs.js.JavaScriptException") private val ObjectClassRef = jstpe.ClassRef(ir.Names.ObjectClass) diff --git a/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala b/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala index c252ac892548..5336d60129ac 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala @@ -162,10 +162,6 @@ final class JSDefinitions()(using Context) { @threadUnsafe lazy val RuntimePackageVal = requiredPackage("scala.scalajs.runtime") @threadUnsafe lazy val RuntimePackageClass = RuntimePackageVal.moduleClass.asClass - @threadUnsafe lazy val RuntimePackage_wrapJavaScriptExceptionR = RuntimePackageClass.requiredMethodRef("wrapJavaScriptException") - def Runtime_wrapJavaScriptException(using Context) = RuntimePackage_wrapJavaScriptExceptionR.symbol - @threadUnsafe lazy val Runtime_unwrapJavaScriptExceptionR = RuntimePackageClass.requiredMethodRef("unwrapJavaScriptException") - def Runtime_unwrapJavaScriptException(using Context) = Runtime_unwrapJavaScriptExceptionR.symbol @threadUnsafe lazy val Runtime_toScalaVarArgsR = RuntimePackageClass.requiredMethodRef("toScalaVarArgs") def Runtime_toScalaVarArgs(using Context) = Runtime_toScalaVarArgsR.symbol @threadUnsafe lazy val Runtime_toJSVarArgsR = RuntimePackageClass.requiredMethodRef("toJSVarArgs") @@ -206,6 +202,14 @@ final class JSDefinitions()(using Context) { def Special_instanceof(using Context) = Special_instanceofR.symbol @threadUnsafe lazy val Special_strictEqualsR = SpecialPackageClass.requiredMethodRef("strictEquals") def Special_strictEquals(using Context) = Special_strictEqualsR.symbol + @threadUnsafe lazy val Special_throwR = SpecialPackageClass.requiredMethodRef("throw") + def Special_throw(using Context) = Special_throwR.symbol + @threadUnsafe lazy val Special_tryCatchR = SpecialPackageClass.requiredMethodRef("tryCatch") + def Special_tryCatch(using Context) = Special_tryCatchR.symbol + @threadUnsafe lazy val Special_wrapAsThrowableR = SpecialPackageClass.requiredMethodRef("wrapAsThrowable") + def Special_wrapAsThrowable(using Context) = Special_wrapAsThrowableR.symbol + @threadUnsafe lazy val Special_unwrapFromThrowableR = SpecialPackageClass.requiredMethodRef("unwrapFromThrowable") + def Special_unwrapFromThrowable(using Context) = Special_unwrapFromThrowableR.symbol @threadUnsafe lazy val WrappedArrayType: TypeRef = requiredClassRef("scala.scalajs.js.WrappedArray") def WrappedArrayClass(using Context) = WrappedArrayType.symbol.asClass diff --git a/compiler/src/dotty/tools/backend/sjs/JSExportsGen.scala b/compiler/src/dotty/tools/backend/sjs/JSExportsGen.scala index 0884ec19b53e..6b4ff111c155 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSExportsGen.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSExportsGen.scala @@ -650,7 +650,7 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) { js.LoadJSConstructor(encodeClassName(superClassSym)) } - val receiver = js.This()(jstpe.AnyType) + val receiver = js.This()(currentThisType) val nameTree = genExpr(sym.jsName) if (sym.isJSGetter) { @@ -754,7 +754,7 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) { genApplyMethodMaybeStatically(receiver, modAccessor, Nil) } } else { - js.This()(encodeClassType(targetSym)) + js.This()(currentThisType) } } @@ -811,7 +811,7 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) { def receiver = if (static) genLoadModule(sym.owner) - else js.This()(encodeClassType(currentClass)) + else js.This()(currentThisType) def boxIfNeeded(call: js.Tree): js.Tree = box(call, atPhase(elimErasedValueTypePhase)(sym.info.resultType)) diff --git a/compiler/src/dotty/tools/backend/sjs/JSPrimitives.scala b/compiler/src/dotty/tools/backend/sjs/JSPrimitives.scala index 6b3854ed677f..6b59c0b7f6a4 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSPrimitives.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSPrimitives.scala @@ -36,12 +36,16 @@ object JSPrimitives { inline val LINKING_INFO = WITH_CONTEXTUAL_JS_CLASS_VALUE + 1 // runtime.linkingInfo inline val DYNAMIC_IMPORT = LINKING_INFO + 1 // runtime.dynamicImport - inline val STRICT_EQ = DYNAMIC_IMPORT + 1 // js.special.strictEquals - inline val IN = STRICT_EQ + 1 // js.special.in - inline val INSTANCEOF = IN + 1 // js.special.instanceof - inline val DELETE = INSTANCEOF + 1 // js.special.delete - inline val FORIN = DELETE + 1 // js.special.forin - inline val DEBUGGER = FORIN + 1 // js.special.debugger + inline val STRICT_EQ = DYNAMIC_IMPORT + 1 // js.special.strictEquals + inline val IN = STRICT_EQ + 1 // js.special.in + inline val INSTANCEOF = IN + 1 // js.special.instanceof + inline val DELETE = INSTANCEOF + 1 // js.special.delete + inline val FORIN = DELETE + 1 // js.special.forin + inline val JS_THROW = FORIN + 1 // js.special.throw + inline val JS_TRY_CATCH = JS_THROW + 1 // js.special.tryCatch + inline val WRAP_AS_THROWABLE = JS_TRY_CATCH + 1 // js.special.wrapAsThrowable + inline val UNWRAP_FROM_THROWABLE = WRAP_AS_THROWABLE + 1 // js.special.unwrapFromThrowable + inline val DEBUGGER = UNWRAP_FROM_THROWABLE + 1 // js.special.debugger inline val THROW = DEBUGGER + 1 @@ -125,6 +129,10 @@ class JSPrimitives(ictx: Context) extends DottyPrimitives(ictx) { addPrimitive(jsdefn.Special_instanceof, INSTANCEOF) addPrimitive(jsdefn.Special_delete, DELETE) addPrimitive(jsdefn.Special_forin, FORIN) + addPrimitive(jsdefn.Special_throw, JS_THROW) + addPrimitive(jsdefn.Special_tryCatch, JS_TRY_CATCH) + addPrimitive(jsdefn.Special_wrapAsThrowable, WRAP_AS_THROWABLE) + addPrimitive(jsdefn.Special_unwrapFromThrowable, UNWRAP_FROM_THROWABLE) addPrimitive(jsdefn.Special_debugger, DEBUGGER) addPrimitive(defn.throwMethod, THROW) diff --git a/compiler/test/dotty/Properties.scala b/compiler/test/dotty/Properties.scala index 71569f2f0e08..cc47303d5468 100644 --- a/compiler/test/dotty/Properties.scala +++ b/compiler/test/dotty/Properties.scala @@ -91,6 +91,9 @@ object Properties { /** jline-reader jar */ def jlineReader: String = sys.props("dotty.tests.classes.jlineReader") + /** scalajs-javalib jar */ + def scalaJSJavalib: String = sys.props("dotty.tests.classes.scalaJSJavalib") + /** scalajs-library jar */ def scalaJSLibrary: String = sys.props("dotty.tests.classes.scalaJSLibrary") } diff --git a/compiler/test/dotty/tools/vulpix/TestConfiguration.scala b/compiler/test/dotty/tools/vulpix/TestConfiguration.scala index 3ea364cc3a68..5d2992b50a09 100644 --- a/compiler/test/dotty/tools/vulpix/TestConfiguration.scala +++ b/compiler/test/dotty/tools/vulpix/TestConfiguration.scala @@ -49,6 +49,7 @@ object TestConfiguration { withCompilerClasspath + File.pathSeparator + mkClasspath(List(Properties.dottyTastyInspector)) lazy val scalaJSClasspath = mkClasspath(List( + Properties.scalaJSJavalib, Properties.scalaJSLibrary, Properties.dottyLibraryJS )) diff --git a/project/Build.scala b/project/Build.scala index d735db6a8a5b..9ca4e619e7d1 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -522,6 +522,9 @@ object Build { // Settings shared between scala3-compiler and scala3-compiler-bootstrapped lazy val commonDottyCompilerSettings = Seq( + // Temporary for the upgrade to Scala.js 1.11.0 - remove with Scala.js 1.12.0 + Compile / scalacOptions -= "-Xfatal-warnings", + // Generate compiler.properties, used by sbt (Compile / resourceGenerators) += Def.task { import java.util._ @@ -1192,6 +1195,7 @@ object Build { "isFullOpt" -> (stage == FullOptStage), "compliantAsInstanceOfs" -> (sems.asInstanceOfs == CheckedBehavior.Compliant), "compliantArrayIndexOutOfBounds" -> (sems.arrayIndexOutOfBounds == CheckedBehavior.Compliant), + "compliantStringIndexOutOfBounds" -> (sems.stringIndexOutOfBounds == CheckedBehavior.Compliant), "compliantModuleInit" -> (sems.moduleInit == CheckedBehavior.Compliant), "strictFloats" -> sems.strictFloats, "productionMode" -> sems.productionMode, @@ -1303,6 +1307,7 @@ object Build { Seq( "-Ddotty.tests.classes.dottyLibraryJS=" + dottyLibraryJSJar, + "-Ddotty.tests.classes.scalaJSJavalib=" + findArtifactPath(externalJSDeps, "scalajs-javalib"), "-Ddotty.tests.classes.scalaJSLibrary=" + findArtifactPath(externalJSDeps, "scalajs-library_2.13"), ) }, diff --git a/project/plugins.sbt b/project/plugins.sbt index b6bc5f1184b6..6b4c54a90a35 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,7 +2,7 @@ // // e.g. addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.1.0") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.10.1") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.11.0") addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.10") From 7c2be6130172c97736e6b9350c7dfc33284fe996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 24 Nov 2022 21:18:21 +0100 Subject: [PATCH 2/2] Upgrade to Scala.js 1.12.0. We omit in this commit the upstream changes to add support for `@JSOperator`, from the PR https://github.com/scala-js/scala-js/pull/4744 Doing so does not prevent the test suite from passing at the moment. We leave them for an upcoming PR. --- community-build/community-projects/spire | 2 +- project/Build.scala | 13 ++++++++++--- project/plugins.sbt | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/community-build/community-projects/spire b/community-build/community-projects/spire index 7f630c0209e3..95a304565549 160000 --- a/community-build/community-projects/spire +++ b/community-build/community-projects/spire @@ -1 +1 @@ -Subproject commit 7f630c0209e327bdc782ade2210d8e4b916fddcc +Subproject commit 95a304565549cb71b111ef208d74c128223adc6e diff --git a/project/Build.scala b/project/Build.scala index 9ca4e619e7d1..abc92d59047b 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -522,9 +522,6 @@ object Build { // Settings shared between scala3-compiler and scala3-compiler-bootstrapped lazy val commonDottyCompilerSettings = Seq( - // Temporary for the upgrade to Scala.js 1.11.0 - remove with Scala.js 1.12.0 - Compile / scalacOptions -= "-Xfatal-warnings", - // Generate compiler.properties, used by sbt (Compile / resourceGenerators) += Def.task { import java.util._ @@ -1195,6 +1192,8 @@ object Build { "isFullOpt" -> (stage == FullOptStage), "compliantAsInstanceOfs" -> (sems.asInstanceOfs == CheckedBehavior.Compliant), "compliantArrayIndexOutOfBounds" -> (sems.arrayIndexOutOfBounds == CheckedBehavior.Compliant), + "compliantArrayStores" -> (sems.arrayStores == CheckedBehavior.Compliant), + "compliantNegativeArraySizes" -> (sems.negativeArraySizes == CheckedBehavior.Compliant), "compliantStringIndexOutOfBounds" -> (sems.stringIndexOutOfBounds == CheckedBehavior.Compliant), "compliantModuleInit" -> (sems.moduleInit == CheckedBehavior.Compliant), "strictFloats" -> sems.strictFloats, @@ -1272,6 +1271,14 @@ object Build { ) }, + /* For some reason, in Scala 3, the implementation of IterableDefaultTest + * resolves to `scala.collection.ArrayOps.ArrayIterator`, whose `next()` + * method is not compliant when called past the last element on Scala.js. + * It relies on catching an `ArrayIndexOutOfBoundsException`. + * We have to ignore it here. + */ + Test / testOptions := Seq(Tests.Filter(_ != "org.scalajs.testsuite.javalib.lang.IterableDefaultTest")), + Test / managedResources ++= { val testDir = fetchScalaJSSource.value / "test-suite/js/src/test" diff --git a/project/plugins.sbt b/project/plugins.sbt index 6b4c54a90a35..5d33ce778e74 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,7 +2,7 @@ // // e.g. addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.1.0") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.11.0") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.12.0") addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.10")