Implement modules in IDE

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
This commit is contained in:
Pavel V. Talanov
2014-06-10 16:50:35 +04:00
parent 07935c837a
commit db5303c019
82 changed files with 1813 additions and 527 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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" />

View File

@@ -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
@@ -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)
@@ -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 / ...)
@@ -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")

View File

@@ -45,9 +45,7 @@ import org.jetbrains.jet.lang.resolve.name.FqName;
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
@@ -192,6 +190,14 @@ public class CliLightClassGenerationSupport extends LightClassGenerationSupport
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;

View File

@@ -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>

View File

@@ -23,6 +23,7 @@ import org.jetbrains.jet.storage.LockBasedStorageManager;
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;
@@ -30,6 +31,7 @@ import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedMethodSignatureCheck
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;
@@ -53,6 +55,7 @@ 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;
@@ -60,6 +63,7 @@ public class InjectorForJavaDescriptorResolver {
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;
@@ -89,9 +93,11 @@ public class 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();
@@ -99,6 +105,7 @@ public class InjectorForJavaDescriptorResolver {
this.descriptorLoadersStorage = new DescriptorLoadersStorage(lockBasedStorageManager);
this.javaClassFinder.setProject(project);
this.javaClassFinder.setScope(globalSearchScope);
traceBasedExternalSignatureResolver.setExternalAnnotationResolver(psiBasedExternalAnnotationResolver);
traceBasedExternalSignatureResolver.setProject(project);
@@ -111,6 +118,8 @@ public class InjectorForJavaDescriptorResolver {
psiBasedMethodSignatureChecker.setExternalAnnotationResolver(psiBasedExternalAnnotationResolver);
psiBasedMethodSignatureChecker.setExternalSignatureResolver(traceBasedExternalSignatureResolver);
singleModuleClassResolver.setResolver(javaDescriptorResolver);
deserializedDescriptorResolver.setContext(deserializationGlobalContextForJava);
deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter);

View File

@@ -17,12 +17,14 @@
package org.jetbrains.jet.di;
import com.intellij.openapi.project.Project;
import org.jetbrains.jet.context.GlobalContextImpl;
import org.jetbrains.jet.storage.LockBasedStorageManager;
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactory;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.context.GlobalContext;
import org.jetbrains.jet.storage.StorageManager;
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactory;
import org.jetbrains.jet.lang.resolve.java.lazy.ModuleClassResolver;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder;
@@ -70,12 +72,14 @@ import javax.annotation.PreDestroy;
public class InjectorForLazyResolveWithJava {
private final Project project;
private final GlobalContextImpl globalContext;
private final LockBasedStorageManager lockBasedStorageManager;
private final DeclarationProviderFactory declarationProviderFactory;
private final BindingTrace bindingTrace;
private final GlobalContext globalContext;
private final StorageManager storageManager;
private final ModuleDescriptorImpl module;
private final PlatformToKotlinClassMap platformToKotlinClassMap;
private final GlobalSearchScope moduleContentScope;
private final BindingTrace bindingTrace;
private final DeclarationProviderFactory declarationProviderFactory;
private final ModuleClassResolver moduleClassResolver;
private final ResolveSession resolveSession;
private final JavaDescriptorResolver javaDescriptorResolver;
private final VirtualFileFinder virtualFileFinder;
@@ -118,20 +122,25 @@ public class InjectorForLazyResolveWithJava {
public InjectorForLazyResolveWithJava(
@NotNull Project project,
@NotNull GlobalContextImpl globalContext,
@NotNull GlobalContext globalContext,
@NotNull ModuleDescriptorImpl module,
@NotNull GlobalSearchScope moduleContentScope,
@NotNull BindingTrace bindingTrace,
@NotNull DeclarationProviderFactory declarationProviderFactory,
@NotNull BindingTrace bindingTrace
@NotNull ModuleClassResolver moduleClassResolver
) {
this.project = project;
this.globalContext = globalContext;
this.lockBasedStorageManager = globalContext.getStorageManager();
this.declarationProviderFactory = declarationProviderFactory;
this.bindingTrace = bindingTrace;
this.module = org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM.createJavaModule("<fake-jdr-module>");
this.storageManager = globalContext.getStorageManager();
this.module = module;
this.platformToKotlinClassMap = module.getPlatformToKotlinClassMap();
this.resolveSession = new ResolveSession(project, globalContext, getModule(), declarationProviderFactory, bindingTrace);
this.moduleContentScope = moduleContentScope;
this.bindingTrace = bindingTrace;
this.declarationProviderFactory = declarationProviderFactory;
this.moduleClassResolver = moduleClassResolver;
this.resolveSession = new ResolveSession(project, globalContext, module, declarationProviderFactory, bindingTrace);
this.javaClassFinder = new JavaClassFinderImpl();
this.virtualFileFinder = org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder.SERVICE.getInstance(project);
this.virtualFileFinder = org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinderFactory.SERVICE.getInstance(project).create(moduleContentScope);
this.deserializedDescriptorResolver = new DeserializedDescriptorResolver();
this.psiBasedExternalAnnotationResolver = new PsiBasedExternalAnnotationResolver();
this.traceBasedExternalSignatureResolver = new TraceBasedExternalSignatureResolver();
@@ -140,9 +149,9 @@ public class InjectorForLazyResolveWithJava {
this.lazyResolveBasedCache = new LazyResolveBasedCache();
this.javaPropertyInitializerEvaluator = new JavaPropertyInitializerEvaluatorImpl();
this.javaSourceElementFactory = new JavaSourceElementFactoryImpl();
this.globalJavaResolverContext = new GlobalJavaResolverContext(lockBasedStorageManager, javaClassFinder, virtualFileFinder, deserializedDescriptorResolver, psiBasedExternalAnnotationResolver, traceBasedExternalSignatureResolver, traceBasedErrorReporter, psiBasedMethodSignatureChecker, lazyResolveBasedCache, javaPropertyInitializerEvaluator, javaSourceElementFactory);
this.lazyJavaPackageFragmentProvider = new LazyJavaPackageFragmentProvider(globalJavaResolverContext, getModule());
this.javaDescriptorResolver = new JavaDescriptorResolver(lazyJavaPackageFragmentProvider, getModule());
this.globalJavaResolverContext = new GlobalJavaResolverContext(storageManager, javaClassFinder, virtualFileFinder, deserializedDescriptorResolver, psiBasedExternalAnnotationResolver, traceBasedExternalSignatureResolver, traceBasedErrorReporter, psiBasedMethodSignatureChecker, lazyResolveBasedCache, javaPropertyInitializerEvaluator, javaSourceElementFactory, moduleClassResolver);
this.lazyJavaPackageFragmentProvider = new LazyJavaPackageFragmentProvider(globalJavaResolverContext, module);
this.javaDescriptorResolver = new JavaDescriptorResolver(lazyJavaPackageFragmentProvider, module);
this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver();
@@ -151,7 +160,7 @@ public class InjectorForLazyResolveWithJava {
this.controlStructureTypingUtils = new ControlStructureTypingUtils(expressionTypingServices);
this.expressionTypingUtils = new ExpressionTypingUtils(expressionTypingServices, callResolver);
this.forLoopConventionsChecker = new ForLoopConventionsChecker();
this.reflectionTypes = new ReflectionTypes(getModule());
this.reflectionTypes = new ReflectionTypes(module);
this.callExpressionResolver = new CallExpressionResolver();
this.descriptorResolver = new DescriptorResolver();
this.delegatedPropertyResolver = new DelegatedPropertyResolver();
@@ -166,8 +175,8 @@ public class InjectorForLazyResolveWithJava {
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.deserializationGlobalContextForJava = new DeserializationGlobalContextForJava(storageManager, module, javaClassDataFinder, annotationDescriptorLoader, constantDescriptorLoader, lazyJavaPackageFragmentProvider);
this.descriptorLoadersStorage = new DescriptorLoadersStorage(storageManager);
this.resolveSession.setAnnotationResolve(annotationResolver);
this.resolveSession.setDescriptorResolver(descriptorResolver);
@@ -178,6 +187,7 @@ public class InjectorForLazyResolveWithJava {
this.resolveSession.setTypeResolver(typeResolver);
javaClassFinder.setProject(project);
javaClassFinder.setScope(moduleContentScope);
traceBasedExternalSignatureResolver.setExternalAnnotationResolver(psiBasedExternalAnnotationResolver);
traceBasedExternalSignatureResolver.setProject(project);
@@ -191,7 +201,7 @@ public class InjectorForLazyResolveWithJava {
psiBasedMethodSignatureChecker.setExternalSignatureResolver(traceBasedExternalSignatureResolver);
annotationResolver.setCallResolver(callResolver);
annotationResolver.setStorageManager(lockBasedStorageManager);
annotationResolver.setStorageManager(storageManager);
annotationResolver.setTypeResolver(typeResolver);
callResolver.setArgumentTypeResolver(argumentTypeResolver);
@@ -229,7 +239,7 @@ public class InjectorForLazyResolveWithJava {
descriptorResolver.setAnnotationResolver(annotationResolver);
descriptorResolver.setDelegatedPropertyResolver(delegatedPropertyResolver);
descriptorResolver.setExpressionTypingServices(expressionTypingServices);
descriptorResolver.setStorageManager(lockBasedStorageManager);
descriptorResolver.setStorageManager(storageManager);
descriptorResolver.setTypeResolver(typeResolver);
delegatedPropertyResolver.setCallResolver(callResolver);
@@ -268,10 +278,6 @@ public class InjectorForLazyResolveWithJava {
public void destroy() {
}
public ModuleDescriptorImpl getModule() {
return this.module;
}
public ResolveSession getResolveSession() {
return this.resolveSession;
}

View File

@@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.resolve.LazyTopDownAnalyzer;
import org.jetbrains.jet.lang.resolve.MutablePackageFragmentProvider;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.kotlin.DeserializationGlobalContextForJava;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.jet.lang.resolve.java.JavaClassFinderImpl;
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedExternalSignatureResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedJavaResolverCache;
@@ -35,6 +36,7 @@ import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedMethodSignatureCheck
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.BodyResolver;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
@@ -90,6 +92,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
private final MutablePackageFragmentProvider mutablePackageFragmentProvider;
private final JavaDescriptorResolver javaDescriptorResolver;
private final DeserializationGlobalContextForJava deserializationGlobalContextForJava;
private final GlobalSearchScope globalSearchScope;
private final JavaClassFinderImpl javaClassFinder;
private final TraceBasedExternalSignatureResolver traceBasedExternalSignatureResolver;
private final TraceBasedJavaResolverCache traceBasedJavaResolverCache;
@@ -98,6 +101,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
private final PsiBasedExternalAnnotationResolver psiBasedExternalAnnotationResolver;
private final JavaPropertyInitializerEvaluatorImpl javaPropertyInitializerEvaluator;
private final JavaSourceElementFactoryImpl javaSourceElementFactory;
private final SingleModuleClassResolver singleModuleClassResolver;
private final VirtualFileFinder virtualFileFinder;
private final BodyResolver bodyResolver;
private final AnnotationResolver annotationResolver;
@@ -161,13 +165,15 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
this.traceBasedJavaResolverCache = new TraceBasedJavaResolverCache();
this.javaPropertyInitializerEvaluator = new JavaPropertyInitializerEvaluatorImpl();
this.javaSourceElementFactory = new JavaSourceElementFactoryImpl();
this.globalJavaResolverContext = new GlobalJavaResolverContext(storageManager, javaClassFinder, virtualFileFinder, deserializedDescriptorResolver, psiBasedExternalAnnotationResolver, traceBasedExternalSignatureResolver, traceBasedErrorReporter, psiBasedMethodSignatureChecker, traceBasedJavaResolverCache, javaPropertyInitializerEvaluator, javaSourceElementFactory);
this.singleModuleClassResolver = new SingleModuleClassResolver();
this.globalJavaResolverContext = new GlobalJavaResolverContext(storageManager, javaClassFinder, virtualFileFinder, deserializedDescriptorResolver, psiBasedExternalAnnotationResolver, traceBasedExternalSignatureResolver, traceBasedErrorReporter, psiBasedMethodSignatureChecker, traceBasedJavaResolverCache, javaPropertyInitializerEvaluator, javaSourceElementFactory, singleModuleClassResolver);
this.lazyJavaPackageFragmentProvider = new LazyJavaPackageFragmentProvider(globalJavaResolverContext, getModuleDescriptor());
this.javaDescriptorResolver = new JavaDescriptorResolver(lazyJavaPackageFragmentProvider, getModuleDescriptor());
this.javaClassDataFinder = new JavaClassDataFinder(virtualFileFinder, deserializedDescriptorResolver);
this.annotationDescriptorLoader = new AnnotationDescriptorLoader();
this.constantDescriptorLoader = new ConstantDescriptorLoader();
this.deserializationGlobalContextForJava = new DeserializationGlobalContextForJava(storageManager, getModuleDescriptor(), javaClassDataFinder, annotationDescriptorLoader, constantDescriptorLoader, lazyJavaPackageFragmentProvider);
this.globalSearchScope = com.intellij.psi.search.GlobalSearchScope.allScope(project);
this.bodyResolver = new BodyResolver();
this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver();
@@ -218,6 +224,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
this.lazyTopDownAnalyzer.setTrace(bindingTrace);
javaClassFinder.setProject(project);
javaClassFinder.setScope(globalSearchScope);
traceBasedExternalSignatureResolver.setExternalAnnotationResolver(psiBasedExternalAnnotationResolver);
traceBasedExternalSignatureResolver.setProject(project);
@@ -230,6 +237,8 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
psiBasedMethodSignatureChecker.setExternalAnnotationResolver(psiBasedExternalAnnotationResolver);
psiBasedMethodSignatureChecker.setExternalSignatureResolver(traceBasedExternalSignatureResolver);
singleModuleClassResolver.setResolver(javaDescriptorResolver);
bodyResolver.setAnnotationResolver(annotationResolver);
bodyResolver.setCallResolver(callResolver);
bodyResolver.setControlFlowAnalyzer(controlFlowAnalyzer);

View File

@@ -19,41 +19,30 @@ package org.jetbrains.jet.lang.resolve.java;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import kotlin.Function1;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.analyzer.AnalyzerFacade;
import org.jetbrains.jet.context.ContextPackage;
import org.jetbrains.jet.context.GlobalContext;
import org.jetbrains.jet.context.GlobalContextImpl;
import org.jetbrains.jet.di.InjectorForLazyResolveWithJava;
import org.jetbrains.jet.di.InjectorForTopDownAnalyzerForJvm;
import org.jetbrains.jet.lang.descriptors.PackageFragmentProvider;
import org.jetbrains.jet.lang.descriptors.impl.CompositePackageFragmentProvider;
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
import org.jetbrains.jet.lang.resolve.ImportPath;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalPackageFragmentProvider;
import org.jetbrains.jet.lang.resolve.kotlin.incremental.cache.IncrementalCache;
import org.jetbrains.jet.lang.resolve.kotlin.incremental.cache.IncrementalCacheProvider;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactory;
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactoryService;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
public enum AnalyzerFacadeForJVM {
INSTANCE;
@@ -64,85 +53,9 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
new ImportPath("kotlin.io.*")
);
public static class JvmSetup extends BasicSetup {
private final JavaDescriptorResolver javaDescriptorResolver;
public JvmSetup(@NotNull ResolveSession session, @NotNull JavaDescriptorResolver javaDescriptorResolver) {
super(session);
this.javaDescriptorResolver = javaDescriptorResolver;
}
@NotNull
public JavaDescriptorResolver getJavaDescriptorResolver() {
return javaDescriptorResolver;
}
}
private AnalyzerFacadeForJVM() {
}
@NotNull
@Override
public JvmSetup createSetup(
@NotNull Project fileProject,
@NotNull Collection<JetFile> syntheticFiles,
@NotNull GlobalSearchScope filesScope
) {
return createSetup(fileProject, syntheticFiles, filesScope, new BindingTraceContext(), true);
}
@NotNull
public static ResolveSession createLazyResolveSession(
@NotNull Project project,
@NotNull Collection<JetFile> files,
@NotNull BindingTrace trace,
boolean addBuiltIns
) {
List<VirtualFile> virtualFiles = KotlinPackage.map(files, new Function1<JetFile, VirtualFile>() {
@Override
public VirtualFile invoke(JetFile file) {
return file.getVirtualFile();
}
});
return createSetup(project, Collections.<JetFile>emptyList(),
GlobalSearchScope.filesScope(project, virtualFiles), trace, addBuiltIns).getLazyResolveSession();
}
public static JvmSetup createSetup(
@NotNull Project project,
@NotNull Collection<JetFile> syntheticFiles,
@NotNull GlobalSearchScope filesScope,
@NotNull BindingTrace trace,
boolean addBuiltIns
) {
GlobalContextImpl globalContext = ContextPackage.GlobalContext();
DeclarationProviderFactory declarationProviderFactory = DeclarationProviderFactoryService.OBJECT$
.createDeclarationProviderFactory(project, globalContext.getStorageManager(), syntheticFiles, filesScope);
InjectorForLazyResolveWithJava resolveWithJava = new InjectorForLazyResolveWithJava(
project,
globalContext,
declarationProviderFactory,
trace);
ModuleDescriptorImpl module = resolveWithJava.getModule();
module.initialize(
new CompositePackageFragmentProvider(
Arrays.asList(
resolveWithJava.getResolveSession().getPackageFragmentProvider(),
resolveWithJava.getJavaDescriptorResolver().getPackageFragmentProvider()
)));
module.addDependencyOnModule(module);
if (addBuiltIns) {
module.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule());
}
module.seal();
return new JvmSetup(resolveWithJava.getResolveSession(), resolveWithJava.getJavaDescriptorResolver());
}
@NotNull
public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
Project project,

View File

@@ -38,6 +38,8 @@ import javax.inject.Inject;
public class JavaClassFinderImpl implements JavaClassFinder {
@NotNull
private Project project;
@NotNull
private GlobalSearchScope baseScope;
private GlobalSearchScope javaSearchScope;
private JavaPsiFacadeKotlinHacks javaFacade;
@@ -47,9 +49,14 @@ public class JavaClassFinderImpl implements JavaClassFinder {
this.project = project;
}
@Inject
public void setScope(@NotNull GlobalSearchScope scope) {
this.baseScope = scope;
}
@PostConstruct
public void initialize() {
javaSearchScope = new DelegatingGlobalSearchScope(GlobalSearchScope.allScope(project)) {
javaSearchScope = new DelegatingGlobalSearchScope(baseScope) {
@Override
public boolean contains(VirtualFile file) {
return myBaseScope.contains(file) && file.getFileType() != JetFileType.INSTANCE;
@@ -57,6 +64,7 @@ public class JavaClassFinderImpl implements JavaClassFinder {
@Override
public int compare(VirtualFile file1, VirtualFile file2) {
//TODO_r: delete this code?
// TODO: this is a hackish workaround for the following problem:
// since we are working with the allScope(), if the same class FqName
// to be on the class path twice, because it is included into different libraries

View File

@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.resolve.java;
import com.google.common.collect.Lists;
import com.intellij.core.CoreJavaFileManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.project.Project;
@@ -41,9 +42,11 @@ public class JavaPsiFacadeKotlinHacks {
private final JavaFileManager javaFileManager;
private final List<PsiElementFinder> extensionPsiElementFinders;
private final boolean isCoreJavaFileManager;
public JavaPsiFacadeKotlinHacks(@NotNull Project project) {
this.javaFileManager = findJavaFileManager(project);
this.isCoreJavaFileManager = javaFileManager instanceof CoreJavaFileManager;
this.extensionPsiElementFinders = Lists.newArrayList();
for (PsiElementFinder finder : project.getExtensions(PsiElementFinder.EP_NAME)) {
if (!(finder instanceof KotlinFinderMarker)) {
@@ -82,7 +85,10 @@ public class JavaPsiFacadeKotlinHacks {
PsiClass aClass = javaFileManager.findClass(qualifiedName, scope);
if (aClass != null) {
return aClass;
//TODO: (module refactoring) CoreJavaFileManager should check scope
if (!isCoreJavaFileManager || scope.contains(aClass.getContainingFile().getOriginalFile().getVirtualFile())) {
return aClass;
}
}
for (PsiElementFinder finder : extensionPsiElementFinders) {

View File

@@ -0,0 +1,79 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve.java
import org.jetbrains.jet.analyzer.AnalyzerFacade
import org.jetbrains.jet.analyzer.ResolverForModule
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession
import org.jetbrains.jet.analyzer.PlatformAnalysisParameters
import org.jetbrains.jet.analyzer.ResolverForProject
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactoryService
import org.jetbrains.jet.lang.resolve.BindingTraceContext
import com.intellij.openapi.project.Project
import org.jetbrains.jet.context.GlobalContext
import org.jetbrains.jet.lang.descriptors.impl.CompositePackageFragmentProvider
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass
import org.jetbrains.jet.lang.resolve.java.lazy.ModuleClassResolverImpl
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.jet.analyzer.ModuleInfo
import org.jetbrains.jet.analyzer.ModuleContent
import org.jetbrains.jet.di.InjectorForLazyResolveWithJava
public class JvmResolverForModule(
override val lazyResolveSession: ResolveSession,
public val javaDescriptorResolver: JavaDescriptorResolver
) : ResolverForModule
public class JvmPlatformParameters(
public val moduleByJavaClass: (JavaClass) -> ModuleInfo
) : PlatformAnalysisParameters
public object JvmAnalyzerFacade : AnalyzerFacade<JvmResolverForModule, JvmPlatformParameters> {
override fun <M : ModuleInfo> createResolverForModule(
project: Project,
globalContext: GlobalContext,
moduleDescriptor: ModuleDescriptorImpl,
moduleContent: ModuleContent,
platformParameters: JvmPlatformParameters,
resolverForProject: ResolverForProject<M, JvmResolverForModule>
): JvmResolverForModule {
val (syntheticFiles, moduleContentScope) = moduleContent
val declarationProviderFactory = DeclarationProviderFactoryService.createDeclarationProviderFactory(
project, globalContext.storageManager, syntheticFiles, moduleContentScope
)
val moduleClassResolver = ModuleClassResolverImpl { javaClass ->
val moduleInfo = platformParameters.moduleByJavaClass(javaClass)
resolverForProject.resolverForModule(moduleInfo as M).javaDescriptorResolver
}
val injector = InjectorForLazyResolveWithJava(
project, globalContext, moduleDescriptor, moduleContentScope, BindingTraceContext(), declarationProviderFactory, moduleClassResolver
)
val resolveSession = injector.getResolveSession()!!
val javaDescriptorResolver = injector.getJavaDescriptorResolver()!!
val providersForModule = listOf(resolveSession.getPackageFragmentProvider(), javaDescriptorResolver.packageFragmentProvider)
moduleDescriptor.initialize(CompositePackageFragmentProvider(providersForModule))
return JvmResolverForModule(resolveSession, javaDescriptorResolver)
}
override val defaultImports = AnalyzerFacadeForJVM.DEFAULT_IMPORTS
override val platformToKotlinClassMap = JavaToKotlinClassMap.getInstance()
}

View File

@@ -16,10 +16,19 @@
package org.jetbrains.jet.lang.resolve.kotlin;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
public interface VirtualFileFinderFactory {
@NotNull
VirtualFileFinder create(@NotNull GlobalSearchScope scope);
class SERVICE {
@NotNull
public static VirtualFileFinderFactory getInstance(@NotNull Project project) {
return ServiceManager.getService(project, VirtualFileFinderFactory.class);
}
}
}

View File

@@ -1,55 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.analyzer;
import com.intellij.openapi.project.Project;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import java.util.Collection;
public interface AnalyzerFacade {
interface Setup {
@NotNull
ResolveSession getLazyResolveSession();
}
class BasicSetup implements Setup {
private final ResolveSession resolveSession;
public BasicSetup(@NotNull ResolveSession session) {
resolveSession = session;
}
@NotNull
@Override
public ResolveSession getLazyResolveSession() {
return resolveSession;
}
}
@NotNull
Setup createSetup(
@NotNull Project project,
@NotNull Collection<JetFile> syntheticFiles,
@NotNull GlobalSearchScope filesScope
);
}

View File

@@ -0,0 +1,174 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.analyzer
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession
import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
import java.util.HashMap
import org.jetbrains.jet.lang.resolve.ImportPath
import org.jetbrains.jet.lang.PlatformToKotlinClassMap
import com.intellij.openapi.project.Project
import org.jetbrains.jet.context.GlobalContext
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl
import java.util.ArrayList
import org.jetbrains.jet.lang.psi.JetFile
import com.intellij.psi.search.GlobalSearchScope
import kotlin.properties.Delegates
public trait ResolverForModule {
public val lazyResolveSession: ResolveSession
}
public trait ResolverForProject<M : ModuleInfo, R : ResolverForModule> {
public fun resolverForModule(moduleInfo: M): R
public fun descriptorForModule(moduleInfo: M): ModuleDescriptor
}
public class ResolverForProjectImpl<M : ModuleInfo, R : ResolverForModule>(
val descriptorByModule: Map<M, ModuleDescriptorImpl>
) : ResolverForProject<M, R> {
val resolverByModuleDescriptor: MutableMap<ModuleDescriptor, R> = HashMap()
private val allModules: Collection<M> by Delegates.lazy {
descriptorByModule.keySet()
}
private fun assertCorrectModuleInfo(moduleInfo: M) {
if (moduleInfo !in allModules) {
throw AssertionError("Requested data for $moduleInfo not contained in this resolver.\nThis resolver was created for following infos:\n${allModules.joinToString("\n")}")
}
}
override fun resolverForModule(moduleInfo: M): R {
assertCorrectModuleInfo(moduleInfo)
val descriptor = descriptorByModule[moduleInfo]!!
return resolverByModuleDescriptor[descriptor]!!
}
override fun descriptorForModule(moduleInfo: M): ModuleDescriptorImpl {
assertCorrectModuleInfo(moduleInfo)
return descriptorByModule[moduleInfo]!!
}
}
public data class ModuleContent(
public val syntheticFiles: Collection<JetFile>,
public val moduleContentScope: GlobalSearchScope
)
public trait PlatformAnalysisParameters
public trait ModuleInfo {
public val name: Name
public fun dependencies(): List<ModuleInfo>
public fun dependencyOnBuiltins(): DependencyOnBuiltins = DependenciesOnBuiltins.LAST
//TODO: (module refactoring) provide dependency on builtins after runtime in IDEA
public trait DependencyOnBuiltins {
public fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList<ModuleDescriptorImpl>)
}
public enum class DependenciesOnBuiltins : DependencyOnBuiltins {
override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList<ModuleDescriptorImpl>) {
//TODO: KT-5457
}
NONE {
override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList<ModuleDescriptorImpl>) {
//do nothing
}
}
LAST {
override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList<ModuleDescriptorImpl>) {
dependencies.add(builtinsModule)
}
}
}
}
//TODO: (module refactoring) extract project context
public trait AnalyzerFacade<out A : ResolverForModule, in P : PlatformAnalysisParameters> {
public fun <M : ModuleInfo> setupResolverForProject(
globalContext: GlobalContext,
project: Project,
modules: Collection<M>,
modulesContent: (M) -> ModuleContent,
platformParameters: P
): ResolverForProject<M, A> {
fun createResolverForProject(): ResolverForProjectImpl<M, A> {
val descriptorByModule = HashMap<M, ModuleDescriptorImpl>()
modules.forEach {
module ->
descriptorByModule[module] = ModuleDescriptorImpl(module.name, defaultImports, platformToKotlinClassMap)
}
return ResolverForProjectImpl(descriptorByModule)
}
val resolverForProject = createResolverForProject()
fun setupModuleDependencies() {
modules.forEach {
module ->
val currentModule = resolverForProject.descriptorForModule(module)
val dependenciesDescriptors = module.dependencies().mapTo(ArrayList<ModuleDescriptorImpl>()) {
dependencyInfo ->
resolverForProject.descriptorForModule(dependencyInfo as M)
}
val builtinsModule = KotlinBuiltIns.getInstance().getBuiltInsModule()
module.dependencyOnBuiltins().adjustDependencies(builtinsModule, dependenciesDescriptors)
dependenciesDescriptors.forEach { currentModule.addDependencyOnModule(it) }
}
resolverForProject.descriptorByModule.values().forEach { it.seal() }
}
setupModuleDependencies()
fun initializeResolverForProject() {
modules.forEach {
module ->
val descriptor = resolverForProject.descriptorForModule(module)
val resolverForModule = createResolverForModule(
project, globalContext, descriptor, modulesContent(module), platformParameters, resolverForProject
)
assert(descriptor.isInitialized, "ModuleDescriptorImpl#initialize() should be called in createResolverForModule")
resolverForProject.resolverByModuleDescriptor[descriptor] = resolverForModule
}
}
initializeResolverForProject()
return resolverForProject
}
protected fun <M : ModuleInfo> createResolverForModule(
project: Project,
globalContext: GlobalContext,
moduleDescriptor: ModuleDescriptorImpl,
moduleContent: ModuleContent,
platformParameters: P,
resolverForProject: ResolverForProject<M, A>
): A
public val defaultImports: List<ImportPath>
public val platformToKotlinClassMap: PlatformToKotlinClassMap
}

View File

@@ -17,8 +17,8 @@
package org.jetbrains.jet.di;
import com.intellij.openapi.project.Project;
import org.jetbrains.jet.context.GlobalContextImpl;
import org.jetbrains.jet.storage.LockBasedStorageManager;
import org.jetbrains.jet.context.GlobalContext;
import org.jetbrains.jet.storage.StorageManager;
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactory;
@@ -52,8 +52,8 @@ import javax.annotation.PreDestroy;
public class InjectorForLazyResolve {
private final Project project;
private final GlobalContextImpl globalContext;
private final LockBasedStorageManager lockBasedStorageManager;
private final GlobalContext globalContext;
private final StorageManager storageManager;
private final ModuleDescriptorImpl moduleDescriptor;
private final PlatformToKotlinClassMap platformToKotlinClassMap;
private final DeclarationProviderFactory declarationProviderFactory;
@@ -82,14 +82,14 @@ public class InjectorForLazyResolve {
public InjectorForLazyResolve(
@NotNull Project project,
@NotNull GlobalContextImpl globalContext,
@NotNull GlobalContext globalContext,
@NotNull ModuleDescriptorImpl moduleDescriptor,
@NotNull DeclarationProviderFactory declarationProviderFactory,
@NotNull BindingTrace bindingTrace
) {
this.project = project;
this.globalContext = globalContext;
this.lockBasedStorageManager = globalContext.getStorageManager();
this.storageManager = globalContext.getStorageManager();
this.moduleDescriptor = moduleDescriptor;
this.platformToKotlinClassMap = moduleDescriptor.getPlatformToKotlinClassMap();
this.declarationProviderFactory = declarationProviderFactory;
@@ -125,7 +125,7 @@ public class InjectorForLazyResolve {
this.resolveSession.setTypeResolver(typeResolver);
annotationResolver.setCallResolver(callResolver);
annotationResolver.setStorageManager(lockBasedStorageManager);
annotationResolver.setStorageManager(storageManager);
annotationResolver.setTypeResolver(typeResolver);
callResolver.setArgumentTypeResolver(argumentTypeResolver);
@@ -163,7 +163,7 @@ public class InjectorForLazyResolve {
descriptorResolver.setAnnotationResolver(annotationResolver);
descriptorResolver.setDelegatedPropertyResolver(delegatedPropertyResolver);
descriptorResolver.setExpressionTypingServices(expressionTypingServices);
descriptorResolver.setStorageManager(lockBasedStorageManager);
descriptorResolver.setStorageManager(storageManager);
descriptorResolver.setTypeResolver(typeResolver);
delegatedPropertyResolver.setCallResolver(callResolver);

View File

@@ -26,10 +26,17 @@ import org.jetbrains.jet.lang.resolve.ImportPath
import org.jetbrains.jet.lexer.JetKeywordToken
import org.jetbrains.jet.plugin.JetFileType
import org.jetbrains.jet.lang.psi.JetPsiFactory.CallableBuilder.Target
import com.intellij.openapi.util.Key
import java.io.PrintWriter
import java.io.StringWriter
import com.intellij.openapi.application.ApplicationManager
public fun JetPsiFactory(project: Project?): JetPsiFactory = JetPsiFactory(project!!)
public fun JetPsiFactory(contextElement: JetElement): JetPsiFactory = JetPsiFactory(contextElement.getProject())
public var JetFile.doNotAnalyze: String? by UserDataProperty(Key.create("DO_NOT_ANALYZE"))
public var JetFile.analysisContext: PsiElement? by UserDataProperty(Key.create("ANALYSIS_CONTEXT"))
public class JetPsiFactory(private val project: Project) {
public fun createValNode(): ASTNode {
@@ -114,10 +121,33 @@ public class JetPsiFactory(private val project: Project) {
return createFile("dummy.kt", text)
}
public fun createFile(fileName: String, text: String): JetFile {
private fun doCreateFile(fileName: String, text: String): JetFile {
return PsiFileFactory.getInstance(project).createFileFromText(fileName, JetFileType.INSTANCE, text, LocalTimeCounter.currentTime(), false) as JetFile
}
public fun createFile(fileName: String, text: String): JetFile {
val file = doCreateFile(fileName, text)
//TODO: KotlinInternalMode should be used here
if (ApplicationManager.getApplication()!!.isInternal()) {
val sw = StringWriter()
Exception().printStackTrace(PrintWriter(sw))
file.doNotAnalyze = "This file was created by JetPsiFactory and should not be analyzed. It was created at:\n" + sw.toString()
}
else {
file.doNotAnalyze = "This file was created by JetPsiFactory and should not be analyzed\n" +
"Enable kotlin internal mode get more info for debugging\n" +
"Use createAnalyzableFile to create file that can be analyzed\n"
}
return file
}
public fun createAnalyzableFile(fileName: String, text: String, contextToAnalyzeIn: PsiElement): JetFile {
val file = doCreateFile(fileName, text)
file.analysisContext = contextToAnalyzeIn
return file
}
public fun createPhysicalFile(fileName: String, text: String): JetFile {
return PsiFileFactory.getInstance(project).createFileFromText(fileName, JetFileType.INSTANCE, text, LocalTimeCounter.currentTime(), true) as JetFile
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.psi
import kotlin.properties.ReadWriteProperty
import com.intellij.openapi.util.Key
public class UserDataProperty<T : Any>(val key: Key<T>) : ReadWriteProperty<JetFile, T?> {
override fun get(thisRef: JetFile, desc: kotlin.PropertyMetadata): T? {
return thisRef.getUserData(key)
}
override fun set(thisRef: JetFile, desc: kotlin.PropertyMetadata, value: T?) {
thisRef.putUserData(key, value)
}
}

View File

@@ -26,7 +26,7 @@ import kotlin.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.jet.context.GlobalContextImpl;
import org.jetbrains.jet.context.GlobalContext;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl;
import org.jetbrains.jet.lang.psi.*;
@@ -111,12 +111,13 @@ public class ResolveSession implements KotlinCodeAnalyzer {
@Deprecated
public ResolveSession(
@NotNull Project project,
@NotNull GlobalContextImpl globalContext,
@NotNull GlobalContext globalContext,
@NotNull ModuleDescriptorImpl rootDescriptor,
@NotNull DeclarationProviderFactory declarationProviderFactory,
@NotNull BindingTrace delegationTrace
) {
LockBasedLazyResolveStorageManager lockBasedLazyResolveStorageManager = new LockBasedLazyResolveStorageManager(globalContext.getStorageManager());
LockBasedLazyResolveStorageManager lockBasedLazyResolveStorageManager = new LockBasedLazyResolveStorageManager(
(LockBasedStorageManager) globalContext.getStorageManager());
this.storageManager = lockBasedLazyResolveStorageManager;
this.exceptionTracker = globalContext.getExceptionTracker();
this.trace = lockBasedLazyResolveStorageManager.createSafeTrace(delegationTrace);

View File

@@ -53,15 +53,8 @@ public class MainFunctionDetector {
};
}
/** Uses the {@code resolveSession} to resolve the function declaration. Suitable when the function declaration is not resolved yet. */
public MainFunctionDetector(@NotNull final ResolveSession resolveSession) {
this.getFunctionDescriptor = new NotNullFunction<JetNamedFunction, FunctionDescriptor>() {
@NotNull
@Override
public FunctionDescriptor fun(JetNamedFunction function) {
return (FunctionDescriptor) resolveSession.resolveToDescriptor(function);
}
};
public MainFunctionDetector(@NotNull NotNullFunction<JetNamedFunction, FunctionDescriptor> functionResolver) {
this.getFunctionDescriptor = functionResolver;
}
public boolean hasMain(@NotNull List<JetDeclaration> declarations) {

View File

@@ -36,7 +36,7 @@ import org.jetbrains.jet.lang.resolve.name.FqName;
* <p/>
* See {@link LineBreakpoint#findClassCandidatesInSourceContent} for the primary usage this was introduced
*/
/* package */ class FakeLightClassForFileOfPackage extends AbstractLightClass implements KotlinLightClass, JetJavaMirrorMarker {
public class FakeLightClassForFileOfPackage extends AbstractLightClass implements KotlinLightClass, JetJavaMirrorMarker {
private final KotlinLightClassForPackage delegate;
private final JetFile file;

View File

@@ -34,7 +34,9 @@ import com.intellij.util.SmartList;
import com.intellij.util.containers.SLRUCache;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetEnumEntry;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.java.JavaPsiFacadeKotlinHacks;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
import org.jetbrains.jet.lang.resolve.kotlin.PackagePartClassUtils;
@@ -141,17 +143,21 @@ public class JavaElementFinder extends PsiElementFinder implements JavaPsiFacade
}
private void findPackageClass(FqName qualifiedName, GlobalSearchScope scope, List<PsiClass> answer) {
Collection<JetFile> filesForPackage = lightClassGenerationSupport.findFilesForPackage(qualifiedName, scope);
if (PackagePartClassUtils.getPackageFilesWithCallables(filesForPackage).isEmpty()) return;
List<LightClassGenerationSupport.KotlinLightPackageClassInfo>
packageClassesInfos = lightClassGenerationSupport.findPackageClassesInfos(qualifiedName, scope);
for (LightClassGenerationSupport.KotlinLightPackageClassInfo info : packageClassesInfos) {
Collection<JetFile> files = info.getFiles();
if (PackagePartClassUtils.getPackageFilesWithCallables(files).isEmpty()) continue;
KotlinLightClassForPackage lightClass =
KotlinLightClassForPackage.create(psiManager, qualifiedName, info.getScope(), files);
if (lightClass == null) continue;
KotlinLightClassForPackage lightClass = KotlinLightClassForPackage.create(psiManager, qualifiedName, scope, filesForPackage);
if (lightClass == null) return;
answer.add(lightClass);
answer.add(lightClass);
if (filesForPackage.size() > 1) {
for (JetFile file : filesForPackage) {
answer.add(new FakeLightClassForFileOfPackage(psiManager, lightClass, file));
if (files.size() > 1) {
for (JetFile file : files) {
answer.add(new FakeLightClassForFileOfPackage(psiManager, lightClass, file));
}
}
}
}

View File

@@ -35,6 +35,7 @@ import com.intellij.util.containers.SLRUCache;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
@@ -424,4 +425,11 @@ public class KotlinLightClassForPackage extends KotlinWrappingLightClass impleme
return KotlinLightClassForPackage.class.getSimpleName() + ":" + e.toString();
}
}
//NOTE: this is only needed to compute plugin module info
@NotNull
@ReadOnly
public final Collection<JetFile> getFiles() {
return files;
}
}

View File

@@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.name.FqName;
import java.util.Collection;
import java.util.List;
public abstract class LightClassGenerationSupport {
@@ -54,6 +55,12 @@ public abstract class LightClassGenerationSupport {
@NotNull
public abstract Collection<JetFile> findFilesForPackage(@NotNull FqName fqName, @NotNull GlobalSearchScope searchScope);
@NotNull
public abstract List<KotlinLightPackageClassInfo> findPackageClassesInfos(
@NotNull FqName fqName,
@NotNull GlobalSearchScope wholeScope
);
// Returns only immediately declared classes/objects, package classes are not included (they have no declarations)
@NotNull
public abstract Collection<JetClassOrObject> findClassOrObjectDeclarationsInPackage(
@@ -68,4 +75,24 @@ public abstract class LightClassGenerationSupport {
@Nullable
public abstract PsiClass getPsiClass(@NotNull JetClassOrObject classOrObject);
public final class KotlinLightPackageClassInfo {
private final Collection<JetFile> files;
private final GlobalSearchScope scope;
public KotlinLightPackageClassInfo(@NotNull Collection<JetFile> files, @NotNull GlobalSearchScope scope) {
this.files = files;
this.scope = scope;
}
@NotNull
public Collection<JetFile> getFiles() {
return files;
}
@NotNull
public GlobalSearchScope getScope() {
return scope;
}
}
}

View File

@@ -32,9 +32,18 @@ import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory.*
import org.jetbrains.jet.lang.psi.JetParameter
import org.jetbrains.jet.lang.psi.JetClass
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory
import org.jetbrains.jet.lang.psi.JetClassObject
public fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostics): Diagnostics? {
public fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostics, moduleScope: GlobalSearchScope): Diagnostics? {
fun getDiagnosticsForPackage(file: JetFile): Diagnostics? {
val project = file.getProject()
val cache = KotlinLightClassForPackage.FileStubCache.getInstance(project)
return cache[file.getPackageFqName(), moduleScope].getValue()?.extraDiagnostics
}
fun getDiagnosticsForClass(jetClassOrObject: JetClassOrObject): Diagnostics {
return KotlinLightClassForExplicitDeclaration.getLightClassData(jetClassOrObject).extraDiagnostics
}
fun doGetDiagnostics(): Diagnostics? {
var parent = element.getParent()
if (element is JetPropertyAccessor) {
@@ -134,13 +143,3 @@ private fun ConflictingJvmDeclarationsData.higherThan(other: ConflictingJvmDecla
else -> false
}
}
private fun getDiagnosticsForPackage(file: JetFile): Diagnostics? {
val project = file.getProject()
val cache = KotlinLightClassForPackage.FileStubCache.getInstance(project)
return cache[file.getPackageFqName(), GlobalSearchScope.allScope(project)].getValue()?.extraDiagnostics
}
private fun getDiagnosticsForClass(jetClassOrObject: JetClassOrObject): Diagnostics {
return KotlinLightClassForExplicitDeclaration.getLightClassData(jetClassOrObject).extraDiagnostics
}

View File

@@ -0,0 +1,11 @@
package test
import custom.*
public class KotlinA: AClass() {
fun returnA(): AClass {}
fun paramA(p: AClass) {}
AAnnotation fun annoA() {}
}

View File

@@ -0,0 +1,5 @@
package custom;
public @interface AAnnotation {
}

View File

@@ -0,0 +1,8 @@
package custom;
public class AClass {
public AClass returnA() {}
public void paramA(AClass a) {}
@AAnnotation
public void annoA() {}
}

View File

@@ -0,0 +1,17 @@
package test
import custom.*
public class KotlinB: AClass() {
public fun returnA(): AClass {}
public fun paramA(a: AClass) {}
public fun paramB(b: BClass) {}
public fun returnB(): BClass { }
AAnnotation fun annoA() {}
BAnnotation fun annoB() {}
}

View File

@@ -0,0 +1,5 @@
package custom;
public @interface BAnnotation {
}

View File

@@ -0,0 +1,12 @@
package custom;
public class BClass extends AClass {
public AClass returnA() {}
public void paramA(AClass a) {}
@AAnnotation
public void annoA() {}
public BClass returnB() {}
public void paramB(BClass b) {}
@BAnnotation
public void annoB() {}
}

View File

@@ -0,0 +1,17 @@
package test
import custom.*
public class KotlinC: AClass() {
public fun returnA(): AClass {}
public fun paramA(a: AClass) {}
public fun paramB(b: BClass) {}
public fun returnB(): BClass { }
AAnnotation fun annoA() {}
BAnnotation fun annoB() {}
}

View File

@@ -0,0 +1,12 @@
package custom;
public class CClass extends BClass {
public AClass returnA() {}
public void paramA(AClass a) {}
@AAnnotation
public void annoA() {}
public BClass returnB() {}
public void paramB(BClass b) {}
@BAnnotation
public void annoB() {}
}

View File

@@ -809,6 +809,7 @@ public class JetTestUtils {
return generatorClassFqName.substring(generatorClassFqName.lastIndexOf(".") + 1);
}
@NotNull
public static JetFile loadJetFile(@NotNull Project project, @NotNull File ioFile) throws IOException {
String text = FileUtil.loadFile(ioFile, true);
return JetPsiFactory(project).createPhysicalFile(ioFile.getName(), text);

View File

@@ -27,6 +27,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
@@ -355,7 +356,8 @@ public abstract class BaseDiagnosticsTest extends JetLiteFixture {
Set<Diagnostic> jvmSignatureDiagnostics = new HashSet<Diagnostic>();
Collection<JetDeclaration> declarations = PsiTreeUtil.findChildrenOfType(jetFile, JetDeclaration.class);
for (JetDeclaration declaration : declarations) {
Diagnostics diagnostics = AsJavaPackage.getJvmSignatureDiagnostics(declaration, bindingContext.getDiagnostics());
Diagnostics diagnostics = AsJavaPackage.getJvmSignatureDiagnostics(declaration, bindingContext.getDiagnostics(),
GlobalSearchScope.allScope(getProject()));
if (diagnostics == null) continue;
jvmSignatureDiagnostics.addAll(diagnostics.forElement(declaration));
}

View File

@@ -0,0 +1,168 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.jvm.compiler
import org.jetbrains.jet.lang.resolve.java.JvmAnalyzerFacade
import org.jetbrains.jet.context.GlobalContext
import org.jetbrains.jet.JetTestUtils
import com.intellij.testFramework.UsefulTestCase
import org.jetbrains.jet.lang.resolve.java.JvmPlatformParameters
import org.jetbrains.jet.lang.psi.JetFile
import java.io.File
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.junit.Assert
import org.jetbrains.jet.lang.resolve.DescriptorUtils
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment
import org.jetbrains.jet.config.CompilerConfiguration
import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys
import com.intellij.psi.search.DelegatingGlobalSearchScope
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.lang.resolve.java.JvmResolverForModule
import org.jetbrains.jet.analyzer.ResolverForProject
import org.jetbrains.jet.analyzer.ModuleInfo
import java.util.HashMap
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
import org.jetbrains.jet.analyzer.ModuleContent
public class MultiModuleJavaAnalysisCustomTest : UsefulTestCase() {
private class TestModule(val _name: String, val kotlinFiles: List<JetFile>, val javaFilesScope: GlobalSearchScope,
val _dependencies: TestModule.() -> List<TestModule>) :
ModuleInfo {
override fun dependencies() = _dependencies()
override val name = Name.special("<$_name>")
}
fun testJavaEntitiesBelongToCorrectModule() {
val moduleDirs = File(PATH_TO_TEST_ROOT_DIR).listFiles { it.isDirectory() }!!
val environment = createEnvironment(moduleDirs)
val modules = setupModules(environment, moduleDirs)
val resolverForProject = JvmAnalyzerFacade.setupResolverForProject(
GlobalContext(), environment.getProject(), modules,
{ m -> ModuleContent(m.kotlinFiles, m.javaFilesScope) },
JvmPlatformParameters {
javaClass ->
val moduleName = javaClass.getName().asString().toLowerCase().first().toString()
modules.first { it._name == moduleName }
}
)
performChecks(resolverForProject, modules)
}
private fun createEnvironment(moduleDirs: Array<File>): JetCoreEnvironment {
val configuration = CompilerConfiguration()
configuration.addAll(JVMConfigurationKeys.CLASSPATH_KEY, moduleDirs.toList())
return JetCoreEnvironment.createForTests(getTestRootDisposable()!!, configuration)
}
private fun setupModules(environment: JetCoreEnvironment, moduleDirs: Array<File>): List<TestModule> {
val project = environment.getProject()
val modules = HashMap<String, TestModule>()
for (dir in moduleDirs) {
val name = dir.getName()
val kotlinFiles = JetTestUtils.loadToJetFiles(environment, dir.listFiles { it.extension == "kt" }?.toList().orEmpty())
val javaFilesScope = object : DelegatingGlobalSearchScope(GlobalSearchScope.allScope(project)) {
override fun contains(file: VirtualFile): Boolean {
if (file !in myBaseScope!!) return false
if (file.isDirectory()) return true
return file.getParent()!!.getParent()!!.getName() == name
}
}
modules[name] = TestModule(name, kotlinFiles, javaFilesScope) {
when (this._name) {
"a" -> listOf(this)
"b" -> listOf(this, modules["a"]!!)
"c" -> listOf(this, modules["b"]!!, modules["a"]!!)
else -> throw IllegalStateException("$_name")
}
}
}
return modules.values().toList()
}
private fun performChecks(resolverForProject: ResolverForProject<TestModule, JvmResolverForModule>, modules: List<TestModule>) {
modules.forEach {
module ->
val moduleDescriptor = resolverForProject.descriptorForModule(module)
checkClassInPackage(moduleDescriptor, "test", "Kotlin${module._name.toUpperCase()}")
checkClassInPackage(moduleDescriptor, "custom", "${module._name.toUpperCase()}Class")
}
}
private fun checkClassInPackage(moduleDescriptor: ModuleDescriptor, packageName: String, className: String) {
val kotlinPackage = moduleDescriptor.getPackage(FqName(packageName))!!
val kotlinClassName = Name.identifier(className)
val kotlinClass = kotlinPackage.getMemberScope().getClassifier(kotlinClassName) as ClassDescriptor
checkClass(kotlinClass)
}
private fun checkClass(classDescriptor: ClassDescriptor) {
classDescriptor.getDefaultType().getMemberScope().getAllDescriptors().filterIsInstance(javaClass<CallableDescriptor>()).forEach {
checkCallable(it, classDescriptor)
}
}
private fun checkCallable(callable: CallableDescriptor, classDescriptor: ClassDescriptor) {
val returnType = callable.getReturnType()!!
if (!KotlinBuiltIns.getInstance().isUnit(returnType)) {
checkDescriptor(returnType.getConstructor().getDeclarationDescriptor()!!, callable)
}
callable.getValueParameters().map {
it.getType().getConstructor().getDeclarationDescriptor()!!
}.forEach { checkDescriptor(it, callable) }
callable.getAnnotations().map {
it.getType().getConstructor().getDeclarationDescriptor()!!
}.forEach { checkDescriptor(it, callable) }
checkSupertypes(classDescriptor)
}
private fun checkSupertypes(classDescriptor: ClassDescriptor) {
classDescriptor.getDefaultType().getConstructor().getSupertypes().filter {
!KotlinBuiltIns.getInstance().isAnyOrNullableAny(it)
}.map {
it.getConstructor().getDeclarationDescriptor()!!
}.forEach {
checkDescriptor(it, classDescriptor)
}
}
private fun checkDescriptor(referencedDescriptor: ClassifierDescriptor, context: DeclarationDescriptor) {
val descriptorName = referencedDescriptor.getName().asString()
val expectedModuleName = "<${descriptorName.toLowerCase().first().toString()}>"
val moduleName = DescriptorUtils.getContainingModule(referencedDescriptor).getName().asString()
Assert.assertEquals(
"Java class $descriptorName in $context should be in module $expectedModuleName, but instead was in $moduleName",
expectedModuleName, moduleName
)
}
class object {
val PATH_TO_TEST_ROOT_DIR = "compiler/testData/multiModule/java/custom"
}
}

View File

@@ -20,7 +20,6 @@ import com.google.common.base.Predicates;
import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.cli.jvm.compiler.CliLightClassGenerationSupport;
@@ -33,14 +32,14 @@ import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.name.SpecialNames;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.List;
import java.util.Set;
import static org.jetbrains.jet.lang.resolve.lazy.LazyPackage.createResolveSessionForFiles;
public class LazyResolveTestUtil {
private LazyResolveTestUtil() {
}
@@ -61,16 +60,18 @@ public class LazyResolveTestUtil {
return injector.getModuleDescriptor();
}
public static KotlinCodeAnalyzer resolveLazilyWithSession(List<JetFile> files, JetCoreEnvironment environment, boolean addBuiltIns) {
@NotNull
public static KotlinCodeAnalyzer resolveLazilyWithSession(
@NotNull List<JetFile> files,
@NotNull JetCoreEnvironment environment,
boolean addBuiltIns
) {
JetTestUtils.newTrace(environment);
Project project = environment.getProject();
CliLightClassGenerationSupport support = CliLightClassGenerationSupport.getInstanceForCli(project);
BindingTrace sharedTrace = support.getTrace();
ResolveSession lazyResolveSession = AnalyzerFacadeForJVM.createSetup(project, files, GlobalSearchScope.EMPTY_SCOPE,
sharedTrace, addBuiltIns).getLazyResolveSession();
support.setModule((ModuleDescriptorImpl)lazyResolveSession.getModuleDescriptor());
ResolveSession lazyResolveSession = createResolveSessionForFiles(project, files, addBuiltIns);
support.setModule((ModuleDescriptorImpl) lazyResolveSession.getModuleDescriptor());
return lazyResolveSession;
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve.lazy
import com.intellij.openapi.project.Project
import org.jetbrains.jet.lang.psi.JetFile
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.jet.context.GlobalContext
import org.jetbrains.jet.lang.resolve.java.JvmAnalyzerFacade
import org.jetbrains.jet.analyzer.ModuleInfo
import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.lang.resolve.java.JvmPlatformParameters
import org.jetbrains.jet.analyzer.ModuleContent
public fun createResolveSessionForFiles(
project: Project,
syntheticFiles: Collection<JetFile>,
addBuiltIns: Boolean
): ResolveSession {
val globalContext = GlobalContext()
val testModule = TestModule(addBuiltIns)
val resolverForProject = JvmAnalyzerFacade.setupResolverForProject(
globalContext, project, listOf(testModule),
{ ModuleContent(syntheticFiles, GlobalSearchScope.allScope(project)) },
JvmPlatformParameters { testModule }
)
return resolverForProject.resolverForModule(testModule).lazyResolveSession
}
private class TestModule(val dependsOnBuiltins: Boolean) : ModuleInfo {
override val name: Name = Name.special("<Test module for lazy resolve>")
override fun dependencies() = listOf(this)
override fun dependencyOnBuiltins() =
if (dependsOnBuiltins)
ModuleInfo.DependenciesOnBuiltins.LAST
else
ModuleInfo.DependenciesOnBuiltins.NONE
}

View File

@@ -23,7 +23,6 @@ import org.jetbrains.jet.lang.resolve.java.structure.JavaPackage;
import org.jetbrains.jet.lang.resolve.name.FqName;
public interface JavaClassFinder {
// TODO: scope
@Nullable
JavaClass findClass(@NotNull FqName fqName);

View File

@@ -47,7 +47,8 @@ public class LazyJavaPackageFragmentProvider(
outerContext.methodSignatureChecker,
outerContext.javaResolverCache,
outerContext.javaPropertyInitializerEvaluator,
outerContext.sourceElementFactory
outerContext.sourceElementFactory,
outerContext.moduleClassResolver
)
override fun getModule() = _module
@@ -105,13 +106,8 @@ public class LazyJavaPackageFragmentProvider(
private inner class FragmentClassResolver : LazyJavaClassResolver {
override fun resolveClass(javaClass: JavaClass): ClassDescriptor? {
// TODO: there's no notion of module separation here. We must refuse to resolve classes from other modules
val fqName = javaClass.getFqName()
if (fqName != null) {
// TODO: this should be handled by module separation logic
val builtinClass = DescriptorResolverUtils.getKotlinBuiltinClassDescriptor(fqName)
if (builtinClass != null) return builtinClass
if (javaClass.getOriginKind() == JavaClass.OriginKind.KOTLIN_LIGHT_CLASS) {
return c.javaResolverCache.getClassResolvedFromSource(fqName)
}
@@ -121,8 +117,7 @@ public class LazyJavaPackageFragmentProvider(
return c.lookupBinaryClass(javaClass) ?: topLevelClasses(javaClass)
}
val outerClassScope = resolveClass(outerClass)?.getUnsubstitutedInnerClassesScope()
val nestedClass = outerClassScope?.getClassifier(javaClass.getName()) as? ClassDescriptor
return nestedClass ?: c.javaResolverCache.getClass(javaClass)
return outerClassScope?.getClassifier(javaClass.getName()) as? ClassDescriptor
}
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve.java.lazy
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import kotlin.properties.Delegates
import javax.inject.Inject
trait ModuleClassResolver {
fun resolveClass(javaClass: JavaClass): ClassDescriptor?
}
public class SingleModuleClassResolver() : ModuleClassResolver {
override fun resolveClass(javaClass: JavaClass): ClassDescriptor? {
return resolver!!.resolveClass(javaClass)
}
var resolver: JavaDescriptorResolver? = null
[Inject] set
}
public class ModuleClassResolverImpl(private val descriptorResolverByJavaClass: (JavaClass) -> JavaDescriptorResolver): ModuleClassResolver {
override fun resolveClass(javaClass: JavaClass): ClassDescriptor? = descriptorResolverByJavaClass(javaClass).resolveClass(javaClass)
}

View File

@@ -42,7 +42,8 @@ open class GlobalJavaResolverContext(
val methodSignatureChecker: MethodSignatureChecker,
val javaResolverCache: JavaResolverCache,
val javaPropertyInitializerEvaluator: JavaPropertyInitializerEvaluator,
val sourceElementFactory: JavaSourceElementFactory
val sourceElementFactory: JavaSourceElementFactory,
val moduleClassResolver: ModuleClassResolver
)
open class LazyJavaResolverContext(
@@ -58,11 +59,12 @@ open class LazyJavaResolverContext(
methodSignatureChecker: MethodSignatureChecker,
javaResolverCache: JavaResolverCache,
javaPropertyInitializerEvaluator: JavaPropertyInitializerEvaluator,
sourceElementFactory: JavaSourceElementFactory
sourceElementFactory: JavaSourceElementFactory,
moduleClassResolver: ModuleClassResolver
) : GlobalJavaResolverContext(storageManager, finder, kotlinClassFinder, deserializedDescriptorResolver,
externalAnnotationResolver, externalSignatureResolver,
errorReporter, methodSignatureChecker, javaResolverCache, javaPropertyInitializerEvaluator,
sourceElementFactory)
sourceElementFactory, moduleClassResolver)
fun LazyJavaResolverContext.withTypes(
typeParameterResolver: TypeParameterResolver = TypeParameterResolver.EMPTY
@@ -80,6 +82,7 @@ fun LazyJavaResolverContext.withTypes(
javaResolverCache,
javaPropertyInitializerEvaluator,
sourceElementFactory,
moduleClassResolver,
LazyJavaTypeResolver(this, typeParameterResolver),
typeParameterResolver)
@@ -97,12 +100,13 @@ class LazyJavaResolverContextWithTypes(
javaResolverCache: JavaResolverCache,
javaPropertyInitializerEvaluator: JavaPropertyInitializerEvaluator,
sourceElementFactory: JavaSourceElementFactory,
moduleClassResolver: ModuleClassResolver,
val typeResolver: LazyJavaTypeResolver,
val typeParameterResolver: TypeParameterResolver
) : LazyJavaResolverContext(packageFragmentProvider, javaClassResolver, storageManager, finder,
kotlinClassFinder, deserializedDescriptorResolver,
externalAnnotationResolver, externalSignatureResolver, errorReporter, methodSignatureChecker,
javaResolverCache, javaPropertyInitializerEvaluator, sourceElementFactory)
javaResolverCache, javaPropertyInitializerEvaluator, sourceElementFactory, moduleClassResolver)
fun LazyJavaResolverContextWithTypes.child(
containingDeclaration: DeclarationDescriptor,

View File

@@ -65,7 +65,7 @@ class LazyJavaAnnotationDescriptor(
val fqName = _fqName()
if (fqName == null) return@createLazyValue ErrorUtils.createErrorType("No fqName: $javaAnnotation")
val annotationClass = JavaToKotlinClassMap.getInstance().mapKotlinClass(fqName, TypeUsage.MEMBER_SIGNATURE_INVARIANT)
?: javaAnnotation.resolve()?.let { javaClass -> c.javaClassResolver.resolveClass(javaClass) }
?: javaAnnotation.resolve()?.let { javaClass -> c.moduleClassResolver.resolveClass(javaClass) }
annotationClass?.getDefaultType() ?: ErrorUtils.createErrorType(fqName.asString())
}
@@ -148,6 +148,7 @@ class LazyJavaAnnotationDescriptor(
val containingJavaClass = element.getContainingClass()
//TODO: (module refactoring) moduleClassResolver should be used here
val enumClass = c.javaClassResolver.resolveClass(containingJavaClass)
if (enumClass == null) return null

View File

@@ -232,6 +232,7 @@ public class LazyJavaClassMemberScope(
}
else {
// TODO: this caching is a temporary workaround, should be replaced with properly caching the whole LazyJavaPackageFragmentProvider
//TODO_R: remove this logic?
val alreadyResolved = c.javaResolverCache.getClass(jNestedClass)
if (alreadyResolved != null)
alreadyResolved

View File

@@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass
import org.jetbrains.jet.lang.resolve.resolveTopLevelClass
//TODO: (module refactoring) usages of this interface should be replaced by ModuleClassResolver
trait LazyJavaClassResolver {
fun resolveClass(javaClass: JavaClass): ClassDescriptor?
}

View File

@@ -113,7 +113,7 @@ class LazyJavaTypeResolver(
}
val classData = javaToKotlinClassMap.mapKotlinClass(fqName, howThisTypeIsUsedEffectively)
?: c.javaClassResolver.resolveClass(classifier)
?: c.moduleClassResolver.resolveClass(classifier)
classData?.getTypeConstructor()
?: ErrorUtils.createErrorTypeConstructor("Unresolved java classifier: " + javaType.getPresentableText())

View File

@@ -62,7 +62,7 @@ public class ModuleDescriptorImpl(
})
}
private val isInitialized: Boolean
public val isInitialized: Boolean
get() = packageFragmentProviderForModuleContent != null
public fun addDependencyOnModule(dependency: ModuleDescriptorImpl) {

View File

@@ -34,7 +34,11 @@ import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils
import org.jetbrains.jet.lang.resolve.calls.CallResolver
import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaPropertyInitializerEvaluatorImpl
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.jet.lang.resolve.java.lazy.ModuleClassResolver
import org.jetbrains.jet.lang.resolve.kotlin.DeserializationGlobalContextForJava
import org.jetbrains.jet.lang.resolve.java.lazy.SingleModuleClassResolver
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinderFactory
// NOTE: After making changes, you need to re-generate the injectors.
// To do that, you can run main in this file.
@@ -95,6 +99,8 @@ private fun generatorForTopDownAnalyzerForJvm() =
publicField(javaClass<JavaDescriptorResolver>())
publicField(javaClass<DeserializationGlobalContextForJava>())
field(javaClass <GlobalSearchScope>(),
init = GivenExpression(javaClass<GlobalSearchScope>().getName() + ".allScope(project)"))
fields(
javaClass<JavaClassFinderImpl>(),
javaClass<TraceBasedExternalSignatureResolver>(),
@@ -104,7 +110,8 @@ private fun generatorForTopDownAnalyzerForJvm() =
javaClass<PsiBasedExternalAnnotationResolver>(),
javaClass<MutablePackageFragmentProvider>(),
javaClass<JavaPropertyInitializerEvaluatorImpl>(),
javaClass<JavaSourceElementFactoryImpl>()
javaClass<JavaSourceElementFactoryImpl>(),
javaClass<SingleModuleClassResolver>()
)
field(javaClass<VirtualFileFinder>(), init = GivenExpression(javaClass<VirtualFileFinder>().getName() + ".SERVICE.getInstance(project)"))
}
@@ -123,6 +130,9 @@ private fun generatorForJavaDescriptorResolver() =
publicField(javaClass<JavaDescriptorResolver>())
publicField(javaClass<JavaClassFinderImpl>())
field(javaClass <GlobalSearchScope>(),
init = GivenExpression(javaClass<GlobalSearchScope>().getName() + ".allScope(project)"))
fields(
javaClass<TraceBasedExternalSignatureResolver>(),
javaClass<TraceBasedJavaResolverCache>(),
@@ -130,7 +140,8 @@ private fun generatorForJavaDescriptorResolver() =
javaClass<PsiBasedMethodSignatureChecker>(),
javaClass<PsiBasedExternalAnnotationResolver>(),
javaClass<JavaPropertyInitializerEvaluatorImpl>(),
javaClass<JavaSourceElementFactoryImpl>()
javaClass<JavaSourceElementFactoryImpl>(),
javaClass<SingleModuleClassResolver>()
)
field(javaClass<VirtualFileFinder>(),
init = GivenExpression(javaClass<VirtualFileFinder>().getName() + ".SERVICE.getInstance(project)"))
@@ -139,21 +150,24 @@ private fun generatorForJavaDescriptorResolver() =
private fun generatorForLazyResolveWithJava() =
generator("compiler/frontend.java/src", "org.jetbrains.jet.di", "InjectorForLazyResolveWithJava") {
parameter(javaClass<Project>())
parameter(javaClass<GlobalContextImpl>(), useAsContext = true)
parameter(javaClass<GlobalContext>(), useAsContext = true)
parameter(javaClass<ModuleDescriptorImpl>(), name = "module", useAsContext = true)
parameter(javaClass<GlobalSearchScope>(), name = "moduleContentScope")
parameters(
javaClass<BindingTrace>(),
javaClass<DeclarationProviderFactory>(),
javaClass<BindingTrace>()
javaClass<ModuleClassResolver>()
)
publicField(javaClass<ModuleDescriptorImpl>(), name = "module", useAsContext = true,
init = GivenExpression("org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM.createJavaModule(\"<fake-jdr-module>\")"))
publicFields(
javaClass<ResolveSession>(),
javaClass<JavaDescriptorResolver>()
)
field(javaClass<VirtualFileFinder>(),
init = GivenExpression(javaClass<VirtualFileFinder>().getName() + ".SERVICE.getInstance(project)"))
init = GivenExpression(javaClass<VirtualFileFinderFactory>().getName()
+ ".SERVICE.getInstance(project).create(moduleContentScope)")
)
fields(
javaClass<JavaClassFinderImpl>(),
javaClass<TraceBasedExternalSignatureResolver>(),
@@ -208,7 +222,7 @@ private fun generatorForBodyResolve() =
private fun generatorForLazyResolve() =
generator("compiler/frontend/src", "org.jetbrains.jet.di", "InjectorForLazyResolve") {
parameter(javaClass<Project>())
parameter(javaClass<GlobalContextImpl>(), useAsContext = true)
parameter(javaClass<GlobalContext>(), useAsContext = true)
parameter(javaClass<ModuleDescriptorImpl>(), useAsContext = true)
parameter(javaClass<DeclarationProviderFactory>())
parameter(javaClass<BindingTrace>())

View File

@@ -24,6 +24,8 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.containers.MultiMap;
import kotlin.Function1;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.asJava.KotlinLightClassForExplicitDeclaration;
@@ -65,20 +67,10 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport
public IDELightClassGenerationSupport(@NotNull Project project) {
this.project = project;
final GlobalSearchScope searchScope = GlobalSearchScope.allScope(project);
this.jetFileComparator = new Comparator<JetFile>() {
@Override
public int compare(@NotNull JetFile o1, @NotNull JetFile o2) {
VirtualFile f1 = o1.getVirtualFile();
VirtualFile f2 = o2.getVirtualFile();
if (f1 == f2) return 0;
if (f1 == null) return -1;
if (f2 == null) return 1;
return searchScope.compare(f1, f2);
}
};
this.jetFileComparator = byScopeComparator(GlobalSearchScope.allScope(project));
}
@NotNull
@Override
public LightClassConstructionContext getContextForPackage(@NotNull Collection<JetFile> files) {
@@ -169,6 +161,47 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport
return PackageIndexUtil.findFilesWithExactPackage(fqName, kotlinSources(searchScope, project), project);
}
@NotNull
@Override
public List<KotlinLightPackageClassInfo> findPackageClassesInfos(
@NotNull FqName fqName, @NotNull GlobalSearchScope wholeScope
) {
Collection<JetFile> allFiles = findFilesForPackage(fqName, wholeScope);
Map<IdeaModuleInfo, List<JetFile>> filesByInfo = groupByModuleInfo(allFiles);
List<KotlinLightPackageClassInfo> result = new ArrayList<KotlinLightPackageClassInfo>();
for (Map.Entry<IdeaModuleInfo, List<JetFile>> entry : filesByInfo.entrySet()) {
result.add(new KotlinLightPackageClassInfo(entry.getValue(), entry.getKey().contentScope()));
}
sortByClasspath(wholeScope, result);
return result;
}
@NotNull
private static Map<IdeaModuleInfo, List<JetFile>> groupByModuleInfo(@NotNull Collection<JetFile> allFiles) {
return KotlinPackage.groupByTo(
allFiles,
new LinkedHashMap<IdeaModuleInfo, List<JetFile>>(),
new Function1<JetFile, IdeaModuleInfo>() {
@Override
public IdeaModuleInfo invoke(JetFile file) {
return ResolvePackage.getModuleInfo(file);
}
});
}
private static void sortByClasspath(@NotNull GlobalSearchScope wholeScope, @NotNull List<KotlinLightPackageClassInfo> result) {
final Comparator<JetFile> byScopeComparator = byScopeComparator(wholeScope);
Collections.sort(result, new Comparator<KotlinLightPackageClassInfo>() {
@Override
public int compare(@NotNull KotlinLightPackageClassInfo info1, @NotNull KotlinLightPackageClassInfo info2) {
JetFile file1 = info1.getFiles().iterator().next();
JetFile file2 = info2.getFiles().iterator().next();
//classes earlier that would appear earlier on classpath should go first
return -byScopeComparator.compare(file1, file2);
}
});
}
@NotNull
@Override
public Collection<JetClassOrObject> findClassOrObjectDeclarationsInPackage(
@@ -211,4 +244,19 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport
return result;
}
@NotNull
private static Comparator<JetFile> byScopeComparator(@NotNull final GlobalSearchScope searchScope) {
return new Comparator<JetFile>() {
@Override
public int compare(@NotNull JetFile o1, @NotNull JetFile o2) {
VirtualFile f1 = o1.getVirtualFile();
VirtualFile f2 = o2.getVirtualFile();
if (f1 == f2) return 0;
if (f1 == null) return -1;
if (f2 == null) return 1;
return searchScope.compare(f1, f2);
}
};
}
}

View File

@@ -0,0 +1,134 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.caches.resolve
import org.jetbrains.jet.analyzer.ModuleInfo
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.OrderEntry
import com.intellij.openapi.roots.ModuleSourceOrderEntry
import com.intellij.openapi.roots.ModuleOrderEntry
import com.intellij.openapi.roots.LibraryOrderEntry
import com.intellij.openapi.roots.JdkOrderEntry
import com.intellij.openapi.module.Module
import org.jetbrains.jet.lang.resolve.name.Name
import java.util.LinkedHashSet
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.module.impl.scopes.LibraryScopeBase
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.jet.utils.emptyOrSingletonList
private abstract class IdeaModuleInfo : ModuleInfo {
abstract fun contentScope(): GlobalSearchScope
}
private fun orderEntryToModuleInfo(project: Project, orderEntry: OrderEntry): List<IdeaModuleInfo> {
return when (orderEntry) {
is ModuleSourceOrderEntry -> {
listOf(orderEntry.getOwnerModule().toSourceInfo())
}
is ModuleOrderEntry -> {
emptyOrSingletonList(orderEntry.getModule()?.toSourceInfo())
}
is LibraryOrderEntry -> {
val library = orderEntry.getLibrary() ?: return listOf()
emptyOrSingletonList(LibraryInfo(project, library))
}
is JdkOrderEntry -> {
val sdk = orderEntry.getJdk() ?: return listOf()
emptyOrSingletonList(SdkInfo(project, sdk))
}
else -> {
throw IllegalStateException("Unexpected order entry $orderEntry")
}
}
}
//TODO: (module refactoring) there should be separate ModuleTestInfo
private data class ModuleSourceInfo(val module: Module) : IdeaModuleInfo() {
override val name = Name.special("<sources for module ${module.getName()}>")
override fun contentScope() = GlobalSearchScope.moduleScope(module)
override fun dependencies(): List<IdeaModuleInfo> {
//NOTE: lib dependencies can be processed several times during recursive traversal
val result = LinkedHashSet<IdeaModuleInfo>()
ModuleRootManager.getInstance(module).orderEntries().compileOnly().recursively().exportedOnly().forEach {
orderEntry ->
result.addAll(orderEntryToModuleInfo(module.getProject(), orderEntry!!))
true
}
return result.toList()
}
}
private fun Module.toSourceInfo() = ModuleSourceInfo(this)
private data class LibraryInfo(val project: Project, val library: Library) : IdeaModuleInfo() {
override val name: Name = Name.special("<library ${library.getName()}>")
override fun contentScope() = LibraryWithoutSourceScope(project, library)
override fun dependencies(): List<IdeaModuleInfo> {
//TODO: (module refactoring) heuristic dependencies for libraries
val orderEntry = ModuleManager.getInstance(project).getModules().stream().flatMap {
ModuleRootManager.getInstance(it).getOrderEntries().stream()
}.firstOrNull { it is JdkOrderEntry } as? JdkOrderEntry
val sdk = orderEntry?.getJdk()
return if (sdk != null) listOf(SdkInfo(project, sdk), this) else listOf(this)
}
}
private data class LibrarySourceInfo(val project: Project, val library: Library) : IdeaModuleInfo() {
override val name: Name = Name.special("<sources for library ${library.getName()}>")
override fun contentScope() = GlobalSearchScope.EMPTY_SCOPE
override fun dependencies(): List<IdeaModuleInfo> {
return listOf(this) + LibraryInfo(project, library).dependencies()
}
}
//TODO: (module refactoring) there should be separate SdkSourceInfo but there are no kotlin source in existing sdks for now :)
private data class SdkInfo(val project: Project, val sdk: Sdk) : IdeaModuleInfo() {
override val name: Name = Name.special("<library ${sdk.getName()}>")
override fun contentScope() = SdkScope(project, sdk)
override fun dependencies(): List<IdeaModuleInfo> = listOf(this)
}
private object NotUnderContentRootModuleInfo : IdeaModuleInfo() {
override val name: Name = Name.special("<special module for files not under source root>")
override fun contentScope() = GlobalSearchScope.EMPTY_SCOPE
//TODO: (module refactoring) dependency on runtime can be of use here
override fun dependencies(): List<IdeaModuleInfo> = listOf(this)
}
private data class LibraryWithoutSourceScope(project: Project, private val library: Library) :
LibraryScopeBase(project, library.getFiles(OrderRootType.CLASSES), array<VirtualFile>()) {
}
//TODO: (module refactoring) android sdk has modified scope
private data class SdkScope(project: Project, private val sdk: Sdk) :
LibraryScopeBase(project, sdk.getRootProvider().getFiles(OrderRootType.CLASSES), array<VirtualFile>())

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.caches.resolve
import org.jetbrains.jet.plugin.project.TargetPlatform
import com.intellij.psi.PsiElement
import org.jetbrains.jet.lang.resolve.java.JvmResolverForModule
import com.intellij.openapi.project.Project
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver
import org.jetbrains.jet.lang.resolve.BindingContext
public object JavaResolveExtension : CacheExtension<(PsiElement) -> Pair<JavaDescriptorResolver, BindingContext>> {
override val platform: TargetPlatform = TargetPlatform.JVM
override fun getData(resolverProvider: ModuleResolverProvider): (PsiElement) -> Pair<JavaDescriptorResolver, BindingContext> {
return {
val resolverForModule = resolverProvider.resolverByModule(it.getModuleInfo()) as JvmResolverForModule
Pair(resolverForModule.javaDescriptorResolver, resolverForModule.lazyResolveSession.getBindingContext())
}
}
public fun getResolver(project: Project, element: PsiElement): JavaDescriptorResolver =
KotlinCacheService.getInstance(project)[this](element).first
public fun getContext(project: Project, element: PsiElement): BindingContext =
KotlinCacheService.getInstance(project)[this](element).second
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.caches.resolve
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession
import org.jetbrains.jet.analyzer.ResolverForModule
import org.jetbrains.jet.lang.psi.JetFile
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.jet.analyzer.PlatformAnalysisParameters
import org.jetbrains.jet.analyzer.AnalyzerFacade
import com.intellij.openapi.project.Project
import org.jetbrains.jet.context.GlobalContext
import org.jetbrains.jet.analyzer.ResolverForProject
import org.jetbrains.k2js.analyze.AnalyzerFacadeForJS
import org.jetbrains.jet.lang.PlatformToKotlinClassMap
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactoryService
import org.jetbrains.jet.lang.resolve.BindingTraceContext
import org.jetbrains.jet.di.InjectorForLazyResolve
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.jet.analyzer.ModuleInfo
import org.jetbrains.jet.analyzer.ModuleContent
public class JsResolverForModule(
override val lazyResolveSession: ResolveSession
) : ResolverForModule
public object JsAnalyzerFacade : AnalyzerFacade<JsResolverForModule, PlatformAnalysisParameters> {
override fun <M : ModuleInfo> createResolverForModule(
project: Project,
globalContext: GlobalContext,
moduleDescriptor: ModuleDescriptorImpl,
moduleContent: ModuleContent,
platformParameters: PlatformAnalysisParameters,
resolverForProject: ResolverForProject<M, JsResolverForModule>
): JsResolverForModule {
val (syntheticFiles, moduleContentScope) = moduleContent
val declarationProviderFactory = DeclarationProviderFactoryService.createDeclarationProviderFactory(
project, globalContext.storageManager, syntheticFiles, moduleContentScope
)
val injector = InjectorForLazyResolve(project, globalContext, moduleDescriptor, declarationProviderFactory, BindingTraceContext())
val resolveSession = injector.getResolveSession()!!
moduleDescriptor.initialize(resolveSession.getPackageFragmentProvider())
return JsResolverForModule(resolveSession)
}
override val defaultImports = AnalyzerFacadeForJS.DEFAULT_IMPORTS
override val platformToKotlinClassMap = PlatformToKotlinClassMap.EMPTY
}

View File

@@ -33,7 +33,12 @@ import org.jetbrains.jet.plugin.project.TargetPlatform.*
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies
import org.jetbrains.jet.plugin.project.TargetPlatformDetector
import org.jetbrains.jet.lang.psi.JetCodeFragment
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
import org.jetbrains.jet.lang.resolve.DescriptorUtils
import org.jetbrains.jet.context.GlobalContext
import org.jetbrains.jet.plugin.stubindex.JetSourceFilterScope
import com.intellij.psi.PsiElement
private val LOG = Logger.getInstance(javaClass<KotlinCacheService>())
@@ -41,10 +46,6 @@ public fun JetElement.getLazyResolveSession(): ResolveSessionForBodies {
return KotlinCacheService.getInstance(getProject()).getLazyResolveSession(this)
}
public fun Project.getLazyResolveSession(platform: TargetPlatform): ResolveSessionForBodies {
return KotlinCacheService.getInstance(this).getGlobalLazyResolveSession(platform)
}
public fun JetElement.getAnalysisResults(): AnalyzeExhaust {
return KotlinCacheService.getInstance(getProject()).getAnalysisResults(listOf(this))
}
@@ -64,19 +65,16 @@ public class KotlinCacheService(val project: Project) {
public fun getInstance(project: Project): KotlinCacheService = ServiceManager.getService(project, javaClass<KotlinCacheService>())!!
}
private fun globalResolveSessionProvider(platform: TargetPlatform, syntheticFiles: Collection<JetFile> = listOf()) = {
val setup = AnalyzerFacadeProvider.getAnalyzerFacade(platform)
.createSetup(project, syntheticFiles, GlobalSearchScope.allScope(project))
val resolveSessionForBodies = ResolveSessionForBodies(project, setup.getLazyResolveSession())
private fun globalResolveSessionProvider(platform: TargetPlatform, syntheticFiles: Collection<JetFile> = listOf()):
() -> CachedValueProvider.Result<ModuleResolverProvider> = {
val analyzerFacade = AnalyzerFacadeProvider.getAnalyzerFacade(platform)
val moduleMapping = createModuleResolverProvider(project, analyzerFacade, syntheticFiles)
CachedValueProvider.Result.create(
SessionAndSetup(
platform,
resolveSessionForBodies,
setup
),
moduleMapping,
PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT,
resolveSessionForBodies
moduleMapping.exceptionTracker
)
}
private val globalCachesPerPlatform = mapOf(
@@ -102,17 +100,17 @@ public class KotlinCacheService(val project: Project) {
}
}
public fun getGlobalLazyResolveSession(platform: TargetPlatform): ResolveSessionForBodies {
return globalCachesPerPlatform[platform]!!.getLazyResolveSession()
public fun getGlobalLazyResolveSession(file: JetFile, platform: TargetPlatform): ResolveSessionForBodies {
return globalCachesPerPlatform[platform]!!.getLazyResolveSession(file)
}
public fun getLazyResolveSession(element: JetElement): ResolveSessionForBodies {
val file = element.getContainingJetFile()
if (!isFileInScope(file)) {
return getCacheForSyntheticFile(file).getLazyResolveSession()
return getCacheForSyntheticFile(file).getLazyResolveSession(file)
}
return getGlobalLazyResolveSession(TargetPlatformDetector.getPlatform(file))
return getGlobalLazyResolveSession(file, TargetPlatformDetector.getPlatform(file))
}
public fun getAnalysisResults(elements: Collection<JetElement>): AnalyzeExhaust {

View File

@@ -38,7 +38,6 @@ import com.intellij.openapi.roots.libraries.LibraryUtil
import org.jetbrains.jet.lang.resolve.LibrarySourceHacks
import org.jetbrains.jet.plugin.project.TargetPlatform
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies
import org.jetbrains.jet.analyzer.AnalyzerFacade
import java.util.HashMap
import com.intellij.psi.PsiElement
import org.jetbrains.jet.lang.resolve.BindingContext
@@ -64,43 +63,37 @@ import org.jetbrains.jet.analyzer.analyzeInContext
import org.jetbrains.jet.lang.resolve.BindingTraceContext
import org.jetbrains.jet.lang.types.TypeUtils
import org.jetbrains.jet.lang.resolve.scopes.ChainedScope
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
public trait CacheExtension<T> {
public val platform: TargetPlatform
public fun getData(setup: AnalyzerFacade.Setup): T
public fun getData(resolverProvider: ModuleResolverProvider): T
}
private class SessionAndSetup(
val platform: TargetPlatform,
val resolveSessionForBodies: ResolveSessionForBodies,
val setup: AnalyzerFacade.Setup
)
private class KotlinResolveCache(
val project: Project,
setupProvider: () -> CachedValueProvider.Result<SessionAndSetup>
setupProvider: () -> CachedValueProvider.Result<ModuleResolverProvider>
) {
private val setupCache = SynchronizedCachedValue(project, setupProvider, trackValue = false)
private val resolverCache = SynchronizedCachedValue(project, setupProvider, trackValue = false)
public fun getLazyResolveSession(): ResolveSessionForBodies = setupCache.getValue().resolveSessionForBodies
public fun <T> get(extension: CacheExtension<T>): T {
val sessionAndSetup = setupCache.getValue()
assert(extension.platform == sessionAndSetup.platform,
"Extension $extension declares platfrom ${extension.platform} which is incompatible with ${sessionAndSetup.platform}")
return extension.getData(sessionAndSetup.setup)
public fun getLazyResolveSession(element: JetElement): ResolveSessionForBodies {
return resolverCache.getValue().resolveSessionForBodiesByModule(element.getModuleInfo())
}
private val analysisResults = CachedValuesManager.getManager(project).createCachedValue ({
val resolveSession = getLazyResolveSession()
public fun <T> get(extension: CacheExtension<T>): T {
return extension.getData(resolverCache.getValue())
}
private val analysisResults = CachedValuesManager.getManager(project).createCachedValue(
{
val resolverProvider = resolverCache.getValue()
val results = object : SLRUCache<JetFile, PerFileAnalysisCache>(2, 3) {
override fun createValue(file: JetFile?): PerFileAnalysisCache {
return PerFileAnalysisCache(file!!, resolveSession)
return PerFileAnalysisCache(file!!, resolverProvider.resolveSessionForBodiesByModule(file.getModuleInfo()))
}
}
CachedValueProvider.Result(results, PsiModificationTracker.MODIFICATION_COUNT, resolveSession.getExceptionTracker())
CachedValueProvider.Result(results, PsiModificationTracker.MODIFICATION_COUNT, resolverProvider.exceptionTracker)
}, false)
fun getAnalysisResultsForElements(elements: Collection<JetElement>): AnalyzeExhaust {
@@ -118,7 +111,8 @@ private class KotlinResolveCache(
return if (error != null)
AnalyzeExhaust.error(bindingContext, error.getError())
else
AnalyzeExhaust.success(bindingContext, getLazyResolveSession().getModuleDescriptor())
//TODO: (module refactoring) several elements are passed here in debugger
AnalyzeExhaust.success(bindingContext, getLazyResolveSession(elements.first()).getModuleDescriptor())
}
}

View File

@@ -0,0 +1,119 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.caches.resolve
import com.intellij.openapi.project.Project
import org.jetbrains.jet.context.GlobalContext
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.module.ModuleManager
import org.jetbrains.jet.utils.keysToMap
import com.intellij.openapi.roots.LibraryOrderEntry
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies
import org.jetbrains.jet.lang.resolve.java.JvmPlatformParameters
import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaClassImpl
import com.intellij.openapi.roots.JdkOrderEntry
import org.jetbrains.kotlin.util.sure
import org.jetbrains.jet.analyzer.AnalyzerFacade
import org.jetbrains.jet.analyzer.ResolverForModule
import org.jetbrains.jet.lang.psi.*
import org.jetbrains.jet.storage.ExceptionTracker
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass
import org.jetbrains.jet.analyzer.ResolverForProject
import org.jetbrains.jet.analyzer.ModuleContent
import org.jetbrains.jet.analyzer.PlatformAnalysisParameters
import org.jetbrains.jet.plugin.caches.resolve
fun createModuleResolverProvider(
project: Project,
analyzerFacade: AnalyzerFacade<ResolverForModule, JvmPlatformParameters>,
syntheticFiles: Collection<JetFile>
): ModuleResolverProvider {
val allModuleInfos = collectAllModuleInfosFromIdeaModel(project).toHashSet()
val globalContext = GlobalContext()
fun createResolverForProject(): ResolverForProject<IdeaModuleInfo, ResolverForModule> {
val syntheticFilesByModule = syntheticFiles.groupBy { it.getModuleInfo() }
allModuleInfos.addAll(syntheticFilesByModule.keySet())
val modulesContent = {(module: IdeaModuleInfo) ->
ModuleContent(syntheticFilesByModule[module] ?: listOf(), module.contentScope())
}
val jvmPlatformParameters = JvmPlatformParameters {
(javaClass: JavaClass) ->
val psiClass = (javaClass as JavaClassImpl).getPsi()
psiClass.getModuleInfo()
}
val resolverForProject = analyzerFacade.setupResolverForProject(
globalContext, project, allModuleInfos, modulesContent, jvmPlatformParameters
)
return resolverForProject
}
val resolverForProject = createResolverForProject()
val moduleToBodiesResolveSession = allModuleInfos.keysToMap {
module ->
val analyzer = resolverForProject.resolverForModule(module)
ResolveSessionForBodies(project, analyzer.lazyResolveSession)
}
return ModuleResolverProvider(
resolverForProject,
moduleToBodiesResolveSession,
globalContext.exceptionTracker
)
}
private fun collectAllModuleInfosFromIdeaModel(project: Project): List<IdeaModuleInfo> {
val ideaModules = ModuleManager.getInstance(project).getModules().toList()
val modulesSourcesInfos = ideaModules.map { it.toSourceInfo() }
//TODO: (module refactoring) include libraries that are not among dependencies of any module
val ideaLibraries = ideaModules.flatMap {
ModuleRootManager.getInstance(it).getOrderEntries().filterIsInstance(javaClass<LibraryOrderEntry>()).map {
it.getLibrary()
}
}.filterNotNull().toSet()
val librariesInfos = ideaLibraries.map { LibraryInfo(project, it) }
val ideaSdks = ideaModules.flatMap {
ModuleRootManager.getInstance(it).getOrderEntries().filterIsInstance(javaClass<JdkOrderEntry>()).map {
it.getJdk()
}
}.filterNotNull().toSet()
val sdksInfos = ideaSdks.map { SdkInfo(project, it) }
val collectAllModuleInfos = modulesSourcesInfos + librariesInfos + sdksInfos
return collectAllModuleInfos
}
class ModuleResolverProvider(
private val resolverForProject: ResolverForProject<IdeaModuleInfo, *>,
private val bodiesResolveByModule: Map<IdeaModuleInfo, ResolveSessionForBodies>,
val exceptionTracker: ExceptionTracker
) {
fun resolverByModule(module: IdeaModuleInfo): ResolverForModule = resolverForProject.resolverForModule(module)
fun resolveSessionForBodiesByModule(module: IdeaModuleInfo) =
//NOTE: if this assert fails in production, additional information can be obtained by logging on the call site
bodiesResolveByModule[module] ?: throw AssertionError("Requested data for $module not contained in this resolver.")
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.caches.resolve
import com.intellij.psi.PsiElement
import org.jetbrains.jet.lang.resolve.java.jetAsJava.KotlinLightElement
import org.jetbrains.jet.lang.psi.*
import com.intellij.openapi.roots.ProjectFileIndex
import com.intellij.openapi.roots.LibraryOrSdkOrderEntry
import com.intellij.openapi.roots.LibraryOrderEntry
import com.intellij.openapi.roots.JdkOrderEntry
import org.jetbrains.jet.asJava.FakeLightClassForFileOfPackage
import org.jetbrains.jet.asJava.KotlinLightClassForPackage
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
fun PsiElement.getModuleInfo(): IdeaModuleInfo {
fun logAndReturnDefault(message: String): IdeaModuleInfo {
LOG.error("Could not find correct module information.\nReason: $message")
return NotUnderContentRootModuleInfo
}
if (this is KotlinLightElement<*, *>)
return this.getModuleInfoForLightElement()
if (this is JetCodeFragment)
return this.getContext()?.getModuleInfo()
?: logAndReturnDefault("Analyzing code fragment of type $javaClass with no context element\nText:\n${getText()}")
val containingJetFile = (this as? JetElement)?.getContainingFile() as? JetFile
val context = containingJetFile?.analysisContext
if (context != null) return context.getModuleInfo()
val doNotAnalyze = containingJetFile?.doNotAnalyze
if (doNotAnalyze != null) {
return logAndReturnDefault(
"Should not analyze element: ${getText()} in file ${containingJetFile?.getName() ?: " <no file>"}\n$doNotAnalyze"
)
}
val project = getProject()
val containingFile = getContainingFile()
?: return logAndReturnDefault("Analyzing element of type $javaClass with no containing file\nText:\n${getText()}")
val virtualFile = containingFile.getOriginalFile().getVirtualFile()
?: return logAndReturnDefault("Analyzing non-physical file $containingFile of type ${containingFile.javaClass}")
return getModuleInfoByVirtualFile(project, virtualFile)
}
private fun getModuleInfoByVirtualFile(project: Project, virtualFile: VirtualFile): IdeaModuleInfo {
val projectFileIndex = ProjectFileIndex.SERVICE.getInstance(project)
val module = projectFileIndex.getModuleForFile(virtualFile)
if (module != null) return module.toSourceInfo()
val orderEntries = projectFileIndex.getOrderEntriesForFile(virtualFile)
val libraryOrSdkEntries = orderEntries.filterIsInstance(javaClass<LibraryOrSdkOrderEntry>())
@entries for (libraryOrSdkOrderEntry in libraryOrSdkEntries) {
when (libraryOrSdkOrderEntry) {
is LibraryOrderEntry -> {
val library = libraryOrSdkOrderEntry.getLibrary() ?: continue @entries
if (projectFileIndex.isInLibrarySource(virtualFile)) {
return LibrarySourceInfo(project, library)
}
else {
return LibraryInfo(project, library)
}
}
is JdkOrderEntry -> {
val sdk = libraryOrSdkOrderEntry.getJdk() ?: continue @entries
return SdkInfo(project, sdk)
}
}
}
return NotUnderContentRootModuleInfo
}
private fun KotlinLightElement<*, *>.getModuleInfoForLightElement(): IdeaModuleInfo {
val element = origin ?: when (this) {
is FakeLightClassForFileOfPackage -> this.getContainingFile()!!
is KotlinLightClassForPackage -> this.getFiles().first()
else -> throw IllegalStateException("Unknown light class without origin is referenced by IDE lazy resolve: $javaClass")
}
return element.getModuleInfo()
}

View File

@@ -20,6 +20,7 @@ import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.asJava.AsJavaPackage;
import org.jetbrains.jet.lang.psi.JetDeclaration;
@@ -31,6 +32,8 @@ import org.jetbrains.jet.plugin.caches.resolve.ResolvePackage;
import org.jetbrains.jet.plugin.project.TargetPlatform;
import org.jetbrains.jet.plugin.project.TargetPlatformDetector;
import static org.jetbrains.jet.plugin.caches.resolve.ResolvePackage.getModuleInfo;
public class DuplicateJvmSignatureAnnotator implements Annotator {
@Override
@@ -42,7 +45,8 @@ public class DuplicateJvmSignatureAnnotator implements Annotator {
if (!(file instanceof JetFile) || TargetPlatformDetector.getPlatform((JetFile) file) != TargetPlatform.JVM) return;
Diagnostics otherDiagnostics = ResolvePackage.getBindingContext((JetElement) element).getDiagnostics();
Diagnostics diagnostics = AsJavaPackage.getJvmSignatureDiagnostics(element, otherDiagnostics);
GlobalSearchScope moduleScope = getModuleInfo(element).contentScope();
Diagnostics diagnostics = AsJavaPackage.getJvmSignatureDiagnostics(element, otherDiagnostics, moduleScope);
if (diagnostics == null) return;
JetPsiChecker.annotateElement(element, holder, diagnostics);

View File

@@ -1,37 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.analyzer.AnalyzerFacade;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
public final class AnalyzerFacadeProvider {
private AnalyzerFacadeProvider() {
}
@NotNull
public static AnalyzerFacade getAnalyzerFacadeForFile(@NotNull JetFile file) {
return getAnalyzerFacade(TargetPlatformDetector.getPlatform(file));
}
@NotNull
public static AnalyzerFacade getAnalyzerFacade(@NotNull TargetPlatform targetPlatform) {
return targetPlatform == TargetPlatform.JVM ? AnalyzerFacadeForJVM.INSTANCE : JSAnalyzerFacadeForIDEA.INSTANCE;
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.project
import org.jetbrains.jet.analyzer.AnalyzerFacade
import org.jetbrains.jet.lang.resolve.java.JvmPlatformParameters
import org.jetbrains.jet.analyzer.ResolverForModule
import org.jetbrains.jet.lang.resolve.java.JvmAnalyzerFacade
import org.jetbrains.jet.plugin.caches.resolve.JsAnalyzerFacade
public object AnalyzerFacadeProvider {
//NOTE: it's convenient that JS backend doesn't have platform parameters (for now)
// otherwise we would be forced to add casts on the call site of setupResolverForProject
public fun getAnalyzerFacade(targetPlatform: TargetPlatform): AnalyzerFacade<ResolverForModule, JvmPlatformParameters> {
return when (targetPlatform) {
TargetPlatform.JVM -> JvmAnalyzerFacade
TargetPlatform.JS -> JsAnalyzerFacade
else -> throw IllegalArgumentException("Unsupported platfrom: $targetPlatform")
}
}
}

View File

@@ -1,40 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.project;
import com.intellij.openapi.project.Project;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.analyzer.AnalyzerFacade;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.k2js.analyze.AnalyzerFacadeForJS;
import java.util.Collection;
public enum JSAnalyzerFacadeForIDEA implements AnalyzerFacade {
INSTANCE;
private JSAnalyzerFacadeForIDEA() {
}
@NotNull
@Override
public Setup createSetup(@NotNull Project project, @NotNull Collection<JetFile> syntheticFiles, @NotNull GlobalSearchScope filesScope) {
return new BasicSetup(AnalyzerFacadeForJS.getLazyResolveSession(syntheticFiles, filesScope, new IDEAConfig(project)));
}
}

View File

@@ -21,12 +21,11 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.analyzer.AnalyzerFacade;
import org.jetbrains.jet.lang.psi.JetFile;
public class TargetPlatformDetector {
public static final TargetPlatformDetector INSTANCE = new TargetPlatformDetector();
private static final Logger LOG = Logger.getInstance(AnalyzerFacade.class);
private static final Logger LOG = Logger.getInstance(TargetPlatformDetector.class);
private TargetPlatformDetector() {
}

View File

@@ -56,7 +56,8 @@ public class JavaToKotlinAction extends AnAction {
final Converter converter = Converter.OBJECT$.create(project,
ConverterSettings.defaultSettings,
new FilesConversionScope(selectedJavaFiles),
J2kPostProcessor.INSTANCE$);
//TODO: (module refactoring) resulting files should be analyzed in context of respective java files
new J2kPostProcessor(selectedJavaFiles.iterator().next()));
CommandProcessor.getInstance().executeCommand(
project,
new Runnable() {

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.caches.resolve
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver
import org.jetbrains.jet.analyzer.AnalyzerFacade
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM.JvmSetup
import org.jetbrains.jet.plugin.project.TargetPlatform
import com.intellij.openapi.project.Project
object JavaResolveExtension : CacheExtension<JavaDescriptorResolver> {
override val platform: TargetPlatform = TargetPlatform.JVM
override fun getData(setup: AnalyzerFacade.Setup): JavaDescriptorResolver {
return (setup as JvmSetup).getJavaDescriptorResolver()
}
public fun get(project: Project): JavaDescriptorResolver = KotlinCacheService.getInstance(project)[this]
}

View File

@@ -70,7 +70,7 @@ public class ConvertJavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBl
val jetEditorOptions = JetEditorOptions.getInstance()!!
val needConvert = jetEditorOptions.isEnableJavaToKotlinConversion() && (jetEditorOptions.isDonTShowConversionDialog() || okFromDialog(project))
if (needConvert) {
val text = convertCopiedCodeToKotlin(value, sourceFile)
val text = convertCopiedCodeToKotlin(value, sourceFile, targetFile)
if (text.isNotEmpty()) {
ApplicationManager.getApplication()!!.runWriteAction {
val startOffset = bounds.getStartOffset()
@@ -84,11 +84,11 @@ public class ConvertJavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBl
}
}
private fun convertCopiedCodeToKotlin(code: CopiedCode, file: PsiJavaFile): String {
val converter = Converter.create(file.getProject(),
private fun convertCopiedCodeToKotlin(code: CopiedCode, fileCopiedFrom: PsiJavaFile, fileCopiedTo: JetFile): String {
val converter = Converter.create(fileCopiedFrom.getProject(),
ConverterSettings.defaultSettings,
FilesConversionScope(listOf(file)),
J2kPostProcessor)
FilesConversionScope(listOf(fileCopiedFrom)),
J2kPostProcessor(fileCopiedTo))
val startOffsets = code.getStartOffsets()
val endOffsets = code.getEndOffsets()
assert(startOffsets.size == endOffsets.size) { "Must have the same size" }
@@ -96,7 +96,7 @@ public class ConvertJavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBl
for (i in startOffsets.indices) {
val startOffset = startOffsets[i]
val endOffset = endOffsets[i]
result.append(convertRangeToKotlin(file, TextRange(startOffset, endOffset), converter))
result.append(convertRangeToKotlin(fileCopiedFrom, TextRange(startOffset, endOffset), converter))
}
return StringUtil.convertLineSeparators(result.toString())
}

View File

@@ -102,7 +102,10 @@ class KotlinEvaluateExpressionCache(val project: Project) {
return runReadAction {
val classes = JavaPsiFacade.getInstance(project).findClasses(jvmName.asString(), GlobalSearchScope.allScope(project))
if (classes.isEmpty()) null else JavaResolveExtension[project].resolveClass(JavaClassImpl(classes.first()))
if (classes.isEmpty()) null else {
val clazz = classes.first()
JavaResolveExtension.getResolver(project, clazz).resolveClass(JavaClassImpl(clazz))
}
}
}

View File

@@ -25,7 +25,6 @@ import org.jetbrains.jet.lang.resolve.AnalyzingUtils
import org.jetbrains.jet.codegen.state.GenerationState
import org.jetbrains.jet.codegen.ClassBuilderFactories
import org.jetbrains.jet.codegen.KotlinCodegenFacade
import com.intellij.openapi.application.ApplicationManager
import com.intellij.testFramework.LightVirtualFile
import org.jetbrains.jet.plugin.JetLanguage
import org.jetbrains.jet.lang.psi.JetFile
@@ -35,7 +34,6 @@ import com.intellij.openapi.vfs.CharsetToolkit
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.org.objectweb.asm.Opcodes.ASM5
import org.jetbrains.org.objectweb.asm.*
import com.intellij.openapi.util.Computable
import org.jetbrains.eval4j.*
import org.jetbrains.eval4j.jdi.JDIEval
import org.jetbrains.eval4j.jdi.asJdiValue
@@ -62,6 +60,7 @@ import com.sun.jdi.VirtualMachine
import org.jetbrains.jet.codegen.AsmUtil
import com.sun.jdi.InvalidStackFrameException
import org.jetbrains.jet.plugin.refactoring.runReadAction
import org.jetbrains.jet.lang.psi.analysisContext
private val RECEIVER_NAME = "\$receiver"
private val THIS_NAME = "this"
@@ -278,6 +277,7 @@ private fun createFileForDebugger(codeFragment: JetCodeFragment,
val jetFile = (PsiFileFactory.getInstance(codeFragment.getProject()) as PsiFileFactoryImpl)
.trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false) as JetFile
jetFile.skipVisibilityCheck = true
jetFile.analysisContext = codeFragment
return jetFile
}

View File

@@ -22,8 +22,9 @@ import org.jetbrains.jet.lang.resolve.BindingContext
import org.jetbrains.jet.plugin.intentions.RemoveExplicitTypeArguments
import org.jetbrains.jet.plugin.caches.resolve.getAnalysisResults
import java.util.ArrayList
import com.intellij.psi.PsiElement
public object J2kPostProcessor : PostProcessor {
public class J2kPostProcessor(override val contextToAnalyzeIn: PsiElement) : PostProcessor {
override fun analyzeFile(file: JetFile): BindingContext {
return file.getAnalysisResults().getBindingContext()
}

View File

@@ -106,7 +106,7 @@ public class KotlinSignatureAnnotationIntention extends BaseIntentionAction impl
return;
}
String signature = getDefaultSignature(project, annotatedElement);
String signature = getDefaultSignature(project, (PsiMember) KotlinSignatureUtil.getAnnotationOwner(annotatedElement));
final MessageBusConnection busConnection = project.getMessageBus().connect();
busConnection.subscribe(ExternalAnnotationsManager.TOPIC, new ExternalAnnotationsListener.Adapter() {
@@ -143,7 +143,7 @@ public class KotlinSignatureAnnotationIntention extends BaseIntentionAction impl
@NotNull
private static String getDefaultSignature(@NotNull Project project, @NotNull PsiMember psiMember) {
JavaDescriptorResolver javaDescriptorResolver = JavaResolveExtension.INSTANCE$.get(project);
JavaDescriptorResolver javaDescriptorResolver = JavaResolveExtension.INSTANCE$.getResolver(project, psiMember);
if (psiMember instanceof PsiMethod) {
PsiMethod psiMethod = (PsiMethod) psiMember;

View File

@@ -31,6 +31,7 @@ import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Function;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -44,9 +45,7 @@ import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaFieldImpl;
import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaMethodImpl;
import org.jetbrains.jet.plugin.JetIcons;
import org.jetbrains.jet.plugin.caches.resolve.JavaResolveExtension;
import org.jetbrains.jet.plugin.caches.resolve.ResolvePackage;
import org.jetbrains.jet.plugin.project.ProjectStructureUtil;
import org.jetbrains.jet.plugin.project.TargetPlatform;
import java.awt.event.MouseEvent;
import java.util.Collection;
@@ -76,7 +75,8 @@ public class KotlinSignatureInJavaMarkerProvider implements LineMarkerProvider {
return;
}
Project project = elements.get(0).getProject();
PsiElement firstElement = elements.get(0);
Project project = firstElement.getProject();
if (!isMarkersEnabled(project)) {
return;
}
@@ -85,17 +85,13 @@ public class KotlinSignatureInJavaMarkerProvider implements LineMarkerProvider {
return;
}
Module module = ModuleUtilCore.findModuleForPsiElement(elements.get(0));
Module module = ModuleUtilCore.findModuleForPsiElement(firstElement);
if (module != null && !ProjectStructureUtil.isUsedInKotlinJavaModule(module)) {
return;
}
BindingContext bindingContext = ResolvePackage.getLazyResolveSession(project, TargetPlatform.JVM).getBindingContext();
JavaDescriptorResolver javaDescriptorResolver = JavaResolveExtension.INSTANCE$.get(project);
for (PsiElement element : elements) {
if (!(element instanceof PsiMember)) {
if (!(element instanceof PsiMember) || element instanceof PsiClass) {
continue;
}
@@ -103,8 +99,18 @@ public class KotlinSignatureInJavaMarkerProvider implements LineMarkerProvider {
if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
continue;
}
PsiClass containingClass = member.getContainingClass();
if (containingClass != null && PsiUtil.isLocalOrAnonymousClass(containingClass)) {
continue;
}
PsiModifierListOwner annotationOwner = KotlinSignatureUtil.getAnnotationOwner(element);
JavaResolveExtension resolveExtension = JavaResolveExtension.INSTANCE$;
BindingContext bindingContext = resolveExtension.getContext(project, annotationOwner);
JavaDescriptorResolver javaDescriptorResolver = resolveExtension.getResolver(project, annotationOwner);
DeclarationDescriptor memberDescriptor = getDescriptorForMember(javaDescriptorResolver, annotationOwner);
if (memberDescriptor == null) continue;

View File

@@ -141,7 +141,7 @@ public fun PsiElement.isInJavaSourceRoot(): Boolean =
!JavaProjectRootsUtil.isOutsideJavaSourceRoot(getContainingFile())
public inline fun JetFile.createTempCopy(textTransform: (String) -> String): JetFile {
val tmpFile = JetPsiFactory(this).createFile(getName(), textTransform(getText() ?: ""))
val tmpFile = JetPsiFactory(this).createAnalyzableFile(getName(), textTransform(getText() ?: ""), this)
tmpFile.setOriginalFile(this)
tmpFile.skipVisibilityCheck = skipVisibilityCheck
return tmpFile

View File

@@ -25,20 +25,20 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.NotNullFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.analyzer.AnalyzerFacade;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetNamedFunction;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.plugin.MainFunctionDetector;
import org.jetbrains.jet.plugin.ProjectRootsUtil;
import org.jetbrains.jet.plugin.project.AnalyzerFacadeProvider;
import org.jetbrains.jet.plugin.caches.resolve.ResolvePackage;
import org.jetbrains.jet.plugin.project.ProjectStructureUtil;
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies;
import java.util.Collections;
import java.util.List;
public class JetRunConfigurationProducer extends RuntimeConfigurationProducer implements Cloneable {
@@ -83,11 +83,15 @@ public class JetRunConfigurationProducer extends RuntimeConfigurationProducer im
PsiFile psiFile = location.getPsiElement().getContainingFile();
if (psiFile instanceof JetFile) {
JetFile jetFile = (JetFile) psiFile;
AnalyzerFacade facade = AnalyzerFacadeProvider.getAnalyzerFacadeForFile(jetFile);
ResolveSession resolveSession =
facade.createSetup(jetFile.getProject(), Collections.<JetFile>emptyList(), GlobalSearchScope.fileScope(jetFile))
.getLazyResolveSession();
MainFunctionDetector mainFunctionDetector = new MainFunctionDetector(resolveSession);
final ResolveSessionForBodies session = ResolvePackage.getLazyResolveSession(jetFile);
MainFunctionDetector mainFunctionDetector = new MainFunctionDetector(
new NotNullFunction<JetNamedFunction, FunctionDescriptor>() {
@NotNull
@Override
public FunctionDescriptor fun(JetNamedFunction function) {
return (FunctionDescriptor) session.resolveToDescriptor(function);
}
});
if (mainFunctionDetector.hasMain(jetFile.getDeclarations())) {
return jetFile;
}

View File

@@ -1,8 +1,8 @@
package dependency
fun <T, R> T.get(thisRef: R, desc: PropertyMetadata): Int {
public fun <T, R> T.get(thisRef: R, desc: PropertyMetadata): Int {
return 3
}
fun <T, R> T.set(thisRef: R, desc: PropertyMetadata, value: Int) {
public fun <T, R> T.set(thisRef: R, desc: PropertyMetadata, value: Int) {
}

View File

@@ -1,11 +1,11 @@
package dependency
class Foo<T> {
public class Foo<T> {
}
class FooIterator<T> {
public class FooIterator<T> {
}
fun <T> Foo<T>.iterator() = FooIterator<T>()
fun <T> FooIterator<T>.hasNext() = false
fun <T> FooIterator<T>.next() = throw IllegalStateException()
public fun <T> Foo<T>.iterator(): FooIterator<T> = FooIterator<T>()
public fun <T> FooIterator<T>.hasNext(): Boolean = false
public fun <T> FooIterator<T>.next(): T = throw IllegalStateException()

View File

@@ -1,5 +1,5 @@
package dependency
fun <T> List<T>.component1() = get(0)
fun <T> List<T>.component2() = get(1)
fun <T> List<T>.component3() = get(2)
public fun <T> List<T>.component1(): T = get(0)
public fun <T> List<T>.component2(): T = get(1)
public fun <T> List<T>.component3(): T = get(2)

View File

@@ -0,0 +1,199 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.caches.resolve
import com.intellij.testFramework.ModuleTestCase
import com.intellij.openapi.module.StdModuleTypes
import com.intellij.openapi.module.Module
import com.intellij.openapi.roots.ModuleRootModificationUtil
import com.intellij.openapi.roots.DependencyScope
import com.intellij.testFramework.UsefulTestCase
import junit.framework.Assert
import com.intellij.openapi.roots.libraries.LibraryTable
import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.command.WriteCommandAction
class IdeaModuleInfoTest : ModuleTestCase() {
fun testSimpleModuleDependency() {
val (a, b) = modules()
b.addDependency(a)
b.source.assertDependenciesEqual(b.source, a.source)
assertDoesntContain(a.source.dependencies(), b.source)
}
fun testCircularDependency() {
val (a, b) = modules()
b.addDependency(a)
a.addDependency(b)
a.source.assertDependenciesEqual(a.source, b.source)
b.source.assertDependenciesEqual(b.source, a.source)
}
fun testExportedDependency() {
val (a, b, c) = modules()
b.addDependency(a, exported = true)
c.addDependency(b)
a.source.assertDependenciesEqual(a.source)
b.source.assertDependenciesEqual(b.source, a.source)
c.source.assertDependenciesEqual(c.source, b.source, a.source)
}
fun testRedundantExportedDependency() {
val (a, b, c) = modules()
b.addDependency(a, exported = true)
c.addDependency(a)
c.addDependency(b)
a.source.assertDependenciesEqual(a.source)
b.source.assertDependenciesEqual(b.source, a.source)
c.source.assertDependenciesEqual(c.source, a.source, b.source)
}
fun testCircularExportedDependency() {
val (a, b, c) = modules()
b.addDependency(a, exported = true)
c.addDependency(b, exported = true)
a.addDependency(c, exported = true)
a.source.assertDependenciesEqual(a.source, c.source, b.source)
b.source.assertDependenciesEqual(b.source, a.source, c.source)
c.source.assertDependenciesEqual(c.source, b.source, a.source)
}
fun testSimpleLibDependency() {
val a = module("a")
val lib = projectLibrary()
a.addDependency(lib)
a.source.assertDependenciesEqual(a.source, lib.classes)
}
fun testCircularExportedDependencyWithLib() {
val (a, b, c) = modules()
val lib = projectLibrary()
a.addDependency(lib)
b.addDependency(a, exported = true)
c.addDependency(b, exported = true)
a.addDependency(c, exported = true)
b.addDependency(lib)
c.addDependency(lib)
a.source.assertDependenciesEqual(a.source, lib.classes, c.source, b.source)
b.source.assertDependenciesEqual(b.source, a.source, c.source, lib.classes)
c.source.assertDependenciesEqual(c.source, b.source, a.source, lib.classes)
}
fun testSeveralModulesExportLibs() {
val (a, b, c) = modules()
val lib1 = projectLibrary("lib1")
val lib2 = projectLibrary("lib2")
a.addDependency(lib1, exported = true)
b.addDependency(lib2, exported = true)
c.addDependency(a)
c.addDependency(b)
c.source.assertDependenciesEqual(c.source, a.source, lib1.classes, b.source, lib2.classes)
}
fun testSeveralModulesExportSameLib() {
val (a, b, c) = modules()
val lib = projectLibrary()
a.addDependency(lib, exported = true)
b.addDependency(lib, exported = true)
c.addDependency(a)
c.addDependency(b)
c.source.assertDependenciesEqual(c.source, a.source, lib.classes, b.source)
}
fun testRuntimeDependency() {
val (a, b) = modules()
b.addDependency(a, dependencyScope = DependencyScope.RUNTIME)
b.addDependency(projectLibrary(), dependencyScope = DependencyScope.RUNTIME)
b.source.assertDependenciesEqual(b.source)
}
fun testProvidedDependency() {
val (a, b) = modules()
val lib = projectLibrary()
b.addDependency(a, dependencyScope = DependencyScope.PROVIDED)
b.addDependency(lib, dependencyScope = DependencyScope.PROVIDED)
b.source.assertDependenciesEqual(b.source, a.source, lib.classes)
}
//NOTE: wrapper classes to reduce boilerplate in test cases
private class ModuleDef(val ideaModule: Module) {
val source = ideaModule.toSourceInfo()
}
private inner class LibraryDef(val ideaLibrary: Library) {
val classes = LibraryInfo(getProject()!!, ideaLibrary)
}
private fun ModuleDef.addDependency(
other: ModuleDef,
dependencyScope: DependencyScope = DependencyScope.COMPILE,
exported: Boolean = false
) = ModuleRootModificationUtil.addDependency(this.ideaModule, other.ideaModule, dependencyScope, exported)
private fun ModuleDef.addDependency(
lib: LibraryDef,
dependencyScope: DependencyScope = DependencyScope.COMPILE,
exported: Boolean = false
) = ModuleRootModificationUtil.addDependency(this.ideaModule, lib.ideaLibrary, dependencyScope, exported)
private fun module(name: String): ModuleDef {
val ideaModule = createModuleFromTestData(createTempDirectory()!!.getAbsolutePath(), name, StdModuleTypes.JAVA, false)!!
return ModuleDef(ideaModule)
}
private fun modules(name1: String = "a", name2: String = "b", name3: String = "c") = Triple(module(name1), module(name2), module(name3))
private fun IdeaModuleInfo.assertDependenciesEqual(vararg dependencies: IdeaModuleInfo) {
Assert.assertEquals(dependencies.toList(), this.dependencies())
}
private fun projectLibrary(name: String = "lib"): LibraryDef {
val libraryTable = ProjectLibraryTable.getInstance(myProject)!!
val library = WriteCommandAction.runWriteCommandAction<Library>(myProject) {
libraryTable.createLibrary(name)
}!!
return LibraryDef(library)
}
}

View File

@@ -25,15 +25,13 @@ import org.jetbrains.jet.lang.resolve.java.PackageClassUtils
import com.intellij.openapi.project.Project
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import java.util.Collections
import org.jetbrains.jet.plugin.caches.resolve.JavaResolveExtension
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
import org.jetbrains.jet.lang.resolve.DescriptorUtils
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.lang.resolve.resolveTopLevelClass
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor
import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheService
import org.jetbrains.jet.plugin.project.TargetPlatform
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM
import org.jetbrains.jet.lang.resolve.BindingTraceContext
public class DecompiledTextConsistencyTest : JetLightCodeInsightFixtureTestCase() {
@@ -58,8 +56,16 @@ public class DecompiledTextConsistencyTest : JetLightCodeInsightFixtureTestCase(
}
class ProjectBasedResolverForDecompiler(project: Project) : ResolverForDecompiler {
val module = KotlinCacheService.getInstance(project).getGlobalLazyResolveSession(TargetPlatform.JVM).getModuleDescriptor()
val module: ModuleDescriptor = run {
val module = AnalyzerFacadeForJVM.createJavaModule("<module for resolving stdlib with java top down analysis>")
module.addDependencyOnModule(module)
module.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule())
module.seal()
AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
project, listOf(), BindingTraceContext(), { false },
module, null, null
).getModuleDescriptor()
}
override fun resolveTopLevelClass(classFqName: FqName): ClassDescriptor? {
return module.resolveTopLevelClass(classFqName)
}

View File

@@ -25,10 +25,13 @@ import org.jetbrains.jet.lang.psi.JetUnaryExpression
import org.jetbrains.jet.lang.psi.JetProperty
import com.intellij.psi.PsiFile
import org.jetbrains.jet.lang.resolve.BindingContext
import com.intellij.psi.PsiElement
class AfterConversionPass(val project: Project, val postProcessor: PostProcessor) {
public fun run(kotlinCode: String): String {
val kotlinFile = JetPsiFactory(project).createFile(kotlinCode)
val kotlinFile = JetPsiFactory(project).createAnalyzableFile(
"fileForAfterConversionPass.kt", kotlinCode, postProcessor.contextToAnalyzeIn
)
val bindingContext = postProcessor.analyzeFile(kotlinFile)
val fixes = bindingContext.getDiagnostics().map {

View File

@@ -37,6 +37,7 @@ public class FilesConversionScope(val files: Collection<PsiJavaFile>) : Conversi
}
public trait PostProcessor {
public val contextToAnalyzeIn: PsiElement
public fun analyzeFile(file: JetFile): BindingContext
public fun doAdditionalProcessing(file: JetFile)
}

View File

@@ -36,10 +36,6 @@ public object JavaToKotlinTranslator {
return PsiFileFactory.getInstance(javaCoreEnvironment?.getProject()!!)?.createFileFromText("test.java", JavaLanguage.INSTANCE, text)
}
fun createFile(project: Project, text: String): PsiJavaFile {
return PsiFileFactory.getInstance(project)?.createFileFromText("test.java", JavaLanguage.INSTANCE, text) as PsiJavaFile
}
fun setUpJavaCoreEnvironment(): JavaCoreProjectEnvironment {
val applicationEnvironment = JavaCoreApplicationEnvironment(DISPOSABLE)
val javaCoreEnvironment = JavaCoreProjectEnvironment(DISPOSABLE, applicationEnvironment)

View File

@@ -34,6 +34,8 @@ import org.jetbrains.jet.plugin.j2k.J2kPostProcessor
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import com.intellij.testFramework.LightProjectDescriptor
import org.jetbrains.jet.plugin.JetWithJdkAndRuntimeLightProjectDescriptor
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiFile
public abstract class AbstractJavaToKotlinConverterTest() : LightCodeInsightFixtureTestCase() {
val testHeaderPattern = Pattern.compile("//(element|expression|statement|method|class|file|comp)\n")
@@ -122,15 +124,15 @@ public abstract class AbstractJavaToKotlinConverterTest() : LightCodeInsightFixt
}
private fun elementToKotlin(text: String, settings: ConverterSettings, project: Project): String {
val fileWithText = JavaToKotlinTranslator.createFile(project, text)
val converter = Converter.create(project, settings, FilesConversionScope(listOf(fileWithText)), J2kPostProcessor)
val fileWithText = createJavaFile(text)
val converter = Converter.create(project, settings, FilesConversionScope(listOf(fileWithText)), J2kPostProcessor(fileWithText))
val element = fileWithText.getFirstChild()!!
return converter.elementToKotlin(element)
}
private fun fileToKotlin(text: String, settings: ConverterSettings, project: Project): String {
val file = JavaToKotlinTranslator.createFile(project, text)
val converter = Converter.create(project, settings, FilesConversionScope(listOf(file)), J2kPostProcessor)
val file = createJavaFile(text)
val converter = Converter.create(project, settings, FilesConversionScope(listOf(file)), J2kPostProcessor(file))
return converter.elementToKotlin(file)
}
@@ -161,4 +163,8 @@ public abstract class AbstractJavaToKotlinConverterTest() : LightCodeInsightFixt
val lastNewLine = lastIndexOf('\n')
return if (lastNewLine == -1) "" else substring(0, lastNewLine)
}
}
private fun createJavaFile(text: String): PsiJavaFile {
return myFixture.configureByText("converterTestFile.java", text) as PsiJavaFile
}
}

View File

@@ -21,22 +21,17 @@ import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.context.ContextPackage;
import org.jetbrains.jet.context.GlobalContextImpl;
import org.jetbrains.jet.di.InjectorForLazyResolve;
import org.jetbrains.jet.di.InjectorForTopDownAnalyzerForJs;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactory;
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactoryService;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.k2js.config.Config;
@@ -122,36 +117,6 @@ public final class AnalyzerFacadeForJS {
};
}
@NotNull
public static ResolveSession getLazyResolveSession(
@NotNull Collection<JetFile> syntheticFiles,
@NotNull GlobalSearchScope filesScope,
@NotNull Config config
) {
GlobalContextImpl globalContext = ContextPackage.GlobalContext();
DeclarationProviderFactory declarationProviderFactory = DeclarationProviderFactoryService.OBJECT$
.createDeclarationProviderFactory(
config.getProject(),
globalContext.getStorageManager(),
//TODO: lib files are not really synthetic
Config.withJsLibAdded(syntheticFiles, config),
filesScope
);
ModuleDescriptorImpl module = createJsModule("<lazy module>");
module.addDependencyOnModule(module);
module.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule());
module.seal();
ResolveSession session = new InjectorForLazyResolve(
config.getProject(),
globalContext,
module,
declarationProviderFactory,
new BindingTraceContext()).getResolveSession();
module.initialize(session.getPackageFragmentProvider());
return session;
}
@NotNull
private static ModuleDescriptorImpl createJsModule(@NotNull String name) {
return new ModuleDescriptorImpl(Name.special(name), DEFAULT_IMPORTS, PlatformToKotlinClassMap.EMPTY);