Skip to content
Closed
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
5 changes: 5 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,10 @@ lazy val compiler = configureAsSubproject(project)
name := "scala-compiler",
description := "Scala Compiler",
libraryDependencies += asmDep,
// If we're building on Java 11 or later, unlock more functionality implemented in compiler-jdk11,
// otherwise, pull in stubs from compiler-pre-jdk11
unmanagedSourceDirectories in Compile += (baseDirectory in ThisBuild).value / "src" / (if (javaAtLeast11) "compiler-jdk11" else "compiler-pre-jdk11"),

// These are only needed for the POM:
// TODO: jline dependency is only needed for the REPL shell, which should move to its own jar
libraryDependencies ++= Seq(jlineDep),
Expand Down Expand Up @@ -490,6 +494,7 @@ lazy val compiler = configureAsSubproject(project)
)
.dependsOn(library, reflect)


lazy val interactive = configureAsSubproject(project)
.settings(disableDocs)
.settings(disablePublishing)
Expand Down
12 changes: 6 additions & 6 deletions project/GenerateAnyVals.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import scala.language.implicitConversions"""
case _ => Nil
}
if (coercions.isEmpty) Nil
else coercionComment.lines.toList ++ coercions
else coercionComment.linesIterator.toList ++ coercions
}

def isCardinal: Boolean = isIntegerType(this)
Expand Down Expand Up @@ -176,7 +176,7 @@ import scala.language.implicitConversions"""
}
def objectLines = {
val comp = if (isCardinal) cardinalCompanion else floatingCompanion
interpolate(comp + allCompanions + "\n" + nonUnitCompanions).trim.lines.toList ++ (implicitCoercions map interpolate)
interpolate(comp + allCompanions + "\n" + nonUnitCompanions).trim.linesIterator.toList ++ (implicitCoercions map interpolate)
}

