Skip to content

Commit

Permalink
Avoid costly calls to SettingsManager.getScalaSdk
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszwawrzyk committed Jan 30, 2019
1 parent dc550fd commit cffcbdb
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class IdeaIncrementalBuilder(category: BuilderCategory) extends ModuleLevelBuild

val successfullyCompiled = mutable.Set[File]()

val compilerName = if (modules.exists(CompilerData.isDottyModule)) "dotc" else "scalac"
val compilerName = if (modules.exists(CompilerData.isDottyModule(context, _))) "dotc" else "scalac"

val client = new IdeClientIdea(compilerName, context, modules.map(_.getName).toSeq, outputConsumer,
callback, successfullyCompiled, packageObjectsData)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import org.jetbrains.jps.incremental.scala.ScalaBuilder.projectSettings
import org.jetbrains.jps.incremental.scala.model.IncrementalityType
import org.jetbrains.jps.incremental._
import org.jetbrains.jps.incremental.scala.InitialScalaBuilder._
import org.jetbrains.jps.model.library.JpsLibrary
import org.jetbrains.jps.model.module.JpsModule

import _root_.scala.collection.JavaConverters._
Expand Down Expand Up @@ -46,29 +47,30 @@ object InitialScalaBuilder {
//should be before other scala builders
private def buildCategory = BuilderCategory.SOURCE_INSTRUMENTER

private val scalaModulesKey: Key[Set[JpsModule]] =
Key.create[Set[JpsModule]]("jps.scala.modules")
private val scalaSdkForModulesKey: Key[Map[JpsModule, JpsLibrary]] =
Key.create[Map[JpsModule, JpsLibrary]]("jps.scala.modules")

def hasScala(context: CompileContext, module: JpsModule): Boolean =
Option(context.getUserData(scalaModulesKey)).exists(_.contains(module))
Option(context.getUserData(scalaSdkForModulesKey)).exists(_.contains(module))

def hasScalaModules(context: CompileContext, chunk: ModuleChunk): Boolean =
chunk.getModules.asScala.exists(hasScala(context, _))

def isScalaProject(context: CompileContext): Boolean =
Option(context.getUserData(scalaModulesKey)).exists(_.nonEmpty)
Option(context.getUserData(scalaSdkForModulesKey)).exists(_.nonEmpty)

def scalaSdk(context: CompileContext, module: JpsModule): Option[JpsLibrary] =
Option(context.getUserData(scalaSdkForModulesKey)).flatMap(_.get(module))

private def storeScalaModules(context: CompileContext, scalaModules: Set[JpsModule]): Unit = {
context.putUserData(scalaModulesKey, scalaModules)
private def storeScalaModules(context: CompileContext, scalaSdkForModules: Map[JpsModule, JpsLibrary]): Unit = {
context.putUserData(scalaSdkForModulesKey, scalaSdkForModules)
}

private def collectAndStoreScalaModules(context: CompileContext): Set[JpsModule] = {
private def collectAndStoreScalaModules(context: CompileContext): Map[JpsModule, JpsLibrary] = {
val project = context.getProjectDescriptor.getProject
var result = Set.empty[JpsModule]
project.getModules.forEach { m =>
if (SettingsManager.hasScalaSdk(m)) result += m
}
val result = project.getModules.asScala.flatMap { module =>
Option(SettingsManager.getScalaSdk(module)).map(sdk => module -> sdk)
}.toMap
storeScalaModules(context, result)
result
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,6 @@ public static void setZincProjectSettings(JpsProject project, ZincProjectSetting
project.getContainer().setChild(ZINC_PROJECT_SETTINGS_ROLE, settings);
}

public static boolean hasScalaSdk(JpsModule module) {
return getScalaSdk(module) != null;
}

@Nullable
public static JpsLibrary getScalaSdk(JpsModule module) {
for (JpsLibrary library : libraryDependenciesIn(module)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ abstract class BaseCompilationData extends CompilationDataFactory {
}
}

def scalaOptionsFor(compilerSettings: CompilerSettings, chunk: ModuleChunk): Array[String] = {
val noBootCp = if (CompilerData.needNoBootCp(chunk)) Nil else Seq("-nobootcp", "-javabootclasspath", File.pathSeparator)
def scalaOptionsFor(compilerSettings: CompilerSettings, context: CompileContext, chunk: ModuleChunk): Array[String] = {
val noBootCp = if (CompilerData.needNoBootCp(context, chunk)) Nil else Seq("-nobootcp", "-javabootclasspath", File.pathSeparator)
val scalaOptions = noBootCp ++: compilerSettings.getCompilerOptions
scalaOptions
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ object CompilerConfiguration {
val order = compilerSettings.getCompileOrder

CompilerConfiguration(
scalacOptions = commonOptions ++ scalaOptionsFor(compilerSettings, chunk),
scalacOptions = commonOptions ++ scalaOptionsFor(compilerSettings, context, chunk),
javacOptions = commonOptions ++ javaOptionsFor(context, chunk),
order
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.scala._
import org.jetbrains.jps.incremental.scala.model.{IncrementalityType, LibrarySettings}
import org.jetbrains.jps.model.java.JpsJavaSdkType
import org.jetbrains.jps.model.library.JpsLibrary
import org.jetbrains.jps.model.module.JpsModule

import scala.collection.JavaConverters._
Expand All @@ -26,8 +27,8 @@ object CompilerData extends CompilerDataFactory {
val target = chunk.representativeTarget
val module = target.getModule

val compilerJars = if (SettingsManager.hasScalaSdk(module)) {
compilerJarsIn(module).flatMap { case jars: CompilerJars =>
val compilerJars = if (InitialScalaBuilder.hasScala(context, module)) {
compilerJarsIn(context, module).flatMap { jars: CompilerJars =>
val absentJars = jars.files.filter(!_.exists)
Either.cond(absentJars.isEmpty,
Some(jars),
Expand Down Expand Up @@ -73,65 +74,49 @@ object CompilerData extends CompilerDataFactory {
}
}

def isDottyModule(module: JpsModule): Boolean = {
compilerJarsIn(module) match {
def isDottyModule(context: CompileContext, module: JpsModule): Boolean = {
compilerJarsIn(context, module) match {
case Right(jars) => jars.dotty.isDefined
case _ => false
}
}

def needNoBootCp(chunk: ModuleChunk): Boolean = {
chunk.getModules.asScala.forall(needNoBootCp)
def needNoBootCp(context: CompileContext, chunk: ModuleChunk): Boolean = {
chunk.getModules.asScala.forall(needNoBootCp(context, _))
}

def compilerVersion(module: JpsModule): Option[String] = compilerJarsIn(module) match {
case Right(CompilerJars(_, compiler, _)) => version(compiler)
case Left(error) => Log.error(error)
None
def compilerVersion(context: CompileContext, module: JpsModule): Option[String] = {
compilerJarsIn(context, module) match {
case Right(CompilerJars(_, compiler, _)) => version(compiler)
case Left(error) => Log.error(error)
None
}
}

private def needNoBootCp(module: JpsModule): Boolean = {
private def needNoBootCp(context: CompileContext, module: JpsModule): Boolean = {
def tooOld(version: Option[String]) = version.exists(v => v.startsWith("2.8") || v.startsWith("2.9"))

compilerJarsIn(module) match {
compilerJarsIn(context, module) match {
case Right(jars @ CompilerJars(_, compiler, _)) => jars.dotty.isEmpty && !tooOld(version(compiler))
case _ => false
}
}

def compilerJarsIn(module: JpsModule): Either[String, CompilerJars] = {
val sdk = SettingsManager.getScalaSdk(module)

if (sdk == null) return Left(s"Scala SDK not found in module ${module.getName}")

val files = sdk.getProperties.asInstanceOf[LibrarySettings].getCompilerClasspath

val library = find(files, "scala-library", ".jar") match {
case Left(error) => Left(error + " in Scala compiler classpath in Scala SDK " + sdk.getName)
case right => right
def compilerJarsIn(context: CompileContext, module: JpsModule): Either[String, CompilerJars] = {
def findJar(files: Seq[File], prefix: String, sdk: JpsLibrary): Either[String, File] = {
find(files, prefix, suffix = ".jar").left.map(_ + " in Scala compiler classpath in Scala SDK " + sdk.getName)
}

library.flatMap { libraryJar =>
val compiler = find(files, "scala-compiler", ".jar") match {
case Left(error) => Left(error + " in Scala compiler classpath in Scala SDK " + sdk.getName)
case right => right
}

compiler.flatMap { compilerJar =>
val extraJars = files.filterNot(file => file == libraryJar || file == compilerJar)

val reflectJarError = {
version(compilerJar).flatMap {
case version if version.startsWith("2.10") => // TODO implement a better version comparison
find(extraJars, "scala-reflect", ".jar").left.toOption
.map(_ + " in Scala compiler classpath in Scala SDK " + sdk.getName)
case _ => None
}
}

reflectJarError.toLeft(CompilerJars(libraryJar, compilerJar, extraJars))
}
}
for {
sdk <- InitialScalaBuilder.scalaSdk(context, module).toRight(s"Scala SDK not found in module ${module.getName}")
files = sdk.getProperties.asInstanceOf[LibrarySettings].getCompilerClasspath
libraryJar <- findJar(files, "scala-library", sdk)
compilerJar <- findJar(files, "scala-compiler", sdk)
extraJars = files.filterNot(file => file == libraryJar || file == compilerJar)
_ <- version(compilerJar).filter(_.startsWith("2.10")) // TODO implement a better version comparison)
.map(_ => findJar(extraJars, "scala-reflect", sdk).map(_ => ()))
.getOrElse(Right(()))
} yield CompilerJars(libraryJar, compilerJar, extraJars)
}

def find(files: Seq[File], prefix: String, suffix: String): Either[String, File] = {
Expand Down

0 comments on commit cffcbdb

Please sign in to comment.