diff --git a/compiler/tests/compiler-tests.iml b/compiler/tests/compiler-tests.iml index bafde0d6bff..f02d57b1c8d 100644 --- a/compiler/tests/compiler-tests.iml +++ b/compiler/tests/compiler-tests.iml @@ -19,6 +19,6 @@ + - - + \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/JetTestUtils.java b/compiler/tests/org/jetbrains/jet/JetTestUtils.java index 095322f77d5..94b7bbcf901 100644 --- a/compiler/tests/org/jetbrains/jet/JetTestUtils.java +++ b/compiler/tests/org/jetbrains/jet/JetTestUtils.java @@ -112,7 +112,7 @@ public class JetTestUtils { * * Several files may follow one module */ - public static final Pattern FILE_OR_MODULE_PATTERN = Pattern.compile("(?://\\s*MODULE:\\s*(\\w+)(\\(\\w+(?:, \\w+)*\\))?\\s*)?" + + public static final Pattern FILE_OR_MODULE_PATTERN = Pattern.compile("(?://\\s*MODULE(?:\\[(\\w+)\\])?:\\s*(\\w+)(\\(\\w+(?:, \\w+)*\\))?\\s*)?" + "//\\s*FILE:\\s*(.*)$", Pattern.MULTILINE); public static final Pattern DIRECTIVE_PATTERN = Pattern.compile("^//\\s*!(\\w+)(:\\s*(.*)$)?", Pattern.MULTILINE); @@ -502,7 +502,7 @@ public class JetTestUtils { public interface TestFileFactory { F createFile(@Nullable M module, @NotNull String fileName, @NotNull String text, @NotNull Map directives); - M createModule(@NotNull String name, @NotNull List dependencies); + M createModule(@NotNull String name, @Nullable String platform, @NotNull List dependencies); } public static abstract class TestFileFactoryNoModules implements TestFileFactory { @@ -520,7 +520,7 @@ public class JetTestUtils { public abstract F create(@NotNull String fileName, @NotNull String text, @NotNull Map directives); @Override - public Void createModule(@NotNull String name, @NotNull List dependencies) { + public Void createModule(@NotNull String name, @Nullable String platform, @NotNull List dependencies) { return null; } } @@ -540,13 +540,14 @@ public class JetTestUtils { M module = null; // Many files while (true) { - String moduleName = matcher.group(1); - String moduleDependencies = matcher.group(2); + String platform = matcher.group(1); + String moduleName = matcher.group(2); + String moduleDependencies = matcher.group(3); if (moduleName != null) { - module = factory.createModule(moduleName, parseDependencies(moduleDependencies)); + module = factory.createModule(moduleName, platform, parseDependencies(moduleDependencies)); } - String fileName = matcher.group(3); + String fileName = matcher.group(4); int start = processedChars; boolean nextFileExists = matcher.find(); diff --git a/compiler/tests/org/jetbrains/jet/asJava/AbstractKotlinLightClassTest.java b/compiler/tests/org/jetbrains/jet/asJava/AbstractKotlinLightClassTest.java index 6c6060a5b12..9e06ce541db 100644 --- a/compiler/tests/org/jetbrains/jet/asJava/AbstractKotlinLightClassTest.java +++ b/compiler/tests/org/jetbrains/jet/asJava/AbstractKotlinLightClassTest.java @@ -21,6 +21,7 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.impl.compiled.ClsElementImpl; import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.checkers.KotlinMultiFileTestWithWithJava; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; @@ -76,7 +77,7 @@ public abstract class AbstractKotlinLightClassTest extends KotlinMultiFileTestWi } @Override - protected Void createTestModule(String name) { + protected Void createTestModule(@NotNull String name, @Nullable String platform) { return null; } diff --git a/compiler/tests/org/jetbrains/jet/checkers/AbstractJetDiagnosticsTest.java b/compiler/tests/org/jetbrains/jet/checkers/AbstractJetDiagnosticsTest.java index 6dc39263ac1..51686fc5969 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/AbstractJetDiagnosticsTest.java +++ b/compiler/tests/org/jetbrains/jet/checkers/AbstractJetDiagnosticsTest.java @@ -54,6 +54,9 @@ import org.jetbrains.jet.storage.LockBasedStorageManager; import org.jetbrains.jet.test.util.DescriptorValidator; import org.jetbrains.jet.test.util.RecursiveDescriptorComparator; import org.jetbrains.jet.utils.UtilsPackage; +import org.jetbrains.k2js.analyze.TopDownAnalyzerFacadeForJS; +import org.jetbrains.k2js.config.Config; +import org.jetbrains.k2js.config.EcmaVersion; import java.io.File; import java.util.*; @@ -114,8 +117,6 @@ public abstract class AbstractJetDiagnosticsTest extends BaseDiagnosticsTest { module.seal(); } - // New JavaDescriptorResolver is created for each module, which is good because it emulates different Java libraries for each module, - // albeit with same class names ExceptionTracker tracker = new ExceptionTracker(); GlobalContext context = new SimpleGlobalContext( new LoggingStorageManager( @@ -124,17 +125,7 @@ public abstract class AbstractJetDiagnosticsTest extends BaseDiagnosticsTest { ), tracker ); - - TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegrationWithCustomContext( - getProject(), - context, - jetFiles, - moduleTrace, - Predicates.alwaysTrue(), - module, - null, - null - ); + analyzeModuleContents(context, jetFiles, module, moduleTrace, testModule); checkAllResolvedCallsAreCompleted(jetFiles, moduleTrace.getBindingContext()); } @@ -209,6 +200,49 @@ public abstract class AbstractJetDiagnosticsTest extends BaseDiagnosticsTest { return new File(FileUtil.getNameWithoutExtension(testDataFile.getAbsolutePath()) + ".lazy.log"); } + protected void analyzeModuleContents( + GlobalContext context, + List jetFiles, + ModuleDescriptorImpl module, + BindingTrace moduleTrace, + TestModule testModule + ) { + + String platform = getPlatform(testModule); + if ("jvm".equals(platform)) { + // New JavaDescriptorResolver is created for each module, which is good because it emulates different Java libraries for each module, + // albeit with same class names + TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegrationWithCustomContext( + getProject(), + context, + jetFiles, + moduleTrace, + Predicates.alwaysTrue(), + module, + null, + null + ); + } + else if ("js".equals(platform)) { + TopDownAnalyzerFacadeForJS.analyzeFilesWithGivenTrace( + jetFiles, + moduleTrace, + module, + Predicates.alwaysTrue(), + new Config(getProject(), "module", EcmaVersion.v5, false, true) { + @NotNull + @Override + protected List generateLibFiles() { + return Collections.emptyList(); + } + } + ); + } + else { + throw new IllegalStateException("Unknown platform in module " + testModule.getName() + ": " + platform); + } + } + private void validateAndCompareDescriptorWithFile( File expectedFile, List testFiles, @@ -281,12 +315,12 @@ public abstract class AbstractJetDiagnosticsTest extends BaseDiagnosticsTest { return RECURSIVE.filterRecursion(stepIntoFilter).withValidationStrategy(DescriptorValidator.ValidationVisitor.errorTypesAllowed()); } - public static Map createModules(Map> groupedByModule) { + private Map createModules(Map> groupedByModule) { Map modules = new HashMap(); for (TestModule testModule : groupedByModule.keySet()) { if (testModule == null) continue; - ModuleDescriptorImpl module = TopDownAnalyzerFacadeForJVM.createJavaModule("<" + testModule.getName() + ">"); + ModuleDescriptorImpl module = createModule(testModule); modules.put(testModule, module); } @@ -302,6 +336,28 @@ public abstract class AbstractJetDiagnosticsTest extends BaseDiagnosticsTest { return modules; } + protected ModuleDescriptorImpl createModule(TestModule testModule) { + String name = "<" + testModule.getName() + ">"; + String platform = getPlatform(testModule); + if ("jvm".equals(platform)) { + return TopDownAnalyzerFacadeForJVM.createJavaModule(name); + } + else if ("js".equals(platform)) { + return TopDownAnalyzerFacadeForJS.createJsModule(name); + } + + throw new IllegalStateException("Unknown platform in module " + testModule.getName() + ": " + platform); + } + + @NotNull + private static String getPlatform(@Nullable TestModule testModule) { + if (testModule == null) return "jvm"; + + String platform = testModule.getPlatform(); + if (platform == null) return "jvm"; + return platform; + } + private static void checkAllResolvedCallsAreCompleted(@NotNull List jetFiles, @NotNull BindingContext bindingContext) { for (JetFile file : jetFiles) { if (!AnalyzingUtils.getSyntaxErrorRanges(file).isEmpty()) { diff --git a/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java b/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java index 97cc4fe60c2..49d48fc65be 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java +++ b/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java @@ -79,8 +79,8 @@ public abstract class BaseDiagnosticsTest extends public static final boolean CHECK_LAZY_LOG_DEFAULT = "true".equals(System.getProperty("check.lazy.logs", "false")); @Override - protected TestModule createTestModule(String name) { - return new TestModule(name); + protected TestModule createTestModule(@NotNull String name, @Nullable String platform) { + return new TestModule(name, platform); } @Override @@ -208,10 +208,12 @@ public abstract class BaseDiagnosticsTest extends protected static class TestModule implements Comparable { private final String name; + private final String platform; private final List dependencies = new ArrayList(); - public TestModule(@NotNull String name) { + public TestModule(@NotNull String name, @Nullable String platform) { this.name = name; + this.platform = platform; } @NotNull @@ -219,6 +221,11 @@ public abstract class BaseDiagnosticsTest extends return name; } + @Nullable + public String getPlatform() { + return platform; + } + @NotNull public List getDependencies() { return dependencies; diff --git a/compiler/tests/org/jetbrains/jet/checkers/KotlinMultiFileTestWithWithJava.java b/compiler/tests/org/jetbrains/jet/checkers/KotlinMultiFileTestWithWithJava.java index 34894d32bef..5dbd6420d26 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/KotlinMultiFileTestWithWithJava.java +++ b/compiler/tests/org/jetbrains/jet/checkers/KotlinMultiFileTestWithWithJava.java @@ -126,8 +126,8 @@ public abstract class KotlinMultiFileTestWithWithJava extends JetLiteFixtu } @Override - public M createModule(@NotNull String name, @NotNull List dependencies) { - M module = createTestModule(name); + public M createModule(@NotNull String name, @Nullable String platform, @NotNull List dependencies) { + M module = createTestModule(name, platform); ModuleAndDependencies oldValue = modules.put(name, new ModuleAndDependencies(module, dependencies)); assert oldValue == null : "Module " + name + " declared more than once"; @@ -138,7 +138,7 @@ public abstract class KotlinMultiFileTestWithWithJava extends JetLiteFixtu doMultiFileTest(file, modules, testFiles); } - protected abstract M createTestModule(String name); + protected abstract M createTestModule(@NotNull String name, @Nullable String platform); protected abstract F createTestFile(M module, String fileName, String text, Map directives); diff --git a/js/js.frontend/src/org/jetbrains/k2js/analyze/TopDownAnalyzerFacadeForJS.java b/js/js.frontend/src/org/jetbrains/k2js/analyze/TopDownAnalyzerFacadeForJS.java index f734f5bfb3e..f53f49bbfb3 100644 --- a/js/js.frontend/src/org/jetbrains/k2js/analyze/TopDownAnalyzerFacadeForJS.java +++ b/js/js.frontend/src/org/jetbrains/k2js/analyze/TopDownAnalyzerFacadeForJS.java @@ -63,9 +63,32 @@ public final class TopDownAnalyzerFacadeForJS { @NotNull Predicate filesToAnalyzeCompletely, @NotNull Config config ) { - Project project = config.getProject(); + BindingContext libraryContext = config.getLibraryContext(); + BindingTrace trace = libraryContext == null + ? new BindingTraceContext() + : new DelegatingBindingTrace(libraryContext, "trace with preanalyzed library"); - ModuleDescriptorImpl owner = createJsModule(""); + ModuleDescriptorImpl module = createJsModule(""); + module.addDependencyOnModule(module); + module.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule()); + ModuleDescriptor libraryModule = config.getLibraryModule(); + if (libraryModule != null) { + module.addDependencyOnModule((ModuleDescriptorImpl) libraryModule); // "import" analyzed library module + } + module.seal(); + + return analyzeFilesWithGivenTrace(files, trace, module, filesToAnalyzeCompletely, config); + } + + @NotNull + public static AnalysisResult analyzeFilesWithGivenTrace( + @NotNull Collection files, + @NotNull BindingTrace trace, + @NotNull ModuleDescriptorImpl module, + @NotNull Predicate filesToAnalyzeCompletely, + @NotNull Config config + ) { + Project project = config.getProject(); Predicate completely = Predicates.and(notLibFiles(config.getLibFiles()), filesToAnalyzeCompletely); @@ -73,25 +96,13 @@ public final class TopDownAnalyzerFacadeForJS { TopDownAnalysisParameters topDownAnalysisParameters = TopDownAnalysisParameters.create( globalContext.getStorageManager(), globalContext.getExceptionTracker(), completely, false, false); - owner.addDependencyOnModule(owner); - owner.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule()); - ModuleDescriptor libraryModule = config.getLibraryModule(); - if (libraryModule != null) { - owner.addDependencyOnModule((ModuleDescriptorImpl) libraryModule); // "import" analyzed library module - } - owner.seal(); - - BindingContext libraryContext = config.getLibraryContext(); - BindingTrace trace = libraryContext == null - ? new BindingTraceContext() - : new DelegatingBindingTrace(libraryContext, "trace with preanalyzed library"); - InjectorForTopDownAnalyzerForJs injector = new InjectorForTopDownAnalyzerForJs(project, topDownAnalysisParameters, trace, owner); + InjectorForTopDownAnalyzerForJs injector = new InjectorForTopDownAnalyzerForJs(project, topDownAnalysisParameters, trace, module); try { - Collection allFiles = libraryModule != null ? + Collection allFiles = config.getLibraryModule() != null ? files : Config.withJsLibAdded(files, config); injector.getTopDownAnalyzer().analyzeFiles(topDownAnalysisParameters, allFiles); - return AnalysisResult.success(trace.getBindingContext(), owner); + return AnalysisResult.success(trace.getBindingContext(), module); } finally { injector.destroy(); @@ -118,7 +129,7 @@ public final class TopDownAnalyzerFacadeForJS { } @NotNull - private static ModuleDescriptorImpl createJsModule(@NotNull String name) { + public static ModuleDescriptorImpl createJsModule(@NotNull String name) { return new ModuleDescriptorImpl(Name.special(name), DEFAULT_IMPORTS, PlatformToKotlinClassMap.EMPTY); }