diff options
author | Jan Christopher Vogt <oss.nsp@cvogt.org> | 2016-12-24 05:32:15 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-24 05:32:15 +0100 |
commit | e2cb8726735ba306ade3befefae3b87549b52c9f (patch) | |
tree | 940579734bb7c858a6a00e39ff441f7db280c642 /stage2/plugins | |
parent | 9de445f2b8c5b6c6a8cb81f2bc84d9ebabdda200 (diff) | |
parent | 0d42c10b3fa4dd4bef40528d5a52fbc6cf77119a (diff) | |
download | cbt-e2cb8726735ba306ade3befefae3b87549b52c9f.tar.gz cbt-e2cb8726735ba306ade3befefae3b87549b52c9f.tar.bz2 cbt-e2cb8726735ba306ade3befefae3b87549b52c9f.zip |
Merge pull request #330 from mchav/frege-support
Frege support.
Diffstat (limited to 'stage2/plugins')
-rw-r--r-- | stage2/plugins/Frege.scala | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/stage2/plugins/Frege.scala b/stage2/plugins/Frege.scala new file mode 100644 index 0000000..88e1f59 --- /dev/null +++ b/stage2/plugins/Frege.scala @@ -0,0 +1,136 @@ +package cbt +import java.io.File +import java.net.URL +import java.nio.file.Files +import java.nio.file.attribute.FileTime + +trait Frege extends BaseBuild{ + def fregeVersion: String = "3.24.100.1" + def classifier: Option[String] = Some("jdk8") + def fregeTarget: String = "1.8" + def enableMakeMode = true + def enableOptimisation = true + def fregeDependencies: Seq[String] = dependencies.map{ _.classpath.string} + def inline = true + + private def fregeOptions: Seq[String] = { + val opts : Seq[(String, Boolean)] = Seq(("-make", enableMakeMode), ("-O", enableOptimisation), ("-inline", inline) ) + opts.filter(_._2).map(_._1) + } + override def scalaTarget: File = target ++ s"/frege-$fregeVersion" + + private lazy val fregeLib = new FregeLib( + logger, context.cbtHasChanged, context.paths.mavenCache, + context.classLoaderCache, fregeVersion = fregeVersion, classifier = classifier, + fregeDependencies = fregeDependencies, fregeTarget = fregeTarget + ) + + override def sourceFileFilter(file: File): Boolean = file.toString.endsWith(".fr") || file.toString.endsWith(".java") + + private object compileCache extends Cache[Option[File]] + override def compile: Option[File] = compileCache{ + fregeLib.compile( + needsUpdate || context.parentBuild.map(_.needsUpdate).getOrElse(false), + sourceFiles, compileTarget, compileStatusFile, compileClasspath, + fregeOptions + ) + } + + override def dependencies = Resolver(mavenCentral).bind( + MavenDependency("org.frege-lang","frege",fregeVersion, Classifier(classifier)) + ) + +} + +class FregeLib( + logger: Logger, + cbtHasChanged: Boolean, + mavenCache: File, + classLoaderCache: ClassLoaderCache, + fregeVersion: String, + classifier: Option[String], + fregeDependencies: Seq[String], + fregeTarget: String +){ + val lib = new Lib(logger) + import lib._ + + private def Resolver(urls: URL*) = MavenResolver(cbtHasChanged, mavenCache, urls: _*) + private lazy val fregeDependency = Resolver(mavenCentral).bindOne( + MavenDependency("org.frege-lang","frege",fregeVersion, Classifier(classifier)) + ) + + def compile( + needsRecompile: Boolean, + files: Seq[File], + compileTarget: File, + statusFile: File, + classpath: ClassPath, + fregeOptions: Seq[String] + ): Option[File] = { + + if(classpath.files.isEmpty) + throw new Exception("Trying to compile with empty classpath. Source files: " ++ files.toString) + + if( files.isEmpty ){ + None + }else{ + if( needsRecompile ){ + val start = System.currentTimeMillis + + val _class = "frege.compiler.Main" + val dualArgs = + Seq( + "-target", fregeTarget, + "-d", compileTarget.toString, + "-fp", (fregeDependency.classpath.strings ++ fregeDependencies).mkString(":") + ) + val singleArgs = fregeOptions + val code = + try{ + System.err.println("Compiling with Frege to " ++ compileTarget.toString) + compileTarget.mkdirs + redirectOutToErr{ + lib.runMain( + _class, + dualArgs ++ singleArgs ++ files.map(_.toString), + fregeDependency.classLoader(classLoaderCache) + ) + } + } catch { + case e: Exception => + System.err.println(red("Frege crashed. To reproduce run:")) + System.out.println(s""" +java -cp \\ +${fregeDependency.classpath.strings.mkString(":\\\n")} \\ +\\ +${_class} \\ +\\ +${dualArgs.grouped(2).map(_.mkString(" ")).mkString(" \\\n")} \\ +\\ +${singleArgs.mkString(" \\\n")} \\ +\\ +-bootclasspath \\ +${fregeDependency.classpath.strings.mkString(":\\\n")} \\ +-classpath \\ +${classpath.strings.mkString(":\\\n")} \\ +\\ +${files.sorted.mkString(" \\\n")} +""" + ) + ExitCode.Failure + } + + if(code == ExitCode.Success){ + // write version and when last compilation started so we can trigger + // recompile if cbt version changed or newer source files are seen + write(statusFile, "")//cbtVersion.getBytes) + Files.setLastModifiedTime(statusFile.toPath, FileTime.fromMillis(start) ) + } else { + System.exit(code.integer) // FIXME: let's find a better solution for error handling. Maybe a monad after all. + } + } + Some( compileTarget ) + } + } +} |