From f8f7ea8998b7d6907df4bbc447e6566904232745 Mon Sep 17 00:00:00 2001 From: Michael Nedzelsky Date: Mon, 8 Dec 2014 12:41:34 +0300 Subject: [PATCH] JS backend: check libraries in cli compiler before translation --- .../jetbrains/jet/cli/js/K2JSCompiler.java | 14 +++- .../testData/cli/js/libraryDirNotFound.args | 5 ++ .../testData/cli/js/libraryDirNotFound.out | 2 + .../testData/cli/js/notValidLibraryDir.args | 5 ++ .../testData/cli/js/notValidLibraryDir.out | 2 + .../cli/KotlincExecutableTestGenerated.java | 12 ++++ .../org/jetbrains/jet/cli/js/K2JsCliTest.java | 14 ++++ .../src/org/jetbrains/k2js/config/Config.java | 4 ++ .../k2js/config/LibrarySourcesConfig.java | 70 +++++++++++++++---- .../LibrarySourcesConfigWithCaching.java | 6 ++ 10 files changed, 121 insertions(+), 13 deletions(-) create mode 100644 compiler/testData/cli/js/libraryDirNotFound.args create mode 100644 compiler/testData/cli/js/libraryDirNotFound.out create mode 100644 compiler/testData/cli/js/notValidLibraryDir.args create mode 100644 compiler/testData/cli/js/notValidLibraryDir.out 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 125c7daa75a..5c7a43bf0c4 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java @@ -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 { 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 { File outputFile = new File(arguments.outputFile); Config config = getConfig(arguments, project); + if (config.checkLibFilesAndReportErrors(new Function1() { + @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; } diff --git a/compiler/testData/cli/js/libraryDirNotFound.args b/compiler/testData/cli/js/libraryDirNotFound.args new file mode 100644 index 00000000000..c145bc0a751 --- /dev/null +++ b/compiler/testData/cli/js/libraryDirNotFound.args @@ -0,0 +1,5 @@ +$TESTDATA_DIR$/withLib.kt +-library-files +not/existing/path +-output +$TEMP_DIR$/out.js diff --git a/compiler/testData/cli/js/libraryDirNotFound.out b/compiler/testData/cli/js/libraryDirNotFound.out new file mode 100644 index 00000000000..3edf354d04a --- /dev/null +++ b/compiler/testData/cli/js/libraryDirNotFound.out @@ -0,0 +1,2 @@ +ERROR: Path 'not/existing/path'does not exist +COMPILATION_ERROR \ No newline at end of file diff --git a/compiler/testData/cli/js/notValidLibraryDir.args b/compiler/testData/cli/js/notValidLibraryDir.args new file mode 100644 index 00000000000..8919d7856e8 --- /dev/null +++ b/compiler/testData/cli/js/notValidLibraryDir.args @@ -0,0 +1,5 @@ +$TESTDATA_DIR$/withLib.kt +-library-files +compiler/integration-tests/testData/ant/js/simpleWithStdlibAndFolderAsAnotherLib +-output +$TEMP_DIR$/out.js diff --git a/compiler/testData/cli/js/notValidLibraryDir.out b/compiler/testData/cli/js/notValidLibraryDir.out new file mode 100644 index 00000000000..6b388c9055a --- /dev/null +++ b/compiler/testData/cli/js/notValidLibraryDir.out @@ -0,0 +1,2 @@ +ERROR: 'compiler/integration-tests/testData/ant/js/simpleWithStdlibAndFolderAsAnotherLib' is not a valid Kotlin Javascript library +COMPILATION_ERROR \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/cli/KotlincExecutableTestGenerated.java b/compiler/tests/org/jetbrains/jet/cli/KotlincExecutableTestGenerated.java index adb9d8f4954..330441a5a72 100644 --- a/compiler/tests/org/jetbrains/jet/cli/KotlincExecutableTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/cli/KotlincExecutableTestGenerated.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/jet/cli/js/K2JsCliTest.java b/compiler/tests/org/jetbrains/jet/cli/js/K2JsCliTest.java index 12a1dafbdf9..6eaaa3218d4 100644 --- a/compiler/tests/org/jetbrains/jet/cli/js/K2JsCliTest.java +++ b/compiler/tests/org/jetbrains/jet/cli/js/K2JsCliTest.java @@ -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()); + } } diff --git a/js/js.frontend/src/org/jetbrains/k2js/config/Config.java b/js/js.frontend/src/org/jetbrains/k2js/config/Config.java index 10deea6706c..0d1c46fe193 100644 --- a/js/js.frontend/src/org/jetbrains/k2js/config/Config.java +++ b/js/js.frontend/src/org/jetbrains/k2js/config/Config.java @@ -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 report); + @NotNull protected abstract List generateLibFiles(); diff --git a/js/js.frontend/src/org/jetbrains/k2js/config/LibrarySourcesConfig.java b/js/js.frontend/src/org/jetbrains/k2js/config/LibrarySourcesConfig.java index 90bcf5919eb..95f3033c846 100644 --- a/js/js.frontend/src/org/jetbrains/k2js/config/LibrarySourcesConfig.java +++ b/js/js.frontend/src/org/jetbrains/k2js/config/LibrarySourcesConfig.java @@ -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 = ""; - @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 jetFiles = new ArrayList(); + final List jetFiles = new ArrayList(); + final PsiManager psiManager = PsiManager.getInstance(getProject()); + + Function1 report = new Function1() { + @Override + public Unit invoke(String message) { + throw new IllegalStateException(message); + } + }; + + Function2 action = new Function2() { + @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 report) { + return checkLibFilesAndReportErrors(report, null); + } + + private boolean checkLibFilesAndReportErrors(@NotNull Function1 report, @Nullable Function2 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) { diff --git a/js/js.frontend/src/org/jetbrains/k2js/config/LibrarySourcesConfigWithCaching.java b/js/js.frontend/src/org/jetbrains/k2js/config/LibrarySourcesConfigWithCaching.java index caa1a523c83..a6a697c335f 100644 --- a/js/js.frontend/src/org/jetbrains/k2js/config/LibrarySourcesConfigWithCaching.java +++ b/js/js.frontend/src/org/jetbrains/k2js/config/LibrarySourcesConfigWithCaching.java @@ -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 generateLibFiles() { return Collections.emptyList(); } + @Override + public boolean checkLibFilesAndReportErrors(@NotNull Function1 report) { + return false; + } }; } }