/** Makes a set of binary operations based on the given set of ops, args, and resultFn.
Expand Down Expand Up @@ -222,7 +222,7 @@ import scala.language.implicitConversions"""
def representation = repr.map(", a " + _).getOrElse("")

def indent(s: String) = if (s == "") "" else " " + s
def indentN(s: String) = s.lines map indent mkString "\n"
def indentN(s: String) = s.linesIterator map indent mkString "\n"

def boxUnboxInterpolations = Map(
"@boxRunTimeDoc@" -> """
Expand Down Expand Up @@ -446,9 +446,9 @@ def ^(x: Boolean): Boolean

// Provide a more specific return type for Scaladoc
override def getClass(): Class[Boolean] = ???
""".trim.lines.toList
""".trim.linesIterator.toList

def objectLines = interpolate(allCompanions + "\n" + nonUnitCompanions).lines.toList
def objectLines = interpolate(allCompanions + "\n" + nonUnitCompanions).linesIterator.toList
}
object U extends AnyValRep("Unit", None, "void") {
override def classDoc = """
Expand All @@ -462,7 +462,7 @@ override def getClass(): Class[Boolean] = ???
"// Provide a more specific return type for Scaladoc",
"override def getClass(): Class[Unit] = ???"
)
def objectLines = interpolate(allCompanions).lines.toList
def objectLines = interpolate(allCompanions).linesIterator.toList

override def boxUnboxInterpolations = Map(
"@boxRunTimeDoc@" -> "",
Expand Down
6 changes: 4 additions & 2 deletions project/ScalaOptionParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,12 @@ object ScalaOptionParser {
"-Ypatmat-debug", "-Yno-adapted-args", "-Ypos-debug", "-Ypresentation-debug",
"-Ypresentation-strict", "-Ypresentation-verbose", "-Yquasiquote-debug", "-Yrangepos", "-Yreify-copypaste", "-Yreify-debug", "-Yrepl-class-based",
"-Yrepl-sync", "-Yshow-member-pos", "-Yshow-symkinds", "-Yshow-symowners", "-Yshow-syms", "-Yshow-trees", "-Yshow-trees-compact", "-Yshow-trees-stringified", "-Ytyper-debug",
"-Ywarn-dead-code", "-Ywarn-numeric-widen", "-Ywarn-value-discard", "-Ywarn-extra-implicit", "-Ywarn-self-implicit",
"-Ywarn-dead-code", "-Ywarn-numeric-widen", "-Ywarn-value-discard", "-Ywarn-extra-implicit", "-Ywarn-self-implicit", "-Yjpms",
"-deprecation", "-explaintypes", "-feature", "-help", "-no-specialization", "-nobootcp", "-nowarn", "-optimise", "-print", "-unchecked", "-uniqid", "-usejavacp", "-usemanifestcp", "-verbose", "-version")
private def stringSettingNames = List("-Xgenerate-phase-graph", "-Xmain-class", "-Xpluginsdir", "-Xshow-class", "-Xshow-object", "-Xsource-reader", "-Ydump-classes", "-Ygen-asmp",
"-Ypresentation-log", "-Ypresentation-replay", "-Yrepl-outdir", "-d", "-dependencyfile", "-encoding", "-Xscript")
"-Ypresentation-log", "-Ypresentation-replay", "-Yrepl-outdir", "-d", "-dependencyfile", "-encoding", "-Xscript",
"-modulepath", "-patchmodule", "-upgrademodulepath", "-limitmodules", "-addmodules", "-addexports", "-addreads", "--module-path", "--patch-module", "--upgrade-module-path", "--limit-modules", "--add-modules", "--add-exports", "--add-reads"
)
private def pathSettingNames = List("-bootclasspath", "-classpath", "-extdirs", "-javabootclasspath", "-javaextdirs", "-sourcepath", "-toolcp")
private val phases = List("all", "parser", "namer", "packageobjects", "typer", "patmat", "superaccessors", "extmethods", "pickler", "refchecks", "uncurry", "tailcalls", "specialize", "explicitouter", "erasure", "posterasure", "fields", "lambdalift", "constructors", "flatten", "mixin", "cleanup", "delambdafy", "icode", "jvm", "terminal")
private val phaseSettings = List("-Xprint-icode", "-Ystop-after", "-Yskip", "-Yshow", "-Ystop-before", "-Ybrowse", "-Ylog", "-Ycheck", "-Xprint", "-Yvalidate-pos")
Expand Down
14 changes: 8 additions & 6 deletions project/VersionUtil.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ object VersionUtil {
| / __/ __// _ | / / / _ |
| __\ \/ /__/ __ |/ /__/ __ |
| /____/\___/_/ |_/____/_/ | |
| |/ %s""".stripMargin.lines.drop(1).map(s => s"${ "%n" }${ s }").mkString,
| |/ %s""".stripMargin.linesIterator.drop(1).map(s => s"${ "%n" }${ s }").mkString,
resourceGenerators in Compile += generateVersionPropertiesFile.map(file => Seq(file)).taskValue,
generateVersionPropertiesFile := generateVersionPropertiesFileImpl.value
)
Expand Down Expand Up @@ -92,6 +92,8 @@ object VersionUtil {
GitProperties(date, sha)
}

lazy val javaAtLeast11: Boolean = sys.props.get("java.vm.specification.version").flatMap{s => util.Try{s.toInt}.toOption}.exists(_ >= 11)

/** Compute the canonical, Maven and OSGi version number from `baseVersion` and `baseVersionSuffix`.
* Examples of the generated versions:
*
Expand Down Expand Up @@ -121,18 +123,18 @@ object VersionUtil {
} else (b, s)
}



val Patch = """\d+\.\d+\.(\d+)""".r
def cross = base match {
case Patch(p) if p.toInt > 0 => "bin"
case _ => "pre"
}

val jdk = if (javaAtLeast11) "-jdk11" else ""

val (canonicalV, mavenSuffix, osgiV, release) = suffix match {
case "SNAPSHOT" => (s"$base-$date-$sha", s"-$cross-SNAPSHOT", s"$base.v$date-$sha", false)
case "SHA-SNAPSHOT" => (s"$base-$date-$sha", s"-$cross-$sha-SNAPSHOT", s"$base.v$date-$sha", false)
case "SHA" => (s"$base-$sha", s"-$cross-$sha", s"$base.v$date-$sha", false)
case "SNAPSHOT" => (s"$base-$date-$sha", s"-$cross$jdk-SNAPSHOT", s"$base.v$date-$sha", false)
case "SHA-SNAPSHOT" => (s"$base-$date-$sha", s"-$cross$jdk-$sha-SNAPSHOT", s"$base.v$date-$sha", false)
case "SHA" => (s"$base-$sha", s"-$cross$jdk-$sha", s"$base.v$date-$sha", false)
case "" => (s"$base", "", s"$base.v$date-VFINAL-$sha", true)
case _ => (s"$base-$suffix", s"-$suffix", s"$base.v$date-$suffix-$sha", true)
}
Expand Down
71 changes: 71 additions & 0 deletions src/compiler-jdk11/scala/reflect/internal/jpms/ClassOutput.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package scala.reflect.internal.jpms;

import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import java.io.IOException;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Set;
import java.util.function.Supplier;

public abstract class ClassOutput {
public void configure(StandardJavaFileManager fileManager) {
}

public abstract ModuleFinder moduleFinder(StandardJavaFileManager fileManager) throws IOException;

public static class OutputPathClassOutput extends ClassOutput {
private Path path;

public OutputPathClassOutput(Path path) {
this.path = path;
}

@Override
public void configure(StandardJavaFileManager fileManager) {
try {
fileManager.setLocationFromPaths(StandardLocation.CLASS_OUTPUT, Collections.singleton(path));
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}

@Override
public ModuleFinder moduleFinder(StandardJavaFileManager fileManager) throws IOException {
// Consider a module-info.class from the class output directory if there is not module-info.java among the compiled sources.
JavaFileObject module = fileManager.getJavaFileForInput(StandardLocation.CLASS_OUTPUT, "module-info", JavaFileObject.Kind.CLASS);
if (module != null) {
ModuleFinder classOutputModuleFinder = ModuleFinder.of(path);
Set<ModuleReference> classOutputModules = classOutputModuleFinder.findAll();
if (classOutputModules.size() != 1) {
throw new IllegalStateException("Expected one module-info.class in " + path);
}
return classOutputModuleFinder;
} else return null;
}
}

public static class SupplierClassOutput extends ClassOutput {
private Supplier<byte[]> supplier;

public SupplierClassOutput(Supplier<byte[]> supplier) {
this.supplier = supplier;
}

@Override
public ModuleFinder moduleFinder(StandardJavaFileManager fileManager) throws IOException {
byte[] contents = supplier.get();
if (contents == null) return null;
// Annoyingly, I can't find a way to load a module-info.class file with `ModuleFinder.of`
// without writing into to a NIO Path directory.
// TODO JPMS This cleanup up this temp directory.
Path tempDirectory = Files.createTempDirectory("suppler-class-output-");
Files.write(tempDirectory.resolve("module-info.class"), contents);
return ModuleFinder.of(tempDirectory);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package scala.reflect.internal.jpms;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import java.io.IOException;
import java.lang.module.ModuleFinder;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/** Support for <a href="http://openjdk.java.net/jeps/247">JEP 247: Compile for Older Platform Versions - OpenJDK</a>
* and <a href="http://openjdk.java.net/jeps/238">JEP 238: Multi-Release JAR Files</a> */
final class CtSymClassAndModulePath extends ModuleFinderAndFileManager {
private String release;
private FileSystem fileSystem = getCtSymFileSystem();
private StandardJavaFileManager fileManager;
private HashMap<String, Path> includedSysModuleNames = new HashMap<>();

CtSymClassAndModulePath(String release, Consumer<StandardJavaFileManager> optionSetter) {
super();
this.release = release;
init(optionSetter);
}

private void init(Consumer<StandardJavaFileManager> optionSetter) {
JavaCompiler systemJavaCompiler = ToolProvider.getSystemJavaCompiler();
fileManager = systemJavaCompiler.getStandardFileManager(new NullDiagnosticListener<>(), Locale.getDefault(), Charset.defaultCharset());

// Hidden option in the FILEMANAGER group that lets us control which parts of multi-release JARs are served up
fileManager.handleOption("--multi-release", List.of(release).iterator());

try {
int releaseInt = Integer.parseInt(release);
String releaseCode = "" + (releaseInt <= 9 ? release.charAt(0) : (char) ('A' + (releaseInt - 10)));

Path root = fileSystem.getRootDirectories().iterator().next();
List<Path> platformPath = new ArrayList<>();
// JDK9 ct.sym contains a file `N/system-modules` with the list of modules that contribute to the
// JDK7/8 platform class path.
List<Path> versionDirs = Files.list(root).collect(Collectors.toList());
for (Path versionDir : versionDirs) {
String dirName = versionDir.getFileName().toString();
if (!dirName.contains("-") && dirName.contains(releaseCode)) {
Path systemModules = versionDir.resolve("system-modules");

if (Files.isRegularFile(systemModules)) {
Path modules = FileSystems.getFileSystem(URI.create("jrt:/")).getPath("modules");
List<String> lines = Files.readAllLines(systemModules, Charset.forName("UTF-8"));
for (String moduleName : lines) {
Path path = modules.resolve(moduleName);
if (Files.exists(path)) {
includedSysModuleNames.put(moduleName, path);
}
}
} else {
platformPath.add(versionDir);
}
}
}

for (Map.Entry<String, Path> path : includedSysModuleNames.entrySet()) {
fileManager.setLocationForModule(StandardLocation.SYSTEM_MODULES, path.getKey(), List.of(path.getValue()));
}

Path releaseModules = root.resolve("" + releaseCode + "-modules");
if (Files.isDirectory(releaseModules)) {
for (Path path : Files.list(releaseModules).collect(Collectors.toList())) {
String moduleName = path.getFileName().toString();
ArrayList<Path> paths = new ArrayList<>();
paths.add(path);
paths.addAll(platformPath);
includedSysModuleNames.put(moduleName, path);
fileManager.setLocationForModule(StandardLocation.SYSTEM_MODULES, moduleName, paths);
}
} else if (includedSysModuleNames.isEmpty()) {
// Clear the platform classpath...
fileManager.handleOption("--system", List.of("none").iterator());
fileManager.setLocationFromPaths(StandardLocation.PLATFORM_CLASS_PATH, platformPath);
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}

optionSetter.accept(fileManager);
}

@Override
public StandardJavaFileManager fileManager() {
return fileManager;
}

private static FileSystem ctSymFileSystem;

private static FileSystem getCtSymFileSystem() {
if (ctSymFileSystem == null) {
try {
Path ctsym = Paths.get(System.getProperty("java.home"), "lib", "ct.sym");
if (Files.isRegularFile(ctsym)) {
ctSymFileSystem = FileSystems.newFileSystem(ctsym, null);
}
} catch (IOException e) {
throw new RuntimeException(e);
}

}
return ctSymFileSystem;
}

public ModuleFinder moduleFinder() {
return ModuleFinder.compose(
new FilteringSystemModuleFinder(includedSysModuleNames),
locationToFinder(fileManager, StandardLocation.CLASS_OUTPUT),
locationToFinder(fileManager, StandardLocation.MODULE_PATH)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package scala.reflect.internal.jpms;

import java.lang.module.ModuleDescriptor;
import java.util.*;

class ExportRequireAdder {
public Iterable<ModuleDescriptor.Exports> addExports(String moduleName) { return Collections.emptyList(); };
public Iterable<String> addReads(String moduleName) { return Collections.emptyList(); };;

public ModuleDescriptor patch(ModuleDescriptor d) {
ModuleDescriptor.Builder builder = ModuleDescriptor.newModule(d.name(), d.modifiers());

addPatchedExports(d, builder);
if (!d.isAutomatic())
addPatchedRequires(d, builder);
if (!d.isAutomatic() && !d.isOpen())
d.opens().forEach(builder::opens);
d.mainClass().ifPresent(builder::mainClass);
d.provides().forEach(builder::provides);
builder.packages(d.packages());
d.rawVersion().ifPresent(builder::version);
ModuleDescriptor build = builder.build();
if (build.equals(d)) return d;
else return build;
}

protected static Iterable<ModuleDescriptor.Exports> mkExport(String source, String target) {
return ModuleDescriptor.newModule("dummy").exports(Set.of(), source, Collections.singleton(target)).build().exports();
}


private void addPatchedRequires(ModuleDescriptor d, ModuleDescriptor.Builder builder) {
Map<String, ModuleDescriptor.Requires> newRequires = new LinkedHashMap<>();
d.requires().forEach(x -> {newRequires.put(x.name(), x); builder.requires(x);});
addReads(d.name()).forEach(x -> {if (!newRequires.containsKey(x)) builder.requires(x);});
}

private void addPatchedExports(ModuleDescriptor d, ModuleDescriptor.Builder builder) {
Map<String, ModuleDescriptor.Exports> newExportsMap = new LinkedHashMap<>();
for (ModuleDescriptor.Exports x : d.exports()) {
newExportsMap.put(x.source(), x);
}
for (ModuleDescriptor.Exports x : addExports(d.name())) {
if (newExportsMap.containsKey(x.source())) {
ModuleDescriptor.Exports existing = newExportsMap.get(x.source());
HashSet<String> newTargets = new HashSet<>(existing.targets());
newTargets.addAll(x.targets());
ModuleDescriptor.Exports newExports = ModuleDescriptor.newModule("dummy").exports(existing.modifiers(), existing.source(), newTargets).build().exports().iterator().next();
newExportsMap.put(x.source(), newExports);
} else {
newExportsMap.put(x.source(), x);
}
}
for (ModuleDescriptor.Exports exports : newExportsMap.values()) {
builder.exports(exports);
}
}
}
Loading