forked from VirtusLab/scala-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
JavaPreprocessor.scala
121 lines (116 loc) · 4.29 KB
/
JavaPreprocessor.scala
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
package scala.build.preprocessing
import coursier.cache.ArchiveCache
import coursier.util.Task
import java.nio.charset.StandardCharsets
import scala.build.EitherCps.{either, value}
import scala.build.Logger
import scala.build.errors.BuildException
import scala.build.input.{Inputs, JavaFile, ScalaCliInvokeData, SingleElement, VirtualJavaFile}
import scala.build.internal.JavaParserProxyMaker
import scala.build.options.{
BuildOptions,
BuildRequirements,
SuppressWarningOptions,
WithBuildRequirements
}
import scala.build.preprocessing.directives.PreprocessedDirectives
/** Java source preprocessor.
*
* Doesn't modify Java sources. This only extracts using directives from them, and for unnamed
* sources (like stdin), tries to infer a class name from the sources themselves.
*
* @param archiveCache
* when using a java-class-name external binary to infer a class name (see [[JavaParserProxy]]),
* a cache to download that binary with
* @param javaClassNameVersionOpt
* when using a java-class-name external binary to infer a class name (see [[JavaParserProxy]]),
* this forces the java-class-name version to download
*/
final case class JavaPreprocessor(
archiveCache: ArchiveCache[Task],
javaClassNameVersionOpt: Option[String],
javaCommand: () => String
) extends Preprocessor {
def preprocess(
input: SingleElement,
logger: Logger,
maybeRecoverOnError: BuildException => Option[BuildException] = e => Some(e),
allowRestrictedFeatures: Boolean,
suppressWarningOptions: SuppressWarningOptions
)(using ScalaCliInvokeData): Option[Either[BuildException, Seq[PreprocessedSource]]] =
input match {
case j: JavaFile => Some(either {
val content: String = value(PreprocessingUtil.maybeRead(j.path))
val scopePath = ScopePath.fromPath(j.path)
val preprocessedDirectives: PreprocessedDirectives = value {
DirectivesPreprocessor.preprocess(
content,
Right(j.path),
scopePath,
logger,
allowRestrictedFeatures,
suppressWarningOptions,
maybeRecoverOnError
)
}
Seq(PreprocessedSource.OnDisk(
path = j.path,
options = Some(preprocessedDirectives.globalUsings),
optionsWithTargetRequirements = preprocessedDirectives.usingsWithReqs,
requirements = Some(BuildRequirements()),
scopedRequirements = Nil,
mainClassOpt = None,
directivesPositions = preprocessedDirectives.directivesPositions
))
})
case v: VirtualJavaFile =>
val res = either {
val relPath =
if (v.isStdin || v.isSnippet) {
val classNameOpt = value {
(new JavaParserProxyMaker)
.get(
archiveCache,
javaClassNameVersionOpt,
logger,
() => javaCommand()
)
.className(v.content)
}
val fileName = classNameOpt
.map(_ + ".java")
.getOrElse(v.generatedSourceFileName)
os.sub / fileName
}
else v.subPath
val content = new String(v.content, StandardCharsets.UTF_8)
val preprocessedDirectives: PreprocessedDirectives = value {
DirectivesPreprocessor.preprocess(
content,
Left(relPath.toString),
v.scopePath,
logger,
allowRestrictedFeatures,
suppressWarningOptions,
maybeRecoverOnError
)
}
val s = PreprocessedSource.InMemory(
originalPath = Left(v.source),
relPath = relPath,
code = content,
ignoreLen = 0,
options = Some(preprocessedDirectives.globalUsings),
optionsWithTargetRequirements = preprocessedDirectives.usingsWithReqs,
requirements = Some(BuildRequirements()),
scopedRequirements = Nil,
mainClassOpt = None,
scopePath = v.scopePath,
directivesPositions = preprocessedDirectives.directivesPositions
)
Seq(s)
}
Some(res)
case _ => None
}
}