[JS IR] Generate special region comments at the start and the end of each file block

It allows to fold these blocks and navigate to them in the IDEA.

Also, this commit adds compiler configuration keys to control generating comments with paths for file blocks,
and now generating such comments is enabled only in our tests.
This commit is contained in:
Zalim Bashorov
2019-11-20 22:44:28 +03:00
parent fa76b9cf83
commit c05c07f243
3 changed files with 67 additions and 16 deletions
@@ -31,34 +31,52 @@ class IrModuleToJsTransformer(
) { ) {
val moduleName = backendContext.configuration[CommonConfigurationKeys.MODULE_NAME]!! val moduleName = backendContext.configuration[CommonConfigurationKeys.MODULE_NAME]!!
private val moduleKind = backendContext.configuration[JSConfigurationKeys.MODULE_KIND]!! private val moduleKind = backendContext.configuration[JSConfigurationKeys.MODULE_KIND]!!
private val generateRegionComments = backendContext.configuration.getBoolean(JSConfigurationKeys.GENERATE_REGION_COMMENTS)
private fun generateModuleBody(module: IrModuleFragment, context: JsGenerationContext): List<JsStatement> { private fun generateModuleBody(module: IrModuleFragment, context: JsGenerationContext): List<JsStatement> {
val statements = mutableListOf<JsStatement>().also { val statements = mutableListOf<JsStatement>().also {
if (!generateScriptModule) it += JsStringLiteral("use strict").makeStmt() if (!generateScriptModule) it += JsStringLiteral("use strict").makeStmt()
} }
val preDeclarationBlock = JsBlock() val preDeclarationBlock = JsGlobalBlock()
val postDeclarationBlock = JsBlock() val postDeclarationBlock = JsGlobalBlock()
statements += preDeclarationBlock statements.addWithComment("block: pre-declaration", preDeclarationBlock)
val generateFilePaths = backendContext.configuration.getBoolean(JSConfigurationKeys.GENERATE_COMMENTS_WITH_FILE_PATH)
module.files.forEach { module.files.forEach {
val fileStatements = it.accept(IrFileToJsTransformer(), context).statements val fileStatements = it.accept(IrFileToJsTransformer(), context).statements
if (fileStatements.isNotEmpty()) { if (fileStatements.isNotEmpty()) {
statements.add(JsSingleLineComment("file: ${it.path}")) var startComment = ""
if (generateRegionComments) {
startComment = "region "
}
if (generateRegionComments || generateFilePaths) {
startComment += "file: ${it.path}"
}
if (startComment.isNotEmpty()) {
statements.add(JsSingleLineComment(startComment))
}
statements.addAll(fileStatements) statements.addAll(fileStatements)
statements.endRegion()
} }
} }
// sort member forwarding code // sort member forwarding code
processClassModels(context.staticContext.classModels, preDeclarationBlock, postDeclarationBlock) processClassModels(context.staticContext.classModels, preDeclarationBlock, postDeclarationBlock)
statements += postDeclarationBlock statements.addWithComment("block: post-declaration", postDeclarationBlock.statements)
statements += context.staticContext.initializerBlock statements.addWithComment("block: init", context.staticContext.initializerBlock.statements)
if (backendContext.hasTests) { if (backendContext.hasTests) {
statements.startRegion("block: tests")
statements += JsInvocation(context.getNameForStaticFunction(backendContext.testContainer).makeRef()).makeStmt() statements += JsInvocation(context.getNameForStaticFunction(backendContext.testContainer).makeRef()).makeStmt()
statements.endRegion()
} }
return statements return statements
@@ -108,18 +126,18 @@ class IrModuleToJsTransformer(
if (generateScriptModule) { if (generateScriptModule) {
with(program.globalBlock) { with(program.globalBlock) {
statements += importStatements statements.addWithComment("block: imports", importStatements)
statements += moduleBody statements += moduleBody
statements += exportStatements statements.addWithComment("block: exports", exportStatements)
} }
} else { } else {
with(rootFunction) { with(rootFunction) {
parameters += JsParameter(internalModuleName) parameters += JsParameter(internalModuleName)
parameters += importedJsModules.map { JsParameter(it.internalName) } parameters += importedJsModules.map { JsParameter(it.internalName) }
with(body) { with(body) {
statements += importStatements statements.addWithComment("block: imports", importStatements)
statements += moduleBody statements += moduleBody
statements += exportStatements statements.addWithComment("block: exports", exportStatements)
statements += generateCallToMain(rootContext) statements += generateCallToMain(rootContext)
statements += JsReturn(internalModuleName.makeRef()) statements += JsReturn(internalModuleName.makeRef())
} }
@@ -229,4 +247,30 @@ class IrModuleToJsTransformer(
declarationHandler declarationHandler
) )
} }
private fun MutableList<JsStatement>.startRegion(description: String = "") {
if (generateRegionComments) {
this += JsSingleLineComment("region $description")
}
}
private fun MutableList<JsStatement>.endRegion() {
if (generateRegionComments) {
this += JsSingleLineComment("endregion")
}
}
private fun MutableList<JsStatement>.addWithComment(regionDescription: String = "", block: JsBlock) {
startRegion(regionDescription)
this += block
endRegion()
}
private fun MutableList<JsStatement>.addWithComment(regionDescription: String = "", statements: List<JsStatement>) {
if (statements.isEmpty()) return
startRegion(regionDescription)
this += statements
endRegion()
}
} }
@@ -75,4 +75,10 @@ public class JSConfigurationKeys {
public static final CompilerConfigurationKey<Boolean> DEVELOPER_MODE = public static final CompilerConfigurationKey<Boolean> DEVELOPER_MODE =
CompilerConfigurationKey.create("enables additional checkers"); CompilerConfigurationKey.create("enables additional checkers");
public static final CompilerConfigurationKey<Boolean> GENERATE_COMMENTS_WITH_FILE_PATH =
CompilerConfigurationKey.create("generate comments with file path at the start of each file block");
public static final CompilerConfigurationKey<Boolean> GENERATE_REGION_COMMENTS =
CompilerConfigurationKey.create("generate special comments at the start and the end of each file block, it allows to fold them and navigate to them in the IDEA");
} }
@@ -55,16 +55,15 @@ import org.jetbrains.kotlin.serialization.js.JsModuleDescriptor
import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil
import org.jetbrains.kotlin.serialization.js.ModuleKind import org.jetbrains.kotlin.serialization.js.ModuleKind
import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.*
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestFiles
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.JsMetadataVersion import org.jetbrains.kotlin.utils.JsMetadataVersion
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadata import org.jetbrains.kotlin.utils.KotlinJavascriptMetadata
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils
import java.io.* import java.io.ByteArrayOutputStream
import java.io.Closeable
import java.io.File
import java.io.PrintStream
import java.lang.Boolean.getBoolean import java.lang.Boolean.getBoolean
import java.nio.charset.Charset import java.nio.charset.Charset
import java.util.regex.Pattern import java.util.regex.Pattern
@@ -672,6 +671,8 @@ abstract class BasicBoxTest(
configuration.put(JSConfigurationKeys.TYPED_ARRAYS_ENABLED, typedArraysEnabled) configuration.put(JSConfigurationKeys.TYPED_ARRAYS_ENABLED, typedArraysEnabled)
configuration.put(JSConfigurationKeys.GENERATE_REGION_COMMENTS, true)
return JsConfig(project, configuration, METADATA_CACHE, (JsConfig.JS_STDLIB + JsConfig.JS_KOTLIN_TEST).toSet()) return JsConfig(project, configuration, METADATA_CACHE, (JsConfig.JS_STDLIB + JsConfig.JS_KOTLIN_TEST).toSet())
} }