diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/AbstractJetDiagnosticsTestWithJsStdLib.java b/compiler/tests/org/jetbrains/kotlin/checkers/AbstractJetDiagnosticsTestWithJsStdLib.java
index 7d8027dd19a..5da39652045 100644
--- a/compiler/tests/org/jetbrains/kotlin/checkers/AbstractJetDiagnosticsTestWithJsStdLib.java
+++ b/compiler/tests/org/jetbrains/kotlin/checkers/AbstractJetDiagnosticsTestWithJsStdLib.java
@@ -23,22 +23,19 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
import org.jetbrains.kotlin.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.kotlin.config.CompilerConfiguration;
import org.jetbrains.kotlin.context.GlobalContext;
-import org.jetbrains.kotlin.descriptors.ModuleDescriptor;
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS;
import org.jetbrains.kotlin.js.config.EcmaVersion;
+import org.jetbrains.kotlin.js.config.LibrarySourcesConfig;
import org.jetbrains.kotlin.js.config.LibrarySourcesConfigWithCaching;
import org.jetbrains.kotlin.psi.JetFile;
-import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingTrace;
-import org.jetbrains.kotlin.resolve.DelegatingBindingTrace;
import java.util.List;
import java.util.Map;
public abstract class AbstractJetDiagnosticsTestWithJsStdLib extends AbstractJetDiagnosticsTest {
-
- private LibrarySourcesConfigWithCaching config;
+ private LibrarySourcesConfig config;
@Override
protected void setUp() throws Exception {
@@ -65,12 +62,7 @@ public abstract class AbstractJetDiagnosticsTestWithJsStdLib extends AbstractJet
ModuleDescriptorImpl module,
BindingTrace moduleTrace
) {
- BindingContext libraryContext = config.getLibraryContext();
- DelegatingBindingTrace trace = new DelegatingBindingTrace(libraryContext, "trace with preanalyzed library");
-
TopDownAnalyzerFacadeForJS.analyzeFilesWithGivenTrace(jetFiles, moduleTrace, module, config);
-
- trace.addAllMyDataTo(moduleTrace);
}
@Override
@@ -93,9 +85,9 @@ public abstract class AbstractJetDiagnosticsTestWithJsStdLib extends AbstractJet
module.addDependencyOnModule(module);
module.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule());
- ModuleDescriptor libraryModule = config.getLibraryModule();
- assert libraryModule instanceof ModuleDescriptorImpl;
- module.addDependencyOnModule((ModuleDescriptorImpl) libraryModule);
+ for(ModuleDescriptorImpl moduleDescriptor : config.getModuleDescriptors()) {
+ module.addDependencyOnModule(moduleDescriptor);
+ }
module.seal();
diff --git a/js/js.frontend/js.frontend.iml b/js/js.frontend/js.frontend.iml
index 0d9bc35f0f2..8ead2455283 100644
--- a/js/js.frontend/js.frontend.iml
+++ b/js/js.frontend/js.frontend.iml
@@ -12,5 +12,7 @@
+
+
\ No newline at end of file
diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.java b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.java
index 871d506ff64..29047d4ada9 100644
--- a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.java
+++ b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.java
@@ -19,11 +19,9 @@ package org.jetbrains.kotlin.js.analyze;
import com.google.common.collect.ImmutableList;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.kotlin.analyzer.AnalysisResult;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.context.ContextPackage;
import org.jetbrains.kotlin.context.GlobalContextImpl;
-import org.jetbrains.kotlin.descriptors.ModuleDescriptor;
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider;
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
import org.jetbrains.kotlin.di.InjectorForTopDownAnalyzerForJs;
@@ -55,18 +53,16 @@ public final class TopDownAnalyzerFacadeForJS {
@NotNull Collection files,
@NotNull Config config
) {
- BindingContext libraryContext = config.getLibraryContext();
- BindingTrace trace = libraryContext == null
- ? new BindingTraceContext()
- : new DelegatingBindingTrace(libraryContext, "trace with preanalyzed library");
+ BindingTrace trace = new BindingTraceContext();
ModuleDescriptorImpl module = createJsModule("<" + config.getModuleId() + ">");
module.addDependencyOnModule(module);
module.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule());
- ModuleDescriptor libraryModule = config.getLibraryModule();
- if (libraryModule != null) {
- module.addDependencyOnModule((ModuleDescriptorImpl) libraryModule); // "import" analyzed library module
+
+ for(ModuleDescriptorImpl moduleDescriptor : config.getModuleDescriptors()) {
+ module.addDependencyOnModule(moduleDescriptor);
}
+
module.seal();
return analyzeFilesWithGivenTrace(files, trace, module, config);
@@ -85,10 +81,8 @@ public final class TopDownAnalyzerFacadeForJS {
TopDownAnalysisParameters topDownAnalysisParameters = TopDownAnalysisParameters.create(
globalContext.getStorageManager(), globalContext.getExceptionTracker(), false, false);
- Collection allFiles = config.getLibraryModule() != null ?
- files :
- Config.withJsLibAdded(files, config);
-
+ Collection allFiles = Config.withJsLibAdded(files, config);
+
InjectorForTopDownAnalyzerForJs injector = new InjectorForTopDownAnalyzerForJs(
project, topDownAnalysisParameters, trace, module,
new FileBasedDeclarationProviderFactory(topDownAnalysisParameters.getStorageManager(), allFiles));
@@ -113,5 +107,4 @@ public final class TopDownAnalyzerFacadeForJS {
public static ModuleDescriptorImpl createJsModule(@NotNull String name) {
return new ModuleDescriptorImpl(Name.special(name), DEFAULT_IMPORTS, PlatformToKotlinClassMap.EMPTY);
}
-
}
diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/config/Config.java b/js/js.frontend/src/org/jetbrains/kotlin/js/config/Config.java
index adab164e589..c2ea60bf37a 100644
--- a/js/js.frontend/src/org/jetbrains/kotlin/js/config/Config.java
+++ b/js/js.frontend/src/org/jetbrains/kotlin/js/config/Config.java
@@ -18,15 +18,19 @@ package org.jetbrains.kotlin.js.config;
import com.google.common.collect.Lists;
import com.intellij.openapi.project.Project;
+import com.intellij.util.SmartList;
import kotlin.Function1;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.kotlin.descriptors.ModuleDescriptor;
+import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
+import org.jetbrains.kotlin.descriptors.PackageFragmentProvider;
+import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider;
+import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
+import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS;
import org.jetbrains.kotlin.psi.JetFile;
-import org.jetbrains.kotlin.resolve.BindingContext;
-import org.jetbrains.kotlin.resolve.BindingTrace;
-import org.jetbrains.kotlin.resolve.BindingTraceContext;
+import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil;
+import org.jetbrains.kotlin.utils.KotlinJavascriptMetadata;
import java.util.Collection;
import java.util.List;
@@ -39,8 +43,8 @@ public abstract class Config {
@NotNull
private final Project project;
- @Nullable
- private List libFiles = null;
+ @NotNull
+ private final List sourceFilesFromLibraries = new SmartList();
@NotNull
private final EcmaVersion target;
@@ -49,6 +53,14 @@ public abstract class Config {
private final boolean sourcemap;
+ @NotNull
+ protected final List metadata = new SmartList();
+
+ @Nullable
+ private List moduleDescriptors = null;
+
+ private boolean initialized = false;
+
public Config(
@NotNull Project project,
@NotNull String moduleId,
@@ -88,36 +100,59 @@ public abstract class Config {
public abstract boolean checkLibFilesAndReportErrors(@NotNull Function1 report);
- @NotNull
- protected abstract List generateLibFiles();
+ protected abstract void init(@NotNull List sourceFilesInLibraries, @NotNull List metadata);
@NotNull
- public final List getLibFiles() {
- if (libFiles == null) {
- libFiles = generateLibFiles();
+ public List getModuleDescriptors() {
+ init();
+ if (moduleDescriptors != null) return moduleDescriptors;
+
+ moduleDescriptors = new SmartList();
+ for(KotlinJavascriptMetadata metadataEntry : metadata) {
+ moduleDescriptors.add(createModuleDescriptor(metadataEntry));
}
- return libFiles;
+
+ return moduleDescriptors;
}
- @Nullable
- public BindingContext getLibraryContext() {
- return null;
+ @NotNull
+ public List getSourceFilesFromLibraries() {
+ init();
+ return sourceFilesFromLibraries;
}
- @Nullable
- public ModuleDescriptor getLibraryModule() {
- return null;
+
+ public boolean isTestConfig() {
+ return false;
+ }
+
+ private void init() {
+ if (initialized) return;
+
+ init(sourceFilesFromLibraries, metadata);
+ initialized = true;
+ }
+
+ private static ModuleDescriptorImpl createModuleDescriptor(KotlinJavascriptMetadata metadata) {
+ ModuleDescriptorImpl moduleDescriptor = TopDownAnalyzerFacadeForJS.createJsModule("<" + metadata.getModuleName() + ">");
+
+ List providers = KotlinJavascriptSerializationUtil
+ .getPackageFragmentProviders(moduleDescriptor, metadata.getBody());
+ CompositePackageFragmentProvider compositePackageFragmentProvider = new CompositePackageFragmentProvider(providers);
+
+ moduleDescriptor.initialize(compositePackageFragmentProvider);
+ moduleDescriptor.addDependencyOnModule(moduleDescriptor);
+ moduleDescriptor.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule());
+ moduleDescriptor.seal();
+
+ return moduleDescriptor;
}
@NotNull
public static Collection withJsLibAdded(@NotNull Collection files, @NotNull Config config) {
Collection allFiles = Lists.newArrayList();
allFiles.addAll(files);
- allFiles.addAll(config.getLibFiles());
+ allFiles.addAll(config.getSourceFilesFromLibraries());
return allFiles;
}
-
- public boolean isTestConfig() {
- return false;
- }
}
diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/config/LibrarySourcesConfig.java b/js/js.frontend/src/org/jetbrains/kotlin/js/config/LibrarySourcesConfig.java
index 063c8f885ee..9e15abab859 100644
--- a/js/js.frontend/src/org/jetbrains/kotlin/js/config/LibrarySourcesConfig.java
+++ b/js/js.frontend/src/org/jetbrains/kotlin/js/config/LibrarySourcesConfig.java
@@ -22,24 +22,24 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
+import com.intellij.util.PathUtil;
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.kotlin.js.JavaScript;
import org.jetbrains.kotlin.idea.JetFileType;
+import org.jetbrains.kotlin.js.JavaScript;
import org.jetbrains.kotlin.psi.JetFile;
+import org.jetbrains.kotlin.utils.KotlinJavascriptMetadata;
+import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils;
import org.jetbrains.kotlin.utils.LibraryUtils;
import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
-import static org.jetbrains.kotlin.utils.LibraryUtils.isKotlinJavascriptLibrary;
-import static org.jetbrains.kotlin.utils.LibraryUtils.isKotlinJavascriptStdLibrary;
+import static org.jetbrains.kotlin.utils.LibraryUtils.*;
public class LibrarySourcesConfig extends Config {
@NotNull
@@ -72,14 +72,10 @@ public class LibrarySourcesConfig extends Config {
return files;
}
- @NotNull
@Override
- protected List generateLibFiles() {
- if (files.isEmpty()) {
- return Collections.emptyList();
- }
+ protected void init(@NotNull final List sourceFilesInLibraries, @NotNull final List metadata) {
+ if (files.isEmpty()) return;
- final List jetFiles = new ArrayList();
final PsiManager psiManager = PsiManager.getInstance(getProject());
Function1 report = new Function1() {
@@ -92,16 +88,22 @@ public class LibrarySourcesConfig extends Config {
Function2 action = new Function2() {
@Override
public Unit invoke(String moduleName, VirtualFile file) {
- JetFileCollector jetFileCollector = new JetFileCollector(jetFiles, moduleName, psiManager);
- VfsUtilCore.visitChildrenRecursively(file, jetFileCollector);
+ if (moduleName != null) {
+ JetFileCollector jetFileCollector = new JetFileCollector(sourceFilesInLibraries, moduleName, psiManager);
+ VfsUtilCore.visitChildrenRecursively(file, jetFileCollector);
+ }
+ else {
+ String libraryPath = PathUtil.getLocalPath(file);
+ assert libraryPath != null : "libraryPath for " + file + " should not be null";
+ metadata.addAll(KotlinJavascriptMetadataUtils.loadMetadata(libraryPath));
+ }
+
return Unit.INSTANCE$;
}
};
boolean hasErrors = checkLibFilesAndReportErrors(report, action);
assert !hasErrors : "hasErrors should be false";
-
- return jetFiles;
}
@Override
@@ -121,7 +123,6 @@ public class LibrarySourcesConfig extends Config {
for (String path : files) {
VirtualFile file;
- String actualModuleName = moduleName;
if (path.charAt(0) == '@') {
moduleName = path.substring(1);
continue;
@@ -145,20 +146,22 @@ public class LibrarySourcesConfig extends Config {
return true;
}
else {
- if (isKotlinJavascriptStdLibrary(filePath)) {
- actualModuleName = STDLIB_JS_MODULE_NAME;
+ String actualModuleName;
+
+ if (moduleName != null) {
+ actualModuleName = moduleName;
}
- else if (isKotlinJavascriptLibrary(filePath)) {
+ else if (isOldKotlinJavascriptLibrary(filePath)) {
actualModuleName = LibraryUtils.getKotlinJsModuleName(filePath);
}
- else if (actualModuleName == null) {
+ else if (isKotlinJavascriptLibraryWithMetadata(filePath)) {
+ actualModuleName = null;
+ }
+ else {
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);
}
@@ -169,7 +172,7 @@ public class LibrarySourcesConfig extends Config {
return false;
}
- protected JetFile getJetFileByVirtualFile(VirtualFile file, String moduleName, PsiManager psiManager) {
+ protected static JetFile getJetFileByVirtualFile(VirtualFile file, String moduleName, PsiManager psiManager) {
PsiFile psiFile = psiManager.findFile(file);
assert psiFile != null;
@@ -181,7 +184,7 @@ public class LibrarySourcesConfig extends Config {
psiFile.putUserData(EXTERNAL_MODULE_NAME, moduleName);
}
- private class JetFileCollector extends VirtualFileVisitor {
+ private static class JetFileCollector extends VirtualFileVisitor {
private final List jetFiles;
private final String moduleName;
private final PsiManager psiManager;
diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/config/LibrarySourcesConfigWithCaching.java b/js/js.frontend/src/org/jetbrains/kotlin/js/config/LibrarySourcesConfigWithCaching.java
index d16d0375024..999c5995be1 100644
--- a/js/js.frontend/src/org/jetbrains/kotlin/js/config/LibrarySourcesConfigWithCaching.java
+++ b/js/js.frontend/src/org/jetbrains/kotlin/js/config/LibrarySourcesConfigWithCaching.java
@@ -17,35 +17,20 @@
package org.jetbrains.kotlin.js.config;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiManager;
-import kotlin.Function1;
-import kotlin.Unit;
+import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.kotlin.analyzer.AnalysisResult;
-import org.jetbrains.kotlin.descriptors.ModuleDescriptor;
-import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS;
import org.jetbrains.kotlin.psi.JetFile;
-import org.jetbrains.kotlin.psi.JetPsiFactory;
-import org.jetbrains.kotlin.resolve.BindingContext;
+import org.jetbrains.kotlin.utils.KotlinJavascriptMetadata;
import org.jetbrains.kotlin.utils.PathUtil;
-import java.io.IOException;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class LibrarySourcesConfigWithCaching extends LibrarySourcesConfig {
public static final List JS_STDLIB =
- Arrays.asList(PathUtil.getKotlinPathsForDistDirectory().getJsStdLibJarPath().getAbsolutePath());
+ Collections.singletonList(PathUtil.getKotlinPathsForDistDirectory().getJsStdLibJarPath().getAbsolutePath());
- private static List jsLibFiles;
- private static AnalysisResult result;
-
- private BindingContext libraryContext;
- private ModuleDescriptor libraryModule;
+ private static List stdlibMetadata = null;
private final boolean isUnitTestConfig;
@@ -61,85 +46,19 @@ public class LibrarySourcesConfigWithCaching extends LibrarySourcesConfig {
this.isUnitTestConfig = isUnitTestConfig;
}
- @NotNull
@Override
- public List generateLibFiles() {
- if (jsLibFiles == null) {
+ protected void init(@NotNull List sourceFilesInLibraries, @NotNull List metadata) {
+ if (stdlibMetadata == null) {
//noinspection AssignmentToStaticFieldFromInstanceMethod
- jsLibFiles = super.generateLibFiles();
- }
- return jsLibFiles;
- }
-
-
-
- @Nullable
- @Override
- public ModuleDescriptor getLibraryModule() {
- if (libraryModule == null) {
- libraryModule = getResult().getModuleDescriptor();
+ stdlibMetadata = new SmartList();
+ super.init(sourceFilesInLibraries, stdlibMetadata);
}
- return libraryModule;
- }
-
- @Nullable
- @Override
- public BindingContext getLibraryContext() {
- if (libraryContext == null) {
- //TODO check errors?
- // TopDownAnalyzerFacadeForJS.checkForErrors(allLibFiles, result.getBindingContext());
- libraryContext = getResult().getBindingContext();
- }
-
- return libraryContext;
+ metadata.addAll(stdlibMetadata);
}
@Override
public boolean isTestConfig() {
return isUnitTestConfig;
}
-
- @Override
- protected JetFile getJetFileByVirtualFile(VirtualFile file, String moduleName, PsiManager psiManager) {
- JetFile jetFile;
- try {
- String text = StringUtil.convertLineSeparators(new String(file.contentsToByteArray(false), file.getCharset()));
- jetFile = new JetPsiFactory(getProject()).createPhysicalFile(file.getName(), text);
- }
- catch (IOException e) {
- JetFile jetFileByVirtualFile = super.getJetFileByVirtualFile(file, moduleName, psiManager);
- jetFile = new JetPsiFactory(getProject()).createPhysicalFile(file.getPath(), jetFileByVirtualFile.getText());
- }
-
- setupPsiFile(jetFile, moduleName);
- return jetFile;
- }
-
- private AnalysisResult getResult() {
- if (result == null) {
- //noinspection AssignmentToStaticFieldFromInstanceMethod
- result = TopDownAnalyzerFacadeForJS.analyzeFiles(
- generateLibFiles(),
- createConfigWithoutLibFiles(getProject(), getModuleId(), getTarget())
- );
- }
-
- return result;
- }
-
- @NotNull
- private static Config createConfigWithoutLibFiles(@NotNull Project project, @NotNull String moduleId, @NotNull EcmaVersion ecmaVersion) {
- return new Config(project, moduleId, ecmaVersion, /* generate sourcemaps = */ false, /* inlineEnabled = */ false) {
- @NotNull
- @Override
- protected List generateLibFiles() {
- return Collections.emptyList();
- }
- @Override
- public boolean checkLibFilesAndReportErrors(@NotNull Function1 report) {
- return false;
- }
- };
- }
}