Added support project settings in old kotlin2js compiler and made minor refactoring.
This commit is contained in:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -189,14 +189,14 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
|
||||
@NotNull MessageRenderer messageRenderer
|
||||
) {
|
||||
if (arguments.printArgs) {
|
||||
String freeArgs = StringUtil.join(arguments.freeArgs, " ");
|
||||
String freeArgs = !arguments.freeArgs.isEmpty() ? " " + StringUtil.join(arguments.freeArgs, " ") : "";
|
||||
|
||||
List<String> 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);
|
||||
}
|
||||
|
||||
@@ -93,17 +93,17 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
fun main(args: Array<String>) {}
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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<PrintStream, Integer>() {
|
||||
private static void doCompile(
|
||||
@NotNull MessageCollector messageCollector, @NotNull OutputSink sink, @NotNull Module module,
|
||||
@NotNull CompilerEnvironment environment, VirtualFile[] files
|
||||
) {
|
||||
List<File> srcFiles = ContainerUtil.map(files, new Function<VirtualFile, File>() {
|
||||
@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<String> 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<String> 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<Module> modules) {
|
||||
@@ -178,67 +148,28 @@ public final class K2JSCompiler implements TranslatingCompiler {
|
||||
.getFiles(JetFileType.INSTANCE, true);
|
||||
}
|
||||
|
||||
private static void addLibLocationAndTarget(@NotNull Module module, @NotNull ArrayList<String> args) {
|
||||
Pair<List<String>, String> libLocationAndTarget = KotlinFrameworkDetector.getLibLocationAndTargetForProject(module);
|
||||
private static List<String> getLibraryFiles(@NotNull Module module) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
|
||||
StringBuilder sb = StringBuilderSpinAllocator.alloc();
|
||||
AccessToken token = ReadAction.start();
|
||||
try {
|
||||
THashSet<Module> modules = new THashSet<Module>();
|
||||
collectModuleDependencies(module, modules);
|
||||
if (!modules.isEmpty()) {
|
||||
for (Module dependency : modules) {
|
||||
sb.append('@').append(dependency.getName()).append(',');
|
||||
List<String> libLocationAndTarget = KotlinFrameworkDetector.getLibLocationForProject(module);
|
||||
|
||||
for (VirtualFile file : getSourceFiles(dependency)) {
|
||||
sb.append(file.getPath()).append(',');
|
||||
}
|
||||
THashSet<Module> modules = new THashSet<Module>();
|
||||
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<String> 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<String> args) {
|
||||
args.add("-output");
|
||||
args.add(outFile.getPath());
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -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<List<String>, String> getLibLocationAndTargetForProject(@NotNull Project project) {
|
||||
public static List<String> 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<List<String>, String> getLibLocationAndTargetForProject(final Module module) {
|
||||
@NotNull
|
||||
public static List<String> getLibLocationForProject(@NotNull final Module module) {
|
||||
final Set<String> pathsToJSLib = Sets.newHashSet();
|
||||
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@@ -120,7 +120,7 @@ public class KotlinFrameworkDetector {
|
||||
}
|
||||
});
|
||||
|
||||
return Pair.<List<String>, String>create(Lists.newArrayList(pathsToJSLib), EcmaVersion.defaultVersion().toString());
|
||||
return Lists.newArrayList(pathsToJSLib);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user