diff --git a/annotations/com/intellij/openapi/module/annotations.xml b/annotations/com/intellij/openapi/module/annotations.xml new file mode 100644 index 00000000000..e4dd6a19d2c --- /dev/null +++ b/annotations/com/intellij/openapi/module/annotations.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/annotations/com/intellij/openapi/roots/annotations.xml b/annotations/com/intellij/openapi/roots/annotations.xml index d3fe22643d8..dc5350f7d09 100644 --- a/annotations/com/intellij/openapi/roots/annotations.xml +++ b/annotations/com/intellij/openapi/roots/annotations.xml @@ -3,4 +3,24 @@ name='com.intellij.openapi.roots.FileIndexFacade com.intellij.openapi.roots.FileIndexFacade getInstance(com.intellij.openapi.project.Project)'> + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/compiler/builtins-serializer/builtins-serializer.iml b/compiler/builtins-serializer/builtins-serializer.iml index 27ea1473eca..b52a03ab852 100644 --- a/compiler/builtins-serializer/builtins-serializer.iml +++ b/compiler/builtins-serializer/builtins-serializer.iml @@ -9,7 +9,6 @@ - diff --git a/compiler/builtins-serializer/src/BuiltInsSerializer.kt b/compiler/builtins-serializer/src/BuiltInsSerializer.kt index 83995818e02..44a5ac77ca7 100644 --- a/compiler/builtins-serializer/src/BuiltInsSerializer.kt +++ b/compiler/builtins-serializer/src/BuiltInsSerializer.kt @@ -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("") + override fun dependencies() = listOf(this) + override fun dependencyOnBuiltins(): ModuleInfo.DependencyOnBuiltins = ModuleInfo.DependenciesOnBuiltins.NONE + } + fun serialize(disposable: Disposable, destDir: File, srcDirs: Collection) { 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") diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CliLightClassGenerationSupport.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CliLightClassGenerationSupport.java index 24a748dfdf3..41e018ee306 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CliLightClassGenerationSupport.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CliLightClassGenerationSupport.java @@ -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 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; diff --git a/compiler/frontend.java/frontend.java.iml b/compiler/frontend.java/frontend.java.iml index b9d735dcb86..d4fba2ed50c 100644 --- a/compiler/frontend.java/frontend.java.iml +++ b/compiler/frontend.java/frontend.java.iml @@ -12,7 +12,7 @@ - + diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java index 4b786de2482..c97741375da 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java @@ -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); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java index 9210af7f15b..082b784bc1f 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java @@ -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(""); + 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; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java index 5283f31accf..ac82017307e 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java @@ -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); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java index d1efea22982..fe9a73f33c4 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java @@ -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 syntheticFiles, - @NotNull GlobalSearchScope filesScope - ) { - return createSetup(fileProject, syntheticFiles, filesScope, new BindingTraceContext(), true); - } - - @NotNull - public static ResolveSession createLazyResolveSession( - @NotNull Project project, - @NotNull Collection files, - @NotNull BindingTrace trace, - boolean addBuiltIns - ) { - List virtualFiles = KotlinPackage.map(files, new Function1() { - @Override - public VirtualFile invoke(JetFile file) { - return file.getVirtualFile(); - } - }); - return createSetup(project, Collections.emptyList(), - GlobalSearchScope.filesScope(project, virtualFiles), trace, addBuiltIns).getLazyResolveSession(); - } - - public static JvmSetup createSetup( - @NotNull Project project, - @NotNull Collection 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, diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassFinderImpl.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassFinderImpl.java index 102957bb90c..436a1d63ec3 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassFinderImpl.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassFinderImpl.java @@ -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 diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPsiFacadeKotlinHacks.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPsiFacadeKotlinHacks.java index b875a2a1db5..62d81062ad9 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPsiFacadeKotlinHacks.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPsiFacadeKotlinHacks.java @@ -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 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) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmAnalyzerFacade.kt b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmAnalyzerFacade.kt new file mode 100644 index 00000000000..f918aa89018 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmAnalyzerFacade.kt @@ -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 { + override fun createResolverForModule( + project: Project, + globalContext: GlobalContext, + moduleDescriptor: ModuleDescriptorImpl, + moduleContent: ModuleContent, + platformParameters: JvmPlatformParameters, + resolverForProject: ResolverForProject + ): 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() + +} \ No newline at end of file diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileFinderFactory.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileFinderFactory.java index 2de244d980c..45d8912127a 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileFinderFactory.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileFinderFactory.java @@ -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); + } + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/analyzer/AnalyzerFacade.java b/compiler/frontend/src/org/jetbrains/jet/analyzer/AnalyzerFacade.java deleted file mode 100644 index 1b02eb27ae1..00000000000 --- a/compiler/frontend/src/org/jetbrains/jet/analyzer/AnalyzerFacade.java +++ /dev/null @@ -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 syntheticFiles, - @NotNull GlobalSearchScope filesScope - ); -} diff --git a/compiler/frontend/src/org/jetbrains/jet/analyzer/AnalyzerFacade.kt b/compiler/frontend/src/org/jetbrains/jet/analyzer/AnalyzerFacade.kt new file mode 100644 index 00000000000..b2c5b933dfd --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/analyzer/AnalyzerFacade.kt @@ -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 { + public fun resolverForModule(moduleInfo: M): R + public fun descriptorForModule(moduleInfo: M): ModuleDescriptor +} + +public class ResolverForProjectImpl( + val descriptorByModule: Map +) : ResolverForProject { + val resolverByModuleDescriptor: MutableMap = HashMap() + + private val allModules: Collection 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, + public val moduleContentScope: GlobalSearchScope +) + +public trait PlatformAnalysisParameters + +public trait ModuleInfo { + public val name: Name + public fun dependencies(): List + 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) + } + + public enum class DependenciesOnBuiltins : DependencyOnBuiltins { + + override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList) { + //TODO: KT-5457 + } + + NONE { + override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList) { + //do nothing + } + } + LAST { + override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList) { + dependencies.add(builtinsModule) + } + } + } +} + +//TODO: (module refactoring) extract project context +public trait AnalyzerFacade { + public fun setupResolverForProject( + globalContext: GlobalContext, + project: Project, + modules: Collection, + modulesContent: (M) -> ModuleContent, + platformParameters: P + ): ResolverForProject { + + fun createResolverForProject(): ResolverForProjectImpl { + val descriptorByModule = HashMap() + 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()) { + 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 createResolverForModule( + project: Project, + globalContext: GlobalContext, + moduleDescriptor: ModuleDescriptorImpl, + moduleContent: ModuleContent, + platformParameters: P, + resolverForProject: ResolverForProject + ): A + + public val defaultImports: List + public val platformToKotlinClassMap: PlatformToKotlinClassMap +} + diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java index 01d442d9259..1b6150e373f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java @@ -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); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.kt b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.kt index 01e6a84197f..1b5823fc4dd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.kt @@ -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 } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/userDataUtil.kt b/compiler/frontend/src/org/jetbrains/jet/lang/psi/userDataUtil.kt new file mode 100644 index 00000000000..62f58fd0bfb --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/userDataUtil.kt @@ -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(val key: Key) : ReadWriteProperty { + 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) + } +} \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java index 50f4c7f6dd5..824b3ba99c8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java @@ -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); diff --git a/compiler/frontend/src/org/jetbrains/jet/plugin/MainFunctionDetector.java b/compiler/frontend/src/org/jetbrains/jet/plugin/MainFunctionDetector.java index 33fb189f141..15c73ec15ea 100644 --- a/compiler/frontend/src/org/jetbrains/jet/plugin/MainFunctionDetector.java +++ b/compiler/frontend/src/org/jetbrains/jet/plugin/MainFunctionDetector.java @@ -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() { - @NotNull - @Override - public FunctionDescriptor fun(JetNamedFunction function) { - return (FunctionDescriptor) resolveSession.resolveToDescriptor(function); - } - }; + public MainFunctionDetector(@NotNull NotNullFunction functionResolver) { + this.getFunctionDescriptor = functionResolver; } public boolean hasMain(@NotNull List declarations) { diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/FakeLightClassForFileOfPackage.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/FakeLightClassForFileOfPackage.java index 8b3317ed6b7..4fc28096706 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/FakeLightClassForFileOfPackage.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/FakeLightClassForFileOfPackage.java @@ -36,7 +36,7 @@ import org.jetbrains.jet.lang.resolve.name.FqName; *

* 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; diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java index aee4ad28a92..1e3412851c3 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java @@ -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 answer) { - Collection filesForPackage = lightClassGenerationSupport.findFilesForPackage(qualifiedName, scope); - if (PackagePartClassUtils.getPackageFilesWithCallables(filesForPackage).isEmpty()) return; + List + packageClassesInfos = lightClassGenerationSupport.findPackageClassesInfos(qualifiedName, scope); + for (LightClassGenerationSupport.KotlinLightPackageClassInfo info : packageClassesInfos) { + Collection 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)); + } } } } diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForPackage.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForPackage.java index 3e26e49537e..4cb39425e4d 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForPackage.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForPackage.java @@ -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 getFiles() { + return files; + } } diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassGenerationSupport.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassGenerationSupport.java index c6ac2a1a231..a9013fd8a9c 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassGenerationSupport.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassGenerationSupport.java @@ -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 findFilesForPackage(@NotNull FqName fqName, @NotNull GlobalSearchScope searchScope); + @NotNull + public abstract List 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 findClassOrObjectDeclarationsInPackage( @@ -68,4 +75,24 @@ public abstract class LightClassGenerationSupport { @Nullable public abstract PsiClass getPsiClass(@NotNull JetClassOrObject classOrObject); + + public final class KotlinLightPackageClassInfo { + private final Collection files; + private final GlobalSearchScope scope; + + public KotlinLightPackageClassInfo(@NotNull Collection files, @NotNull GlobalSearchScope scope) { + this.files = files; + this.scope = scope; + } + + @NotNull + public Collection getFiles() { + return files; + } + + @NotNull + public GlobalSearchScope getScope() { + return scope; + } + } } diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/duplicateJvmSignatureUtil.kt b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/duplicateJvmSignatureUtil.kt index de69b023b3b..1e495fb89fb 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/duplicateJvmSignatureUtil.kt +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/duplicateJvmSignatureUtil.kt @@ -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 -} diff --git a/compiler/testData/multiModule/java/custom/a/a.kt b/compiler/testData/multiModule/java/custom/a/a.kt new file mode 100644 index 00000000000..983c11871c6 --- /dev/null +++ b/compiler/testData/multiModule/java/custom/a/a.kt @@ -0,0 +1,11 @@ +package test + +import custom.* + +public class KotlinA: AClass() { + fun returnA(): AClass {} + + fun paramA(p: AClass) {} + + AAnnotation fun annoA() {} +} \ No newline at end of file diff --git a/compiler/testData/multiModule/java/custom/a/custom/AAnnotation.java b/compiler/testData/multiModule/java/custom/a/custom/AAnnotation.java new file mode 100644 index 00000000000..df5c3e6744f --- /dev/null +++ b/compiler/testData/multiModule/java/custom/a/custom/AAnnotation.java @@ -0,0 +1,5 @@ +package custom; + +public @interface AAnnotation { + +} \ No newline at end of file diff --git a/compiler/testData/multiModule/java/custom/a/custom/AClass.java b/compiler/testData/multiModule/java/custom/a/custom/AClass.java new file mode 100644 index 00000000000..3eb480aa2ef --- /dev/null +++ b/compiler/testData/multiModule/java/custom/a/custom/AClass.java @@ -0,0 +1,8 @@ +package custom; + +public class AClass { + public AClass returnA() {} + public void paramA(AClass a) {} + @AAnnotation + public void annoA() {} +} \ No newline at end of file diff --git a/compiler/testData/multiModule/java/custom/b/b.kt b/compiler/testData/multiModule/java/custom/b/b.kt new file mode 100644 index 00000000000..00c669389ef --- /dev/null +++ b/compiler/testData/multiModule/java/custom/b/b.kt @@ -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() {} +} \ No newline at end of file diff --git a/compiler/testData/multiModule/java/custom/b/custom/BAnnotation.java b/compiler/testData/multiModule/java/custom/b/custom/BAnnotation.java new file mode 100644 index 00000000000..fe57f9d0c4c --- /dev/null +++ b/compiler/testData/multiModule/java/custom/b/custom/BAnnotation.java @@ -0,0 +1,5 @@ +package custom; + +public @interface BAnnotation { + +} \ No newline at end of file diff --git a/compiler/testData/multiModule/java/custom/b/custom/BClass.java b/compiler/testData/multiModule/java/custom/b/custom/BClass.java new file mode 100644 index 00000000000..91d26a05ae3 --- /dev/null +++ b/compiler/testData/multiModule/java/custom/b/custom/BClass.java @@ -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() {} +} \ No newline at end of file diff --git a/compiler/testData/multiModule/java/custom/c/c.kt b/compiler/testData/multiModule/java/custom/c/c.kt new file mode 100644 index 00000000000..0e2260e75a0 --- /dev/null +++ b/compiler/testData/multiModule/java/custom/c/c.kt @@ -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() {} +} \ No newline at end of file diff --git a/compiler/testData/multiModule/java/custom/c/custom/CClass.java b/compiler/testData/multiModule/java/custom/c/custom/CClass.java new file mode 100644 index 00000000000..3a052557996 --- /dev/null +++ b/compiler/testData/multiModule/java/custom/c/custom/CClass.java @@ -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() {} +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/JetTestUtils.java b/compiler/tests/org/jetbrains/jet/JetTestUtils.java index 0fffc64e394..4b973716d5b 100644 --- a/compiler/tests/org/jetbrains/jet/JetTestUtils.java +++ b/compiler/tests/org/jetbrains/jet/JetTestUtils.java @@ -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); diff --git a/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java b/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java index 5d18b63cce4..1636bffc1fa 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java +++ b/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java @@ -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 jvmSignatureDiagnostics = new HashSet(); Collection 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)); } diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/MultiModuleJavaAnalysisCustomTest.kt b/compiler/tests/org/jetbrains/jet/jvm/compiler/MultiModuleJavaAnalysisCustomTest.kt new file mode 100644 index 00000000000..dd489b546ef --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/MultiModuleJavaAnalysisCustomTest.kt @@ -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, val javaFilesScope: GlobalSearchScope, + val _dependencies: TestModule.() -> List) : + 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): JetCoreEnvironment { + val configuration = CompilerConfiguration() + configuration.addAll(JVMConfigurationKeys.CLASSPATH_KEY, moduleDirs.toList()) + return JetCoreEnvironment.createForTests(getTestRootDisposable()!!, configuration) + } + + private fun setupModules(environment: JetCoreEnvironment, moduleDirs: Array): List { + val project = environment.getProject() + val modules = HashMap() + 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, modules: List) { + 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()).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" + } +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveTestUtil.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveTestUtil.java index 76bafde4cd7..83596582f3f 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveTestUtil.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveTestUtil.java @@ -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 files, JetCoreEnvironment environment, boolean addBuiltIns) { + @NotNull + public static KotlinCodeAnalyzer resolveLazilyWithSession( + @NotNull List 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; } diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/lazyResolveTestUtil.kt b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/lazyResolveTestUtil.kt new file mode 100644 index 00000000000..ac6831d5387 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/lazyResolveTestUtil.kt @@ -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, + 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("") + override fun dependencies() = listOf(this) + override fun dependencyOnBuiltins() = + if (dependsOnBuiltins) + ModuleInfo.DependenciesOnBuiltins.LAST + else + ModuleInfo.DependenciesOnBuiltins.NONE +} diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassFinder.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassFinder.java index a41707dab3f..4c3233342dc 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassFinder.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassFinder.java @@ -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); diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/LazyJavaPackageFragmentProvider.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/LazyJavaPackageFragmentProvider.kt index 7a118d723e8..e2d17556712 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/LazyJavaPackageFragmentProvider.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/LazyJavaPackageFragmentProvider.kt @@ -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 } } } \ No newline at end of file diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/ModuleClassResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/ModuleClassResolver.kt new file mode 100644 index 00000000000..082e6f02ec3 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/ModuleClassResolver.kt @@ -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) +} diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/context.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/context.kt index e1fa97d1306..1f7f96655bb 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/context.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/context.kt @@ -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, diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt index 8ec4760e9df..95c590a5cb4 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt @@ -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 diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt index 264ae7ac177..5de6bced1cf 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt @@ -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 diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/resolvers.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/resolvers.kt index e393fa064da..19c1586394c 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/resolvers.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/resolvers.kt @@ -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? } diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/types/LazyJavaTypeResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/types/LazyJavaTypeResolver.kt index b9f46f376cb..2c5e480c74b 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/types/LazyJavaTypeResolver.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/types/LazyJavaTypeResolver.kt @@ -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()) diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/ModuleDescriptorImpl.kt b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/ModuleDescriptorImpl.kt index ba32533c288..97f81e232d5 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/ModuleDescriptorImpl.kt +++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/ModuleDescriptorImpl.kt @@ -62,7 +62,7 @@ public class ModuleDescriptorImpl( }) } - private val isInitialized: Boolean + public val isInitialized: Boolean get() = packageFragmentProviderForModuleContent != null public fun addDependencyOnModule(dependency: ModuleDescriptorImpl) { diff --git a/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.kt b/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.kt index e01cf9da0b1..b5ace516a74 100644 --- a/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.kt +++ b/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.kt @@ -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()) publicField(javaClass()) + field(javaClass (), + init = GivenExpression(javaClass().getName() + ".allScope(project)")) fields( javaClass(), javaClass(), @@ -104,7 +110,8 @@ private fun generatorForTopDownAnalyzerForJvm() = javaClass(), javaClass(), javaClass(), - javaClass() + javaClass(), + javaClass() ) field(javaClass(), init = GivenExpression(javaClass().getName() + ".SERVICE.getInstance(project)")) } @@ -123,6 +130,9 @@ private fun generatorForJavaDescriptorResolver() = publicField(javaClass()) publicField(javaClass()) + field(javaClass (), + init = GivenExpression(javaClass().getName() + ".allScope(project)")) + fields( javaClass(), javaClass(), @@ -130,7 +140,8 @@ private fun generatorForJavaDescriptorResolver() = javaClass(), javaClass(), javaClass(), - javaClass() + javaClass(), + javaClass() ) field(javaClass(), init = GivenExpression(javaClass().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()) - parameter(javaClass(), useAsContext = true) + parameter(javaClass(), useAsContext = true) + parameter(javaClass(), name = "module", useAsContext = true) + parameter(javaClass(), name = "moduleContentScope") parameters( + javaClass(), javaClass(), - javaClass() + javaClass() ) - publicField(javaClass(), name = "module", useAsContext = true, - init = GivenExpression("org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM.createJavaModule(\"\")")) publicFields( javaClass(), javaClass() ) field(javaClass(), - init = GivenExpression(javaClass().getName() + ".SERVICE.getInstance(project)")) + init = GivenExpression(javaClass().getName() + + ".SERVICE.getInstance(project).create(moduleContentScope)") + ) fields( javaClass(), javaClass(), @@ -208,7 +222,7 @@ private fun generatorForBodyResolve() = private fun generatorForLazyResolve() = generator("compiler/frontend/src", "org.jetbrains.jet.di", "InjectorForLazyResolve") { parameter(javaClass()) - parameter(javaClass(), useAsContext = true) + parameter(javaClass(), useAsContext = true) parameter(javaClass(), useAsContext = true) parameter(javaClass()) parameter(javaClass()) diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/IDELightClassGenerationSupport.java b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/IDELightClassGenerationSupport.java index 62f9d8e8a28..df2d1522b8f 100644 --- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/IDELightClassGenerationSupport.java +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/IDELightClassGenerationSupport.java @@ -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() { - @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 files) { @@ -169,6 +161,47 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport return PackageIndexUtil.findFilesWithExactPackage(fqName, kotlinSources(searchScope, project), project); } + @NotNull + @Override + public List findPackageClassesInfos( + @NotNull FqName fqName, @NotNull GlobalSearchScope wholeScope + ) { + Collection allFiles = findFilesForPackage(fqName, wholeScope); + Map> filesByInfo = groupByModuleInfo(allFiles); + List result = new ArrayList(); + for (Map.Entry> entry : filesByInfo.entrySet()) { + result.add(new KotlinLightPackageClassInfo(entry.getValue(), entry.getKey().contentScope())); + } + sortByClasspath(wholeScope, result); + return result; + } + + @NotNull + private static Map> groupByModuleInfo(@NotNull Collection allFiles) { + return KotlinPackage.groupByTo( + allFiles, + new LinkedHashMap>(), + new Function1() { + @Override + public IdeaModuleInfo invoke(JetFile file) { + return ResolvePackage.getModuleInfo(file); + } + }); + } + + private static void sortByClasspath(@NotNull GlobalSearchScope wholeScope, @NotNull List result) { + final Comparator byScopeComparator = byScopeComparator(wholeScope); + Collections.sort(result, new Comparator() { + @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 findClassOrObjectDeclarationsInPackage( @@ -211,4 +244,19 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport return result; } + + @NotNull + private static Comparator byScopeComparator(@NotNull final GlobalSearchScope searchScope) { + return new Comparator() { + @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); + } + }; + } } diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/IdeaModuleInfos.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/IdeaModuleInfos.kt new file mode 100644 index 00000000000..2f141c065b8 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/IdeaModuleInfos.kt @@ -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 { + 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("") + + override fun contentScope() = GlobalSearchScope.moduleScope(module) + + override fun dependencies(): List { + //NOTE: lib dependencies can be processed several times during recursive traversal + val result = LinkedHashSet() + 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("") + + override fun contentScope() = LibraryWithoutSourceScope(project, library) + + override fun dependencies(): List { + //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("") + + override fun contentScope() = GlobalSearchScope.EMPTY_SCOPE + + override fun dependencies(): List { + 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("") + + override fun contentScope() = SdkScope(project, sdk) + + override fun dependencies(): List = listOf(this) +} + +private object NotUnderContentRootModuleInfo : IdeaModuleInfo() { + override val name: Name = Name.special("") + + override fun contentScope() = GlobalSearchScope.EMPTY_SCOPE + + //TODO: (module refactoring) dependency on runtime can be of use here + override fun dependencies(): List = listOf(this) +} + +private data class LibraryWithoutSourceScope(project: Project, private val library: Library) : + LibraryScopeBase(project, library.getFiles(OrderRootType.CLASSES), array()) { +} + +//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()) \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/JavaResolveExtension.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/JavaResolveExtension.kt new file mode 100644 index 00000000000..8c0ec430fdb --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/JavaResolveExtension.kt @@ -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> { + override val platform: TargetPlatform = TargetPlatform.JVM + + override fun getData(resolverProvider: ModuleResolverProvider): (PsiElement) -> Pair { + 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 +} \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/JsAnalyzerFacade.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/JsAnalyzerFacade.kt new file mode 100644 index 00000000000..0e68ad38575 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/JsAnalyzerFacade.kt @@ -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 { + + override fun createResolverForModule( + project: Project, + globalContext: GlobalContext, + moduleDescriptor: ModuleDescriptorImpl, + moduleContent: ModuleContent, + platformParameters: PlatformAnalysisParameters, + resolverForProject: ResolverForProject + ): 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 + +} diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinCacheService.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinCacheService.kt index 044f708a0f6..c013720cce9 100644 --- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinCacheService.kt +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinCacheService.kt @@ -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()) @@ -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())!! } - private fun globalResolveSessionProvider(platform: TargetPlatform, syntheticFiles: Collection = 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 = listOf()): + () -> CachedValueProvider.Result = { + 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): AnalyzeExhaust { diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt index 15dd8210d6f..6c69661a246 100644 --- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt @@ -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 { 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 + setupProvider: () -> CachedValueProvider.Result ) { - 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 get(extension: CacheExtension): 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 get(extension: CacheExtension): T { + return extension.getData(resolverCache.getValue()) + } + + private val analysisResults = CachedValuesManager.getManager(project).createCachedValue( + { + val resolverProvider = resolverCache.getValue() val results = object : SLRUCache(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): 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()) } } diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/ModuleDependencyMapper.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/ModuleDependencyMapper.kt new file mode 100644 index 00000000000..b0a5fdb0c34 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/ModuleDependencyMapper.kt @@ -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, + syntheticFiles: Collection +): ModuleResolverProvider { + + val allModuleInfos = collectAllModuleInfosFromIdeaModel(project).toHashSet() + + val globalContext = GlobalContext() + + fun createResolverForProject(): ResolverForProject { + 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 { + 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()).map { + it.getLibrary() + } + }.filterNotNull().toSet() + + val librariesInfos = ideaLibraries.map { LibraryInfo(project, it) } + + val ideaSdks = ideaModules.flatMap { + ModuleRootManager.getInstance(it).getOrderEntries().filterIsInstance(javaClass()).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, + private val bodiesResolveByModule: Map, + 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.") +} \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/getModuleInfo.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/getModuleInfo.kt new file mode 100644 index 00000000000..c1f80ffa2ef --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/getModuleInfo.kt @@ -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() ?: " "}\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()) + @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() +} \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/highlighter/DuplicateJvmSignatureAnnotator.java b/idea/idea-analysis/src/org/jetbrains/jet/plugin/highlighter/DuplicateJvmSignatureAnnotator.java index f16b54ef6b4..69f23eaec97 100644 --- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/highlighter/DuplicateJvmSignatureAnnotator.java +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/highlighter/DuplicateJvmSignatureAnnotator.java @@ -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); diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeProvider.java b/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeProvider.java deleted file mode 100644 index fa61a2a8429..00000000000 --- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeProvider.java +++ /dev/null @@ -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; - } -} diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeProvider.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeProvider.kt new file mode 100644 index 00000000000..fcb0a217239 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeProvider.kt @@ -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 { + return when (targetPlatform) { + TargetPlatform.JVM -> JvmAnalyzerFacade + TargetPlatform.JS -> JsAnalyzerFacade + else -> throw IllegalArgumentException("Unsupported platfrom: $targetPlatform") + } + } +} \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/JSAnalyzerFacadeForIDEA.java b/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/JSAnalyzerFacadeForIDEA.java deleted file mode 100644 index fdb16bc3472..00000000000 --- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/JSAnalyzerFacadeForIDEA.java +++ /dev/null @@ -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 syntheticFiles, @NotNull GlobalSearchScope filesScope) { - return new BasicSetup(AnalyzerFacadeForJS.getLazyResolveSession(syntheticFiles, filesScope, new IDEAConfig(project))); - } -} diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/TargetPlatformDetector.java b/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/TargetPlatformDetector.java index 7418f221fd3..0968fe8c25f 100644 --- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/TargetPlatformDetector.java +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/TargetPlatformDetector.java @@ -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() { } diff --git a/idea/src/org/jetbrains/jet/plugin/actions/JavaToKotlinAction.java b/idea/src/org/jetbrains/jet/plugin/actions/JavaToKotlinAction.java index 97bd22449d1..4938f17bd05 100644 --- a/idea/src/org/jetbrains/jet/plugin/actions/JavaToKotlinAction.java +++ b/idea/src/org/jetbrains/jet/plugin/actions/JavaToKotlinAction.java @@ -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() { diff --git a/idea/src/org/jetbrains/jet/plugin/caches/resolve/JavaResolveExtension.kt b/idea/src/org/jetbrains/jet/plugin/caches/resolve/JavaResolveExtension.kt deleted file mode 100644 index e83debb205a..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/caches/resolve/JavaResolveExtension.kt +++ /dev/null @@ -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 { - 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] -} \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/conversion/copy/ConvertJavaCopyPastePostProcessor.kt b/idea/src/org/jetbrains/jet/plugin/conversion/copy/ConvertJavaCopyPastePostProcessor.kt index 213f7c2a7ad..69b7e600e5f 100644 --- a/idea/src/org/jetbrains/jet/plugin/conversion/copy/ConvertJavaCopyPastePostProcessor.kt +++ b/idea/src/org/jetbrains/jet/plugin/conversion/copy/ConvertJavaCopyPastePostProcessor.kt @@ -70,7 +70,7 @@ public class ConvertJavaCopyPastePostProcessor() : CopyPastePostProcessor 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 diff --git a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java index 32311983f6a..dabd910fc6d 100644 --- a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java +++ b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java @@ -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.emptyList(), GlobalSearchScope.fileScope(jetFile)) - .getLazyResolveSession(); - MainFunctionDetector mainFunctionDetector = new MainFunctionDetector(resolveSession); + final ResolveSessionForBodies session = ResolvePackage.getLazyResolveSession(jetFile); + MainFunctionDetector mainFunctionDetector = new MainFunctionDetector( + new NotNullFunction() { + @NotNull + @Override + public FunctionDescriptor fun(JetNamedFunction function) { + return (FunctionDescriptor) session.resolveToDescriptor(function); + } + }); if (mainFunctionDetector.hasMain(jetFile.getDeclarations())) { return jetFile; } diff --git a/idea/testData/resolve/referenceWithLib/delegatedPropertyWithTypeParametersSrc/delegatedPropertyWithTypeParametersDependency.kt b/idea/testData/resolve/referenceWithLib/delegatedPropertyWithTypeParametersSrc/delegatedPropertyWithTypeParametersDependency.kt index 91649b7f3af..bf014f3d1f3 100644 --- a/idea/testData/resolve/referenceWithLib/delegatedPropertyWithTypeParametersSrc/delegatedPropertyWithTypeParametersDependency.kt +++ b/idea/testData/resolve/referenceWithLib/delegatedPropertyWithTypeParametersSrc/delegatedPropertyWithTypeParametersDependency.kt @@ -1,8 +1,8 @@ package dependency -fun T.get(thisRef: R, desc: PropertyMetadata): Int { +public fun T.get(thisRef: R, desc: PropertyMetadata): Int { return 3 } -fun T.set(thisRef: R, desc: PropertyMetadata, value: Int) { +public fun T.set(thisRef: R, desc: PropertyMetadata, value: Int) { } diff --git a/idea/testData/resolve/referenceWithLib/iteratorWithTypeParameterSrc/iteratorWithTypeParameterDependency.kt b/idea/testData/resolve/referenceWithLib/iteratorWithTypeParameterSrc/iteratorWithTypeParameterDependency.kt index bf33c2d5141..a3546d3792c 100644 --- a/idea/testData/resolve/referenceWithLib/iteratorWithTypeParameterSrc/iteratorWithTypeParameterDependency.kt +++ b/idea/testData/resolve/referenceWithLib/iteratorWithTypeParameterSrc/iteratorWithTypeParameterDependency.kt @@ -1,11 +1,11 @@ package dependency -class Foo { +public class Foo { } -class FooIterator { +public class FooIterator { } -fun Foo.iterator() = FooIterator() -fun FooIterator.hasNext() = false -fun FooIterator.next() = throw IllegalStateException() +public fun Foo.iterator(): FooIterator = FooIterator() +public fun FooIterator.hasNext(): Boolean = false +public fun FooIterator.next(): T = throw IllegalStateException() diff --git a/idea/testData/resolve/referenceWithLib/multiDeclarationWithTypeParametersSrc/multiDeclarationWithTypeParametersDependency.kt b/idea/testData/resolve/referenceWithLib/multiDeclarationWithTypeParametersSrc/multiDeclarationWithTypeParametersDependency.kt index 1b17e46b082..12d93051ebd 100644 --- a/idea/testData/resolve/referenceWithLib/multiDeclarationWithTypeParametersSrc/multiDeclarationWithTypeParametersDependency.kt +++ b/idea/testData/resolve/referenceWithLib/multiDeclarationWithTypeParametersSrc/multiDeclarationWithTypeParametersDependency.kt @@ -1,5 +1,5 @@ package dependency -fun List.component1() = get(0) -fun List.component2() = get(1) -fun List.component3() = get(2) \ No newline at end of file +public fun List.component1(): T = get(0) +public fun List.component2(): T = get(1) +public fun List.component3(): T = get(2) \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/caches/resolve/IdeaModuleInfoTest.kt b/idea/tests/org/jetbrains/jet/plugin/caches/resolve/IdeaModuleInfoTest.kt new file mode 100644 index 00000000000..1099c974e49 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/caches/resolve/IdeaModuleInfoTest.kt @@ -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(myProject) { + libraryTable.createLibrary(name) + }!! + return LibraryDef(library) + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextConsistencyTest.kt b/idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextConsistencyTest.kt index d8253c43387..85c5935cc58 100644 --- a/idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextConsistencyTest.kt +++ b/idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextConsistencyTest.kt @@ -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.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) } diff --git a/j2k/src/org/jetbrains/jet/j2k/AfterConversionPass.kt b/j2k/src/org/jetbrains/jet/j2k/AfterConversionPass.kt index 4cb735cca70..360be705a5d 100644 --- a/j2k/src/org/jetbrains/jet/j2k/AfterConversionPass.kt +++ b/j2k/src/org/jetbrains/jet/j2k/AfterConversionPass.kt @@ -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 { diff --git a/j2k/src/org/jetbrains/jet/j2k/Converter.kt b/j2k/src/org/jetbrains/jet/j2k/Converter.kt index fe8089a233d..c0e6049b7af 100644 --- a/j2k/src/org/jetbrains/jet/j2k/Converter.kt +++ b/j2k/src/org/jetbrains/jet/j2k/Converter.kt @@ -37,6 +37,7 @@ public class FilesConversionScope(val files: Collection) : Conversi } public trait PostProcessor { + public val contextToAnalyzeIn: PsiElement public fun analyzeFile(file: JetFile): BindingContext public fun doAdditionalProcessing(file: JetFile) } diff --git a/j2k/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.kt b/j2k/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.kt index 758e254d95d..32e92aa135d 100644 --- a/j2k/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.kt +++ b/j2k/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.kt @@ -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) diff --git a/j2k/tests/test/org/jetbrains/jet/j2k/test/AbstractJavaToKotlinConverterTest.kt b/j2k/tests/test/org/jetbrains/jet/j2k/test/AbstractJavaToKotlinConverterTest.kt index c65e0a078ae..a8864a8fa60 100644 --- a/j2k/tests/test/org/jetbrains/jet/j2k/test/AbstractJavaToKotlinConverterTest.kt +++ b/j2k/tests/test/org/jetbrains/jet/j2k/test/AbstractJavaToKotlinConverterTest.kt @@ -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) } -} \ No newline at end of file + + private fun createJavaFile(text: String): PsiJavaFile { + return myFixture.configureByText("converterTestFile.java", text) as PsiJavaFile + } +} diff --git a/js/js.frontend/src/org/jetbrains/k2js/analyze/AnalyzerFacadeForJS.java b/js/js.frontend/src/org/jetbrains/k2js/analyze/AnalyzerFacadeForJS.java index 6e9e427b49d..51a1aefcc9c 100644 --- a/js/js.frontend/src/org/jetbrains/k2js/analyze/AnalyzerFacadeForJS.java +++ b/js/js.frontend/src/org/jetbrains/k2js/analyze/AnalyzerFacadeForJS.java @@ -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 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(""); - 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);