diff --git a/build-tools/core/src/org/jetbrains/jet/buildtools/core/BytecodeCompiler.java b/build-tools/core/src/org/jetbrains/jet/buildtools/core/BytecodeCompiler.java index 7ff11568d09..2acaf470116 100644 --- a/build-tools/core/src/org/jetbrains/jet/buildtools/core/BytecodeCompiler.java +++ b/build-tools/core/src/org/jetbrains/jet/buildtools/core/BytecodeCompiler.java @@ -31,9 +31,9 @@ import org.jetbrains.jet.cli.common.messages.MessageCollectorPlainTextToStream; import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys; import org.jetbrains.jet.cli.jvm.K2JVMCompiler; import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentException; +import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.jet.cli.jvm.compiler.KotlinToJVMBytecodeCompiler; -import org.jetbrains.jet.config.CommonConfigurationKeys; import org.jetbrains.jet.config.CompilerConfiguration; import org.jetbrains.jet.utils.KotlinPaths; import org.jetbrains.jet.utils.KotlinPathsFromHomeDir; @@ -59,6 +59,8 @@ public class BytecodeCompiler { ) { KotlinPaths paths = getKotlinPathsForAntTask(); CompilerConfiguration configuration = new CompilerConfiguration(); + configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollectorPlainTextToStream.PLAIN_TEXT_TO_SYSTEM_ERR); + configuration.addAll(CLASSPATH_KEY, PathUtil.getJdkClassesRoots()); if ((stdlib != null) && (stdlib.trim().length() > 0)) { configuration.add(CLASSPATH_KEY, new File(stdlib)); @@ -84,14 +86,13 @@ public class BytecodeCompiler { configuration.add(ANNOTATIONS_PATH_KEY, jdkAnnotationsPath); } - configuration.addAll(CommonConfigurationKeys.SOURCE_ROOTS_KEY, Arrays.asList(sourceRoots)); + CompileEnvironmentUtil.addSourceFilesCheckingForDuplicates(configuration, Arrays.asList(sourceRoots)); for (String sourceRoot : sourceRoots) { File file = new File(sourceRoot); if (!file.isFile() || !"kt".equals(FileUtilRt.getExtension(file.getName()))) { configuration.add(JVMConfigurationKeys.CLASSPATH_KEY, file); } } - configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollectorPlainTextToStream.PLAIN_TEXT_TO_SYSTEM_ERR); // TODO: use K2JVMCompiler directly, don't duplicate this code here K2JVMCompilerArguments arguments = new K2JVMCompilerArguments(); diff --git a/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java index 466a85b7a14..502fc5bc735 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java @@ -31,6 +31,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.OutputFileCollection; import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.cli.common.CLICompiler; +import org.jetbrains.jet.cli.common.CLIConfigurationKeys; import org.jetbrains.jet.cli.common.ExitCode; import org.jetbrains.jet.cli.common.arguments.K2JSCompilerArguments; import org.jetbrains.jet.cli.common.arguments.K2JsArgumentConstants; @@ -39,6 +40,7 @@ import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation; import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity; import org.jetbrains.jet.cli.common.messages.MessageCollector; import org.jetbrains.jet.cli.common.output.outputUtils.OutputUtilsPackage; +import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.jet.config.CommonConfigurationKeys; import org.jetbrains.jet.config.CompilerConfiguration; @@ -84,7 +86,9 @@ public class K2JSCompiler extends CLICompiler { } CompilerConfiguration configuration = new CompilerConfiguration(); - configuration.addAll(CommonConfigurationKeys.SOURCE_ROOTS_KEY, arguments.freeArgs); + configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector); + + CompileEnvironmentUtil.addSourceFilesCheckingForDuplicates(configuration, arguments.freeArgs); JetCoreEnvironment environmentForJS = JetCoreEnvironment.createForProduction(rootDisposable, configuration); Project project = environmentForJS.getProject(); diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java index 17c10f5fb0d..696ca5d25f2 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java @@ -71,6 +71,7 @@ public class K2JVMCompiler extends CLICompiler { "Using Kotlin home directory " + paths.getHomePath(), CompilerMessageLocation.NO_LOCATION); CompilerConfiguration configuration = new CompilerConfiguration(); + configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector); IncrementalCacheProvider incrementalCacheProvider = (IncrementalCacheProvider) services.get(IncrementalCacheProvider.class); if (incrementalCacheProvider != null) { @@ -105,7 +106,7 @@ public class K2JVMCompiler extends CLICompiler { configuration.add(CommonConfigurationKeys.SOURCE_ROOTS_KEY, arguments.freeArgs.get(0)); } else { - configuration.addAll(CommonConfigurationKeys.SOURCE_ROOTS_KEY, arguments.freeArgs); + CompileEnvironmentUtil.addSourceFilesCheckingForDuplicates(configuration, arguments.freeArgs); } configuration.put(JVMConfigurationKeys.SCRIPT_PARAMETERS, arguments.script @@ -114,8 +115,6 @@ public class K2JVMCompiler extends CLICompiler { putAdvancedOptions(configuration, arguments); - configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector); - messageCollector.report(CompilerMessageSeverity.LOGGING, "Configuring the compilation environment", CompilerMessageLocation.NO_LOCATION); try { diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java index 56e4c1e2b4a..be7cd4c1104 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.cli.jvm.compiler; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import com.intellij.openapi.Disposable; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; @@ -37,6 +38,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.OutputFile; import org.jetbrains.jet.cli.common.CLIConfigurationKeys; +import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity; import org.jetbrains.jet.cli.common.messages.MessageCollector; import org.jetbrains.jet.cli.common.messages.OutputMessageUtil; import org.jetbrains.jet.cli.common.modules.ModuleScriptData; @@ -63,6 +65,7 @@ import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.jar.*; import static org.jetbrains.jet.cli.common.messages.CompilerMessageLocation.NO_LOCATION; @@ -272,6 +275,7 @@ public class CompileEnvironmentUtil { ) { final VirtualFileSystem localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL); + final Set processedFiles = Sets.newHashSet(); final List result = Lists.newArrayList(); for (String sourceRootPath : sourceRoots) { @@ -293,9 +297,10 @@ public class CompileEnvironmentUtil { @Override public Unit invoke(File file) { if (file.isFile()) { - VirtualFile fileByPath = localFileSystem.findFileByPath(file.getAbsolutePath()); - if (fileByPath != null) { - PsiFile psiFile = PsiManager.getInstance(project).findFile(fileByPath); + VirtualFile virtualFile = localFileSystem.findFileByPath(file.getAbsolutePath()); + if (virtualFile != null && !processedFiles.contains(virtualFile)) { + processedFiles.add(virtualFile); + PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); if (psiFile instanceof JetFile) { result.add((JetFile) psiFile); } @@ -308,4 +313,23 @@ public class CompileEnvironmentUtil { return result; } + + public static void addSourceFilesCheckingForDuplicates(@NotNull CompilerConfiguration configuration, @NotNull List sourceRoots) { + MessageCollector messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY); + assert messageCollector != null : "messageCollector should be set: " + configuration; + + Set uniqueSourceRoots = Sets.newLinkedHashSet(); + + for (String sourceRoot : sourceRoots) { + if (!uniqueSourceRoots.add(sourceRoot)) { + messageCollector.report( + CompilerMessageSeverity.WARNING, + "Duplicate source roots: " + sourceRoot, + NO_LOCATION + ); + } + } + + configuration.put(CommonConfigurationKeys.SOURCE_ROOTS_KEY, new ArrayList(uniqueSourceRoots)); + } } diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java index 2832ada89d5..24023f41b0a 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java @@ -19,7 +19,6 @@ package org.jetbrains.jet.cli.jvm.compiler; import com.google.common.base.Predicates; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import com.intellij.openapi.Disposable; import com.intellij.openapi.util.Disposer; import com.intellij.psi.PsiFile; @@ -37,8 +36,6 @@ import org.jetbrains.jet.cli.common.CLIConfigurationKeys; import org.jetbrains.jet.cli.common.CompilerPlugin; import org.jetbrains.jet.cli.common.CompilerPluginContext; import org.jetbrains.jet.cli.common.messages.AnalyzerWithCompilerReport; -import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation; -import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity; import org.jetbrains.jet.cli.common.messages.MessageCollector; import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys; import org.jetbrains.jet.codegen.*; @@ -177,29 +174,11 @@ public class KotlinToJVMBytecodeCompiler { configuration.add(JVMConfigurationKeys.MODULE_IDS, module.getModuleName()); } - MessageCollector messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY); - assert messageCollector != null : "messageCollector should be set: " + base; - configuration.put(CommonConfigurationKeys.SOURCE_ROOTS_KEY, checkForDuplicatePaths(messageCollector, sourceRoots)); + CompileEnvironmentUtil.addSourceFilesCheckingForDuplicates(configuration, sourceRoots); return configuration; } - private static List checkForDuplicatePaths(@NotNull MessageCollector messageCollector, @NotNull List sourceRoots) { - Set uniqueSourceRoots = Sets.newLinkedHashSet(); - - for (String sourceRoot : sourceRoots) { - if (!uniqueSourceRoots.add(sourceRoot)) { - messageCollector.report( - CompilerMessageSeverity.WARNING, - "Duplicate source roots: " + sourceRoot, - CompilerMessageLocation.NO_LOCATION - ); - } - } - - return new ArrayList(uniqueSourceRoots); - } - @Nullable private static FqName findMainClass(@NotNull GenerationState generationState, @NotNull List files) { MainFunctionDetector mainFunctionDetector = new MainFunctionDetector(generationState.getBindingContext()); diff --git a/compiler/testData/cli/jvm/duplicateSource.args b/compiler/testData/cli/jvm/duplicateSource.args deleted file mode 100644 index 5d876a0701e..00000000000 --- a/compiler/testData/cli/jvm/duplicateSource.args +++ /dev/null @@ -1,2 +0,0 @@ --module -$TESTDATA_DIR$/duplicateSource.xml diff --git a/compiler/testData/cli/jvm/duplicateSource.kt b/compiler/testData/cli/jvm/duplicateSource.kt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/compiler/testData/cli/jvm/duplicateSource.out b/compiler/testData/cli/jvm/duplicateSource.out deleted file mode 100644 index 6c63ae17dc9..00000000000 --- a/compiler/testData/cli/jvm/duplicateSource.out +++ /dev/null @@ -1,2 +0,0 @@ -WARNING: Duplicate source roots: $TESTDATA_DIR$/duplicateSource.kt -OK \ No newline at end of file diff --git a/compiler/testData/cli/jvm/duplicateSource.xml b/compiler/testData/cli/jvm/duplicateSource.xml deleted file mode 100644 index 0f352053623..00000000000 --- a/compiler/testData/cli/jvm/duplicateSource.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/compiler/testData/cli/jvm/duplicateSources.args b/compiler/testData/cli/jvm/duplicateSources.args new file mode 100644 index 00000000000..bc97e01e7bc --- /dev/null +++ b/compiler/testData/cli/jvm/duplicateSources.args @@ -0,0 +1,4 @@ +$TESTDATA_DIR$/simple.kt +$TESTDATA_DIR$/simple.kt +-d +$TEMP_DIR$ diff --git a/compiler/testData/cli/jvm/duplicateSources.out b/compiler/testData/cli/jvm/duplicateSources.out new file mode 100644 index 00000000000..3fa46d66e7c --- /dev/null +++ b/compiler/testData/cli/jvm/duplicateSources.out @@ -0,0 +1,2 @@ +WARNING: Duplicate source roots: compiler/testData/cli/jvm/simple.kt +OK \ No newline at end of file diff --git a/compiler/testData/cli/jvm/duplicateSourcesInModule.args b/compiler/testData/cli/jvm/duplicateSourcesInModule.args new file mode 100644 index 00000000000..7f8f50de34c --- /dev/null +++ b/compiler/testData/cli/jvm/duplicateSourcesInModule.args @@ -0,0 +1,2 @@ +-module +$TESTDATA_DIR$/duplicateSourcesInModule.xml diff --git a/compiler/testData/cli/jvm/duplicateSourcesInModule.kt b/compiler/testData/cli/jvm/duplicateSourcesInModule.kt new file mode 100644 index 00000000000..7097ffe076a --- /dev/null +++ b/compiler/testData/cli/jvm/duplicateSourcesInModule.kt @@ -0,0 +1 @@ +// this file is intentionally left blank to avoid creation of class files: this would need tuning test framework \ No newline at end of file diff --git a/compiler/testData/cli/jvm/duplicateSourcesInModule.out b/compiler/testData/cli/jvm/duplicateSourcesInModule.out new file mode 100644 index 00000000000..963b2b6e862 --- /dev/null +++ b/compiler/testData/cli/jvm/duplicateSourcesInModule.out @@ -0,0 +1,2 @@ +WARNING: Duplicate source roots: $TESTDATA_DIR$/duplicateSourcesInModule.kt +OK \ No newline at end of file diff --git a/compiler/testData/cli/jvm/duplicateSourcesInModule.xml b/compiler/testData/cli/jvm/duplicateSourcesInModule.xml new file mode 100644 index 00000000000..dc8dadb8564 --- /dev/null +++ b/compiler/testData/cli/jvm/duplicateSourcesInModule.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/cli/CliCommonTest.java b/compiler/tests/org/jetbrains/jet/cli/CliCommonTest.java index 7d3f939cfbc..c38c99afb2b 100644 --- a/compiler/tests/org/jetbrains/jet/cli/CliCommonTest.java +++ b/compiler/tests/org/jetbrains/jet/cli/CliCommonTest.java @@ -42,7 +42,14 @@ public class CliCommonTest extends CliBaseTest { } @Test - public void duplicateSource() throws Exception { + public void duplicateSources() throws Exception { + executeCompilerCompareOutputJVM(); + + Assert.assertTrue(new File(tmpdir.getTmpDir(), PackageClassUtils.getPackageClassName(FqName.ROOT) + ".class").isFile()); + } + + @Test + public void duplicateSourcesInModule() throws Exception { executeCompilerCompareOutputJVM(); } diff --git a/compiler/tests/org/jetbrains/jet/cli/KotlincExecutableTestGenerated.java b/compiler/tests/org/jetbrains/jet/cli/KotlincExecutableTestGenerated.java index 82f931f19f1..4718a89b34a 100644 --- a/compiler/tests/org/jetbrains/jet/cli/KotlincExecutableTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/cli/KotlincExecutableTestGenerated.java @@ -51,9 +51,14 @@ public class KotlincExecutableTestGenerated extends AbstractKotlincExecutableTes doJvmTest("compiler/testData/cli/jvm/diagnosticsOrder.args"); } - @TestMetadata("duplicateSource.args") - public void testDuplicateSource() throws Exception { - doJvmTest("compiler/testData/cli/jvm/duplicateSource.args"); + @TestMetadata("duplicateSources.args") + public void testDuplicateSources() throws Exception { + doJvmTest("compiler/testData/cli/jvm/duplicateSources.args"); + } + + @TestMetadata("duplicateSourcesInModule.args") + public void testDuplicateSourcesInModule() throws Exception { + doJvmTest("compiler/testData/cli/jvm/duplicateSourcesInModule.args"); } @TestMetadata("extraHelp.args")