diff --git a/build-common/test/org/jetbrains/kotlin/incremental/testingUtils/BuildLogFinder.kt b/build-common/test/org/jetbrains/kotlin/incremental/testingUtils/BuildLogFinder.kt index e15cda25098..6a40e16c54e 100644 --- a/build-common/test/org/jetbrains/kotlin/incremental/testingUtils/BuildLogFinder.kt +++ b/build-common/test/org/jetbrains/kotlin/incremental/testingUtils/BuildLogFinder.kt @@ -22,7 +22,7 @@ data class BuildLogFinder( private val isDataContainerBuildLogEnabled: Boolean = false, private val isGradleEnabled: Boolean = false, private val isJsEnabled: Boolean = false, - private val isJsIrEnabled: Boolean = false + private val isJsIrEnabled: Boolean = false // TODO rename as it is used for metadata-only test ) { companion object { private const val JS_LOG = "js-build.log" diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt index b0702e8f02d..557a0d0939b 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt @@ -134,4 +134,7 @@ class K2JSCompilerArguments : CommonCompilerArguments() { description = "Paths to friend modules" ) var friendModules: String? by NullableStringFreezableVar(null) + + @Argument(value = "-Xmetadata-only", description = "Generate *.meta.js and *.kjsm files only") + var metadataOnly: Boolean by FreezableVar(false) } diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java index 253b2946ff8..6093b7d35cc 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java @@ -318,9 +318,9 @@ public class K2JSCompiler extends CLICompiler { AnalyzerWithCompilerReport.Companion.reportDiagnostics(translationResult.getDiagnostics(), messageCollector); - if (!(translationResult instanceof TranslationResult.Success)) return ExitCode.COMPILATION_ERROR; + if (translationResult instanceof TranslationResult.Fail) return ExitCode.COMPILATION_ERROR; - TranslationResult.Success successResult = (TranslationResult.Success) translationResult; + TranslationResult.SuccessBase successResult = (TranslationResult.SuccessBase) translationResult; OutputFileCollection outputFiles = successResult.getOutputFiles(outputFile, outputPrefixFile, outputPostfixFile); if (outputFile.isDirectory()) { @@ -435,6 +435,8 @@ public class K2JSCompiler extends CLICompiler { configuration.put(JSConfigurationKeys.FRIEND_PATHS, friendPaths); } + configuration.put(JSConfigurationKeys.METADATA_ONLY, arguments.getMetadataOnly()); + String moduleKindName = arguments.getModuleKind(); ModuleKind moduleKind = moduleKindName != null ? moduleKindMap.get(moduleKindName) : ModuleKind.PLAIN; if (moduleKind == null) { diff --git a/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/AbstractIncrementalJsCompilerRunnerWithMetadataOnlyTest.kt b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/AbstractIncrementalJsCompilerRunnerWithMetadataOnlyTest.kt new file mode 100644 index 00000000000..d3b04577f27 --- /dev/null +++ b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/AbstractIncrementalJsCompilerRunnerWithMetadataOnlyTest.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.incremental + +import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments +import org.jetbrains.kotlin.incremental.testingUtils.BuildLogFinder +import java.io.File + +abstract class AbstractIncrementalJsCompilerRunnerWithMetadataOnlyTest : AbstractIncrementalJsCompilerRunnerTest() { + override fun createCompilerArguments(destinationDir: File, testDir: File): K2JSCompilerArguments = + super.createCompilerArguments(destinationDir, testDir).apply { + metadataOnly = true + } + + override val buildLogFinder: BuildLogFinder + get() = super.buildLogFinder.copy(isJsIrEnabled = true) +} \ No newline at end of file diff --git a/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunnerWithMetadataOnlyTestGenerated.java b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunnerWithMetadataOnlyTestGenerated.java new file mode 100644 index 00000000000..c942643295e --- /dev/null +++ b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunnerWithMetadataOnlyTestGenerated.java @@ -0,0 +1,894 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.incremental; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TargetBackend; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@RunWith(JUnit3RunnerWithInners.class) +public class IncrementalJsCompilerRunnerWithMetadataOnlyTestGenerated extends AbstractIncrementalJsCompilerRunnerWithMetadataOnlyTest { + @TestMetadata("jps-plugin/testData/incremental/pureKotlin") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class PureKotlin extends AbstractIncrementalJsCompilerRunnerWithMetadataOnlyTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + @TestMetadata("accessingFunctionsViaPackagePart") + public void testAccessingFunctionsViaPackagePart() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/accessingFunctionsViaPackagePart/"); + } + + @TestMetadata("accessingPropertiesViaField") + public void testAccessingPropertiesViaField() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/accessingPropertiesViaField/"); + } + + @TestMetadata("addClass") + public void testAddClass() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/addClass/"); + } + + @TestMetadata("addFileWithFunctionOverload") + public void testAddFileWithFunctionOverload() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/addFileWithFunctionOverload/"); + } + + @TestMetadata("addMemberTypeAlias") + public void testAddMemberTypeAlias() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/addMemberTypeAlias/"); + } + + @TestMetadata("addTopLevelTypeAlias") + public void testAddTopLevelTypeAlias() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/addTopLevelTypeAlias/"); + } + + @TestMetadata("allConstants") + public void testAllConstants() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/allConstants/"); + } + + public void testAllFilesPresentInPureKotlin() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/pureKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, false); + } + + @TestMetadata("annotations") + public void testAnnotations() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/annotations/"); + } + + @TestMetadata("anonymousObjectChanged") + public void testAnonymousObjectChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/anonymousObjectChanged/"); + } + + @TestMetadata("changeTypeImplicitlyWithCircularDependency") + public void testChangeTypeImplicitlyWithCircularDependency() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/changeTypeImplicitlyWithCircularDependency/"); + } + + @TestMetadata("changeWithRemovingUsage") + public void testChangeWithRemovingUsage() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/changeWithRemovingUsage/"); + } + + @TestMetadata("classInlineFunctionChanged") + public void testClassInlineFunctionChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/classInlineFunctionChanged/"); + } + + @TestMetadata("classObjectConstantChanged") + public void testClassObjectConstantChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/classObjectConstantChanged/"); + } + + @TestMetadata("classRecreated") + public void testClassRecreated() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/classRecreated/"); + } + + @TestMetadata("classRemoved") + public void testClassRemoved() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/classRemoved/"); + } + + @TestMetadata("classSignatureChanged") + public void testClassSignatureChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/classSignatureChanged/"); + } + + @TestMetadata("classSignatureUnchanged") + public void testClassSignatureUnchanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/classSignatureUnchanged/"); + } + + @TestMetadata("compilationErrorThenFixedOtherPackage") + public void testCompilationErrorThenFixedOtherPackage() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/compilationErrorThenFixedOtherPackage/"); + } + + @TestMetadata("compilationErrorThenFixedSamePackage") + public void testCompilationErrorThenFixedSamePackage() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/compilationErrorThenFixedSamePackage/"); + } + + @TestMetadata("compilationErrorThenFixedWithPhantomPart") + public void testCompilationErrorThenFixedWithPhantomPart() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/compilationErrorThenFixedWithPhantomPart/"); + } + + @TestMetadata("compilationErrorThenFixedWithPhantomPart2") + public void testCompilationErrorThenFixedWithPhantomPart2() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/compilationErrorThenFixedWithPhantomPart2/"); + } + + @TestMetadata("compilationErrorThenFixedWithPhantomPart3") + public void testCompilationErrorThenFixedWithPhantomPart3() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/compilationErrorThenFixedWithPhantomPart3/"); + } + + @TestMetadata("constantRemoved") + public void testConstantRemoved() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/constantRemoved/"); + } + + @TestMetadata("constantValueChanged") + public void testConstantValueChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/constantValueChanged/"); + } + + @TestMetadata("constantsUnchanged") + public void testConstantsUnchanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/constantsUnchanged/"); + } + + @TestMetadata("defaultArgumentInConstructorAdded") + public void testDefaultArgumentInConstructorAdded() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/defaultArgumentInConstructorAdded/"); + } + + @TestMetadata("defaultArgumentInConstructorRemoved") + public void testDefaultArgumentInConstructorRemoved() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/defaultArgumentInConstructorRemoved/"); + } + + @TestMetadata("defaultValueAdded") + public void testDefaultValueAdded() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/defaultValueAdded/"); + } + + @TestMetadata("defaultValueChanged") + public void testDefaultValueChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/defaultValueChanged/"); + } + + @TestMetadata("defaultValueInConstructorChanged") + public void testDefaultValueInConstructorChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/defaultValueInConstructorChanged/"); + } + + @TestMetadata("defaultValueInConstructorRemoved") + public void testDefaultValueInConstructorRemoved() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/defaultValueInConstructorRemoved/"); + } + + @TestMetadata("defaultValueRemoved1") + public void testDefaultValueRemoved1() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/defaultValueRemoved1/"); + } + + @TestMetadata("defaultValueRemoved2") + public void testDefaultValueRemoved2() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/defaultValueRemoved2/"); + } + + @TestMetadata("delegatedPropertyInlineExtensionAccessor") + public void testDelegatedPropertyInlineExtensionAccessor() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/delegatedPropertyInlineExtensionAccessor/"); + } + + @TestMetadata("delegatedPropertyInlineMethodAccessor") + public void testDelegatedPropertyInlineMethodAccessor() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/delegatedPropertyInlineMethodAccessor/"); + } + + @TestMetadata("dependencyClassReferenced") + public void testDependencyClassReferenced() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/dependencyClassReferenced/"); + } + + @TestMetadata("fileWithConstantRemoved") + public void testFileWithConstantRemoved() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/fileWithConstantRemoved/"); + } + + @TestMetadata("fileWithInlineFunctionRemoved") + public void testFileWithInlineFunctionRemoved() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/fileWithInlineFunctionRemoved/"); + } + + @TestMetadata("filesExchangePackages") + public void testFilesExchangePackages() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/filesExchangePackages/"); + } + + @TestMetadata("funRedeclaration") + public void testFunRedeclaration() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/funRedeclaration/"); + } + + @TestMetadata("funVsConstructorOverloadConflict") + public void testFunVsConstructorOverloadConflict() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/funVsConstructorOverloadConflict/"); + } + + @TestMetadata("functionBecameInline") + public void testFunctionBecameInline() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/functionBecameInline/"); + } + + @TestMetadata("functionReferencingClass") + public void testFunctionReferencingClass() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/functionReferencingClass/"); + } + + @TestMetadata("independentClasses") + public void testIndependentClasses() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/independentClasses/"); + } + + @TestMetadata("inlineFunctionBecomesNonInline") + public void testInlineFunctionBecomesNonInline() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/inlineFunctionBecomesNonInline/"); + } + + @TestMetadata("inlineFunctionUsageAdded") + public void testInlineFunctionUsageAdded() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/inlineFunctionUsageAdded/"); + } + + @TestMetadata("inlineFunctionsCircularDependency") + public void testInlineFunctionsCircularDependency() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/inlineFunctionsCircularDependency/"); + } + + @TestMetadata("inlineFunctionsUnchanged") + public void testInlineFunctionsUnchanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/inlineFunctionsUnchanged/"); + } + + @TestMetadata("inlineLinesChanged") + public void testInlineLinesChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/inlineLinesChanged/"); + } + + @TestMetadata("inlineModifiedWithUsage") + public void testInlineModifiedWithUsage() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/inlineModifiedWithUsage/"); + } + + @TestMetadata("inlinePrivateFunctionAdded") + public void testInlinePrivateFunctionAdded() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/inlinePrivateFunctionAdded/"); + } + + @TestMetadata("inlinePropertyInClass") + public void testInlinePropertyInClass() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/inlinePropertyInClass/"); + } + + @TestMetadata("inlinePropertyOnTopLevel") + public void testInlinePropertyOnTopLevel() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/inlinePropertyOnTopLevel/"); + } + + @TestMetadata("inlineSuspendFunctionChanged") + public void testInlineSuspendFunctionChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/inlineSuspendFunctionChanged/"); + } + + @TestMetadata("inlineTwoFunctionsOneChanged") + public void testInlineTwoFunctionsOneChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/inlineTwoFunctionsOneChanged/"); + } + + @TestMetadata("inlineUsedWhereDeclared") + public void testInlineUsedWhereDeclared() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/inlineUsedWhereDeclared/"); + } + + @TestMetadata("internalClassChanged") + public void testInternalClassChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/internalClassChanged/"); + } + + @TestMetadata("internalMemberInClassChanged") + public void testInternalMemberInClassChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/internalMemberInClassChanged/"); + } + + @TestMetadata("internalTypealias") + public void testInternalTypealias() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/internalTypealias/"); + } + + @TestMetadata("internalTypealiasConstructor") + public void testInternalTypealiasConstructor() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/internalTypealiasConstructor/"); + } + + @TestMetadata("internalTypealiasObject") + public void testInternalTypealiasObject() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/internalTypealiasObject/"); + } + + @TestMetadata("localClassChanged") + public void testLocalClassChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/localClassChanged/"); + } + + @TestMetadata("moveClass") + public void testMoveClass() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/moveClass/"); + } + + @TestMetadata("moveFileWithChangingPackage") + public void testMoveFileWithChangingPackage() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/moveFileWithChangingPackage/"); + } + + @TestMetadata("moveFileWithoutChangingPackage") + public void testMoveFileWithoutChangingPackage() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/moveFileWithoutChangingPackage/"); + } + + @TestMetadata("multiplePackagesModified") + public void testMultiplePackagesModified() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/multiplePackagesModified/"); + } + + @TestMetadata("objectConstantChanged") + public void testObjectConstantChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/objectConstantChanged/"); + } + + @TestMetadata("ourClassReferenced") + public void testOurClassReferenced() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/ourClassReferenced/"); + } + + @TestMetadata("overloadInlined") + public void testOverloadInlined() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/overloadInlined/"); + } + + @TestMetadata("packageConstantChanged") + public void testPackageConstantChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/packageConstantChanged/"); + } + + @TestMetadata("packageFileAdded") + public void testPackageFileAdded() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/packageFileAdded/"); + } + + @TestMetadata("packageFileChangedPackage") + public void testPackageFileChangedPackage() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/packageFileChangedPackage/"); + } + + @TestMetadata("packageFileChangedThenOtherRemoved") + public void testPackageFileChangedThenOtherRemoved() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/packageFileChangedThenOtherRemoved/"); + } + + @TestMetadata("packageFileRemoved") + public void testPackageFileRemoved() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/packageFileRemoved/"); + } + + @TestMetadata("packageFilesChangedInTurn") + public void testPackageFilesChangedInTurn() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/packageFilesChangedInTurn/"); + } + + @TestMetadata("packageInlineFunctionAccessingField") + public void testPackageInlineFunctionAccessingField() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/packageInlineFunctionAccessingField/"); + } + + @TestMetadata("packageInlineFunctionFromOurPackage") + public void testPackageInlineFunctionFromOurPackage() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/packageInlineFunctionFromOurPackage/"); + } + + @TestMetadata("packagePrivateOnlyChanged") + public void testPackagePrivateOnlyChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/packagePrivateOnlyChanged/"); + } + + @TestMetadata("packageRecreated") + public void testPackageRecreated() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/packageRecreated/"); + } + + @TestMetadata("packageRecreatedAfterRenaming") + public void testPackageRecreatedAfterRenaming() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/packageRecreatedAfterRenaming/"); + } + + @TestMetadata("packageRemoved") + public void testPackageRemoved() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/packageRemoved/"); + } + + @TestMetadata("privateConstantsChanged") + public void testPrivateConstantsChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/privateConstantsChanged/"); + } + + @TestMetadata("privateMethodAdded") + public void testPrivateMethodAdded() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/privateMethodAdded/"); + } + + @TestMetadata("privateMethodDeleted") + public void testPrivateMethodDeleted() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/privateMethodDeleted/"); + } + + @TestMetadata("privateMethodSignatureChanged") + public void testPrivateMethodSignatureChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/privateMethodSignatureChanged/"); + } + + @TestMetadata("privateSecondaryConstructorAdded") + public void testPrivateSecondaryConstructorAdded() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/privateSecondaryConstructorAdded/"); + } + + @TestMetadata("privateSecondaryConstructorDeleted") + public void testPrivateSecondaryConstructorDeleted() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/privateSecondaryConstructorDeleted/"); + } + + @TestMetadata("privateValAccessorChanged") + public void testPrivateValAccessorChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/privateValAccessorChanged/"); + } + + @TestMetadata("privateValAdded") + public void testPrivateValAdded() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/privateValAdded/"); + } + + @TestMetadata("privateValDeleted") + public void testPrivateValDeleted() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/privateValDeleted/"); + } + + @TestMetadata("privateValSignatureChanged") + public void testPrivateValSignatureChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/privateValSignatureChanged/"); + } + + @TestMetadata("privateVarAdded") + public void testPrivateVarAdded() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/privateVarAdded/"); + } + + @TestMetadata("privateVarDeleted") + public void testPrivateVarDeleted() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/privateVarDeleted/"); + } + + @TestMetadata("privateVarSignatureChanged") + public void testPrivateVarSignatureChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/privateVarSignatureChanged/"); + } + + @TestMetadata("propertyRedeclaration") + public void testPropertyRedeclaration() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/propertyRedeclaration/"); + } + + @TestMetadata("publicPropertyWithPrivateSetter") + public void testPublicPropertyWithPrivateSetter() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/"); + } + + @TestMetadata("removeAndRestoreCompanion") + public void testRemoveAndRestoreCompanion() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/removeAndRestoreCompanion/"); + } + + @TestMetadata("removeAndRestoreCompanionWithImplicitUsages") + public void testRemoveAndRestoreCompanionWithImplicitUsages() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/removeAndRestoreCompanionWithImplicitUsages/"); + } + + @TestMetadata("removeClass") + public void testRemoveClass() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/removeClass/"); + } + + @TestMetadata("removeClassInDefaultPackage") + public void testRemoveClassInDefaultPackage() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/removeClassInDefaultPackage/"); + } + + @TestMetadata("removeFileWithFunctionOverload") + public void testRemoveFileWithFunctionOverload() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/removeFileWithFunctionOverload/"); + } + + @TestMetadata("removeMemberTypeAlias") + public void testRemoveMemberTypeAlias() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/removeMemberTypeAlias/"); + } + + @TestMetadata("removeTopLevelTypeAlias") + public void testRemoveTopLevelTypeAlias() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/removeTopLevelTypeAlias/"); + } + + @TestMetadata("removeUnusedFile") + public void testRemoveUnusedFile() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/removeUnusedFile/"); + } + + @TestMetadata("renameClass") + public void testRenameClass() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/renameClass/"); + } + + @TestMetadata("renameFileWithFunctionOverload") + public void testRenameFileWithFunctionOverload() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/renameFileWithFunctionOverload/"); + } + + @TestMetadata("returnTypeChanged") + public void testReturnTypeChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/returnTypeChanged/"); + } + + @TestMetadata("secondaryConstructorInlined") + public void testSecondaryConstructorInlined() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/secondaryConstructorInlined/"); + } + + @TestMetadata("simpleClassDependency") + public void testSimpleClassDependency() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/simpleClassDependency/"); + } + + @TestMetadata("soleFileChangesPackage") + public void testSoleFileChangesPackage() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/soleFileChangesPackage/"); + } + + @TestMetadata("subpackage") + public void testSubpackage() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/subpackage/"); + } + + @TestMetadata("suspendWithStateMachine") + public void testSuspendWithStateMachine() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/suspendWithStateMachine/"); + } + + @TestMetadata("topLevelFunctionSameSignature") + public void testTopLevelFunctionSameSignature() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/topLevelFunctionSameSignature/"); + } + + @TestMetadata("topLevelMembersInTwoFiles") + public void testTopLevelMembersInTwoFiles() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/topLevelMembersInTwoFiles/"); + } + + @TestMetadata("topLevelPrivateValUsageAdded") + public void testTopLevelPrivateValUsageAdded() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/"); + } + + @TestMetadata("traitClassObjectConstantChanged") + public void testTraitClassObjectConstantChanged() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/traitClassObjectConstantChanged/"); + } + + @TestMetadata("valAddCustomAccessor") + public void testValAddCustomAccessor() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/valAddCustomAccessor/"); + } + + @TestMetadata("valRemoveCustomAccessor") + public void testValRemoveCustomAccessor() throws Exception { + runTest("jps-plugin/testData/incremental/pureKotlin/valRemoveCustomAccessor/"); + } + } + + @TestMetadata("jps-plugin/testData/incremental/classHierarchyAffected") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ClassHierarchyAffected extends AbstractIncrementalJsCompilerRunnerWithMetadataOnlyTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInClassHierarchyAffected() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/classHierarchyAffected"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, false); + } + + @TestMetadata("annotationFlagRemoved") + public void testAnnotationFlagRemoved() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/annotationFlagRemoved/"); + } + + @TestMetadata("annotationListChanged") + public void testAnnotationListChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/annotationListChanged/"); + } + + @TestMetadata("bridgeGenerated") + public void testBridgeGenerated() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/bridgeGenerated/"); + } + + @TestMetadata("classBecameFinal") + public void testClassBecameFinal() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/classBecameFinal/"); + } + + @TestMetadata("classBecameInterface") + public void testClassBecameInterface() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/classBecameInterface/"); + } + + @TestMetadata("classBecamePrivate") + public void testClassBecamePrivate() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/classBecamePrivate/"); + } + + @TestMetadata("classMovedIntoOtherClass") + public void testClassMovedIntoOtherClass() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/classMovedIntoOtherClass/"); + } + + @TestMetadata("classRemoved") + public void testClassRemoved() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/classRemoved/"); + } + + @TestMetadata("classRemovedAndRestored") + public void testClassRemovedAndRestored() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/classRemovedAndRestored/"); + } + + @TestMetadata("companionObjectInheritedMemberChanged") + public void testCompanionObjectInheritedMemberChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/companionObjectInheritedMemberChanged/"); + } + + @TestMetadata("companionObjectMemberChanged") + public void testCompanionObjectMemberChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/companionObjectMemberChanged/"); + } + + @TestMetadata("companionObjectNameChanged") + public void testCompanionObjectNameChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/companionObjectNameChanged/"); + } + + @TestMetadata("companionObjectToSimpleObject") + public void testCompanionObjectToSimpleObject() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/companionObjectToSimpleObject/"); + } + + @TestMetadata("constructorVisibilityChanged") + public void testConstructorVisibilityChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/constructorVisibilityChanged/"); + } + + @TestMetadata("enumEntryAdded") + public void testEnumEntryAdded() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/enumEntryAdded/"); + } + + @TestMetadata("enumEntryRemoved") + public void testEnumEntryRemoved() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/enumEntryRemoved/"); + } + + @TestMetadata("enumMemberChanged") + public void testEnumMemberChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/enumMemberChanged/"); + } + + @TestMetadata("flagsAndMemberInDifferentClassesChanged") + public void testFlagsAndMemberInDifferentClassesChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/flagsAndMemberInDifferentClassesChanged/"); + } + + @TestMetadata("flagsAndMemberInSameClassChanged") + public void testFlagsAndMemberInSameClassChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/flagsAndMemberInSameClassChanged/"); + } + + @TestMetadata("implcitUpcast") + public void testImplcitUpcast() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/implcitUpcast/"); + } + + @TestMetadata("inferredTypeArgumentChanged") + public void testInferredTypeArgumentChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/inferredTypeArgumentChanged/"); + } + + @TestMetadata("inferredTypeChanged") + public void testInferredTypeChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/inferredTypeChanged/"); + } + + @TestMetadata("lambdaParameterAffected") + public void testLambdaParameterAffected() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/lambdaParameterAffected/"); + } + + @TestMetadata("methodAdded") + public void testMethodAdded() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/methodAdded/"); + } + + @TestMetadata("methodAnnotationAdded") + public void testMethodAnnotationAdded() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/methodAnnotationAdded/"); + } + + @TestMetadata("methodNullabilityChanged") + public void testMethodNullabilityChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/methodNullabilityChanged/"); + } + + @TestMetadata("methodParameterWithDefaultValueAdded") + public void testMethodParameterWithDefaultValueAdded() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/methodParameterWithDefaultValueAdded/"); + } + + @TestMetadata("methodRemoved") + public void testMethodRemoved() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/methodRemoved/"); + } + + @TestMetadata("overrideExplicit") + public void testOverrideExplicit() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/overrideExplicit/"); + } + + @TestMetadata("overrideImplicit") + public void testOverrideImplicit() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/overrideImplicit/"); + } + + @TestMetadata("propertyNullabilityChanged") + public void testPropertyNullabilityChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/propertyNullabilityChanged/"); + } + + @TestMetadata("sealedClassImplAdded") + public void testSealedClassImplAdded() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/sealedClassImplAdded/"); + } + + @TestMetadata("sealedClassIndirectImplAdded") + public void testSealedClassIndirectImplAdded() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/sealedClassIndirectImplAdded/"); + } + + @TestMetadata("sealedClassNestedImplAdded") + public void testSealedClassNestedImplAdded() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/sealedClassNestedImplAdded/"); + } + + @TestMetadata("secondaryConstructorAdded") + public void testSecondaryConstructorAdded() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/secondaryConstructorAdded/"); + } + + @TestMetadata("starProjectionUpperBoundChanged") + public void testStarProjectionUpperBoundChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/starProjectionUpperBoundChanged/"); + } + + @TestMetadata("supertypesListChanged") + public void testSupertypesListChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/supertypesListChanged/"); + } + + @TestMetadata("typeParameterListChanged") + public void testTypeParameterListChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/typeParameterListChanged/"); + } + + @TestMetadata("varianceChanged") + public void testVarianceChanged() throws Exception { + runTest("jps-plugin/testData/incremental/classHierarchyAffected/varianceChanged/"); + } + } + + @TestMetadata("jps-plugin/testData/incremental/js") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Js extends AbstractIncrementalJsCompilerRunnerWithMetadataOnlyTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInJs() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/js"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); + } + + @TestMetadata("inlineFunctionLocalDeclarationChanges") + public void testInlineFunctionLocalDeclarationChanges() throws Exception { + runTest("jps-plugin/testData/incremental/js/inlineFunctionLocalDeclarationChanges/"); + } + + @TestMetadata("jps-plugin/testData/incremental/js/friendsModuleDisabled") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class FriendsModuleDisabled extends AbstractIncrementalJsCompilerRunnerWithMetadataOnlyTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInFriendsModuleDisabled() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/js/friendsModuleDisabled"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); + } + + @TestMetadata("internalInlineFunctionIsChanged") + public void testInternalInlineFunctionIsChanged() throws Exception { + runTest("jps-plugin/testData/incremental/js/friendsModuleDisabled/internalInlineFunctionIsChanged/"); + } + + @TestMetadata("jps-plugin/testData/incremental/js/friendsModuleDisabled/internalInlineFunctionIsChanged") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InternalInlineFunctionIsChanged extends AbstractIncrementalJsCompilerRunnerWithMetadataOnlyTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInInternalInlineFunctionIsChanged() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/js/friendsModuleDisabled/internalInlineFunctionIsChanged"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); + } + } + } + + @TestMetadata("jps-plugin/testData/incremental/js/inlineFunctionLocalDeclarationChanges") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InlineFunctionLocalDeclarationChanges extends AbstractIncrementalJsCompilerRunnerWithMetadataOnlyTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInInlineFunctionLocalDeclarationChanges() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/js/inlineFunctionLocalDeclarationChanges"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); + } + } + } +} diff --git a/compiler/testData/cli/js/jsExtraHelp.out b/compiler/testData/cli/js/jsExtraHelp.out index 42708db2f83..879f2d82b11 100644 --- a/compiler/testData/cli/js/jsExtraHelp.out +++ b/compiler/testData/cli/js/jsExtraHelp.out @@ -6,6 +6,7 @@ where advanced options include: -Xir-legacy-gradle-plugin-compatibility Make KLIB generation compatible with legacy gradle plugin -Xir-produce-only={ klib, js } Type of output to produce. Overrides -meta-info argument. + -Xmetadata-only Generate *.meta.js and *.kjsm files only -Xtyped-arrays Translate primitive arrays to JS typed arrays -Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info -Xallow-result-return-type Allow compiling code when `kotlin.Result` is used as a return type diff --git a/compiler/testData/cli/js/moduleWithMetadataOnlyDependency.args b/compiler/testData/cli/js/moduleWithMetadataOnlyDependency.args new file mode 100644 index 00000000000..d468e9ca24b --- /dev/null +++ b/compiler/testData/cli/js/moduleWithMetadataOnlyDependency.args @@ -0,0 +1,11 @@ +$TESTDATA_DIR$/separateModules/sepModule1.kt +-meta-info +-Xmetadata-only +-output +$TEMP_DIR$/m1/m1.js +--- +$TESTDATA_DIR$/separateModules/sepModule2.kt +-libraries +$TEMP_DIR$/m1 +-output +$TEMP_DIR$/m2/m2.js \ No newline at end of file diff --git a/compiler/testData/cli/js/moduleWithMetadataOnlyDependency.out b/compiler/testData/cli/js/moduleWithMetadataOnlyDependency.out new file mode 100644 index 00000000000..d86bac9de59 --- /dev/null +++ b/compiler/testData/cli/js/moduleWithMetadataOnlyDependency.out @@ -0,0 +1 @@ +OK diff --git a/compiler/testData/cli/js/moduleWithMetadataOnlyDependency.test b/compiler/testData/cli/js/moduleWithMetadataOnlyDependency.test new file mode 100644 index 00000000000..cafe8620ea5 --- /dev/null +++ b/compiler/testData/cli/js/moduleWithMetadataOnlyDependency.test @@ -0,0 +1,5 @@ +// EXISTS: m1/m1.meta.js +// ABSENT: m1/m1.js +// EXISTS: m1/m1/m1/m1.kjsm + +// EXISTS: m2/m2.js \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java index d0627e2f4c0..307f0b2f020 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java @@ -769,6 +769,11 @@ public class CliTestGenerated extends AbstractCliTest { runTest("compiler/testData/cli/js/libraryDirNotFound.args"); } + @TestMetadata("moduleWithMetadataOnlyDependency.args") + public void testModuleWithMetadataOnlyDependency() throws Exception { + runTest("compiler/testData/cli/js/moduleWithMetadataOnlyDependency.args"); + } + @TestMetadata("modulesWithSameNames.args") public void testModulesWithSameNames() throws Exception { runTest("compiler/testData/cli/js/modulesWithSameNames.args"); diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 02eb1567219..c64d4120715 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -1162,6 +1162,12 @@ fun main(args: Array) { model("incremental/js", extension = null, excludeParentDirs = true) } + testClass { + model("incremental/pureKotlin", extension = null, recursive = false) + model("incremental/classHierarchyAffected", extension = null, recursive = false) + model("incremental/js", extension = null, excludeParentDirs = true) + } + testClass { model("incremental/js/friendsModuleDisabled", extension = null, recursive = false) } 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 98adbca579f..3354c308701 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 @@ -69,4 +69,7 @@ public class JSConfigurationKeys { public static final CompilerConfigurationKey> FRIEND_PATHS = CompilerConfigurationKey.create("friend module paths"); + + public static final CompilerConfigurationKey METADATA_ONLY = + CompilerConfigurationKey.create("generate .meta.js and .kjsm files only"); } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.kt index d42920af994..7873cbb63d5 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.kt @@ -48,7 +48,7 @@ import org.jetbrains.kotlin.js.backend.ast.JsProgramFragment import org.jetbrains.kotlin.js.backend.ast.JsStatement import org.jetbrains.kotlin.js.coroutine.transformCoroutines import org.jetbrains.kotlin.js.inline.util.collectDefinedNamesInAllScopes -import org.jetbrains.kotlin.js.translate.general.AstGenerationResult +import org.jetbrains.kotlin.js.translate.general.SourceFileTranslationResult import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.BindingContext @@ -101,7 +101,47 @@ class K2JSTranslator @JvmOverloads constructor( ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() - return translate(reporter, files, units, mainCallParameters, actualAnalysisResult, packageMetadata) + if (config.configuration.getBoolean(JSConfigurationKeys.METADATA_ONLY)) { + return translateWithoutCode(files, actualAnalysisResult, packageMetadata) + } else { + return translate(reporter, files, units, mainCallParameters, actualAnalysisResult, packageMetadata) + } + } + + private fun translateWithoutCode( + files: List, + analysisResult: JsAnalysisResult, + packageMetadata: MutableMap + ): TranslationResult { + val bindingTrace = analysisResult.bindingTrace + TopDownAnalyzerFacadeForJS.checkForErrors(files, bindingTrace.bindingContext) + val moduleDescriptor = analysisResult.moduleDescriptor + val diagnostics = bindingTrace.bindingContext.diagnostics + val pathResolver = SourceFilePathResolver.create(config) + val bindingContext = bindingTrace.bindingContext + + checkCanceled() + + updateMetadataMap(bindingTrace.bindingContext, moduleDescriptor, packageMetadata) + trySaveIncrementalData(files, pathResolver, bindingTrace, moduleDescriptor) { sourceFile -> + TranslationData(sourceFile.declarations.map { + BindingUtils.getDescriptorForElement(bindingContext, it) + }) + } + + return if (hasError(diagnostics)) { + TranslationResult.Fail(diagnostics) + } else { + TranslationResult.SuccessNoCode( + config, + files, + diagnostics, + emptyList(), + moduleDescriptor, + bindingTrace.bindingContext, + packageMetadata + ) + } } @Throws(TranslationException::class) @@ -142,7 +182,9 @@ class K2JSTranslator @JvmOverloads constructor( checkCanceled() updateMetadataMap(bindingTrace.bindingContext, moduleDescriptor, packageMetadata) - trySaveIncrementalData(translationResult, pathResolver, bindingTrace, moduleDescriptor) + trySaveIncrementalData(translationResult.translatedSourceFiles.keys, pathResolver, bindingTrace, moduleDescriptor) { sourceFile -> + toTranslationData(translationResult.translatedSourceFiles[sourceFile]!!) + } checkCanceled() // Global phases @@ -177,7 +219,8 @@ class K2JSTranslator @JvmOverloads constructor( bindingContext, moduleDescriptor, config.configuration.languageVersionSettings, - config.configuration.get(CommonConfigurationKeys.METADATA_VERSION) as? JsMetadataVersion ?: JsMetadataVersion.INSTANCE) + config.configuration.get(CommonConfigurationKeys.METADATA_VERSION) as? JsMetadataVersion ?: JsMetadataVersion.INSTANCE + ) for ((packageName, metadata) in additionalMetadata) { incrementalResults?.processPackageMetadata(packageName.asString(), metadata) @@ -207,11 +250,33 @@ class K2JSTranslator @JvmOverloads constructor( ) } + private class TranslationData( + val memberScope: Collection, + val binaryAst: ByteArray? = null, + val inlineData: ByteArray? = null + ) + + private fun JsAstSerializer.toTranslationData(fileTranslationResult: SourceFileTranslationResult): TranslationData { + val fragment = fileTranslationResult.fragment + val output = ByteArrayOutputStream() + serialize(fragment, output) + val binaryAst = output.toByteArray() + + val inlineData = serializeInlineData(fileTranslationResult.inlineFunctionTags) + + return TranslationData( + memberScope = fileTranslationResult.memberScope, + binaryAst = binaryAst, + inlineData = inlineData + ) + } + private fun trySaveIncrementalData( - translationResult: AstGenerationResult, + sourceFiles: Iterable, pathResolver: SourceFilePathResolver, bindingTrace: BindingTrace, - moduleDescriptor: ModuleDescriptor + moduleDescriptor: ModuleDescriptor, + translationData: JsAstSerializer.(KtFile) -> TranslationData ) { // TODO Maybe switch validation on for recompile if (incrementalResults == null && !shouldValidateJsAst) return @@ -224,19 +289,19 @@ class K2JSTranslator @JvmOverloads constructor( } } - for ((sourceUnit, fileTranslationResult) in translationResult.translatedSourceFiles) { - val file = sourceUnit.file - val fragment = fileTranslationResult.fragment - val output = ByteArrayOutputStream() - serializer.serialize(fragment, output) - val binaryAst = output.toByteArray() + for (file in sourceFiles) { + val fileTranslationData = serializer.translationData(file) - val packagePart = serializeScope(bindingTrace.bindingContext, moduleDescriptor, file.packageFqName, fileTranslationResult.memberScope) - - val inlineData = serializeInlineData(fileTranslationResult.inlineFunctionTags) + val packagePart = + serializeScope(bindingTrace.bindingContext, moduleDescriptor, file.packageFqName, fileTranslationData.memberScope) val ioFile = VfsUtilCore.virtualToIoFile(file.virtualFile) - incrementalResults?.processPackagePart(ioFile, packagePart.toByteArray(), binaryAst, inlineData) + incrementalResults?.processPackagePart( + ioFile, + packagePart.toByteArray(), + fileTranslationData.binaryAst ?: ByteArray(0), + fileTranslationData.inlineData ?: ByteArray(0) + ) } val settings = config.configuration.languageVersionSettings diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/facade/TranslationResult.kt b/js/js.translator/src/org/jetbrains/kotlin/js/facade/TranslationResult.kt index f8dfc59990d..268260a1a62 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/facade/TranslationResult.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/facade/TranslationResult.kt @@ -48,62 +48,28 @@ import java.util.* abstract class TranslationResult protected constructor(val diagnostics: Diagnostics) { class Fail(diagnostics: Diagnostics) : TranslationResult(diagnostics) - class Success( - private val config: JsConfig, - private val files: List, - val program: JsProgram, - diagnostics: Diagnostics, - private val importedModules: List, - val moduleDescriptor: ModuleDescriptor, - val bindingContext: BindingContext, - val packageMetadata: Map + abstract class SuccessBase( + protected val config: JsConfig, + protected val files: List, + diagnostics: Diagnostics, + protected val importedModules: List, + val moduleDescriptor: ModuleDescriptor, + val bindingContext: BindingContext, + val packageMetadata: Map ) : TranslationResult(diagnostics) { - @Suppress("unused") // Used in kotlin-web-demo in WebDemoTranslatorFacade - fun getCode(): String { - val output = TextOutputImpl() - getCode(output, sourceLocationConsumer = null) - return output.toString() + + abstract fun getOutputFiles(outputFile: File, outputPrefixFile: File?, outputPostfixFile: File?): OutputFileCollection + + protected val sourceFiles = files.map { + val virtualFile = it.originalFile.virtualFile + + when { + virtualFile == null -> File(it.name) + else -> VfsUtilCore.virtualToIoFile(virtualFile) + } } - fun getOutputFiles(outputFile: File, outputPrefixFile: File?, outputPostfixFile: File?): OutputFileCollection { - val output = TextOutputImpl() - - val sourceMapBuilder = SourceMap3Builder(outputFile, output, config.sourceMapPrefix) - val sourceMapBuilderConsumer = - if (config.configuration.getBoolean(JSConfigurationKeys.SOURCE_MAP)) { - val sourceMapContentEmbedding = config.sourceMapContentEmbedding - val pathResolver = SourceFilePathResolver.create(config) - SourceMapBuilderConsumer( - File("."), - sourceMapBuilder, - pathResolver, - sourceMapContentEmbedding == SourceMapSourceEmbedding.ALWAYS, - sourceMapContentEmbedding != SourceMapSourceEmbedding.NEVER) - } - else { - null - } - - getCode(output, sourceMapBuilderConsumer) - if (sourceMapBuilderConsumer != null) { - sourceMapBuilder.addLink() - } - val code = output.toString() - - val prefix = outputPrefixFile?.readText() ?: "" - val postfix = outputPostfixFile?.readText() ?: "" - val sourceFiles = files.map { - val virtualFile = it.originalFile.virtualFile - - when { - virtualFile == null -> File(it.name) - else -> VfsUtilCore.virtualToIoFile(virtualFile) - } - } - - val jsFile = SimpleOutputFile(sourceFiles, outputFile.name, prefix + code + postfix) - val outputFiles = arrayListOf(jsFile) - + protected fun metadataFiles(outputFile: File): List { if (config.configuration.getBoolean(JSConfigurationKeys.META_INFO)) { val metaFileName = KotlinJavascriptMetadataUtils.replaceSuffix(outputFile.name) val moduleDescription = JsModuleDescriptor( @@ -121,12 +87,74 @@ abstract class TranslationResult protected constructor(val diagnostics: Diagnost val metaFileContent = serializedMetadata.asString() val sourceFilesForMetaFile = ArrayList(sourceFiles) val jsMetaFile = SimpleOutputFile(sourceFilesForMetaFile, metaFileName, metaFileContent) - outputFiles.add(jsMetaFile) - for (serializedPackage in serializedMetadata.serializedPackages()) { - outputFiles.add(kjsmFileForPackage(serializedPackage.fqName, serializedPackage.bytes)) + return listOf(jsMetaFile) + serializedMetadata.serializedPackages().map { serializedPackage -> + kjsmFileForPackage(serializedPackage.fqName, serializedPackage.bytes) } + } else { + return emptyList() } + } + + private fun kjsmFileForPackage(packageFqName: FqName, bytes: ByteArray): SimpleOutputBinaryFile { + val ktFiles = (bindingContext.get(BindingContext.PACKAGE_TO_FILES, packageFqName) ?: emptyList()) + val sourceFiles = ktFiles.map { VfsUtilCore.virtualToIoFile(it.virtualFile) } + val relativePath = config.moduleId + + VfsUtilCore.VFS_SEPARATOR_CHAR + + JsSerializerProtocol.getKjsmFilePath(packageFqName) + return SimpleOutputBinaryFile(sourceFiles, relativePath, bytes) + } + } + + class Success( + config: JsConfig, + files: List, + val program: JsProgram, + diagnostics: Diagnostics, + importedModules: List, + moduleDescriptor: ModuleDescriptor, + bindingContext: BindingContext, + packageMetadata: Map + ) : SuccessBase(config, files, diagnostics, importedModules, moduleDescriptor, bindingContext, packageMetadata) { + @Suppress("unused") // Used in kotlin-web-demo in WebDemoTranslatorFacade + fun getCode(): String { + val output = TextOutputImpl() + getCode(output, sourceLocationConsumer = null) + return output.toString() + } + + override fun getOutputFiles(outputFile: File, outputPrefixFile: File?, outputPostfixFile: File?): OutputFileCollection { + val output = TextOutputImpl() + + val sourceMapBuilder = SourceMap3Builder(outputFile, output, config.sourceMapPrefix) + val sourceMapBuilderConsumer = + if (config.configuration.getBoolean(JSConfigurationKeys.SOURCE_MAP)) { + val sourceMapContentEmbedding = config.sourceMapContentEmbedding + val pathResolver = SourceFilePathResolver.create(config) + SourceMapBuilderConsumer( + File("."), + sourceMapBuilder, + pathResolver, + sourceMapContentEmbedding == SourceMapSourceEmbedding.ALWAYS, + sourceMapContentEmbedding != SourceMapSourceEmbedding.NEVER + ) + } else { + null + } + + getCode(output, sourceMapBuilderConsumer) + if (sourceMapBuilderConsumer != null) { + sourceMapBuilder.addLink() + } + val code = output.toString() + + val prefix = outputPrefixFile?.readText() ?: "" + val postfix = outputPostfixFile?.readText() ?: "" + + val jsFile = SimpleOutputFile(sourceFiles, outputFile.name, prefix + code + postfix) + val outputFiles = arrayListOf(jsFile) + + outputFiles += metadataFiles(outputFile) if (sourceMapBuilderConsumer != null) { sourceMapBuilder.skipLinesAtBeginning(StringUtil.getLineBreakCount(prefix)) @@ -138,17 +166,23 @@ abstract class TranslationResult protected constructor(val diagnostics: Diagnost return SimpleOutputFileCollection(outputFiles) } - private fun kjsmFileForPackage(packageFqName: FqName, bytes: ByteArray): SimpleOutputBinaryFile { - val ktFiles = (bindingContext.get(BindingContext.PACKAGE_TO_FILES, packageFqName) ?: emptyList()) - val sourceFiles = ktFiles.map { VfsUtilCore.virtualToIoFile(it.virtualFile) } - val relativePath = config.moduleId + - VfsUtilCore.VFS_SEPARATOR_CHAR + - JsSerializerProtocol.getKjsmFilePath(packageFqName) - return SimpleOutputBinaryFile(sourceFiles, relativePath, bytes) - } - private fun getCode(output: TextOutput, sourceLocationConsumer: SourceLocationConsumer?) { program.accept(JsToStringGenerationVisitor(output, sourceLocationConsumer ?: NoOpSourceLocationConsumer)) } } -} + + class SuccessNoCode( + config: JsConfig, + files: List, + diagnostics: Diagnostics, + importedModules: List, + moduleDescriptor: ModuleDescriptor, + bindingContext: BindingContext, + packageMetadata: Map + ) : SuccessBase(config, files, diagnostics, importedModules, moduleDescriptor, bindingContext, packageMetadata) { + + override fun getOutputFiles(outputFile: File, outputPrefixFile: File?, outputPostfixFile: File?): OutputFileCollection { + return SimpleOutputFileCollection(metadataFiles(outputFile)) + } + } +} \ No newline at end of file diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/AstGenerationResult.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/AstGenerationResult.kt index b3b2194cb95..cad41610d9e 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/AstGenerationResult.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/AstGenerationResult.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.js.backend.ast.* import org.jetbrains.kotlin.js.config.JsConfig import org.jetbrains.kotlin.js.facade.TranslationUnit import org.jetbrains.kotlin.protobuf.CodedInputStream +import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.serialization.js.ast.JsAstDeserializer import org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf import java.io.ByteArrayInputStream @@ -30,7 +31,7 @@ import java.util.HashSet class AstGenerationResult( val units: Collection, - val translatedSourceFiles: Map, + val translatedSourceFiles: Map, val inlineFunctionTagMap: Map, moduleDescriptor: ModuleDescriptor, config: JsConfig @@ -47,7 +48,7 @@ class AstGenerationResult( fun getTranslationResult(unit: TranslationUnit): FileTranslationResult = when (unit) { - is TranslationUnit.SourceFile -> translatedSourceFiles[unit]!! + is TranslationUnit.SourceFile -> translatedSourceFiles[unit.file]!! is TranslationUnit.BinaryAst -> cache.getOrPut(unit) { // TODO Don't deserialize header twice val inlineData = JsAstProtoBuf.InlineData.parseFrom(CodedInputStream.newInstance(unit.inlineData)) diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java index 49defd1f1d0..bc1959fb21c 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java @@ -324,7 +324,7 @@ public final class Translation { Map inlineFunctionTagMap = new HashMap<>(); - Map translatedSourceFiles = new LinkedHashMap<>(); + Map translatedSourceFiles = new LinkedHashMap<>(); for (TranslationUnit unit : units) { if (unit instanceof TranslationUnit.SourceFile) { @@ -344,7 +344,7 @@ public final class Translation { fragment.setTests(mayBeGenerateTests(context, file, fileMemberScope)); fragment.setMainFunction(maybeGenerateCallToMain(context, config, moduleDescriptor, fileMemberScope, mainCallParameters)); - translatedSourceFiles.put(sourceFileUnit, new SourceFileTranslationResult(fragment, staticContext.getInlineFunctionTags(), fileMemberScope)); + translatedSourceFiles.put(file, new SourceFileTranslationResult(fragment, staticContext.getInlineFunctionTags(), fileMemberScope)); } else if (unit instanceof TranslationUnit.BinaryAst) { byte[] inlineDataArray = ((TranslationUnit.BinaryAst) unit).getInlineData();