Skip to content

Commit

Permalink
Implement modules in IDE
Browse files Browse the repository at this point in the history
IDE:
Rewrite AnalyzerFacade and implementations for JS and JVM to support creating separate analyzers for each module
Introduce ModuleInfo which is an intermediate entity between configuration (tests or idea modules) and ModuleDescriptor
Implement IdeaModuleInfos which represent IDEA modules, sdks and libraries
Add (somewhat thin) test checking their behaviour
Implement getModuleInfo() - utility to obtain IdeaModuleInfo for PsiElement
Drop Project.getLazyResolveSession() - not possible to obtain resolve session for the whole project any more
Adjust JavaResolveExtension accordingly
KotlinSignature Intention/Marker - make sure that analyzed element is cls element (he's not in resolve scope otherwise)

LightClasses:
Create separate package light classes for each module
Java code can only reference light class from the first module among it's dependencies
Duplicate jvm signature is only reported on package declarations inside one module

Injectors:
Receive GlobalSearchScope as paramer for VirtualFileFinder and JavaClassFinder
which allows to narrow analyzer scope

JDR:
Introduce ModuleClassResolver resolves java classes in correct java descriptor resolver (corresponding ModuleDescriptor)
Add test checking that java classes belong to correct module

Debugger:
Provide context to analyze files created by debugger in

Converter:
Postprocessor now needs a context to analyze resulting code in

JetPsiFactory:
Add verification that files created by psi factory are not analyzed without context (that is almost never a good idea)

Other:
Use new API in various tests, utilities, run configuration producers and builtin serializers
Various "TODO: (module refactoring)" which mark the unfinished parts
  • Loading branch information
PVTalanov committed Aug 22, 2014
1 parent 07935c8 commit db5303c
Show file tree
Hide file tree
Showing 82 changed files with 1,813 additions and 527 deletions.
6 changes: 6 additions & 0 deletions annotations/com/intellij/openapi/module/annotations.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<root>
<item
name='com.intellij.openapi.module.ModuleManager com.intellij.openapi.module.ModuleManager getInstance(com.intellij.openapi.project.Project)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
</root>
20 changes: 20 additions & 0 deletions annotations/com/intellij/openapi/roots/annotations.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,24 @@
name='com.intellij.openapi.roots.FileIndexFacade com.intellij.openapi.roots.FileIndexFacade getInstance(com.intellij.openapi.project.Project)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.openapi.roots.ModuleRootManager com.intellij.openapi.roots.ModuleRootManager getInstance(com.intellij.openapi.module.Module)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.openapi.roots.ModuleSourceOrderEntry com.intellij.openapi.roots.ModuleRootModel getRootModel()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.openapi.roots.OrderEnumerator com.intellij.openapi.roots.OrderEnumerator compileOnly()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.openapi.roots.OrderEnumerator com.intellij.openapi.roots.OrderEnumerator exportedOnly()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.openapi.roots.OrderEnumerator com.intellij.openapi.roots.OrderEnumerator recursively()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.openapi.roots.ProjectFileIndex.SERVICE com.intellij.openapi.roots.ProjectFileIndex getInstance(com.intellij.openapi.project.Project)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
</root>
1 change: 0 additions & 1 deletion compiler/builtins-serializer/builtins-serializer.iml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="cli" />
<orderEntry type="module" module-name="frontend" />
<orderEntry type="module" module-name="frontend.java" />
<orderEntry type="module" module-name="serialization" />
<orderEntry type="module" module-name="util" />
Expand Down
26 changes: 21 additions & 5 deletions compiler/builtins-serializer/src/BuiltInsSerializer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,16 @@ import com.intellij.openapi.Disposable
import org.jetbrains.jet.cli.common.CLIConfigurationKeys
import org.jetbrains.jet.config.CommonConfigurationKeys
import org.jetbrains.jet.cli.common.messages.MessageCollector
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM
import org.jetbrains.jet.lang.resolve.BindingTraceContext
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.utils.recursePostOrder
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.jet.lang.resolve.java.JvmAnalyzerFacade
import org.jetbrains.jet.context.GlobalContext
import org.jetbrains.jet.analyzer.ModuleInfo
import org.jetbrains.jet.lang.resolve.java.JvmPlatformParameters
import org.jetbrains.jet.analyzer.ModuleContent

public class BuiltInsSerializer(val out: PrintStream?) {
private var totalSize = 0
Expand All @@ -57,6 +61,12 @@ public class BuiltInsSerializer(val out: PrintStream?) {
}
}

private class BuiltinsSourcesModule : ModuleInfo {
override val name: Name = Name.special("<module for resolving builtin source files>")
override fun dependencies() = listOf(this)
override fun dependencyOnBuiltins(): ModuleInfo.DependencyOnBuiltins = ModuleInfo.DependenciesOnBuiltins.NONE
}

fun serialize(disposable: Disposable, destDir: File, srcDirs: Collection<File>) {
val configuration = CompilerConfiguration()
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
Expand All @@ -68,8 +78,14 @@ public class BuiltInsSerializer(val out: PrintStream?) {

val files = environment.getSourceFiles()

val session = AnalyzerFacadeForJVM.createLazyResolveSession(environment.getProject(), files, BindingTraceContext(), false)
val module = session.getModuleDescriptor()
val builtInModule = BuiltinsSourcesModule()
val resolver = JvmAnalyzerFacade.setupResolverForProject(
GlobalContext(), environment.getProject(), listOf(builtInModule),
{ ModuleContent(files, GlobalSearchScope.EMPTY_SCOPE) },
platformParameters = JvmPlatformParameters { throw IllegalStateException() }
)

val moduleDescriptor = resolver.descriptorForModule(builtInModule)

// We don't use FileUtil because it spawns JNA initialization, which fails because we don't have (and don't want to have) its
// native libraries in the compiler jar (libjnidispatch.so / jnidispatch.dll / ...)
Expand All @@ -81,7 +97,7 @@ public class BuiltInsSerializer(val out: PrintStream?) {

files.map { it.getPackageFqName() }.toSet().forEach {
fqName ->
serializePackage(module, fqName, destDir)
serializePackage(moduleDescriptor, fqName, destDir)
}

out?.println("Total bytes written: $totalSize to $totalFiles files")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.util.slicedmap.WritableSlice;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.*;

/**
* This class solves the problem of interdependency between analyzing Kotlin code and generating JetLightClasses
Expand Down Expand Up @@ -192,6 +190,14 @@ public Collection<JetClassOrObject> findClassOrObjectDeclarationsInPackage(
return result;
}

@NotNull
@Override
public List<KotlinLightPackageClassInfo> findPackageClassesInfos(
@NotNull FqName fqName, @NotNull GlobalSearchScope wholeScope
) {
return Collections.singletonList(new KotlinLightPackageClassInfo(findFilesForPackage(fqName, wholeScope), wholeScope));
}

@Override
public boolean packageExists(@NotNull FqName fqName, @NotNull GlobalSearchScope scope) {
return getModule().getPackage(fqName) != null;
Expand Down
2 changes: 1 addition & 1 deletion compiler/frontend.java/frontend.java.iml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<orderEntry type="library" name="javax.inject" level="project" />
<orderEntry type="module" module-name="serialization" />
<orderEntry type="module" module-name="serialization.java" />
<orderEntry type="module" module-name="descriptor.loader.java" />
<orderEntry type="module" module-name="descriptor.loader.java" exported="" />
<orderEntry type="module" module-name="util.runtime" />
<orderEntry type="module" module-name="util" />
</component>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JavaClassFinderImpl;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedExternalSignatureResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedJavaResolverCache;
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedErrorReporter;
import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedMethodSignatureChecker;
import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedExternalAnnotationResolver;
import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaPropertyInitializerEvaluatorImpl;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaSourceElementFactoryImpl;
import org.jetbrains.jet.lang.resolve.java.lazy.SingleModuleClassResolver;
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder;
import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaPackageFragmentProvider;
import org.jetbrains.jet.lang.resolve.java.lazy.GlobalJavaResolverContext;
Expand All @@ -53,13 +55,15 @@ public class InjectorForJavaDescriptorResolver {
private final ModuleDescriptorImpl module;
private final JavaDescriptorResolver javaDescriptorResolver;
private final JavaClassFinderImpl javaClassFinder;
private final GlobalSearchScope globalSearchScope;
private final TraceBasedExternalSignatureResolver traceBasedExternalSignatureResolver;
private final TraceBasedJavaResolverCache traceBasedJavaResolverCache;
private final TraceBasedErrorReporter traceBasedErrorReporter;
private final PsiBasedMethodSignatureChecker psiBasedMethodSignatureChecker;
private final PsiBasedExternalAnnotationResolver psiBasedExternalAnnotationResolver;
private final JavaPropertyInitializerEvaluatorImpl javaPropertyInitializerEvaluator;
private final JavaSourceElementFactoryImpl javaSourceElementFactory;
private final SingleModuleClassResolver singleModuleClassResolver;
private final VirtualFileFinder virtualFileFinder;
private final LazyJavaPackageFragmentProvider lazyJavaPackageFragmentProvider;
private final GlobalJavaResolverContext globalJavaResolverContext;
Expand Down Expand Up @@ -89,16 +93,19 @@ public InjectorForJavaDescriptorResolver(
this.traceBasedJavaResolverCache = new TraceBasedJavaResolverCache();
this.javaPropertyInitializerEvaluator = new JavaPropertyInitializerEvaluatorImpl();
this.javaSourceElementFactory = new JavaSourceElementFactoryImpl();
this.globalJavaResolverContext = new GlobalJavaResolverContext(lockBasedStorageManager, getJavaClassFinder(), virtualFileFinder, deserializedDescriptorResolver, psiBasedExternalAnnotationResolver, traceBasedExternalSignatureResolver, traceBasedErrorReporter, psiBasedMethodSignatureChecker, traceBasedJavaResolverCache, javaPropertyInitializerEvaluator, javaSourceElementFactory);
this.singleModuleClassResolver = new SingleModuleClassResolver();
this.globalJavaResolverContext = new GlobalJavaResolverContext(lockBasedStorageManager, getJavaClassFinder(), virtualFileFinder, deserializedDescriptorResolver, psiBasedExternalAnnotationResolver, traceBasedExternalSignatureResolver, traceBasedErrorReporter, psiBasedMethodSignatureChecker, traceBasedJavaResolverCache, javaPropertyInitializerEvaluator, javaSourceElementFactory, singleModuleClassResolver);
this.lazyJavaPackageFragmentProvider = new LazyJavaPackageFragmentProvider(globalJavaResolverContext, getModule());
this.javaDescriptorResolver = new JavaDescriptorResolver(lazyJavaPackageFragmentProvider, getModule());
this.globalSearchScope = com.intellij.psi.search.GlobalSearchScope.allScope(project);
this.javaClassDataFinder = new JavaClassDataFinder(virtualFileFinder, deserializedDescriptorResolver);
this.annotationDescriptorLoader = new AnnotationDescriptorLoader();
this.constantDescriptorLoader = new ConstantDescriptorLoader();
this.deserializationGlobalContextForJava = new DeserializationGlobalContextForJava(lockBasedStorageManager, getModule(), javaClassDataFinder, annotationDescriptorLoader, constantDescriptorLoader, lazyJavaPackageFragmentProvider);
this.descriptorLoadersStorage = new DescriptorLoadersStorage(lockBasedStorageManager);

this.javaClassFinder.setProject(project);
this.javaClassFinder.setScope(globalSearchScope);

traceBasedExternalSignatureResolver.setExternalAnnotationResolver(psiBasedExternalAnnotationResolver);
traceBasedExternalSignatureResolver.setProject(project);
Expand All @@ -111,6 +118,8 @@ public InjectorForJavaDescriptorResolver(
psiBasedMethodSignatureChecker.setExternalAnnotationResolver(psiBasedExternalAnnotationResolver);
psiBasedMethodSignatureChecker.setExternalSignatureResolver(traceBasedExternalSignatureResolver);

singleModuleClassResolver.setResolver(javaDescriptorResolver);

deserializedDescriptorResolver.setContext(deserializationGlobalContextForJava);
deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter);

Expand Down
Loading

0 comments on commit db5303c

Please sign in to comment.