Skip to content

Java 9 support #3138

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

Merged
merged 8 commits into from
Aug 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[submodule "scala-backend"]
path = scala-backend
url = https://github.com/lampepfl/scala.git
branch = sharing-backend
branch = fix-java9-itf
[submodule "scala2-library"]
path = scala2-library
url = https://github.com/lampepfl/scala.git
Expand Down
2 changes: 1 addition & 1 deletion bench/src/main/scala/Benchmarks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ object Bench {
val libs = System.getProperty("BENCH_CLASS_PATH")

val opts = new OptionsBuilder()
.jvmArgsPrepend("-Xbootclasspath/a:" + libs + ":", "-Xms2G", "-Xmx2G")
.jvmArgsPrepend(s"-classpath $libs", "-Xms2G", "-Xmx2G")
.mode(Mode.AverageTime)
.timeUnit(TimeUnit.MILLISECONDS)
.warmupIterations(warmup)
Expand Down
34 changes: 3 additions & 31 deletions compiler/src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
}
}

def applyOverloaded(receiver: Tree, method: TermName, args: List[Tree], targs: List[Type], expectedType: Type, isAnnotConstructor: Boolean = false)(implicit ctx: Context): Tree = {
def applyOverloaded(receiver: Tree, method: TermName, args: List[Tree], targs: List[Type], expectedType: Type)(implicit ctx: Context): Tree = {
val typer = ctx.typer
val proto = new FunProtoTyped(args, expectedType)(typer)
val denot = receiver.tpe.member(method)
Expand All @@ -998,7 +998,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
assert(alternatives.size == 1,
i"${if (alternatives.isEmpty) "no" else "multiple"} overloads available for " +
i"$method on ${receiver.tpe.widenDealiasKeepAnnots} with targs: $targs%, %; args: $args%, % of types ${args.tpes}%, %; expectedType: $expectedType." +
i" isAnnotConstructor = $isAnnotConstructor.\n" +
i"all alternatives: ${allAlts.map(_.symbol.showDcl).mkString(", ")}\n" +
i"matching alternatives: ${alternatives.map(_.symbol.showDcl).mkString(", ")}.") // this is parsed from bytecode tree. there's nothing user can do about it
alternatives.head
Expand All @@ -1008,35 +1007,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
.select(TermRef(receiver.tpe, selected.termSymbol.asTerm))
.appliedToTypes(targs)

def adaptLastArg(lastParam: Tree, expectedType: Type) = {
if (isAnnotConstructor && !(lastParam.tpe <:< expectedType)) {
val defn = ctx.definitions
val prefix = args.take(selected.widen.paramInfoss.head.size - 1)
expectedType match {
case defn.ArrayOf(el) =>
lastParam.tpe match {
case defn.ArrayOf(el2) if el2 <:< el =>
// we have a JavaSeqLiteral with a more precise type
// we cannot construct a tree as JavaSeqLiteral inferred to precise type
// if we add typed than it would be both type-correct and
// will pass Ycheck
prefix ::: List(tpd.Typed(lastParam, TypeTree(defn.ArrayOf(el))))
case _ =>
???
}
case _ => args
}
} else args
}

val callArgs: List[Tree] = if (args.isEmpty) Nil else {
val expectedType = selected.widen.paramInfoss.head.last
val lastParam = args.last
adaptLastArg(lastParam, expectedType)
}

val apply = untpd.Apply(fun, callArgs)
new typer.ApplyToTyped(apply, fun, selected, callArgs, expectedType).result.asInstanceOf[Tree] // needed to handle varargs
val apply = untpd.Apply(fun, args)
new typer.ApplyToTyped(apply, fun, selected, args, expectedType).result.asInstanceOf[Tree] // needed to handle varargs
}

@tailrec
Expand Down
3 changes: 0 additions & 3 deletions compiler/src/dotty/tools/dotc/config/CompilerCommand.scala
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,6 @@ object CompilerCommand {
else if (settings.version.value) {
ctx.echo(versionMsg)
Nil
} else if (!Properties.isJavaAtLeast("1.8")) {
ctx.error("Dotty requires Java 8 to run")
Nil
}
else if (shouldStopWithInfo) {
ctx.echo(infoMessage)
Expand Down
17 changes: 9 additions & 8 deletions compiler/src/dotty/tools/dotc/config/PathResolver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package config
import java.net.{ URL, MalformedURLException }
import WrappedProperties.AccessControl
import io.{ ClassPath, File, Directory, Path, AbstractFile }
import classpath.{AggregateClassPath, ClassPathFactory }
import classpath.{AggregateClassPath, ClassPathFactory, JrtClassPath }
import ClassPath.{ JavaContext, join, split }
import PartialFunction.condOpt
import scala.language.postfixOps
Expand Down Expand Up @@ -225,13 +225,14 @@ class PathResolver(implicit ctx: Context) {
// priority class path takes precedence
def basis = List[Traversable[ClassPath]](
classesInExpandedPath(priorityClassPath), // 0. The priority class path (for testing).
classesInPath(javaBootClassPath), // 1. The Java bootstrap class path.
contentsOfDirsInPath(javaExtDirs), // 2. The Java extension class path.
classesInExpandedPath(javaUserClassPath), // 3. The Java application class path.
classesInPath(scalaBootClassPath), // 4. The Scala boot class path.
contentsOfDirsInPath(scalaExtDirs), // 5. The Scala extension class path.
classesInExpandedPath(userClassPath), // 6. The Scala application class path.
sourcesInPath(sourcePath) // 7. The Scala source path.
JrtClassPath.apply(), // 1. The Java 9 classpath (backed by the jrt:/ virtual system, if available)
classesInPath(javaBootClassPath), // 2. The Java bootstrap class path.
contentsOfDirsInPath(javaExtDirs), // 3. The Java extension class path.
classesInExpandedPath(javaUserClassPath), // 4. The Java application class path.
classesInPath(scalaBootClassPath), // 5. The Scala boot class path.
contentsOfDirsInPath(scalaExtDirs), // 6. The Scala extension class path.
classesInExpandedPath(userClassPath), // 7. The Scala application class path.
sourcesInPath(sourcePath) // 8. The Scala source path.
)

lazy val containers = basis.flatten.distinct
Expand Down
15 changes: 0 additions & 15 deletions compiler/src/dotty/tools/dotc/config/Properties.scala
Original file line number Diff line number Diff line change
Expand Up @@ -131,19 +131,4 @@ trait PropertiesTrait {
def versionMsg = "Scala %s %s -- %s".format(propCategory, versionString, copyrightString)
def scalaCmd = if (isWin) "dotr.bat" else "dotr"
def scalacCmd = if (isWin) "dotc.bat" else "dotc"

/** Can the java version be determined to be at least as high as the argument?
* Hard to properly future proof this but at the rate 1.7 is going we can leave
* the issue for our cyborg grandchildren to solve.
*/
def isJavaAtLeast(version: String) = {
val okVersions = version match {
case "1.5" => List("1.5", "1.6", "1.7", "1.8")
case "1.6" => List("1.6", "1.7", "1.8")
case "1.7" => List("1.7", "1.8")
case "1.8" => List("1.8")
case _ => Nil
}
okVersions exists (javaVersion startsWith _)
}
}
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/config/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ object Settings {
case (BooleanTag, _) =>
update(true, args)
case (OptionTag, _) =>
update(Some(propertyClass.get.newInstance), args)
update(Some(propertyClass.get.getConstructor().newInstance()), args)
case (ListTag, _) =>
if (argRest.isEmpty) missingArg
else update((argRest split ",").toList, args)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/Annotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ object Annotations {

private def resolveConstructor(atp: Type, args:List[Tree])(implicit ctx: Context): Tree = {
val targs = atp.argTypes
tpd.applyOverloaded(New(atp.typeConstructor), nme.CONSTRUCTOR, args, targs, atp, isAnnotConstructor = true)
tpd.applyOverloaded(New(atp.typeConstructor), nme.CONSTRUCTOR, args, targs, atp)
}

def applyResolve(atp: Type, args: List[Tree])(implicit ctx: Context): Annotation = {
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/plugins/Plugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ object Plugin {
/** Instantiate a plugin class, given the class and
* the compiler it is to be used in.
*/
def instantiate(clazz: AnyClass): Plugin = clazz.newInstance.asInstanceOf[Plugin]
def instantiate(clazz: AnyClass): Plugin = clazz.getConstructor().newInstance().asInstanceOf[Plugin]
}

class PluginLoadException(val path: String, message: String, cause: Exception) extends Exception(message, cause) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/quoted/QuoteDriver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class QuoteDriver extends Driver {

val clazz = classLoader.loadClass(driver.outputClassName.toString)
val method = clazz.getMethod("apply")
val instance = clazz.newInstance()
val instance = clazz.getConstructor().newInstance()

method.invoke(instance).asInstanceOf[T]
}
Expand Down
9 changes: 8 additions & 1 deletion compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,14 @@ class ExtractDependencies extends Phase {
// We can recover the fully qualified name of a classfile from
// its path
val classSegments = pf.givenPath.segments.takeRight(packages + 1)
binaryDependency(pf.file, binaryClassName(classSegments))
// FIXME: pf.file is null for classfiles coming from the modulepath
// (handled by JrtClassPath) because they cannot be represented as
// java.io.File, since the `binaryDependency` callback must take a
// java.io.File, this means that we cannot record dependencies coming
// from the modulepath. For now this isn't a big deal since we only
// support having the standard Java library on the modulepath.
if (pf.file != null)
binaryDependency(pf.file, binaryClassName(classSegments))

case _ =>
ctx.warning(s"sbt-deps: Ignoring dependency $depFile of class ${depFile.getClass}}")
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/transform/Splicer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ object Splicer {
} else {
// nested object in an object
val clazz = loadClass(sym.fullNameSeparated(FlatName))
(clazz, clazz.newInstance().asInstanceOf[Object])
(clazz, clazz.getConstructor().newInstance().asInstanceOf[Object])
}
}

Expand Down
61 changes: 0 additions & 61 deletions compiler/test/dotty/Jars.scala

This file was deleted.

34 changes: 23 additions & 11 deletions compiler/test/dotty/Properties.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,30 @@ object Properties {
*/
val testsSafeMode: Boolean = sys.props.isDefinedAt("dotty.tests.safemode")

/** Dotty compiler path provided through define */
def dottyCompiler: String = sys.props("dotty.tests.classes.compiler")
/** dotty-interfaces jar */
def dottyInterfaces: String = sys.props("dotty.tests.classes.dottyInterfaces")

/** Dotty classpath extras provided through define */
def dottyExtras: List[String] =
Option(sys.props("dotty.tests.extraclasspath"))
.map(_.split(":").toList)
.getOrElse(Nil)
/** dotty-library jar */
def dottyLibrary: String = sys.props("dotty.tests.classes.dottyLibrary")

/** Dotty interfaces path provided through define */
def dottyInterfaces: String = sys.props("dotty.tests.classes.interfaces")
/** dotty-compiler jar */
def dottyCompiler: String = sys.props("dotty.tests.classes.dottyCompiler")

/** Dotty library path provided through define */
def dottyLib: String = sys.props("dotty.tests.classes.library")
/** compiler-interface jar */
def compilerInterface: String = sys.props("dotty.tests.classes.compilerInterface")

/** scala-library jar */
def scalaLibrary: String = sys.props("dotty.tests.classes.scalaLibrary")

/** scala-asm jar */
def scalaAsm: String = sys.props("dotty.tests.classes.scalaAsm")

/** scala-xml jar */
def scalaXml: String = sys.props("dotty.tests.classes.scalaXml")

/** jline-terminal jar */
def jlineTerminal: String = sys.props("dotty.tests.classes.jlineTerminal")

/** jline-reader jar */
def jlineReader: String = sys.props("dotty.tests.classes.jlineReader")
}
4 changes: 3 additions & 1 deletion compiler/test/dotty/tools/DottyTest.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package dotty
package tools

import vulpix.TestConfiguration

import dotc.core._
import dotc.core.Comments.{ContextDoc, ContextDocstrings}
import dotc.core.Contexts._
Expand Down Expand Up @@ -39,7 +41,7 @@ trait DottyTest extends ContextEscapeDetection {

protected def initializeCtx(fc: FreshContext): Unit = {
fc.setSetting(fc.settings.encoding, "UTF8")
fc.setSetting(fc.settings.classpath, Jars.dottyLib)
fc.setSetting(fc.settings.classpath, TestConfiguration.basicClasspath)
fc.setProperty(ContextDoc, new ContextDocstrings)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package dotty
package tools
package backend.jvm

import vulpix.TestConfiguration

import dotc.core.Contexts.{Context, ContextBase}
import dotc.core.Comments.{ContextDoc, ContextDocstrings}
import dotc.core.Phases.Phase
Expand Down Expand Up @@ -44,7 +46,7 @@ trait DottyBytecodeTest {
def initCtx = {
val ctx0 = (new ContextBase).initialCtx.fresh
val outputDir = new VirtualDirectory("<DottyBytecodeTest output>")
ctx0.setSetting(ctx0.settings.classpath, Jars.dottyLib)
ctx0.setSetting(ctx0.settings.classpath, TestConfiguration.basicClasspath)
ctx0.setProperty(ContextDoc, new ContextDocstrings)
ctx0.setSetting(ctx0.settings.outputDir, outputDir)
}
Expand Down
Loading