Added check for duplicate source paths in all compiler workflows.

This commit is contained in:
Evgeny Gerashchenko
2014-08-29 17:49:10 +04:00
parent 35720ff46d
commit 4e41673b75
17 changed files with 72 additions and 46 deletions
@@ -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();
@@ -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<K2JSCompilerArguments> {
}
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();
@@ -71,6 +71,7 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments> {
"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<K2JVMCompilerArguments> {
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<K2JVMCompilerArguments> {
putAdvancedOptions(configuration, arguments);
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector);
messageCollector.report(CompilerMessageSeverity.LOGGING, "Configuring the compilation environment",
CompilerMessageLocation.NO_LOCATION);
try {
@@ -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<VirtualFile> processedFiles = Sets.newHashSet();
final List<JetFile> 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<String> sourceRoots) {
MessageCollector messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY);
assert messageCollector != null : "messageCollector should be set: " + configuration;
Set<String> 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<String>(uniqueSourceRoots));
}
}
@@ -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<String> checkForDuplicatePaths(@NotNull MessageCollector messageCollector, @NotNull List<String> sourceRoots) {
Set<String> 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<String>(uniqueSourceRoots);
}
@Nullable
private static FqName findMainClass(@NotNull GenerationState generationState, @NotNull List<JetFile> files) {
MainFunctionDetector mainFunctionDetector = new MainFunctionDetector(generationState.getBindingContext());
@@ -1,2 +0,0 @@
-module
$TESTDATA_DIR$/duplicateSource.xml
@@ -1,2 +0,0 @@
WARNING: Duplicate source roots: $TESTDATA_DIR$/duplicateSource.kt
OK
@@ -1,6 +0,0 @@
<modules>
<module name="name" outputDir="whatever">
<sources path="duplicateSource.kt"/>
<sources path="duplicateSource.kt"/>
</module>
</modules>
@@ -0,0 +1,4 @@
$TESTDATA_DIR$/simple.kt
$TESTDATA_DIR$/simple.kt
-d
$TEMP_DIR$
@@ -0,0 +1,2 @@
WARNING: Duplicate source roots: compiler/testData/cli/jvm/simple.kt
OK
@@ -0,0 +1,2 @@
-module
$TESTDATA_DIR$/duplicateSourcesInModule.xml
@@ -0,0 +1 @@
// this file is intentionally left blank to avoid creation of class files: this would need tuning test framework
@@ -0,0 +1,2 @@
WARNING: Duplicate source roots: $TESTDATA_DIR$/duplicateSourcesInModule.kt
OK
@@ -0,0 +1,6 @@
<modules>
<module name="name" outputDir="whatever">
<sources path="duplicateSourcesInModule.kt"/>
<sources path="duplicateSourcesInModule.kt"/>
</module>
</modules>
@@ -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();
}
@@ -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")