@@ -9,13 +9,6 @@ package org.jetbrains.kotlin.cli.pipeline.jvm
9
9
import com.intellij.openapi.Disposable
10
10
import com.intellij.openapi.vfs.StandardFileSystems
11
11
import com.intellij.openapi.vfs.VirtualFileManager
12
- import com.intellij.util.xmlb.SkipDefaultsSerializationFilter
13
- import com.intellij.util.xmlb.XmlSerializer
14
- import org.jdom.Attribute
15
- import org.jdom.Document
16
- import org.jdom.Element
17
- import org.jdom.output.Format
18
- import org.jdom.output.XMLOutputter
19
12
import org.jetbrains.kotlin.KtPsiSourceFile
20
13
import org.jetbrains.kotlin.KtSourceFile
21
14
import org.jetbrains.kotlin.cli.common.*
@@ -38,6 +31,7 @@ import org.jetbrains.kotlin.cli.pipeline.*
38
31
import org.jetbrains.kotlin.cli.pipeline.jvm.JvmFrontendPipelinePhase.createEnvironmentAndSources
39
32
import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
40
33
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
34
+ import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
41
35
import org.jetbrains.kotlin.config.*
42
36
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
43
37
import org.jetbrains.kotlin.fir.DependencyListForCliModule
@@ -55,6 +49,8 @@ import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
55
49
import org.jetbrains.kotlin.util.PhaseType
56
50
import org.jetbrains.kotlin.utils.fileUtils.descendantRelativeTo
57
51
import java.io.File
52
+ import javax.xml.stream.XMLOutputFactory
53
+ import javax.xml.stream.XMLStreamWriter
58
54
59
55
object JvmFrontendPipelinePhase : PipelinePhase<ConfigurationPipelineArtifact, JvmFrontendPipelineArtifact>(
60
56
name = " JvmFrontendPipelinePhase" ,
@@ -66,63 +62,6 @@ object JvmFrontendPipelinePhase : PipelinePhase<ConfigurationPipelineArtifact, J
66
62
configuration : CompilerConfiguration ,
67
63
arguments : CommonCompilerArguments ,
68
64
) {
69
- val modules = Element (" modules" ).apply {
70
- // Just write out all compiler arguments as is
71
- addContent(
72
- Element (" compilerArguments" ).apply {
73
- val skipDefaultsFilter = SkipDefaultsSerializationFilter ()
74
- val element = XmlSerializer .serialize(arguments, skipDefaultsFilter)
75
- addContent(element)
76
- }
77
- )
78
- for (module in chunk) {
79
- addContent(Element (" module" ).apply {
80
- attributes.add(
81
- Attribute (" timestamp" , System .currentTimeMillis().toString())
82
- )
83
-
84
- attributes.add(
85
- Attribute (" name" , module.getModuleName())
86
- )
87
- attributes.add(
88
- Attribute (" type" , module.getModuleType())
89
- )
90
- attributes.add(
91
- Attribute (" outputDir" , module.getOutputDirectory())
92
- )
93
-
94
- for (friendDir in module.getFriendPaths()) {
95
- addContent(Element (" friendDir" ).setAttribute(" path" , friendDir))
96
- }
97
- for (source in module.getSourceFiles()) {
98
- addContent(Element (" sources" ).setAttribute(" path" , source))
99
- }
100
- for (javaSourceRoots in module.getJavaSourceRoots()) {
101
- addContent(
102
- Element (" javaSourceRoots" ).apply {
103
- setAttribute(" path" , javaSourceRoots.path)
104
- javaSourceRoots.packagePrefix?.let { setAttribute(" packagePrefix" , it) }
105
- }
106
- )
107
- }
108
- for (classpath in configuration.get(CONTENT_ROOTS ).orEmpty()) {
109
- if (classpath is JvmClasspathRoot ) {
110
- addContent(Element (" classpath" ).setAttribute(" path" , classpath.file.absolutePath))
111
- } else if (classpath is JvmModulePathRoot ) {
112
- addContent(Element (" modulepath" ).setAttribute(" path" , classpath.file.absolutePath))
113
- }
114
- }
115
- for (commonSources in module.getCommonSourceFiles()) {
116
- addContent(Element (" commonSources" ).setAttribute(" path" , commonSources))
117
- }
118
- module.modularJdkRoot?.let {
119
- addContent(Element (" modularJdkRoot" ).setAttribute(" path" , module.modularJdkRoot))
120
- }
121
- })
122
- }
123
- }
124
- val document = Document (modules)
125
- val outputter = XMLOutputter (Format .getPrettyFormat())
126
65
val dirFile = File (dir)
127
66
if (! dirFile.exists()) {
128
67
dirFile.mkdirs()
@@ -139,10 +78,78 @@ object JvmFrontendPipelinePhase : PipelinePhase<ConfigurationPipelineArtifact, J
139
78
outputFile = file()
140
79
counter++
141
80
} while (outputFile.exists())
142
- outputFile.bufferedWriter().use {
143
- outputter.output(document, it)
144
- }
145
81
82
+ // Write XML using StAX
83
+ outputFile.bufferedWriter().use { writer ->
84
+ val xmlFactory = XMLOutputFactory .newInstance()
85
+ with (xmlFactory.createXMLStreamWriter(writer)) {
86
+ writeStartDocument(" UTF-8" , " 1.0" )
87
+ val depth = PrettyPrintDepth (0 )
88
+
89
+ // <modules>
90
+ start(" modules" , depth)
91
+
92
+ // compilerArguments
93
+ start(" compilerArguments" , depth)
94
+ for (arg in ArgumentUtils .convertArgumentsToStringList(arguments)) {
95
+ empty(" arg" , depth)
96
+ writeAttribute(" value" , arg)
97
+ }
98
+ end(depth) // compilerArguments
99
+
100
+ // modules
101
+ for (module in chunk) {
102
+ start(" module" , depth)
103
+ writeAttribute(" timestamp" , System .currentTimeMillis().toString())
104
+ writeAttribute(" name" , module.getModuleName())
105
+ writeAttribute(" type" , module.getModuleType())
106
+ writeAttribute(" outputDir" , module.getOutputDirectory())
107
+
108
+ for (friendDir in module.getFriendPaths()) {
109
+ empty(" friendDir" , depth)
110
+ writeAttribute(" path" , friendDir)
111
+ }
112
+ for (source in module.getSourceFiles()) {
113
+ empty(" sources" , depth)
114
+ writeAttribute(" path" , source)
115
+ }
116
+ for (javaSourceRoots in module.getJavaSourceRoots()) {
117
+ start(" javaSourceRoots" , depth)
118
+ writeAttribute(" path" , javaSourceRoots.path)
119
+ javaSourceRoots.packagePrefix?.let { writeAttribute(" packagePrefix" , it) }
120
+ end(depth)
121
+ }
122
+ for (classpath in configuration.get(CONTENT_ROOTS ).orEmpty()) {
123
+ when (classpath) {
124
+ is JvmClasspathRoot -> {
125
+ empty(" classpath" , depth)
126
+ writeAttribute(" path" , classpath.file.absolutePath)
127
+ }
128
+ is JvmModulePathRoot -> {
129
+ empty(" modulepath" , depth)
130
+ writeAttribute(" path" , classpath.file.absolutePath)
131
+ }
132
+ }
133
+ }
134
+ for (commonSources in module.getCommonSourceFiles()) {
135
+ empty(" commonSources" , depth)
136
+ writeAttribute(" path" , commonSources)
137
+ }
138
+ module.modularJdkRoot?.let {
139
+ empty(" modularJdkRoot" , depth)
140
+ writeAttribute(" path" , it)
141
+ }
142
+
143
+ end(depth) // module
144
+ }
145
+
146
+ end(depth) // modules
147
+ writeCharacters(" \n " )
148
+ writeEndDocument()
149
+ flush()
150
+ close()
151
+ }
152
+ }
146
153
}
147
154
148
155
override fun executePhase (input : ConfigurationPipelineArtifact ): JvmFrontendPipelineArtifact ? {
@@ -473,3 +480,29 @@ object JvmFrontendPipelinePhase : PipelinePhase<ConfigurationPipelineArtifact, J
473
480
)
474
481
}
475
482
}
483
+
484
+
485
+ // Pretty-printing helpers for StAX writer
486
+ private data class PrettyPrintDepth (var value : Int )
487
+
488
+ private fun XMLStreamWriter.indent (depth : PrettyPrintDepth ) {
489
+ writeCharacters(" \n " )
490
+ if (depth.value > 0 ) writeCharacters(" " .repeat(depth.value))
491
+ }
492
+
493
+ private fun XMLStreamWriter.start (name : String , depth : PrettyPrintDepth ) {
494
+ indent(depth)
495
+ writeStartElement(name)
496
+ depth.value++
497
+ }
498
+
499
+ private fun XMLStreamWriter.end (depth : PrettyPrintDepth ) {
500
+ depth.value--
501
+ indent(depth)
502
+ writeEndElement()
503
+ }
504
+
505
+ private fun XMLStreamWriter.empty (name : String , depth : PrettyPrintDepth ) {
506
+ indent(depth)
507
+ writeEmptyElement(name)
508
+ }
0 commit comments