diff --git a/compiler/cli/cli-common/src/com/sampullara/cli/ArgumentUtils.java b/compiler/cli/cli-common/src/com/sampullara/cli/ArgumentUtils.java index 4aff8fa1a49..51e2ff854d7 100644 --- a/compiler/cli/cli-common/src/com/sampullara/cli/ArgumentUtils.java +++ b/compiler/cli/cli-common/src/com/sampullara/cli/ArgumentUtils.java @@ -16,6 +16,8 @@ package com.sampullara.cli; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.Function; import com.intellij.util.containers.ComparatorUtil; import org.jetbrains.annotations.NotNull; @@ -66,12 +68,19 @@ public class ArgumentUtils { name = Args.getName(argument, field); } + Class fieldType = field.getType(); + + if (fieldType.isArray()) { + Object[] values = (Object[]) value; + if (values.length == 0) continue; + value = StringUtil.join(values, Function.TO_STRING, argument.delimiter()); + } + result.add(argument.prefix() + name); - Class fieldType = field.getType(); - if (fieldType != boolean.class && fieldType != Boolean.class) { - result.add(value.toString()); - } + if (fieldType == boolean.class || fieldType == Boolean.class) continue; + + result.add(value.toString()); } } diff --git a/compiler/cli/src/org/jetbrains/jet/cli/common/CLICompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/common/CLICompiler.java index 5b7c4e8f55d..59892dc1846 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/common/CLICompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/common/CLICompiler.java @@ -189,14 +189,14 @@ public abstract class CLICompiler { @NotNull MessageRenderer messageRenderer ) { if (arguments.printArgs) { - String freeArgs = StringUtil.join(arguments.freeArgs, " "); + String freeArgs = !arguments.freeArgs.isEmpty() ? " " + StringUtil.join(arguments.freeArgs, " ") : ""; List argumentsAsList = ArgumentUtils.convertArgumentsToStringList(arguments, createArguments()); String argumentsAsString = StringUtil.join(argumentsAsList, " "); String printArgsMessage = messageRenderer.render(CompilerMessageSeverity.INFO, "Invoking compiler " + getClass().getName() + - " with arguments " + argumentsAsString + " " + freeArgs, + " with arguments " + argumentsAsString + freeArgs, CompilerMessageLocation.NO_LOCATION); errStream.println(printArgsMessage); } 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 d4cdfc63466..cc0bd6f3981 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java @@ -93,17 +93,17 @@ public class K2JSCompiler extends CLICompiler { reportCompiledSourcesList(messageCollector, environmentForJS); } - Config config = getConfig(arguments, project); - if (analyzeAndReportErrors(messageCollector, environmentForJS.getSourceFiles(), config)) { - return COMPILATION_ERROR; - } - String outputFile = arguments.outputFile; if (outputFile == null) { messageCollector.report(CompilerMessageSeverity.ERROR, "Specify output file via -output", CompilerMessageLocation.NO_LOCATION); return ExitCode.INTERNAL_ERROR; } + Config config = getConfig(arguments, project); + if (analyzeAndReportErrors(messageCollector, environmentForJS.getSourceFiles(), config)) { + return COMPILATION_ERROR; + } + MainCallParameters mainCallParameters = createMainCallParameters(arguments.main); return translateAndGenerateOutputFile(mainCallParameters, environmentForJS, config, outputFile); } diff --git a/compiler/testData/cli/printArgumentsWithManyValue.out b/compiler/testData/cli/printArgumentsWithManyValue.out new file mode 100644 index 00000000000..90e2a190ea1 --- /dev/null +++ b/compiler/testData/cli/printArgumentsWithManyValue.out @@ -0,0 +1,3 @@ +INFO: Invoking compiler org.jetbrains.jet.cli.js.K2JSCompiler with arguments -suppress warnings -printArgs -sourceFiles compiler/testData/cli/simple2js.kt,compiler/testData/cli/warnings.kt +ERROR: Specify output file via -output +COMPILATION_ERROR diff --git a/compiler/testData/cli/simple2js.kt b/compiler/testData/cli/simple2js.kt new file mode 100644 index 00000000000..7de943c30d9 --- /dev/null +++ b/compiler/testData/cli/simple2js.kt @@ -0,0 +1 @@ +fun main(args: Array) {} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/cli/jvm/CliTest.java b/compiler/tests/org/jetbrains/jet/cli/jvm/CliTest.java index f1f66c1854b..840c47b419d 100644 --- a/compiler/tests/org/jetbrains/jet/cli/jvm/CliTest.java +++ b/compiler/tests/org/jetbrains/jet/cli/jvm/CliTest.java @@ -201,6 +201,14 @@ public class CliTest { executeCompilerCompareOutputJVM(new String[] {"-printArgs", "-script", "compiler/testData/cli/hello.ktscript"}); } + @Test + public void printArgumentsWithManyValue() { + executeCompilerCompareOutputJS(new String[] { + "-printArgs", + "-sourceFiles", "compiler/testData/cli/simple2js.kt,compiler/testData/cli/warnings.kt", + "-suppress", "warnings"}); + } + @Test public void nonExistingClassPathAndAnnotationsPath() { String[] args = { diff --git a/idea/src/org/jetbrains/jet/plugin/caches/resolve/JSDeclarationsCacheProvider.java b/idea/src/org/jetbrains/jet/plugin/caches/resolve/JSDeclarationsCacheProvider.java index b7b4924ac68..fb2f8fa755c 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/resolve/JSDeclarationsCacheProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/resolve/JSDeclarationsCacheProvider.java @@ -51,7 +51,7 @@ class JSDeclarationsCacheProvider extends DeclarationsCacheProvider { synchronized (declarationAnalysisLock) { LibrarySourcesConfig config = new LibrarySourcesConfig( project, "default", - KotlinFrameworkDetector.getLibLocationAndTargetForProject(project).first, + KotlinFrameworkDetector.getLibLocationForProject(project), EcmaVersion.defaultVersion(), false); AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJS.analyzeFiles( diff --git a/idea/src/org/jetbrains/jet/plugin/compiler/K2JSCompiler.java b/idea/src/org/jetbrains/jet/plugin/compiler/K2JSCompiler.java index c40aac9a473..d8d8af9186c 100644 --- a/idea/src/org/jetbrains/jet/plugin/compiler/K2JSCompiler.java +++ b/idea/src/org/jetbrains/jet/plugin/compiler/K2JSCompiler.java @@ -16,43 +16,36 @@ package org.jetbrains.jet.plugin.compiler; -import com.google.common.collect.Lists; -import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.compiler.*; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.ModuleOrderEntry; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.OrderEntry; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.ArrayUtil; import com.intellij.util.Chunk; import com.intellij.util.Function; -import com.intellij.util.StringBuilderSpinAllocator; +import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation; -import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity; +import org.jetbrains.jet.cli.common.arguments.CommonCompilerArguments; +import org.jetbrains.jet.cli.common.arguments.K2JSCompilerArguments; import org.jetbrains.jet.cli.common.messages.MessageCollector; import org.jetbrains.jet.compiler.runner.CompilerEnvironment; -import org.jetbrains.jet.compiler.runner.CompilerRunnerUtil; +import org.jetbrains.jet.compiler.runner.KotlinCompilerRunner; import org.jetbrains.jet.compiler.runner.OutputItemsCollectorImpl; import org.jetbrains.jet.plugin.JetFileType; +import org.jetbrains.jet.plugin.compiler.configuration.Kotlin2JsCompilerSettings; +import org.jetbrains.jet.plugin.compiler.configuration.KotlinCommonCompilerSettings; import org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector; import java.io.File; -import java.io.PrintStream; import java.util.ArrayList; import java.util.List; import java.util.Set; -import static org.jetbrains.jet.compiler.runner.CompilerRunnerUtil.invokeExecMethod; -import static org.jetbrains.jet.compiler.runner.CompilerRunnerUtil.outputCompilerMessagesAndHandleExitCode; - public final class K2JSCompiler implements TranslatingCompiler { @Override public boolean isCompilableFile(VirtualFile file, CompileContext context) { @@ -85,19 +78,38 @@ public final class K2JSCompiler implements TranslatingCompiler { return; } - doCompile(messageCollector, sink, module, environment); + doCompile(messageCollector, sink, module, environment, files); } - private static void doCompile(@NotNull final MessageCollector messageCollector, @NotNull OutputSink sink, @NotNull final Module module, - @NotNull final CompilerEnvironment environment) { - OutputItemsCollectorImpl collector = new OutputItemsCollectorImpl(); - outputCompilerMessagesAndHandleExitCode(messageCollector, collector, new Function() { + private static void doCompile( + @NotNull MessageCollector messageCollector, @NotNull OutputSink sink, @NotNull Module module, + @NotNull CompilerEnvironment environment, VirtualFile[] files + ) { + List srcFiles = ContainerUtil.map(files, new Function() { @Override - public Integer fun(PrintStream stream) { - return execInProcess(messageCollector, environment, stream, module); + public File fun(VirtualFile file) { + return new File(file.getPath()); } }); - TranslatingCompilerUtils.reportOutputs(sink, environment.getOutput(), collector); + List libraryFiles = getLibraryFiles(module); + File outDir = environment.getOutput(); + File outFile = new File(outDir, module.getName() + ".js"); + + OutputItemsCollectorImpl outputItemsCollector = new OutputItemsCollectorImpl(); + + CommonCompilerArguments commonArguments = KotlinCommonCompilerSettings.getInstance(module.getProject()).getSettings(); + K2JSCompilerArguments k2jsArguments = Kotlin2JsCompilerSettings.getInstance(module.getProject()).getSettings(); + + KotlinCompilerRunner.runK2JsCompiler(commonArguments, k2jsArguments, messageCollector, environment, + outputItemsCollector, srcFiles, libraryFiles, outFile); + + if (!ApplicationManager.getApplication().isUnitTestMode()) { + VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(outDir); + assert virtualFile != null : "Virtual file not found for module output: " + outDir; + virtualFile.refresh(false, true); + } + + TranslatingCompilerUtils.reportOutputs(sink, environment.getOutput(), outputItemsCollector); } @Nullable @@ -109,48 +121,6 @@ public final class K2JSCompiler implements TranslatingCompiler { return moduleChunk.getNodes().iterator().next(); } - @NotNull - private static Integer execInProcess(@NotNull MessageCollector messageCollector, - @NotNull CompilerEnvironment environment, @NotNull PrintStream out, @NotNull Module module) { - try { - return doExec(messageCollector, environment, out, module); - } - catch (Throwable e) { - messageCollector.report(CompilerMessageSeverity.ERROR, - "Exception while executing compiler:\n" + e.getMessage(), - CompilerMessageLocation.NO_LOCATION); - } - return -1; - } - - @NotNull - private static Integer doExec(@NotNull MessageCollector messageCollector, @NotNull CompilerEnvironment environment, @NotNull PrintStream out, - @NotNull Module module) throws Exception { - File outDir = environment.getOutput(); - File outFile = new File(outDir, module.getName() + ".js"); - String[] commandLineArgs = constructArguments(module, outFile); - // No preloading for in-process compiler - Object rc = invokeExecMethod("org.jetbrains.jet.cli.js.K2JSCompiler", commandLineArgs, environment, messageCollector, out, false); - - if (!ApplicationManager.getApplication().isUnitTestMode()) { - VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(outDir); - assert virtualFile != null : "Virtual file not found for module output: " + outDir; - virtualFile.refresh(false, true); - } - return CompilerRunnerUtil.getReturnCodeFromObject(rc); - } - - @NotNull - private static String[] constructArguments(@NotNull Module module, @NotNull File outFile) { - VirtualFile[] sourceFiles = getSourceFiles(module); - - ArrayList args = Lists.newArrayList("-tags", "-verbose", "-version"); - addPathToSourcesDir(sourceFiles, args); - addOutputPath(outFile, args); - addLibLocationAndTarget(module, args); - return ArrayUtil.toStringArray(args); - } - // we cannot use OrderEnumerator because it has critical bug - try https://gist.github.com/2953261, processor will never be called for module dependency // we don't use context.getCompileScope().getAffectedModules() because we want to know about linkage type (well, we ignore scope right now, but in future...) private static void collectModuleDependencies(Module dependentModule, Set modules) { @@ -178,67 +148,28 @@ public final class K2JSCompiler implements TranslatingCompiler { .getFiles(JetFileType.INSTANCE, true); } - private static void addLibLocationAndTarget(@NotNull Module module, @NotNull ArrayList args) { - Pair, String> libLocationAndTarget = KotlinFrameworkDetector.getLibLocationAndTargetForProject(module); + private static List getLibraryFiles(@NotNull Module module) { + List result = new ArrayList(); - StringBuilder sb = StringBuilderSpinAllocator.alloc(); - AccessToken token = ReadAction.start(); - try { - THashSet modules = new THashSet(); - collectModuleDependencies(module, modules); - if (!modules.isEmpty()) { - for (Module dependency : modules) { - sb.append('@').append(dependency.getName()).append(','); + List libLocationAndTarget = KotlinFrameworkDetector.getLibLocationForProject(module); - for (VirtualFile file : getSourceFiles(dependency)) { - sb.append(file.getPath()).append(','); - } + THashSet modules = new THashSet(); + collectModuleDependencies(module, modules); + if (!modules.isEmpty()) { + for (Module dependency : modules) { + result.add("@" + dependency.getName()); + + for (VirtualFile file : getSourceFiles(dependency)) { + result.add(file.getPath()); } } - - if (libLocationAndTarget.first != null) { - for (String file : libLocationAndTarget.first) { - sb.append(file).append(','); - } - } - - if (sb.length() > 0) { - args.add("-libraryFiles"); - args.add(sb.substring(0, sb.length() - 1)); - } - } - finally { - token.finish(); - StringBuilderSpinAllocator.dispose(sb); } - if (libLocationAndTarget.second != null) { - args.add("-target"); - args.add(libLocationAndTarget.second); + for (String file : libLocationAndTarget) { + result.add(file); } - //TODO drop later - args.add("-sourcemap"); - } - - private static void addPathToSourcesDir(@NotNull VirtualFile[] sourceFiles, @NotNull ArrayList args) { - args.add("-sourceFiles"); - - StringBuilder sb = StringBuilderSpinAllocator.alloc(); - try { - for (VirtualFile file : sourceFiles) { - sb.append(file.getPath()).append(','); - } - args.add(sb.substring(0, sb.length() - 1)); - } - finally { - StringBuilderSpinAllocator.dispose(sb); - } - } - - private static void addOutputPath(@NotNull File outFile, @NotNull ArrayList args) { - args.add("-output"); - args.add(outFile.getPath()); + return result; } @NotNull diff --git a/idea/src/org/jetbrains/jet/plugin/framework/KotlinFrameworkDetector.java b/idea/src/org/jetbrains/jet/plugin/framework/KotlinFrameworkDetector.java index 2a4e59317ae..bfe5fcc0d92 100644 --- a/idea/src/org/jetbrains/jet/plugin/framework/KotlinFrameworkDetector.java +++ b/idea/src/org/jetbrains/jet/plugin/framework/KotlinFrameworkDetector.java @@ -29,7 +29,6 @@ import com.intellij.openapi.roots.ProjectRootModificationTracker; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.search.GlobalSearchScope; @@ -43,8 +42,8 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.plugin.configuration.ConfigureKotlinInProjectUtils; import org.jetbrains.jet.plugin.versions.KotlinRuntimeLibraryUtil; -import org.jetbrains.k2js.config.EcmaVersion; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -82,18 +81,19 @@ public class KotlinFrameworkDetector { } @NotNull - public static Pair, String> getLibLocationAndTargetForProject(@NotNull Project project) { + public static List getLibLocationForProject(@NotNull Project project) { Module[] modules = ModuleManager.getInstance(project).getModules(); for (Module module : modules) { if (isJsKotlinModule(module)) { - return getLibLocationAndTargetForProject(module); + return getLibLocationForProject(module); } } - return Pair.empty(); + return Collections.emptyList(); } - public static Pair, String> getLibLocationAndTargetForProject(final Module module) { + @NotNull + public static List getLibLocationForProject(@NotNull final Module module) { final Set pathsToJSLib = Sets.newHashSet(); ApplicationManager.getApplication().runReadAction(new Runnable() { @@ -120,7 +120,7 @@ public class KotlinFrameworkDetector { } }); - return Pair., String>create(Lists.newArrayList(pathsToJSLib), EcmaVersion.defaultVersion().toString()); + return Lists.newArrayList(pathsToJSLib); } diff --git a/idea/src/org/jetbrains/jet/plugin/project/IDEAConfig.java b/idea/src/org/jetbrains/jet/plugin/project/IDEAConfig.java index 59f445ba7ba..45cc79f196a 100644 --- a/idea/src/org/jetbrains/jet/plugin/project/IDEAConfig.java +++ b/idea/src/org/jetbrains/jet/plugin/project/IDEAConfig.java @@ -18,13 +18,12 @@ package org.jetbrains.jet.plugin.project; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector; import org.jetbrains.k2js.config.EcmaVersion; import org.jetbrains.k2js.config.LibrarySourcesConfig; -import static org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector.getLibLocationAndTargetForProject; - public final class IDEAConfig extends LibrarySourcesConfig { public IDEAConfig(@NotNull Project project) { - super(project, "default", getLibLocationAndTargetForProject(project).first, EcmaVersion.defaultVersion(), false); + super(project, "default", KotlinFrameworkDetector.getLibLocationForProject(project), EcmaVersion.defaultVersion(), false); } } \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/compilerMessages/K2JSCompilerMessagingTest.java b/idea/tests/org/jetbrains/jet/plugin/compilerMessages/K2JSCompilerMessagingTest.java index f343e1793aa..cc4480080fc 100644 --- a/idea/tests/org/jetbrains/jet/plugin/compilerMessages/K2JSCompilerMessagingTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/compilerMessages/K2JSCompilerMessagingTest.java @@ -100,7 +100,9 @@ public final class K2JSCompilerMessagingTest extends IDECompilerMessagingTest { @Override protected void checkHeader(@NotNull MessageChecker checker) { - checker.expect(Message.info().textStartsWith("Kotlin Compiler version")); + checker.expect(info().textStartsWith("Using kotlinHome=")); + checker.expect(info().textStartsWith("Invoking compiler")); + checker.expect(info().textStartsWith("Kotlin Compiler version")); checker.expect(stats().textMatchesRegexp("Compiling source files: .*/src/test.kt")); } }