diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformer.kt index 0e829a03f36..14ad1760fe4 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformer.kt @@ -31,34 +31,52 @@ class IrModuleToJsTransformer( ) { val moduleName = backendContext.configuration[CommonConfigurationKeys.MODULE_NAME]!! 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 { val statements = mutableListOf().also { if (!generateScriptModule) it += JsStringLiteral("use strict").makeStmt() } - val preDeclarationBlock = JsBlock() - val postDeclarationBlock = JsBlock() + val preDeclarationBlock = JsGlobalBlock() + 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 { val fileStatements = it.accept(IrFileToJsTransformer(), context).statements 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.endRegion() } } // sort member forwarding code processClassModels(context.staticContext.classModels, preDeclarationBlock, postDeclarationBlock) - statements += postDeclarationBlock - statements += context.staticContext.initializerBlock + statements.addWithComment("block: post-declaration", postDeclarationBlock.statements) + statements.addWithComment("block: init", context.staticContext.initializerBlock.statements) if (backendContext.hasTests) { + statements.startRegion("block: tests") statements += JsInvocation(context.getNameForStaticFunction(backendContext.testContainer).makeRef()).makeStmt() + statements.endRegion() } return statements @@ -108,18 +126,18 @@ class IrModuleToJsTransformer( if (generateScriptModule) { with(program.globalBlock) { - statements += importStatements + statements.addWithComment("block: imports", importStatements) statements += moduleBody - statements += exportStatements + statements.addWithComment("block: exports", exportStatements) } } else { with(rootFunction) { parameters += JsParameter(internalModuleName) parameters += importedJsModules.map { JsParameter(it.internalName) } with(body) { - statements += importStatements + statements.addWithComment("block: imports", importStatements) statements += moduleBody - statements += exportStatements + statements.addWithComment("block: exports", exportStatements) statements += generateCallToMain(rootContext) statements += JsReturn(internalModuleName.makeRef()) } @@ -229,4 +247,30 @@ class IrModuleToJsTransformer( declarationHandler ) } + + private fun MutableList.startRegion(description: String = "") { + if (generateRegionComments) { + this += JsSingleLineComment("region $description") + } + } + + private fun MutableList.endRegion() { + if (generateRegionComments) { + this += JsSingleLineComment("endregion") + } + } + + private fun MutableList.addWithComment(regionDescription: String = "", block: JsBlock) { + startRegion(regionDescription) + this += block + endRegion() + } + + private fun MutableList.addWithComment(regionDescription: String = "", statements: List) { + if (statements.isEmpty()) return + + startRegion(regionDescription) + this += statements + endRegion() + } } \ No newline at end of file diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java b/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java index 3ce2cf024a1..7924b8cdde8 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java @@ -75,4 +75,10 @@ public class JSConfigurationKeys { public static final CompilerConfigurationKey DEVELOPER_MODE = CompilerConfigurationKey.create("enables additional checkers"); + + public static final CompilerConfigurationKey GENERATE_COMMENTS_WITH_FILE_PATH = + CompilerConfigurationKey.create("generate comments with file path at the start of each file block"); + + public static final CompilerConfigurationKey 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"); } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt index 09888cf3307..c3c484458c3 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt @@ -55,16 +55,15 @@ import org.jetbrains.kotlin.serialization.js.JsModuleDescriptor import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil import org.jetbrains.kotlin.serialization.js.ModuleKind -import org.jetbrains.kotlin.test.InTextDirectivesUtils -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.test.* import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.JsMetadataVersion import org.jetbrains.kotlin.utils.KotlinJavascriptMetadata 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.nio.charset.Charset import java.util.regex.Pattern @@ -672,6 +671,8 @@ abstract class BasicBoxTest( 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()) }