JS: fixed support for test source roots (KT-6627)
This commit is contained in:
@@ -25,8 +25,6 @@ import com.intellij.util.Function;
|
|||||||
import com.intellij.util.SmartList;
|
import com.intellij.util.SmartList;
|
||||||
import com.intellij.util.containers.ContainerUtil;
|
import com.intellij.util.containers.ContainerUtil;
|
||||||
import com.intellij.util.containers.HashMap;
|
import com.intellij.util.containers.HashMap;
|
||||||
import kotlin.Unit;
|
|
||||||
import kotlin.jvm.functions.Function1;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.analyzer.AnalysisResult;
|
import org.jetbrains.kotlin.analyzer.AnalysisResult;
|
||||||
@@ -140,11 +138,15 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
|||||||
configuration.put(CommonConfigurationKeys.MODULE_NAME, FileUtil.getNameWithoutExtension(outputFile));
|
configuration.put(CommonConfigurationKeys.MODULE_NAME, FileUtil.getNameWithoutExtension(outputFile));
|
||||||
|
|
||||||
JsConfig config = new LibrarySourcesConfig(project, configuration);
|
JsConfig config = new LibrarySourcesConfig(project, configuration);
|
||||||
if (config.checkLibFilesAndReportErrors(new Function1<String, Unit>() {
|
if (config.checkLibFilesAndReportErrors(new JsConfig.Reporter() {
|
||||||
@Override
|
@Override
|
||||||
public Unit invoke(String message) {
|
public void error(@NotNull String message) {
|
||||||
messageCollector.report(CompilerMessageSeverity.ERROR, message, CompilerMessageLocation.NO_LOCATION);
|
messageCollector.report(CompilerMessageSeverity.ERROR, message, CompilerMessageLocation.NO_LOCATION);
|
||||||
return Unit.INSTANCE;
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warning(@NotNull String message) {
|
||||||
|
messageCollector.report(CompilerMessageSeverity.WARNING, message, CompilerMessageLocation.NO_LOCATION);
|
||||||
}
|
}
|
||||||
})) {
|
})) {
|
||||||
return COMPILATION_ERROR;
|
return COMPILATION_ERROR;
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import org.jetbrains.jps.builders.CompileScopeTestBuilder
|
|||||||
import org.jetbrains.jps.builders.JpsBuildTestCase
|
import org.jetbrains.jps.builders.JpsBuildTestCase
|
||||||
import org.jetbrains.jps.builders.TestProjectBuilderLogger
|
import org.jetbrains.jps.builders.TestProjectBuilderLogger
|
||||||
import org.jetbrains.jps.builders.impl.BuildDataPathsImpl
|
import org.jetbrains.jps.builders.impl.BuildDataPathsImpl
|
||||||
import org.jetbrains.jps.builders.impl.logging.ProjectBuilderLoggerImpl
|
|
||||||
import org.jetbrains.jps.builders.logging.BuildLoggingManager
|
import org.jetbrains.jps.builders.logging.BuildLoggingManager
|
||||||
import org.jetbrains.jps.cmdline.ProjectDescriptor
|
import org.jetbrains.jps.cmdline.ProjectDescriptor
|
||||||
import org.jetbrains.jps.incremental.BuilderRegistry
|
import org.jetbrains.jps.incremental.BuilderRegistry
|
||||||
@@ -50,13 +49,10 @@ import org.jetbrains.jps.model.module.JpsModule
|
|||||||
import org.jetbrains.jps.util.JpsPathUtil
|
import org.jetbrains.jps.util.JpsPathUtil
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
||||||
import org.jetbrains.kotlin.config.KotlinCompilerVersion
|
|
||||||
import org.jetbrains.kotlin.daemon.common.COMPILE_DAEMON_ENABLED_PROPERTY
|
|
||||||
import org.jetbrains.kotlin.incremental.CacheVersion
|
import org.jetbrains.kotlin.incremental.CacheVersion
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
import org.jetbrains.kotlin.incremental.withIC
|
import org.jetbrains.kotlin.incremental.withIC
|
||||||
import org.jetbrains.kotlin.jps.build.KotlinJpsBuildTest.LibraryDependency.*
|
import org.jetbrains.kotlin.jps.build.KotlinJpsBuildTest.LibraryDependency.*
|
||||||
import org.jetbrains.kotlin.load.kotlin.DeserializedDescriptorResolver
|
|
||||||
import org.jetbrains.kotlin.load.kotlin.DeserializedDescriptorResolver.Companion.TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY
|
import org.jetbrains.kotlin.load.kotlin.DeserializedDescriptorResolver.Companion.TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -376,6 +372,26 @@ class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
|||||||
assertEquals(Collections.EMPTY_SET, contentOfOutputDir(PROJECT_NAME))
|
assertEquals(Collections.EMPTY_SET, contentOfOutputDir(PROJECT_NAME))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testKotlinJavaScriptProjectWithTests() {
|
||||||
|
initProject(JS_STDLIB)
|
||||||
|
makeAll().assertSuccessful()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testKotlinJavaScriptProjectWithTestsAndSeparateTestAndSrcModuleDependencies() {
|
||||||
|
initProject(JS_STDLIB)
|
||||||
|
makeAll().assertSuccessful()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testKotlinJavaScriptProjectWithTestsAndTestAndSrcModuleDependency() {
|
||||||
|
initProject(JS_STDLIB)
|
||||||
|
val buildResult = makeAll()
|
||||||
|
buildResult.assertSuccessful()
|
||||||
|
|
||||||
|
val warnings = buildResult.getMessages(BuildMessage.Kind.WARNING)
|
||||||
|
assertEquals("Warning about duplicate module definition: $warnings", 1, warnings.size)
|
||||||
|
assertEquals("Module \"srcAndTests\" is defined in more, than one file", warnings.first().messageText)
|
||||||
|
}
|
||||||
|
|
||||||
fun testExcludeFolderInSourceRoot() {
|
fun testExcludeFolderInSourceRoot() {
|
||||||
doTest()
|
doTest()
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.jps.build
|
|||||||
import com.intellij.util.Consumer
|
import com.intellij.util.Consumer
|
||||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType
|
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType
|
||||||
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
||||||
|
import org.jetbrains.jps.model.java.JavaSourceRootType
|
||||||
import org.jetbrains.jps.model.java.JpsJavaModuleType
|
import org.jetbrains.jps.model.java.JpsJavaModuleType
|
||||||
import org.jetbrains.jps.model.library.JpsOrderRootType
|
import org.jetbrains.jps.model.library.JpsOrderRootType
|
||||||
import org.jetbrains.jps.model.module.JpsModule
|
import org.jetbrains.jps.model.module.JpsModule
|
||||||
@@ -47,12 +48,21 @@ object JpsJsModuleUtils {
|
|||||||
fun getDependencyModulesAndSources(target: ModuleBuildTarget, result: MutableList<String>) {
|
fun getDependencyModulesAndSources(target: ModuleBuildTarget, result: MutableList<String>) {
|
||||||
JpsUtils.getAllDependencies(target).processModules(object : Consumer<JpsModule> {
|
JpsUtils.getAllDependencies(target).processModules(object : Consumer<JpsModule> {
|
||||||
override fun consume(module: JpsModule) {
|
override fun consume(module: JpsModule) {
|
||||||
if (module == target.module || module.moduleType != JpsJavaModuleType.INSTANCE) return
|
if (module.moduleType != JpsJavaModuleType.INSTANCE) return
|
||||||
|
|
||||||
val moduleBuildTarget = ModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION)
|
for (root in module.sourceRoots) {
|
||||||
val outputDir = KotlinBuilderModuleScriptGenerator.getOutputDirSafe(moduleBuildTarget)
|
val isTestSource = root.rootType == JavaSourceRootType.TEST_SOURCE
|
||||||
val metaInfoFile = getOutputMetaFile(outputDir, module.name)
|
|
||||||
result.add(metaInfoFile.absolutePath)
|
if (module == target.module && isTestSource == target.isTests) continue
|
||||||
|
|
||||||
|
if (!isTestSource || target.isTests) {
|
||||||
|
val targetType = if (isTestSource) JavaModuleBuildTargetType.TEST else JavaModuleBuildTargetType.PRODUCTION
|
||||||
|
val moduleBuildTarget = ModuleBuildTarget(module, targetType)
|
||||||
|
val outputDir = KotlinBuilderModuleScriptGenerator.getOutputDirSafe(moduleBuildTarget)
|
||||||
|
val metaInfoFile = getOutputMetaFile(outputDir, module.name)
|
||||||
|
result.add(metaInfoFile.absolutePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/kotlinProject.iml" filepath="$PROJECT_DIR$/kotlinProject.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fun main() {
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun testMain() {
|
||||||
|
main()
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module" module-name="srcOnly" />
|
||||||
|
<orderEntry type="module" module-name="testsOnly" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/srcOnly/srcOnly.iml" filepath="$PROJECT_DIR$/srcOnly/srcOnly.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/kotlinProject.iml" filepath="$PROJECT_DIR$/kotlinProject.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/testsOnly/testsOnly.iml" filepath="$PROJECT_DIR$/testsOnly/testsOnly.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun main() {
|
||||||
|
srcOnly()
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fun srcOnly() {}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
fun testMain() {
|
||||||
|
main()
|
||||||
|
srcOnly()
|
||||||
|
testsOnly()
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fun testsOnly() {}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module" module-name="srcAndTests" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/srcAndTests/srcAndTests.iml" filepath="$PROJECT_DIR$/srcAndTests/srcAndTests.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/kotlinProject.iml" filepath="$PROJECT_DIR$/kotlinProject.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun main() {
|
||||||
|
srcAndTests()
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fun srcAndTests() {}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun testSrcAndTests() {
|
||||||
|
srcAndTests()
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
fun testMain() {
|
||||||
|
main()
|
||||||
|
srcAndTests()
|
||||||
|
testSrcAndTests()
|
||||||
|
}
|
||||||
@@ -19,9 +19,7 @@ package org.jetbrains.kotlin.js.config;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.util.SmartList;
|
import com.intellij.util.SmartList;
|
||||||
import kotlin.Unit;
|
|
||||||
import kotlin.collections.CollectionsKt;
|
import kotlin.collections.CollectionsKt;
|
||||||
import kotlin.jvm.functions.Function1;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys;
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys;
|
||||||
@@ -87,7 +85,12 @@ public abstract class JsConfig {
|
|||||||
return configuration.get(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN);
|
return configuration.get(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract boolean checkLibFilesAndReportErrors(@NotNull Function1<String, Unit> report);
|
public static abstract class Reporter {
|
||||||
|
public void error(@NotNull String message) { /*Do nothing*/ }
|
||||||
|
public void warning(@NotNull String message) { /*Do nothing*/ }
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean checkLibFilesAndReportErrors(@NotNull Reporter report);
|
||||||
|
|
||||||
protected abstract void init(@NotNull List<KtFile> sourceFilesInLibraries, @NotNull List<KotlinJavascriptMetadata> metadata);
|
protected abstract void init(@NotNull List<KtFile> sourceFilesInLibraries, @NotNull List<KotlinJavascriptMetadata> metadata);
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import com.intellij.psi.PsiManager;
|
|||||||
import com.intellij.util.PathUtil;
|
import com.intellij.util.PathUtil;
|
||||||
import com.intellij.util.io.URLUtil;
|
import com.intellij.util.io.URLUtil;
|
||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
import kotlin.jvm.functions.Function1;
|
|
||||||
import kotlin.jvm.functions.Function2;
|
import kotlin.jvm.functions.Function2;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -39,7 +38,9 @@ import org.jetbrains.kotlin.utils.LibraryUtils;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.utils.LibraryUtils.isOldKotlinJavascriptLibrary;
|
import static org.jetbrains.kotlin.utils.LibraryUtils.isOldKotlinJavascriptLibrary;
|
||||||
import static org.jetbrains.kotlin.utils.PathUtil.getKotlinPathsForDistDirectory;
|
import static org.jetbrains.kotlin.utils.PathUtil.getKotlinPathsForDistDirectory;
|
||||||
@@ -69,9 +70,9 @@ public class LibrarySourcesConfig extends JsConfig {
|
|||||||
|
|
||||||
final PsiManager psiManager = PsiManager.getInstance(getProject());
|
final PsiManager psiManager = PsiManager.getInstance(getProject());
|
||||||
|
|
||||||
Function1<String, Unit> report = new Function1<String, Unit>() {
|
JsConfig.Reporter report = new JsConfig.Reporter() {
|
||||||
@Override
|
@Override
|
||||||
public Unit invoke(String message) {
|
public void error(@NotNull String message) {
|
||||||
throw new IllegalStateException(message);
|
throw new IllegalStateException(message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -98,11 +99,11 @@ public class LibrarySourcesConfig extends JsConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkLibFilesAndReportErrors(@NotNull Function1<String, Unit> report) {
|
public boolean checkLibFilesAndReportErrors(@NotNull JsConfig.Reporter report) {
|
||||||
return checkLibFilesAndReportErrors(report, null);
|
return checkLibFilesAndReportErrors(report, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkLibFilesAndReportErrors(@NotNull Function1<String, Unit> report, @Nullable Function2<String, VirtualFile, Unit> action) {
|
private boolean checkLibFilesAndReportErrors(@NotNull JsConfig.Reporter report, @Nullable Function2<String, VirtualFile, Unit> action) {
|
||||||
List<String> libraries = getLibraries();
|
List<String> libraries = getLibraries();
|
||||||
if (libraries.isEmpty()) {
|
if (libraries.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -111,12 +112,14 @@ public class LibrarySourcesConfig extends JsConfig {
|
|||||||
VirtualFileSystem fileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL);
|
VirtualFileSystem fileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL);
|
||||||
VirtualFileSystem jarFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JAR_PROTOCOL);
|
VirtualFileSystem jarFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JAR_PROTOCOL);
|
||||||
|
|
||||||
|
Set<String> modules = new HashSet<String>();
|
||||||
|
|
||||||
for (String path : libraries) {
|
for (String path : libraries) {
|
||||||
VirtualFile file;
|
VirtualFile file;
|
||||||
|
|
||||||
File filePath = new File(path);
|
File filePath = new File(path);
|
||||||
if (!filePath.exists()) {
|
if (!filePath.exists()) {
|
||||||
report.invoke("Path '" + path + "' does not exist");
|
report.error("Path '" + path + "' does not exist");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +131,7 @@ public class LibrarySourcesConfig extends JsConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
report.invoke("File '" + path + "' does not exist or could not be read");
|
report.error("File '" + path + "' does not exist or could not be read");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,21 +139,27 @@ public class LibrarySourcesConfig extends JsConfig {
|
|||||||
|
|
||||||
if (isOldKotlinJavascriptLibrary(filePath)) {
|
if (isOldKotlinJavascriptLibrary(filePath)) {
|
||||||
moduleName = LibraryUtils.getKotlinJsModuleName(filePath);
|
moduleName = LibraryUtils.getKotlinJsModuleName(filePath);
|
||||||
|
if (!modules.add(moduleName)) {
|
||||||
|
report.warning("Module \"" + moduleName + "\" is defined in more, than one file");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
List<KotlinJavascriptMetadata> metadataList = KotlinJavascriptMetadataUtils.loadMetadata(filePath);
|
List<KotlinJavascriptMetadata> metadataList = KotlinJavascriptMetadataUtils.loadMetadata(filePath);
|
||||||
if (metadataList.isEmpty()) {
|
if (metadataList.isEmpty()) {
|
||||||
report.invoke("'" + path + "' is not a valid Kotlin Javascript library");
|
report.error("'" + path + "' is not a valid Kotlin Javascript library");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (KotlinJavascriptMetadata metadata : metadataList) {
|
for (KotlinJavascriptMetadata metadata : metadataList) {
|
||||||
if (!metadata.getVersion().isCompatible()) {
|
if (!metadata.getVersion().isCompatible()) {
|
||||||
report.invoke("File '" + path + "' was compiled with an incompatible version of Kotlin. " +
|
report.error("File '" + path + "' was compiled with an incompatible version of Kotlin. " +
|
||||||
"The binary version of its metadata is " + metadata.getVersion() +
|
"The binary version of its metadata is " + metadata.getVersion() +
|
||||||
", expected version is " + JsMetadataVersion.INSTANCE);
|
", expected version is " + JsMetadataVersion.INSTANCE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (!modules.add(metadata.getModuleName())) {
|
||||||
|
report.warning("Module \"" + metadata.getModuleName() + "\" is defined in more, than one file");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
moduleName = null;
|
moduleName = null;
|
||||||
|
|||||||
@@ -16,13 +16,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.js.inline
|
package org.jetbrains.kotlin.js.inline
|
||||||
|
|
||||||
import org.jetbrains.kotlin.js.backend.ast.metadata.inlineStrategy
|
import com.google.common.collect.HashMultimap
|
||||||
import com.google.gwt.dev.js.ThrowExceptionOnErrorReporter
|
import com.google.gwt.dev.js.ThrowExceptionOnErrorReporter
|
||||||
import com.intellij.util.containers.SLRUCache
|
import com.intellij.util.containers.SLRUCache
|
||||||
import org.jetbrains.kotlin.builtins.isExtensionFunctionType
|
|
||||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
|
import org.jetbrains.kotlin.js.backend.ast.metadata.inlineStrategy
|
||||||
import org.jetbrains.kotlin.js.config.LibrarySourcesConfig
|
import org.jetbrains.kotlin.js.config.LibrarySourcesConfig
|
||||||
import org.jetbrains.kotlin.js.inline.util.IdentitySet
|
import org.jetbrains.kotlin.js.inline.util.IdentitySet
|
||||||
import org.jetbrains.kotlin.js.inline.util.isCallInvocation
|
import org.jetbrains.kotlin.js.inline.util.isCallInvocation
|
||||||
@@ -51,22 +51,18 @@ private val DEFINE_MODULE_FIND_PATTERN = ".defineModule("
|
|||||||
|
|
||||||
class FunctionReader(private val context: TranslationContext) {
|
class FunctionReader(private val context: TranslationContext) {
|
||||||
/**
|
/**
|
||||||
* Maps module name to .js file content, that contains this module definition.
|
* fileContent: .js file content, that contains this module definition.
|
||||||
* One file can contain more than one module definition.
|
* One file can contain more than one module definition.
|
||||||
|
*
|
||||||
|
* moduleVariable: the variable used to call functions inside module.
|
||||||
|
* The default variable is _, but it can be renamed by minifier.
|
||||||
|
*
|
||||||
|
* kotlinVariable: kotlin object variable.
|
||||||
|
* The default variable is Kotlin, but it can be renamed by minifier.
|
||||||
*/
|
*/
|
||||||
private val moduleJsDefinition = hashMapOf<String, String>()
|
data class ModuleInfo(val fileContent: String, val moduleVariable: String, val kotlinVariable: String)
|
||||||
|
|
||||||
/**
|
private val moduleNameToInfo = HashMultimap.create<String, ModuleInfo>()
|
||||||
* Maps module name to variable, that is used to call functions inside module.
|
|
||||||
* The default variable is _, but it can be renamed by minifier.
|
|
||||||
*/
|
|
||||||
private val moduleRootVariable = hashMapOf<String, String>()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps moduleName to kotlin object variable.
|
|
||||||
* The default variable is Kotlin, but it can be renamed by minifier.
|
|
||||||
*/
|
|
||||||
private val moduleKotlinVariable = hashMapOf<String, String>()
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val config = context.config as LibrarySourcesConfig
|
val config = context.config as LibrarySourcesConfig
|
||||||
@@ -87,10 +83,7 @@ class FunctionReader(private val context: TranslationContext) {
|
|||||||
val moduleName = preciseMatcher.group(3)
|
val moduleName = preciseMatcher.group(3)
|
||||||
val moduleVariable = preciseMatcher.group(4)
|
val moduleVariable = preciseMatcher.group(4)
|
||||||
val kotlinVariable = preciseMatcher.group(1)
|
val kotlinVariable = preciseMatcher.group(1)
|
||||||
assert(moduleName !in moduleJsDefinition) { "Module \"$moduleName\" is defined in more, than one file" }
|
moduleNameToInfo.put(moduleName, ModuleInfo(fileContent, moduleVariable, kotlinVariable))
|
||||||
moduleJsDefinition[moduleName] = fileContent
|
|
||||||
moduleRootVariable[moduleName] = moduleVariable
|
|
||||||
moduleKotlinVariable[moduleName] = kotlinVariable
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,7 +115,7 @@ class FunctionReader(private val context: TranslationContext) {
|
|||||||
operator fun contains(descriptor: CallableDescriptor): Boolean {
|
operator fun contains(descriptor: CallableDescriptor): Boolean {
|
||||||
val moduleName = getExternalModuleName(descriptor)
|
val moduleName = getExternalModuleName(descriptor)
|
||||||
val currentModuleName = context.config.moduleId
|
val currentModuleName = context.config.moduleId
|
||||||
return currentModuleName != moduleName && moduleName != null && moduleName in moduleJsDefinition
|
return currentModuleName != moduleName && moduleName != null && moduleName in moduleNameToInfo.keys()
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun get(descriptor: CallableDescriptor): JsFunction = functionCache.get(descriptor)
|
operator fun get(descriptor: CallableDescriptor): JsFunction = functionCache.get(descriptor)
|
||||||
@@ -131,13 +124,17 @@ class FunctionReader(private val context: TranslationContext) {
|
|||||||
if (descriptor !in this) return null
|
if (descriptor !in this) return null
|
||||||
|
|
||||||
val moduleName = getExternalModuleName(descriptor)
|
val moduleName = getExternalModuleName(descriptor)
|
||||||
val file = moduleJsDefinition[moduleName].sure { "Module $moduleName file have not been read" }
|
|
||||||
val function = readFunctionFromSource(descriptor, file)
|
for (info in moduleNameToInfo[moduleName]) {
|
||||||
function?.markInlineArguments(descriptor)
|
val function = readFunctionFromSource(descriptor, info)
|
||||||
return function
|
if (function != null) return function
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readFunctionFromSource(descriptor: CallableDescriptor, source: String): JsFunction? {
|
private fun readFunctionFromSource(descriptor: CallableDescriptor, info: ModuleInfo): JsFunction? {
|
||||||
|
val source = info.fileContent
|
||||||
val tag = Namer.getFunctionTag(descriptor)
|
val tag = Namer.getFunctionTag(descriptor)
|
||||||
val index = source.indexOf(tag)
|
val index = source.indexOf(tag)
|
||||||
if (index < 0) return null
|
if (index < 0) return null
|
||||||
@@ -149,12 +146,12 @@ class FunctionReader(private val context: TranslationContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val function = parseFunction(source, offset, ThrowExceptionOnErrorReporter, JsRootScope(JsProgram()))
|
val function = parseFunction(source, offset, ThrowExceptionOnErrorReporter, JsRootScope(JsProgram()))
|
||||||
val moduleName = getExternalModuleName(descriptor)!!
|
|
||||||
val moduleReference = context.getModuleExpressionFor(descriptor) ?: getRootPackage()
|
val moduleReference = context.getModuleExpressionFor(descriptor) ?: getRootPackage()
|
||||||
|
|
||||||
val replacements = hashMapOf(moduleRootVariable[moduleName]!! to moduleReference,
|
val replacements = hashMapOf(info.moduleVariable to moduleReference,
|
||||||
moduleKotlinVariable[moduleName]!! to Namer.kotlinObject())
|
info.kotlinVariable to Namer.kotlinObject())
|
||||||
replaceExternalNames(function, replacements)
|
replaceExternalNames(function, replacements)
|
||||||
|
function.markInlineArguments(descriptor)
|
||||||
return function
|
return function
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user