Refactor: refine API of LightClassGenerationSupport
Move some specific code to IDELightClassGenerationSupport
This commit is contained in:
+19
-11
@@ -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<KotlinLightPackageClassInfo> findPackageClassesInfos(
|
||||
@NotNull FqName fqName, @NotNull GlobalSearchScope wholeScope
|
||||
) {
|
||||
return Collections.singletonList(new KotlinLightPackageClassInfo(findFilesForPackage(fqName, wholeScope), wholeScope));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean packageExists(@NotNull FqName fqName, @NotNull GlobalSearchScope scope) {
|
||||
return getModule().getPackage(fqName) != null;
|
||||
@@ -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<PsiClass> getPackageClasses(@NotNull FqName packageFqName, @NotNull GlobalSearchScope scope) {
|
||||
Collection<JetFile> filesInPackage = findFilesForPackage(packageFqName, scope);
|
||||
|
||||
if (PackagePartClassUtils.getPackageFilesWithCallables(filesInPackage).isEmpty()) return Collections.emptyList();
|
||||
|
||||
return UtilsPackage.<PsiClass>emptyOrSingletonList(KotlinLightClassForPackage.create(psiManager, packageFqName, scope, filesInPackage));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -267,7 +275,7 @@ public class CliLightClassGenerationSupport extends LightClassGenerationSupport
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return super.get(slice, key);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<PsiClass> answer) {
|
||||
List<LightClassGenerationSupport.KotlinLightPackageClassInfo>
|
||||
packageClassesInfos = lightClassGenerationSupport.findPackageClassesInfos(qualifiedName, scope);
|
||||
for (LightClassGenerationSupport.KotlinLightPackageClassInfo info : packageClassesInfos) {
|
||||
Collection<JetFile> files = info.getFiles();
|
||||
if (PackagePartClassUtils.getPackageFilesWithCallables(files).isEmpty()) continue;
|
||||
KotlinLightClassForPackage lightClass =
|
||||
KotlinLightClassForPackage.create(psiManager, qualifiedName, info.getScope(), files);
|
||||
if (lightClass == null) continue;
|
||||
|
||||
answer.add(lightClass);
|
||||
|
||||
if (files.size() > 1) {
|
||||
for (JetFile file : files) {
|
||||
answer.add(new FakeLightClassForFileOfPackage(psiManager, lightClass, file));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<String> getClassNames(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
@@ -222,7 +200,7 @@ public class JavaElementFinder extends PsiElementFinder implements JavaPsiFacade
|
||||
List<PsiClass> answer = new SmartList<PsiClass>();
|
||||
FqName packageFQN = new FqName(psiPackage.getQualifiedName());
|
||||
|
||||
findPackageClass(packageFQN, scope, answer);
|
||||
answer.addAll(lightClassGenerationSupport.getPackageClasses(packageFQN, scope));
|
||||
|
||||
Collection<JetClassOrObject> declarations = lightClassGenerationSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope);
|
||||
for (JetClassOrObject declaration : declarations) {
|
||||
|
||||
+2
-26
@@ -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<JetFile> findFilesForPackage(@NotNull FqName fqName, @NotNull GlobalSearchScope searchScope);
|
||||
|
||||
@NotNull
|
||||
public abstract List<KotlinLightPackageClassInfo> findPackageClassesInfos(
|
||||
@NotNull FqName fqName,
|
||||
@NotNull GlobalSearchScope wholeScope
|
||||
);
|
||||
|
||||
// Returns only immediately declared classes/objects, package classes are not included (they have no declarations)
|
||||
@NotNull
|
||||
public abstract Collection<JetClassOrObject> findClassOrObjectDeclarationsInPackage(
|
||||
@@ -76,23 +69,6 @@ public abstract class LightClassGenerationSupport {
|
||||
@Nullable
|
||||
public abstract PsiClass getPsiClass(@NotNull JetClassOrObject classOrObject);
|
||||
|
||||
public final class KotlinLightPackageClassInfo {
|
||||
private final Collection<JetFile> files;
|
||||
private final GlobalSearchScope scope;
|
||||
|
||||
public KotlinLightPackageClassInfo(@NotNull Collection<JetFile> files, @NotNull GlobalSearchScope scope) {
|
||||
this.files = files;
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<JetFile> getFiles() {
|
||||
return files;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public GlobalSearchScope getScope() {
|
||||
return scope;
|
||||
}
|
||||
}
|
||||
@NotNull
|
||||
public abstract Collection<PsiClass> getPackageClasses(@NotNull FqName packageFqName, @NotNull GlobalSearchScope scope);
|
||||
}
|
||||
|
||||
+75
-32
@@ -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<JetFile> 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<KotlinLightPackageClassInfo> findPackageClassesInfos(
|
||||
@NotNull FqName fqName, @NotNull GlobalSearchScope wholeScope
|
||||
) {
|
||||
Collection<JetFile> allFiles = findFilesForPackage(fqName, wholeScope);
|
||||
Map<IdeaModuleInfo, List<JetFile>> filesByInfo = groupByModuleInfo(allFiles);
|
||||
List<KotlinLightPackageClassInfo> result = new ArrayList<KotlinLightPackageClassInfo>();
|
||||
for (Map.Entry<IdeaModuleInfo, List<JetFile>> entry : filesByInfo.entrySet()) {
|
||||
result.add(new KotlinLightPackageClassInfo(entry.getValue(), entry.getKey().contentScope()));
|
||||
}
|
||||
sortByClasspath(wholeScope, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<IdeaModuleInfo, List<JetFile>> groupByModuleInfo(@NotNull Collection<JetFile> allFiles) {
|
||||
return KotlinPackage.groupByTo(
|
||||
@@ -184,19 +171,6 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport
|
||||
});
|
||||
}
|
||||
|
||||
private static void sortByClasspath(@NotNull GlobalSearchScope wholeScope, @NotNull List<KotlinLightPackageClassInfo> result) {
|
||||
final Comparator<JetFile> byScopeComparator = byScopeComparator(wholeScope);
|
||||
Collections.sort(result, new Comparator<KotlinLightPackageClassInfo>() {
|
||||
@Override
|
||||
public int compare(@NotNull KotlinLightPackageClassInfo info1, @NotNull KotlinLightPackageClassInfo info2) {
|
||||
JetFile file1 = info1.getFiles().iterator().next();
|
||||
JetFile file2 = info2.getFiles().iterator().next();
|
||||
//classes earlier that would appear earlier on classpath should go first
|
||||
return -byScopeComparator.compare(file1, file2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<JetClassOrObject> findClassOrObjectDeclarationsInPackage(
|
||||
@@ -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<PsiClass> getPackageClasses(@NotNull FqName packageFqName, @NotNull GlobalSearchScope scope) {
|
||||
List<PsiClass> result = new ArrayList<PsiClass>();
|
||||
List<KotlinLightPackageClassInfo> packageClassesInfos = findPackageClassesInfos(packageFqName, scope);
|
||||
for (KotlinLightPackageClassInfo info : packageClassesInfos) {
|
||||
Collection<JetFile> 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<KotlinLightPackageClassInfo> findPackageClassesInfos(
|
||||
@NotNull FqName fqName, @NotNull GlobalSearchScope wholeScope
|
||||
) {
|
||||
Collection<JetFile> allFiles = findFilesForPackage(fqName, wholeScope);
|
||||
Map<IdeaModuleInfo, List<JetFile>> filesByInfo = groupByModuleInfo(allFiles);
|
||||
List<KotlinLightPackageClassInfo> result = new ArrayList<KotlinLightPackageClassInfo>();
|
||||
for (Map.Entry<IdeaModuleInfo, List<JetFile>> entry : filesByInfo.entrySet()) {
|
||||
result.add(new KotlinLightPackageClassInfo(entry.getValue(), entry.getKey().contentScope()));
|
||||
}
|
||||
sortByClasspath(wholeScope, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -241,4 +251,37 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static void sortByClasspath(@NotNull GlobalSearchScope wholeScope, @NotNull List<KotlinLightPackageClassInfo> result) {
|
||||
final Comparator<JetFile> byScopeComparator = byScopeComparator(wholeScope);
|
||||
Collections.sort(result, new Comparator<KotlinLightPackageClassInfo>() {
|
||||
@Override
|
||||
public int compare(@NotNull KotlinLightPackageClassInfo info1, @NotNull KotlinLightPackageClassInfo info2) {
|
||||
JetFile file1 = info1.getFiles().iterator().next();
|
||||
JetFile file2 = info2.getFiles().iterator().next();
|
||||
//classes earlier that would appear earlier on classpath should go first
|
||||
return -byScopeComparator.compare(file1, file2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static final class KotlinLightPackageClassInfo {
|
||||
private final Collection<JetFile> files;
|
||||
private final GlobalSearchScope scope;
|
||||
|
||||
public KotlinLightPackageClassInfo(@NotNull Collection<JetFile> files, @NotNull GlobalSearchScope scope) {
|
||||
this.files = files;
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<JetFile> getFiles() {
|
||||
return files;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public GlobalSearchScope getScope() {
|
||||
return scope;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user