LTDA: Initialize project components with resolve session after injector construction is finished
This commit is contained in:
+63
-56
@@ -18,6 +18,7 @@ package org.jetbrains.jet.cli.jvm.compiler;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiClass;
|
||||
@@ -29,25 +30,21 @@ import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.jet.asJava.KotlinLightClassForExplicitDeclaration;
|
||||
import org.jetbrains.jet.asJava.LightClassConstructionContext;
|
||||
import org.jetbrains.jet.asJava.LightClassGenerationSupport;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.jet.lang.resolve.*;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.resolve.java.TopDownAnalyzerFacadeForJVM;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.KotlinCodeAnalyzer;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.DescriptorKindFilter;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
|
||||
import org.jetbrains.jet.util.slicedmap.WritableSlice;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -66,60 +63,40 @@ import java.util.List;
|
||||
*
|
||||
* To mitigate this, CliLightClassGenerationSupport hold a trace that is shared between the analyzer and JetLightClasses
|
||||
*/
|
||||
public class CliLightClassGenerationSupport extends LightClassGenerationSupport {
|
||||
|
||||
public class CliLightClassGenerationSupport extends LightClassGenerationSupport implements CodeAnalyzerInitializer {
|
||||
public static CliLightClassGenerationSupport getInstanceForCli(@NotNull Project project) {
|
||||
return ServiceManager.getService(project, CliLightClassGenerationSupport.class);
|
||||
}
|
||||
|
||||
private BindingTrace trace;
|
||||
private ModuleDescriptorImpl module;
|
||||
private BindingContext bindingContext = null;
|
||||
private ModuleDescriptor module = null;
|
||||
|
||||
public CliLightClassGenerationSupport() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public BindingTrace getTrace() {
|
||||
if (trace == null) {
|
||||
trace = new BindingTraceContextWithoutScopeRecording();
|
||||
}
|
||||
return trace;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ModuleDescriptorImpl newModule() {
|
||||
assert this.module == null : "module already configured: " + module;
|
||||
module = TopDownAnalyzerFacadeForJVM.createJavaModule("<shared-module-for-cli-light-classes>");
|
||||
module.addDependencyOnModule(module);
|
||||
module.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule());
|
||||
module.seal();
|
||||
return module;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ModuleDescriptorImpl getModule() {
|
||||
if (module == null) {
|
||||
return newModule();
|
||||
}
|
||||
return module;
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
@Nullable
|
||||
public ModuleDescriptorImpl getLightClassModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public void setModule(@NotNull ModuleDescriptorImpl module) {
|
||||
assert this.module == null : "module already configured: " + module;
|
||||
@Override
|
||||
public void initialize(@NotNull BindingTrace trace, @NotNull ModuleDescriptor module, @Nullable KotlinCodeAnalyzer analyzer) {
|
||||
this.bindingContext = trace.getBindingContext();
|
||||
this.module = module;
|
||||
|
||||
if (trace instanceof CliBindingTrace) {
|
||||
((CliBindingTrace) trace).setKotlinCodeAnalyzer(analyzer);
|
||||
}
|
||||
else {
|
||||
assert ApplicationManager.getApplication().isUnitTestMode();
|
||||
}
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public void newBindingTrace() {
|
||||
trace = null;
|
||||
module = null;
|
||||
@NotNull
|
||||
private BindingContext getBindingContext() {
|
||||
assert bindingContext != null : "Call initialize() first";
|
||||
return bindingContext;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ModuleDescriptor getModule() {
|
||||
assert module != null : "Call initialize() first";
|
||||
return module;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -136,13 +113,13 @@ public class CliLightClassGenerationSupport extends LightClassGenerationSupport
|
||||
|
||||
@NotNull
|
||||
private LightClassConstructionContext getContext() {
|
||||
return new LightClassConstructionContext(getTrace().getBindingContext(), getModule());
|
||||
return new LightClassConstructionContext(bindingContext, getModule());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<JetClassOrObject> findClassOrObjectDeclarations(@NotNull FqName fqName, @NotNull GlobalSearchScope searchScope) {
|
||||
ClassDescriptor classDescriptor = getTrace().get(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, fqName.toUnsafe());
|
||||
ClassDescriptor classDescriptor = getBindingContext().get(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, fqName.toUnsafe());
|
||||
if (classDescriptor != null) {
|
||||
PsiElement element = DescriptorToSourceUtils.classDescriptorToDeclaration(classDescriptor);
|
||||
if (element != null && PsiSearchScopeUtil.isInScope(searchScope, element)) {
|
||||
@@ -174,7 +151,7 @@ public class CliLightClassGenerationSupport extends LightClassGenerationSupport
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<JetFile> findFilesForPackage(@NotNull FqName fqName, @NotNull final GlobalSearchScope searchScope) {
|
||||
Collection<JetFile> files = getTrace().get(BindingContext.PACKAGE_TO_FILES, fqName);
|
||||
Collection<JetFile> files = getBindingContext().get(BindingContext.PACKAGE_TO_FILES, fqName);
|
||||
if (files != null) {
|
||||
return Collections2.filter(files, new Predicate<JetFile>() {
|
||||
@Override
|
||||
@@ -240,7 +217,13 @@ public class CliLightClassGenerationSupport extends LightClassGenerationSupport
|
||||
return KotlinLightClassForExplicitDeclaration.create(classOrObject.getManager(), classOrObject);
|
||||
}
|
||||
|
||||
public static class BindingTraceContextWithoutScopeRecording extends BindingTraceContext {
|
||||
public static BindingTrace createTrace() {
|
||||
return new CliBindingTrace();
|
||||
}
|
||||
|
||||
public static class CliBindingTrace extends BindingTraceContext {
|
||||
private KotlinCodeAnalyzer kotlinCodeAnalyzer;
|
||||
|
||||
@Override
|
||||
public <K, V> void record(WritableSlice<K, V> slice, K key, V value) {
|
||||
if (slice == BindingContext.RESOLUTION_SCOPE || slice == BindingContext.TYPE_RESOLUTION_SCOPE) {
|
||||
@@ -252,7 +235,31 @@ public class CliLightClassGenerationSupport extends LightClassGenerationSupport
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Filtering trace for the CLI compiler: does not save scopes";
|
||||
return CliBindingTrace.class.getName();
|
||||
}
|
||||
|
||||
public void setKotlinCodeAnalyzer(KotlinCodeAnalyzer kotlinCodeAnalyzer) {
|
||||
this.kotlinCodeAnalyzer = kotlinCodeAnalyzer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
|
||||
V value = super.get(slice, key);
|
||||
|
||||
if (value == null) {
|
||||
if (BindingContext.FUNCTION == slice || BindingContext.VARIABLE == slice) {
|
||||
if (key instanceof JetDeclaration) {
|
||||
JetDeclaration jetDeclaration = (JetDeclaration) key;
|
||||
if (!JetPsiUtil.isLocal(jetDeclaration)) {
|
||||
kotlinCodeAnalyzer.resolveToDescriptor(jetDeclaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super.get(slice, key);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ import org.jetbrains.jet.config.CompilerConfiguration;
|
||||
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
|
||||
import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.CodeAnalyzerInitializer;
|
||||
import org.jetbrains.jet.lang.resolve.DiagnosticsWithSuppression;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinBinaryClassCache;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinderFactory;
|
||||
@@ -236,6 +237,7 @@ public class JetCoreEnvironment {
|
||||
CliLightClassGenerationSupport cliLightClassGenerationSupport = new CliLightClassGenerationSupport();
|
||||
project.registerService(LightClassGenerationSupport.class, cliLightClassGenerationSupport);
|
||||
project.registerService(CliLightClassGenerationSupport.class, cliLightClassGenerationSupport);
|
||||
project.registerService(CodeAnalyzerInitializer.class, cliLightClassGenerationSupport);
|
||||
Extensions.getArea(project)
|
||||
.getExtensionPoint(PsiElementFinder.EP_NAME)
|
||||
.registerExtension(new JavaElementFinder(project, cliLightClassGenerationSupport));
|
||||
|
||||
+7
-6
@@ -282,23 +282,24 @@ public class KotlinToJVMBytecodeCompiler {
|
||||
|
||||
@Nullable
|
||||
private static AnalysisResult analyze(@NotNull final JetCoreEnvironment environment) {
|
||||
AnalyzerWithCompilerReport analyzerWithCompilerReport = new AnalyzerWithCompilerReport(
|
||||
environment.getConfiguration().get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY));
|
||||
MessageCollector collector = environment.getConfiguration().get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY);
|
||||
assert collector != null;
|
||||
|
||||
AnalyzerWithCompilerReport analyzerWithCompilerReport = new AnalyzerWithCompilerReport(collector);
|
||||
analyzerWithCompilerReport.analyzeAndReport(
|
||||
environment.getSourceFiles(), new Function0<AnalysisResult>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public AnalysisResult invoke() {
|
||||
CliLightClassGenerationSupport support = CliLightClassGenerationSupport.getInstanceForCli(environment.getProject());
|
||||
BindingTrace sharedTrace = support.getTrace();
|
||||
ModuleDescriptorImpl sharedModule = support.newModule();
|
||||
BindingTrace sharedTrace = CliLightClassGenerationSupport.createTrace();
|
||||
ModuleDescriptorImpl analyzeModule = TopDownAnalyzerFacadeForJVM.createAnalyzeModule();
|
||||
|
||||
return TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||
environment.getProject(),
|
||||
environment.getSourceFiles(),
|
||||
sharedTrace,
|
||||
Predicates.<PsiFile>alwaysTrue(),
|
||||
sharedModule,
|
||||
analyzeModule,
|
||||
environment.getConfiguration().get(JVMConfigurationKeys.MODULE_IDS),
|
||||
environment.getConfiguration().get(JVMConfigurationKeys.INCREMENTAL_CACHE_PROVIDER)
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user