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 d4ee2f1d44e..bf4df05114e 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 @@ -22,6 +22,7 @@ import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PsiSearchScopeUtil; import com.intellij.util.Function; @@ -31,6 +32,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import org.jetbrains.jet.asJava.KotlinLightClassForExplicitDeclaration; +import org.jetbrains.jet.asJava.KotlinLightClassForPackage; import org.jetbrains.jet.asJava.LightClassConstructionContext; import org.jetbrains.jet.asJava.LightClassGenerationSupport; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; @@ -40,12 +42,14 @@ import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.java.JvmAbi; +import org.jetbrains.jet.lang.resolve.kotlin.PackagePartClassUtils; import org.jetbrains.jet.lang.resolve.lazy.KotlinCodeAnalyzer; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.scopes.DescriptorKindFilter; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.util.slicedmap.ReadOnlySlice; import org.jetbrains.jet.util.slicedmap.WritableSlice; +import org.jetbrains.jet.utils.UtilsPackage; import java.util.Collection; import java.util.Collections; @@ -68,10 +72,12 @@ public class CliLightClassGenerationSupport extends LightClassGenerationSupport return ServiceManager.getService(project, CliLightClassGenerationSupport.class); } + private final PsiManager psiManager; private BindingContext bindingContext = null; private ModuleDescriptor module = null; - public CliLightClassGenerationSupport() { + public CliLightClassGenerationSupport(@NotNull Project project) { + this.psiManager = PsiManager.getInstance(project); } @Override @@ -179,14 +185,6 @@ 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; @@ -213,7 +211,17 @@ public class CliLightClassGenerationSupport extends LightClassGenerationSupport @Nullable @Override public PsiClass getPsiClass(@NotNull JetClassOrObject classOrObject) { - return KotlinLightClassForExplicitDeclaration.create(classOrObject.getManager(), classOrObject); + return KotlinLightClassForExplicitDeclaration.create(psiManager, classOrObject); + } + + @NotNull + @Override + public Collection getPackageClasses(@NotNull FqName packageFqName, @NotNull GlobalSearchScope scope) { + Collection filesInPackage = findFilesForPackage(packageFqName, scope); + + if (PackagePartClassUtils.getPackageFilesWithCallables(filesInPackage).isEmpty()) return Collections.emptyList(); + + return UtilsPackage.emptyOrSingletonList(KotlinLightClassForPackage.create(psiManager, packageFqName, scope, filesInPackage)); } @NotNull @@ -267,7 +275,7 @@ public class CliLightClassGenerationSupport extends LightClassGenerationSupport } } } - + return super.get(slice, key); } diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java index 3fa4e5979b4..08c0b582903 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java @@ -256,7 +256,7 @@ public class JetCoreEnvironment { private static void registerProjectServicesForCLI(@NotNull JavaCoreProjectEnvironment projectEnvironment) { MockProject project = projectEnvironment.getProject(); project.registerService(CoreJavaFileManager.class, (CoreJavaFileManager) ServiceManager.getService(project, JavaFileManager.class)); - CliLightClassGenerationSupport cliLightClassGenerationSupport = new CliLightClassGenerationSupport(); + CliLightClassGenerationSupport cliLightClassGenerationSupport = new CliLightClassGenerationSupport(project); project.registerService(LightClassGenerationSupport.class, cliLightClassGenerationSupport); project.registerService(CliLightClassGenerationSupport.class, cliLightClassGenerationSupport); project.registerService(CodeAnalyzerInitializer.class, cliLightClassGenerationSupport); 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 1e3412851c3..735ff5584f6 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 @@ -36,10 +36,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; 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; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.NamePackage; @@ -121,7 +119,7 @@ public class JavaElementFinder extends PsiElementFinder implements JavaPsiFacade findClassesAndObjects(qualifiedName, scope, answer); if (PackageClassUtils.isPackageClassFqName(qualifiedName)) { - findPackageClass(qualifiedName.parent(), scope, answer); + answer.addAll(lightClassGenerationSupport.getPackageClasses(qualifiedName.parent(), scope)); } return answer.toArray(new PsiClass[answer.size()]); @@ -142,26 +140,6 @@ public class JavaElementFinder extends PsiElementFinder implements JavaPsiFacade } } - private void findPackageClass(FqName qualifiedName, GlobalSearchScope scope, List answer) { - 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; - - answer.add(lightClass); - - if (files.size() > 1) { - for (JetFile file : files) { - answer.add(new FakeLightClassForFileOfPackage(psiManager, lightClass, file)); - } - } - } - } - @NotNull @Override public Set getClassNames(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) { @@ -222,7 +200,7 @@ public class JavaElementFinder extends PsiElementFinder implements JavaPsiFacade List answer = new SmartList(); FqName packageFQN = new FqName(psiPackage.getQualifiedName()); - findPackageClass(packageFQN, scope, answer); + answer.addAll(lightClassGenerationSupport.getPackageClasses(packageFQN, scope)); Collection declarations = lightClassGenerationSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope); for (JetClassOrObject declaration : declarations) { 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 a9013fd8a9c..7f8afdea152 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,7 +27,6 @@ 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 { @@ -55,12 +54,6 @@ 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( @@ -76,23 +69,6 @@ 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; - } - } + @NotNull + public abstract Collection getPackageClasses(@NotNull FqName packageFqName, @NotNull GlobalSearchScope scope); } 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 8c03fd3c739..91d7da07549 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 @@ -21,20 +21,20 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.libraries.LibraryUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiManager; 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.asJava.KotlinLightClassForExplicitDeclaration; -import org.jetbrains.jet.asJava.LightClassConstructionContext; -import org.jetbrains.jet.asJava.LightClassGenerationSupport; +import org.jetbrains.jet.asJava.*; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.kotlin.PackagePartClassUtils; import org.jetbrains.jet.lang.resolve.lazy.BodyResolveMode; import org.jetbrains.jet.lang.resolve.lazy.ForceResolveUtil; import org.jetbrains.jet.lang.resolve.lazy.KotlinCodeAnalyzer; @@ -57,10 +57,12 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport private final Project project; private final Comparator jetFileComparator; + private final PsiManager psiManager; public IDELightClassGenerationSupport(@NotNull Project project) { this.project = project; this.jetFileComparator = byScopeComparator(GlobalSearchScope.allScope(project)); + this.psiManager = PsiManager.getInstance(project); } @@ -156,21 +158,6 @@ 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( @@ -184,19 +171,6 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport }); } - 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( @@ -224,7 +198,43 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport return JetSourceNavigationHelper.getOriginalClass(classOrObject); } - return KotlinLightClassForExplicitDeclaration.create(classOrObject.getManager(), classOrObject); + return KotlinLightClassForExplicitDeclaration.create(psiManager, classOrObject); + } + + @NotNull + @Override + public Collection getPackageClasses(@NotNull FqName packageFqName, @NotNull GlobalSearchScope scope) { + List result = new ArrayList(); + List packageClassesInfos = findPackageClassesInfos(packageFqName, scope); + for (KotlinLightPackageClassInfo info : packageClassesInfos) { + Collection files = info.getFiles(); + if (PackagePartClassUtils.getPackageFilesWithCallables(files).isEmpty()) continue; + KotlinLightClassForPackage lightClass = KotlinLightClassForPackage.create(psiManager, packageFqName, info.getScope(), files); + if (lightClass == null) continue; + + result.add(lightClass); + + if (files.size() > 1) { + for (JetFile file : files) { + result.add(new FakeLightClassForFileOfPackage(psiManager, lightClass, file)); + } + } + } + return result; + } + + @NotNull + private 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 @@ -241,4 +251,37 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport } }; } + + 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); + } + }); + } + + private static 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; + } + } }