diff --git a/compiler/sjs/backend/sjs/GenSJSIR.scala b/compiler/src/dotty/tools/backend/backend/sjs/GenSJSIR.scala similarity index 100% rename from compiler/sjs/backend/sjs/GenSJSIR.scala rename to compiler/src/dotty/tools/backend/backend/sjs/GenSJSIR.scala diff --git a/compiler/sjs/backend/sjs/JSCodeGen.scala b/compiler/src/dotty/tools/backend/backend/sjs/JSCodeGen.scala similarity index 98% rename from compiler/sjs/backend/sjs/JSCodeGen.scala rename to compiler/src/dotty/tools/backend/backend/sjs/JSCodeGen.scala index 2eb8ecadc142..5c8b013af5a6 100644 --- a/compiler/sjs/backend/sjs/JSCodeGen.scala +++ b/compiler/src/dotty/tools/backend/backend/sjs/JSCodeGen.scala @@ -127,7 +127,7 @@ class JSCodeGen()(implicit ctx: Context) { /* Finally, we emit true code for the remaining class defs. */ for (td <- allTypeDefs) { val sym = td.symbol - implicit val pos = sym.pos + implicit val pos: Position = sym.pos /* Do not actually emit code for primitive types nor scala.Array. */ val isPrimitive = @@ -185,7 +185,7 @@ class JSCodeGen()(implicit ctx: Context) { import dotty.tools.io._ val outputDirectory: AbstractFile = // TODO Support virtual files - new PlainDirectory(new Directory(new java.io.File(ctx.settings.d.value))) + new PlainDirectory(ctx.settings.outputDir.value) val pathParts = sym.fullName.toString.split("[./]") val dir = (outputDirectory /: pathParts.init)(_.subdirectoryNamed(_)) @@ -203,7 +203,7 @@ class JSCodeGen()(implicit ctx: Context) { */ private def genScalaClass(td: TypeDef): js.ClassDef = { val sym = td.symbol.asClass - implicit val pos = sym.pos + implicit val pos: Position = sym.pos assert(!sym.is(Trait), "genScalaClass() must be called only for normal classes: "+sym) @@ -285,9 +285,9 @@ class JSCodeGen()(implicit ctx: Context) { js.ModuleExportDef("hello.world"), js.MethodDef(static = false, js.StringLiteral("main"), Nil, jstpe.AnyType, - js.Block(List( + Some(js.Block(List( js.Apply(js.This()(jstpe.ClassType(classIdent.name)), js.Ident("main__V"), Nil)(jstpe.NoType), - js.Undefined())))( + js.Undefined()))))( OptimizerHints.empty, None)) } else { /* @@ -336,20 +336,25 @@ class JSCodeGen()(implicit ctx: Context) { */ private def genRawJSClassData(td: TypeDef): js.ClassDef = { val sym = td.symbol.asClass - implicit val pos = sym.pos + implicit val pos: Position = sym.pos val classIdent = encodeClassFullNameIdent(sym) + val kind = { + if (sym.is(Trait)) ClassKind.AbstractJSType + else if (sym.is(ModuleClass)) ClassKind.NativeJSModuleClass + else ClassKind.NativeJSClass + } val superClass = if (sym.is(Trait)) None else Some(encodeClassFullNameIdent(sym.superClass)) - val jsName = - if (sym.is(Trait) || sym.is(ModuleClass)) None - else Some(fullJSNameOf(sym)) + val jsNativeLoadSpec = + if (sym.is(Trait)) None + else Some(js.JSNativeLoadSpec.Global(fullJSNameOf(sym).split('.').toList)) - js.ClassDef(classIdent, ClassKind.RawJSType, + js.ClassDef(classIdent, kind, superClass, genClassInterfaces(sym), - jsName, + jsNativeLoadSpec, Nil)( OptimizerHints.empty) } @@ -358,7 +363,7 @@ class JSCodeGen()(implicit ctx: Context) { */ private def genInterface(td: TypeDef): js.ClassDef = { val sym = td.symbol.asClass - implicit val pos = sym.pos + implicit val pos: Position = sym.pos val classIdent = encodeClassFullNameIdent(sym) @@ -404,10 +409,7 @@ class JSCodeGen()(implicit ctx: Context) { "genClassFields called with a ClassDef other than the current one") // Non-method term members are fields - (for { - f <- classSym.info.decls - if !f.is(Method) && f.isTerm - } yield { + classSym.info.decls.filter(f => !f.is(Method) && f.isTerm).map({ f => implicit val pos = f.pos val name = @@ -451,7 +453,7 @@ class JSCodeGen()(implicit ctx: Context) { } }*/ - js.FieldDef(name, irTpe, f.is(Mutable)) + js.FieldDef(static = false, name, irTpe, f.is(Mutable)) }).toList } @@ -510,7 +512,7 @@ class JSCodeGen()(implicit ctx: Context) { None } else*/ if (sym.is(Deferred)) { Some(js.MethodDef(static = false, methodName, - jsParams, toIRType(patchedResultType(sym)), js.EmptyTree)( + jsParams, toIRType(patchedResultType(sym)), None)( OptimizerHints.empty, None)) } else /*if (isJSNativeCtorDefaultParam(sym)) { None @@ -549,7 +551,7 @@ class JSCodeGen()(implicit ctx: Context) { } else*/ if (sym.isConstructor) { js.MethodDef(static = false, methodName, jsParams, jstpe.NoType, - genStat(rhs))(optimizerHints, None) + Some(genStat(rhs)))(optimizerHints, None) } else { val resultIRType = toIRType(patchedResultType(sym)) genMethodDef(static = false, methodName, @@ -576,7 +578,7 @@ class JSCodeGen()(implicit ctx: Context) { tree: Tree, optimizerHints: OptimizerHints): js.MethodDef = { implicit val pos = tree.pos - ctx.debuglog("genMethod " + methodName.name) + ctx.debuglog("genMethod " + methodName.encodedName) ctx.debuglog("") val jsParams = for (param <- paramsSyms) yield { @@ -590,7 +592,7 @@ class JSCodeGen()(implicit ctx: Context) { else genExpr(tree) //if (!isScalaJSDefinedJSClass(currentClassSym)) { - js.MethodDef(static, methodName, jsParams, resultIRType, genBody())( + js.MethodDef(static, methodName, jsParams, resultIRType, Some(genBody()))( optimizerHints, None) /*} else { assert(!static, tree.pos) @@ -1021,7 +1023,7 @@ class JSCodeGen()(implicit ctx: Context) { /** Gen JS code for a primitive method call. */ private def genPrimitiveOp(tree: Apply, isStat: Boolean): js.Tree = { - import scala.tools.nsc.backend.ScalaPrimitives._ + import scala.tools.nsc.backend.ScalaPrimitivesOps._ implicit val pos = tree.pos @@ -1061,7 +1063,7 @@ class JSCodeGen()(implicit ctx: Context) { /** Gen JS code for a simple unary operation. */ private def genSimpleUnaryOp(tree: Apply, arg: Tree, code: Int): js.Tree = { - import scala.tools.nsc.backend.ScalaPrimitives._ + import scala.tools.nsc.backend.ScalaPrimitivesOps._ implicit val pos = tree.pos @@ -1102,7 +1104,7 @@ class JSCodeGen()(implicit ctx: Context) { /** Gen JS code for a simple binary operation. */ private def genSimpleBinaryOp(tree: Apply, lhs: Tree, rhs: Tree, code: Int): js.Tree = { - import scala.tools.nsc.backend.ScalaPrimitives._ + import scala.tools.nsc.backend.ScalaPrimitivesOps._ import js.UnaryOp._ /* Codes for operation types, in an object so that they can be 'final val' @@ -1280,7 +1282,7 @@ class JSCodeGen()(implicit ctx: Context) { private def genUniversalEqualityOp(lhs: Tree, rhs: Tree, code: Int)( implicit pos: Position): js.Tree = { - import scala.tools.nsc.backend.ScalaPrimitives._ + import scala.tools.nsc.backend.ScalaPrimitivesOps._ val genLhs = genExpr(lhs) val genRhs = genExpr(rhs) @@ -1409,7 +1411,7 @@ class JSCodeGen()(implicit ctx: Context) { /** Gen JS code for an array operation (get, set or length) */ private def genArrayOp(tree: Tree, code: Int): js.Tree = { - import scala.tools.nsc.backend.ScalaPrimitives._ + import scala.tools.nsc.backend.ScalaPrimitivesOps._ implicit val pos = tree.pos @@ -1423,8 +1425,9 @@ class JSCodeGen()(implicit ctx: Context) { case defn.ArrayOf(el) => el case JavaArrayType(el) => el case tpe => - ctx.error(s"expected Array $tpe") - ErrorType + val msg = ex"expected Array $tpe" + ctx.error(msg) + ErrorType(msg) } def genSelect(): js.Tree = @@ -1472,7 +1475,7 @@ class JSCodeGen()(implicit ctx: Context) { /** Gen JS code for a coercion */ private def genCoercion(tree: Apply, receiver: Tree, code: Int): js.Tree = { - import scala.tools.nsc.backend.ScalaPrimitives._ + import scala.tools.nsc.backend.ScalaPrimitivesOps._ implicit val pos = tree.pos @@ -1881,7 +1884,7 @@ class JSCodeGen()(implicit ctx: Context) { }.unzip val formalParamNames = sym.info.paramNamess.flatten.drop(envSize) - val formalParamTypes = sym.info.paramTypess.flatten.drop(envSize) + val formalParamTypes = sym.info.paramInfoss.flatten.drop(envSize) val (formalParams, actualParams) = formalParamNames.zip(formalParamTypes).map { case (name, tpe) => val formalParam = js.ParamDef(freshLocalIdent(name.toString), @@ -2175,7 +2178,7 @@ class JSCodeGen()(implicit ctx: Context) { implicit pos: Position): List[js.Tree] = { def paramNamesAndTypes(implicit ctx: Context): List[(Names.TermName, Type)] = - sym.info.paramNamess.flatten.zip(sym.info.paramTypess.flatten) + sym.info.paramNamess.flatten.zip(sym.info.paramInfoss.flatten) val wereRepeated = ctx.atPhase(ctx.elimRepeatedPhase) { implicit ctx => for ((name, tpe) <- paramNamesAndTypes) diff --git a/compiler/sjs/backend/sjs/JSDefinitions.scala b/compiler/src/dotty/tools/backend/backend/sjs/JSDefinitions.scala similarity index 97% rename from compiler/sjs/backend/sjs/JSDefinitions.scala rename to compiler/src/dotty/tools/backend/backend/sjs/JSDefinitions.scala index bd0b740318e0..adfc25c9daa7 100644 --- a/compiler/sjs/backend/sjs/JSDefinitions.scala +++ b/compiler/src/dotty/tools/backend/backend/sjs/JSDefinitions.scala @@ -183,17 +183,15 @@ final class JSDefinitions()(implicit ctx: Context) { * * This is similar to `isVarArityClass` in `Definitions.scala`. */ - private def isScalaJSVarArityClass(cls: Symbol, prefix: Name): Boolean = { + private def isScalaJSVarArityClass(cls: Symbol, prefix: String): Boolean = { val name = scalajsClassName(cls) - name.startsWith(prefix) && name.drop(prefix.length).forall(_.isDigit) + name.startsWith(prefix) && name.toString.drop(prefix.length).forall(_.isDigit) } def isJSFunctionClass(cls: Symbol): Boolean = - isScalaJSVarArityClass(cls, nme.Function) - - private val ThisFunctionName = termName("ThisFunction") + isScalaJSVarArityClass(cls, str.Function) def isJSThisFunctionClass(cls: Symbol): Boolean = - isScalaJSVarArityClass(cls, ThisFunctionName) + isScalaJSVarArityClass(cls, "ThisFunction") } diff --git a/compiler/sjs/backend/sjs/JSEncoding.scala b/compiler/src/dotty/tools/backend/backend/sjs/JSEncoding.scala similarity index 99% rename from compiler/sjs/backend/sjs/JSEncoding.scala rename to compiler/src/dotty/tools/backend/backend/sjs/JSEncoding.scala index e8ea3258bfa2..b68535105ba6 100644 --- a/compiler/sjs/backend/sjs/JSEncoding.scala +++ b/compiler/src/dotty/tools/backend/backend/sjs/JSEncoding.scala @@ -209,7 +209,7 @@ object JSEncoding { } def foreignIsImplClass(sym: Symbol)(implicit ctx: Context): Boolean = - sym.name.isImplClassName + sym.name.endsWith(nme.IMPL_CLASS_SUFFIX.toString) def encodeClassType(sym: Symbol)(implicit ctx: Context): jstpe.Type = { if (sym == defn.ObjectClass) jstpe.AnyType diff --git a/compiler/sjs/backend/sjs/JSInterop.scala b/compiler/src/dotty/tools/backend/backend/sjs/JSInterop.scala similarity index 90% rename from compiler/sjs/backend/sjs/JSInterop.scala rename to compiler/src/dotty/tools/backend/backend/sjs/JSInterop.scala index 6d66c32064ee..e984489cf51d 100644 --- a/compiler/sjs/backend/sjs/JSInterop.scala +++ b/compiler/src/dotty/tools/backend/backend/sjs/JSInterop.scala @@ -6,6 +6,7 @@ import Flags._ import Symbols._ import NameOps._ import StdNames._ +import NameKinds.DefaultGetterName import JSDefinitions._ @@ -66,11 +67,17 @@ object JSInterop { * is a JS type. */ def isJSDefaultParam(sym: Symbol)(implicit ctx: Context): Boolean = { - sym.name.isDefaultGetterName && { + sym.name.is(DefaultGetterName) && { val owner = sym.owner - if (owner.is(ModuleClass) && - sym.name.asTermName.defaultGetterToMethod == nme.CONSTRUCTOR) { - isJSType(owner.linkedClass) + if (owner.is(ModuleClass)) { + val isConstructor = sym.name match { + case DefaultGetterName(methName, _) => methName == nme.CONSTRUCTOR + case _ => false + } + if (isConstructor) + isJSType(owner.linkedClass) + else + isJSType(owner) } else { isJSType(owner) } diff --git a/compiler/sjs/backend/sjs/JSPositions.scala b/compiler/src/dotty/tools/backend/backend/sjs/JSPositions.scala similarity index 100% rename from compiler/sjs/backend/sjs/JSPositions.scala rename to compiler/src/dotty/tools/backend/backend/sjs/JSPositions.scala diff --git a/compiler/sjs/backend/sjs/JSPrimitives.scala b/compiler/src/dotty/tools/backend/backend/sjs/JSPrimitives.scala similarity index 98% rename from compiler/sjs/backend/sjs/JSPrimitives.scala rename to compiler/src/dotty/tools/backend/backend/sjs/JSPrimitives.scala index 6c3c5715cac9..7bb9e9f81367 100644 --- a/compiler/sjs/backend/sjs/JSPrimitives.scala +++ b/compiler/src/dotty/tools/backend/backend/sjs/JSPrimitives.scala @@ -43,7 +43,7 @@ object JSPrimitives { class JSPrimitives(ctx: Context) extends DottyPrimitives(ctx) { import JSPrimitives._ - import scala.tools.nsc.backend.ScalaPrimitives._ + import scala.tools.nsc.backend.ScalaPrimitivesOps._ private lazy val jsPrimitives: Map[Symbol, Int] = initJSPrimitives(ctx) diff --git a/compiler/sjs/backend/sjs/ScopedVar.scala b/compiler/src/dotty/tools/backend/backend/sjs/ScopedVar.scala similarity index 96% rename from compiler/sjs/backend/sjs/ScopedVar.scala rename to compiler/src/dotty/tools/backend/backend/sjs/ScopedVar.scala index ac2dacd4a7df..f8185697e15d 100644 --- a/compiler/sjs/backend/sjs/ScopedVar.scala +++ b/compiler/src/dotty/tools/backend/backend/sjs/ScopedVar.scala @@ -5,7 +5,7 @@ import language.implicitConversions class ScopedVar[A](init: A) { import ScopedVar.Assignment - private[this] var value = init + private[ScopedVar] var value = init def this()(implicit ev: Null <:< A) = this(ev(null)) diff --git a/compiler/src/dotty/tools/dotc/Compiler.scala b/compiler/src/dotty/tools/dotc/Compiler.scala index e318332826f6..e40e35e914b3 100644 --- a/compiler/src/dotty/tools/dotc/Compiler.scala +++ b/compiler/src/dotty/tools/dotc/Compiler.scala @@ -15,6 +15,7 @@ import util.FreshNameCreator import core.DenotTransformers.DenotTransformer import core.Denotations.SingleDenotation +import dotty.tools.backend.sjs import dotty.tools.backend.jvm.{LabelDefs, GenBCode, CollectSuperCalls} import dotty.tools.dotc.transform.localopt.Simplify @@ -109,6 +110,7 @@ class Compiler { new CollectSuperCalls, // Find classes that are called with super new DropInlined, // Drop Inlined nodes, since backend has no use for them new LabelDefs), // Converts calls to labels to jumps + List(new sjs.GenSJSIR), // Generate .js code (not enabled by default) List(new GenBCode) // Generate JVM bytecode ) diff --git a/compiler/src/dotty/tools/dotc/Run.scala b/compiler/src/dotty/tools/dotc/Run.scala index 3ebd3a408781..1a8d5f6e3551 100644 --- a/compiler/src/dotty/tools/dotc/Run.scala +++ b/compiler/src/dotty/tools/dotc/Run.scala @@ -22,6 +22,7 @@ import printing.XprintMode import scala.annotation.tailrec import dotty.tools.io.VirtualFile import scala.util.control.NonFatal +import dotty.tools.backend.sjs /** A compiler run. Exports various methods to compile source files */ class Run(comp: Compiler, ictx: Context) { @@ -38,7 +39,23 @@ class Run(comp: Compiler, ictx: Context) { */ protected[this] def rootContext(implicit ctx: Context): Context = { ctx.initialize()(ctx) - ctx.setPhasePlan(comp.phases) + + val actualPhases = if (ctx.settings.scalajs.value) { + // Remove phases that Scala.js does not want + comp.phases.mapConserve(_.filter { + case _: transform.FunctionalInterfaces => false + case _ => true + }).filter(_.nonEmpty) + } else { + // Remove Scala.js-related phases + comp.phases.mapConserve(_.filter { + case _: sjs.GenSJSIR => false + case _ => true + }).filter(_.nonEmpty) + } + + ctx.setPhasePlan(actualPhases) + val rootScope = new MutableScope val bootstrap = ctx.fresh .setPeriod(Period(comp.nextRunId, FirstPhaseId)) diff --git a/compiler/sjs/tools/dotc/config/SJSPlatform.scala b/compiler/src/dotty/tools/dotc/config/SJSPlatform.scala similarity index 100% rename from compiler/sjs/tools/dotc/config/SJSPlatform.scala rename to compiler/src/dotty/tools/dotc/config/SJSPlatform.scala diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index f921ce5041a9..d5897196e5f5 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -33,6 +33,7 @@ class ScalaSettings extends Settings.SettingGroup { val color = ChoiceSetting("-color", "mode", "Colored output", List("always", "never"/*, "auto"*/), "always"/* "auto"*/) val target = ChoiceSetting("-target", "target", "Target platform for object files. All JVM 1.5 targets are deprecated.", List("jvm-1.5", "jvm-1.5-fjbg", "jvm-1.5-asm", "jvm-1.6", "jvm-1.7", "jvm-1.8", "msil"), "jvm-1.8") + val scalajs = BooleanSetting("-scalajs", "Compile in Scala.js mode (requires scalajs-library.jar on the classpath).") val unchecked = BooleanSetting("-unchecked", "Enable additional warnings where generated code depends on assumptions.") val uniqid = BooleanSetting("-uniqid", "Uniquely tag all identifiers in debugging output.") val usejavacp = BooleanSetting("-usejavacp", "Utilize the java.class.path in classpath resolution.") diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala index baea88f0ebed..9e17719641dc 100644 --- a/compiler/src/dotty/tools/dotc/core/Contexts.scala +++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala @@ -27,7 +27,7 @@ import reporting.diagnostic.Message import collection.mutable import collection.immutable.BitSet import printing._ -import config.{Settings, ScalaSettings, Platform, JavaPlatform} +import config.{Settings, ScalaSettings, Platform, JavaPlatform, SJSPlatform} import language.implicitConversions import DenotTransformers.DenotTransformer import util.Property.Key @@ -547,7 +547,8 @@ object Contexts { } protected def newPlatform(implicit ctx: Context): Platform = - new JavaPlatform + if (settings.scalajs.value) new SJSPlatform + else new JavaPlatform /** The loader that loads the members of _root_ */ def rootLoader(root: TermSymbol)(implicit ctx: Context): SymbolLoader = platform.rootLoader(root) diff --git a/compiler/src/dotty/tools/dotc/transform/GetClass.scala b/compiler/src/dotty/tools/dotc/transform/GetClass.scala index e83363d3dea0..427dcfc9d049 100644 --- a/compiler/src/dotty/tools/dotc/transform/GetClass.scala +++ b/compiler/src/dotty/tools/dotc/transform/GetClass.scala @@ -20,8 +20,7 @@ class GetClass extends MiniPhase { override def phaseName: String = "getClass" - // getClass transformation should be applied to specialized methods - override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[Erasure], classOf[FunctionalInterfaces]) + override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[Erasure]) override def transformApply(tree: Apply)(implicit ctx: Context): Tree = { import ast.Trees._ diff --git a/project/Build.scala b/project/Build.scala index 0e28abc47f51..d5a2e45a3d9e 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -554,39 +554,48 @@ object Build { "--run-listener=dotty.tools.ContextEscapeDetector" ), + + + // FIXME: Adding the sources of scala-js ir doesn't work anymore because scalajs-ir has a few + // compilation errors when compiled by Dotty: + // - inline is now a keyword + // - methods defined with () need to be called with () + // Until they're fixed, we rely on scalajs-ir compiled by Scala 2: + libraryDependencies += ("org.scala-js" %% "scalajs-ir" % scalaJSVersion).withDottyCompat(), + /* /* Add the sources of scalajs-ir. * To guarantee that dotty can bootstrap without depending on a version * of scalajs-ir built with a different Scala compiler, we add its * sources instead of depending on the binaries. */ - //TODO: disabling until moved to separate project - //ivyConfigurations += config("sourcedeps").hide, - //libraryDependencies += - // "org.scala-js" %% "scalajs-ir" % scalaJSVersion % "sourcedeps", - //sourceGenerators in Compile += Def.task { - // val s = streams.value - // val cacheDir = s.cacheDirectory - // val trgDir = (sourceManaged in Compile).value / "scalajs-ir-src" - - // val report = updateClassifiers.value - // val scalaJSIRSourcesJar = report.select( - // configuration = Set("sourcedeps"), - // module = (_: ModuleID).name.startsWith("scalajs-ir_"), - // artifact = artifactFilter(`type` = "src")).headOption.getOrElse { - // sys.error(s"Could not fetch scalajs-ir sources") - // } - - // FileFunction.cached(cacheDir / s"fetchScalaJSIRSource", - // FilesInfo.lastModified, FilesInfo.exists) { dependencies => - // s.log.info(s"Unpacking scalajs-ir sources to $trgDir...") - // if (trgDir.exists) - // IO.delete(trgDir) - // IO.createDirectory(trgDir) - // IO.unzip(scalaJSIRSourcesJar, trgDir) - // (trgDir ** "*.scala").get.toSet - // } (Set(scalaJSIRSourcesJar)).toSeq - //}.taskValue, - + ivyConfigurations += config("sourcedeps").hide, + transitiveClassifiers := Seq("sources"), + libraryDependencies += + ("org.scala-js" %% "scalajs-ir" % scalaJSVersion % "sourcedeps").withDottyCompat(), + sourceGenerators in Compile += Def.task { + val s = streams.value + val cacheDir = s.cacheDirectory + val trgDir = (sourceManaged in Compile).value / "scalajs-ir-src" + + val report = updateClassifiers.value + val scalaJSIRSourcesJar = report.select( + configuration = Set("sourcedeps"), + module = (_: ModuleID).name.startsWith("scalajs-ir_"), + artifact = artifactFilter(`type` = "src")).headOption.getOrElse { + sys.error(s"Could not fetch scalajs-ir sources") + } + + FileFunction.cached(cacheDir / s"fetchScalaJSIRSource", + FilesInfo.lastModified, FilesInfo.exists) { dependencies => + s.log.info(s"Unpacking scalajs-ir sources to $trgDir...") + if (trgDir.exists) + IO.delete(trgDir) + IO.createDirectory(trgDir) + IO.unzip(scalaJSIRSourcesJar, trgDir) + (trgDir ** "*.scala").get.toSet + } (Set(scalaJSIRSourcesJar)).toSeq + }.taskValue, + */ // Spawn new JVM in run and test fork in run := true, fork in Test := true, @@ -786,21 +795,20 @@ object Build { */ lazy val sjsSandbox = project.in(file("sandbox/scalajs")). enablePlugins(ScalaJSPlugin). - settings(commonNonBootstrappedSettings). + settings(commonBootstrappedSettings). settings( /* Remove the Scala.js compiler plugin for scalac, and enable the * Scala.js back-end of dotty instead. */ libraryDependencies ~= { deps => - deps.filterNot(_.name.startsWith("scalajs-compiler")) + deps.filterNot(_.name.startsWith("scalajs-compiler")).map(_.withDottyCompat()) }, scalacOptions += "-scalajs", // The main class cannot be found automatically due to the empty inc.Analysis mainClass in Compile := Some("hello.world"), - // While developing the Scala.js back-end, it is very useful to see the trees dotc gives us - scalacOptions += "-Xprint:labelDef", + scalaJSUseMainModuleInitializer := true, /* Debug-friendly Scala.js optimizer options. * In particular, typecheck the Scala.js IR found on the classpath. diff --git a/project/plugins.sbt b/project/plugins.sbt index 6b24922932e3..2c6fb2d71be7 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -5,7 +5,7 @@ // Scala IDE project file generator addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.1.0") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.14") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.19") addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.4") diff --git a/sandbox/scalajs/src/hello.scala b/sandbox/scalajs/src/hello.scala index bd4aa8cc5f55..0e04298bda3b 100644 --- a/sandbox/scalajs/src/hello.scala +++ b/sandbox/scalajs/src/hello.scala @@ -7,7 +7,7 @@ trait MyTrait { def foo(y: Int) = x } -object world extends js.JSApp with MyTrait { +object world extends MyTrait { def main(): Unit = { println("hello dotty.js!") println(foo(4))