1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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[Dependency] = dependencies
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.cbtLastModified, 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")
override def compile: Option[Long] = taskCache[Frege]("compile").memoize{
fregeLib.compile(
sourceFiles, compileTarget, compileStatusFile, dependencies, fregeOptions
)
}
override def dependencies = Resolver(mavenCentral).bind(
MavenDependency("org.frege-lang","frege",fregeVersion, Classifier(classifier))
)
}
class FregeLib(
logger: Logger,
cbtLastModified: Long,
mavenCache: File,
classLoaderCache: ClassLoaderCache,
fregeVersion: String,
classifier: Option[String],
fregeDependencies: Seq[Dependency],
fregeTarget: String
)(implicit transientCache: java.util.Map[AnyRef,AnyRef]){
val lib = new Lib(logger)
import lib._
private def Resolver(urls: URL*) = MavenResolver(cbtLastModified, mavenCache, urls: _*)
private lazy val fregeDependency = Resolver(mavenCentral).bindOne(
MavenDependency("org.frege-lang","frege",fregeVersion, Classifier(classifier))
)
def compile(
sourceFiles: Seq[File],
compileTarget: File,
statusFile: File,
dependencies: Seq[Dependency],
fregeOptions: Seq[String]
): Option[Long] = {
val d = Dependencies(dependencies)
val classpath = d.classpath
val cp = classpath.string
if( sourceFiles.isEmpty ){
None
} else {
val start = System.currentTimeMillis
val lastCompiled = statusFile.lastModified
if( d.lastModified > lastCompiled || sourceFiles.exists(_.lastModified > lastCompiled) ){
val _class = "frege.compiler.Main"
val fp = (fregeDependency.classpath.strings ++ fregeDependencies.map(_.classpath.string))
val dualArgs =
Seq(
"-target", fregeTarget,
"-d", compileTarget.toString
) ++ (
if(fp.isEmpty) Nil else Seq("-fp", fp.mkString(":"))
)
val singleArgs = fregeOptions
val code =
try{
System.err.println("Compiling with Frege to " ++ compileTarget.toString)
compileTarget.mkdirs
redirectOutToErr{
lib.runMain(
_class,
dualArgs ++ singleArgs ++ sourceFiles.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")} \\
${if(classpath.strings.isEmpty) "" else (" -fp \\\n" ++ classpath.strings.mkString(":\\\n"))} \\
\\
${sourceFiles.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( start )
} else {
Some( lastCompiled )
}
}
}
}
|