JS backend: check libraries in cli compiler before translation

This commit is contained in:
Michael Nedzelsky
2014-12-08 12:41:34 +03:00
parent 8e052a9ade
commit f8f7ea8998
10 changed files with 121 additions and 13 deletions
@@ -28,6 +28,8 @@ import com.intellij.util.Function;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import kotlin.Function0;
import kotlin.Function1;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.OutputFileCollection;
@@ -79,7 +81,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
protected ExitCode doExecute(
@NotNull K2JSCompilerArguments arguments,
@NotNull Services services,
@NotNull MessageCollector messageCollector,
@NotNull final MessageCollector messageCollector,
@NotNull Disposable rootDisposable
) {
if (arguments.freeArgs.isEmpty()) {
@@ -109,6 +111,16 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
File outputFile = new File(arguments.outputFile);
Config config = getConfig(arguments, project);
if (config.checkLibFilesAndReportErrors(new Function1<String, Unit>() {
@Override
public Unit invoke(String message) {
messageCollector.report(CompilerMessageSeverity.ERROR, message, CompilerMessageLocation.NO_LOCATION);
return Unit.INSTANCE$;
}
})) {
return COMPILATION_ERROR;
}
if (analyzeAndReportErrors(messageCollector, sourcesFiles, config)) {
return COMPILATION_ERROR;
}
@@ -0,0 +1,5 @@
$TESTDATA_DIR$/withLib.kt
-library-files
not/existing/path
-output
$TEMP_DIR$/out.js
@@ -0,0 +1,2 @@
ERROR: Path 'not/existing/path'does not exist
COMPILATION_ERROR
@@ -0,0 +1,5 @@
$TESTDATA_DIR$/withLib.kt
-library-files
compiler/integration-tests/testData/ant/js/simpleWithStdlibAndFolderAsAnotherLib
-output
$TEMP_DIR$/out.js
@@ -0,0 +1,2 @@
ERROR: 'compiler/integration-tests/testData/ant/js/simpleWithStdlibAndFolderAsAnotherLib' is not a valid Kotlin Javascript library
COMPILATION_ERROR
@@ -168,6 +168,12 @@ public class KotlincExecutableTestGenerated extends AbstractKotlincExecutableTes
doJsTest(fileName);
}
@TestMetadata("libraryDirNotFound.args")
public void testLibraryDirNotFound() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/cli/js/libraryDirNotFound.args");
doJsTest(fileName);
}
@TestMetadata("nativeDeclarations.args")
public void testNativeDeclarations() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/cli/js/nativeDeclarations.args");
@@ -180,6 +186,12 @@ public class KotlincExecutableTestGenerated extends AbstractKotlincExecutableTes
doJsTest(fileName);
}
@TestMetadata("notValidLibraryDir.args")
public void testNotValidLibraryDir() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/cli/js/notValidLibraryDir.args");
doJsTest(fileName);
}
@TestMetadata("outputPostfixFileNotFound.args")
public void testOutputPostfixFileNotFound() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/cli/js/outputPostfixFileNotFound.args");
@@ -76,4 +76,18 @@ public class K2JsCliTest extends CliBaseTest {
Assert.assertTrue(new File(tmpdir.getTmpDir(), "out.js").isFile());
}
@Test
public void libraryDirNotFound() throws Exception {
executeCompilerCompareOutputJS();
Assert.assertFalse(new File(tmpdir.getTmpDir(), "out.js").isFile());
}
@Test
public void notValidLibraryDir() throws Exception {
executeCompilerCompareOutputJS();
Assert.assertFalse(new File(tmpdir.getTmpDir(), "out.js").isFile());
}
}
@@ -18,6 +18,8 @@ package org.jetbrains.k2js.config;
import com.google.common.collect.Lists;
import com.intellij.openapi.project.Project;
import kotlin.Function1;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
@@ -82,6 +84,8 @@ public abstract class Config {
return moduleId;
}
public abstract boolean checkLibFilesAndReportErrors(@NotNull Function1<String, Unit> report);
@NotNull
protected abstract List<JetFile> generateLibFiles();
@@ -16,7 +16,6 @@
package org.jetbrains.k2js.config;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
@@ -24,7 +23,11 @@ import com.intellij.openapi.vfs.*;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.util.io.URLUtil;
import kotlin.Function1;
import kotlin.Function2;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.plugin.JetFileType;
import org.jetbrains.k2js.JavaScript;
@@ -43,8 +46,6 @@ public class LibrarySourcesConfig extends Config {
@NotNull
public static final String UNKNOWN_EXTERNAL_MODULE_NAME = "<unknown>";
@NotNull
private static final Logger LOG = Logger.getInstance("#org.jetbrains.k2js.config.LibrarySourcesConfig");
public static final String STDLIB_JS_MODULE_NAME = "stdlib";
public static final String BUILTINS_JS_MODULE_NAME = "builtins";
public static final String BUILTINS_JS_FILE_NAME = BUILTINS_JS_MODULE_NAME + JavaScript.DOT_EXTENSION;
@@ -72,11 +73,44 @@ public class LibrarySourcesConfig extends Config {
return Collections.emptyList();
}
List<JetFile> jetFiles = new ArrayList<JetFile>();
final List<JetFile> jetFiles = new ArrayList<JetFile>();
final PsiManager psiManager = PsiManager.getInstance(getProject());
Function1<String, Unit> report = new Function1<String, Unit>() {
@Override
public Unit invoke(String message) {
throw new IllegalStateException(message);
}
};
Function2<String, VirtualFile, Unit> action = new Function2<String, VirtualFile, Unit>() {
@Override
public Unit invoke(String moduleName, VirtualFile file) {
JetFileCollector jetFileCollector = new JetFileCollector(jetFiles, moduleName, psiManager);
VfsUtilCore.visitChildrenRecursively(file, jetFileCollector);
return Unit.INSTANCE$;
}
};
boolean hasErrors = checkLibFilesAndReportErrors(report, action);
assert !hasErrors : "hasErrors should be false";
return jetFiles;
}
@Override
public boolean checkLibFilesAndReportErrors(@NotNull Function1<String, Unit> report) {
return checkLibFilesAndReportErrors(report, null);
}
private boolean checkLibFilesAndReportErrors(@NotNull Function1<String, Unit> report, @Nullable Function2<String, VirtualFile, Unit> action) {
if (files.isEmpty()) {
return false;
}
VirtualFileSystem fileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL);
VirtualFileSystem jarFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JAR_PROTOCOL);
PsiManager psiManager = PsiManager.getInstance(getProject());
String moduleName = null;
for (String path : files) {
@@ -87,6 +121,12 @@ public class LibrarySourcesConfig extends Config {
continue;
}
File filePath = new File(path);
if (!filePath.exists()) {
report.invoke("Path '" + path + "'does not exist");
return true;
}
if (path.endsWith(".jar") || path.endsWith(".zip")) {
file = jarFileSystem.findFileByPath(path + URLUtil.JAR_SEPARATOR);
}
@@ -95,23 +135,29 @@ public class LibrarySourcesConfig extends Config {
}
if (file == null) {
LOG.error("File '" + path + "' not found.'");
report.invoke("File '" + path + "'does not exist or could not be read");
return true;
}
else {
File filePath = new File(path);
if (isKotlinJavascriptLibrary(filePath)) {
actualModuleName = LibraryUtils.getKotlinJsModuleName(filePath);
}
if (actualModuleName == null) {
LOG.error("Could not find " + LibraryUtils.KOTLIN_JS_MODULE_NAME + " for " + filePath);
else if (actualModuleName == null) {
report.invoke("'" + path + "' is not a valid Kotlin Javascript library");
return true;
}
if (actualModuleName == null) {
report.invoke("Could not find " + LibraryUtils.KOTLIN_JS_MODULE_NAME + " for '" + path + "'");
return true;
}
if (action != null) {
action.invoke(actualModuleName, file);
}
JetFileCollector jetFileCollector = new JetFileCollector(jetFiles, actualModuleName, psiManager);
VfsUtilCore.visitChildrenRecursively(file, jetFileCollector);
}
moduleName = null;
}
return jetFiles;
return false;
}
protected JetFile getJetFileByVirtualFile(VirtualFile file, String moduleName, PsiManager psiManager) {
@@ -22,6 +22,8 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import kotlin.Function1;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.analyzer.AnalysisResult;
@@ -137,6 +139,10 @@ public class LibrarySourcesConfigWithCaching extends LibrarySourcesConfig {
protected List<JetFile> generateLibFiles() {
return Collections.emptyList();
}
@Override
public boolean checkLibFilesAndReportErrors(@NotNull Function1<String, Unit> report) {
return false;
}
};
}
}