Use new annotations throughout JetFromJavaDescriptorHelper

Remove rest of JetClass annotation uses
This commit is contained in:
Pavel V. Talanov
2013-07-05 19:40:53 +04:00
parent ba8732d10f
commit 33d40f8a50
6 changed files with 178 additions and 222 deletions
@@ -1,60 +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.lang.resolve.java.kt;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver;
public class JetClassAnnotation extends PsiAnnotationWithAbiVersion {
private static final JetClassAnnotation NULL_ANNOTATION = new JetClassAnnotation(null);
static {
NULL_ANNOTATION.checkInitialized();
}
private String signature;
private JetClassAnnotation(@Nullable PsiAnnotation psiAnnotation) {
super(psiAnnotation);
}
@Override
protected void initialize() {
super.initialize();
signature = getStringAttribute(JvmStdlibNames.JET_CLASS_SIGNATURE, "");
}
@NotNull
public String signature() {
checkInitialized();
return signature;
}
public int kind() {
return flags() & JvmStdlibNames.FLAG_CLASS_KIND_MASK;
}
@NotNull
public static JetClassAnnotation get(PsiClass psiClass) {
PsiAnnotation annotation = JavaAnnotationResolver.findOwnAnnotation(psiClass,
JvmStdlibNames.JET_CLASS.getFqName().asString());
return annotation != null ? new JetClassAnnotation(annotation) : NULL_ANNOTATION;
}
}
@@ -53,6 +53,17 @@ import static org.jetbrains.jet.lang.resolve.java.resolver.DeserializedResolverU
import static org.jetbrains.jet.lang.resolve.java.resolver.DeserializedResolverUtils.kotlinFqNameToJavaFqName; import static org.jetbrains.jet.lang.resolve.java.resolver.DeserializedResolverUtils.kotlinFqNameToJavaFqName;
public final class DeserializedDescriptorResolver { public final class DeserializedDescriptorResolver {
@Nullable
public static ClassData readClassDataNoErrorReporting(@NotNull VirtualFile virtualFile) {
String[] data = visitClassFile(virtualFile).getData();
return data != null ? JavaProtoBufUtil.readClassDataFrom(data) : null;
}
@Nullable
public static PackageData readPackageDataNoErrorReporting(@NotNull VirtualFile virtualFile) {
String[] data = visitClassFile(virtualFile).getData();
return data != null ? JavaProtoBufUtil.readPackageDataFrom(data) : null;
}
private AnnotationDescriptorDeserializer annotationDeserializer; private AnnotationDescriptorDeserializer annotationDeserializer;
+1
View File
@@ -36,6 +36,7 @@
<orderEntry type="module" module-name="jps-plugin" scope="TEST" /> <orderEntry type="module" module-name="jps-plugin" scope="TEST" />
<orderEntry type="library" scope="PROVIDED" name="properties" level="project" /> <orderEntry type="library" scope="PROVIDED" name="properties" level="project" />
<orderEntry type="library" scope="PROVIDED" name="java-i18n" level="project" /> <orderEntry type="library" scope="PROVIDED" name="java-i18n" level="project" />
<orderEntry type="module" module-name="serialization" />
</component> </component>
</module> </module>
@@ -16,36 +16,34 @@
package org.jetbrains.jet.plugin.caches; package org.jetbrains.jet.plugin.caches;
import com.google.common.base.Predicate;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*; import com.intellij.psi.*;
import com.intellij.psi.impl.java.stubs.index.JavaAnnotationIndex; import com.intellij.psi.impl.java.stubs.index.JavaAnnotationIndex;
import com.intellij.psi.impl.java.stubs.index.JavaMethodNameIndex;
import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.GlobalSearchScope;
import jet.KotlinClass;
import jet.KotlinPackage;
import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTreeUtil;
import jet.runtime.typeinfo.JetClass;
import jet.runtime.typeinfo.JetPackageClass; import jet.runtime.typeinfo.JetPackageClass;
import jet.runtime.typeinfo.JetValueParameter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.descriptors.serialization.*;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation; import org.jetbrains.jet.lang.resolve.java.resolver.DeserializedDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.kt.JetValueParameterAnnotation;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.util.QualifiedNamesUtil; import org.jetbrains.jet.util.QualifiedNamesUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
/** /**
* Number of helper methods for searching jet element prototypes in java. Methods use java indices for search. * Number of helper methods for searching jet element prototypes in java. Methods use java indices for search.
*/ */
class JetFromJavaDescriptorHelper { public class JetFromJavaDescriptorHelper {
private JetFromJavaDescriptorHelper() { private JetFromJavaDescriptorHelper() {
} }
@@ -57,8 +55,7 @@ class JetFromJavaDescriptorHelper {
/* Will iterate through short name caches /* Will iterate through short name caches
Kotlin namespaces from jar a class files will be collected from java cache Kotlin namespaces from jar a class files will be collected from java cache
Kotlin namespaces classes from sources will be collected with JetShortNamesCache.getClassesByName */ Kotlin namespaces classes from sources will be collected with JetShortNamesCache.getClassesByName */
return getClassesByAnnotation(KotlinPackage.class.getSimpleName(), project, scope);
return getClassesByAnnotation(JetPackageClass.class.getSimpleName(), project, scope);
} }
/** /**
@@ -81,10 +78,14 @@ class JetFromJavaDescriptorHelper {
static Collection<PsiClass> getCompiledClassesForTopLevelObjects(Project project, GlobalSearchScope scope) { static Collection<PsiClass> getCompiledClassesForTopLevelObjects(Project project, GlobalSearchScope scope) {
Set<PsiClass> jetObjectClasses = Sets.newHashSet(); Set<PsiClass> jetObjectClasses = Sets.newHashSet();
Collection<PsiClass> classesByAnnotation = getClassesByAnnotation(JetClass.class.getSimpleName(), project, scope); Collection<PsiClass> classesByAnnotation = getClassesByAnnotation(KotlinClass.class.getSimpleName(), project, scope);
for (PsiClass psiClass : classesByAnnotation) { for (PsiClass psiClass : classesByAnnotation) {
JetClassAnnotation jetAnnotation = JetClassAnnotation.get(psiClass); ClassKind kind = getCompiledClassKind(psiClass);
if (psiClass.getContainingClass() == null && jetAnnotation.kind() == JvmStdlibNames.FLAG_CLASS_KIND_OBJECT) { if (kind == null) {
continue;
}
if (psiClass.getContainingClass() == null && kind == ClassKind.OBJECT) {
jetObjectClasses.add(psiClass); jetObjectClasses.add(psiClass);
} }
} }
@@ -92,58 +93,44 @@ class JetFromJavaDescriptorHelper {
return jetObjectClasses; return jetObjectClasses;
} }
static Collection<String> getTopExtensionFunctionNames(Project project, GlobalSearchScope scope) { @Nullable
public static ClassKind getCompiledClassKind(@NotNull PsiClass psiClass) {
// Extension function should have an parameter of type JetValueParameter with explicit receiver parameter. if (PackageClassUtils.isPackageClass(psiClass)) {
return null;
Set<String> extensionNames = new HashSet<String>();
Collection<PsiAnnotation> valueParametersAnnotations = JavaAnnotationIndex.getInstance().get(
JetValueParameter.class.getSimpleName(), project, scope);
for (PsiAnnotation parameterAnnotation : valueParametersAnnotations) {
PsiParameter parameter = PsiTreeUtil.getParentOfType(parameterAnnotation, PsiParameter.class);
if (parameter == null) {
continue;
}
if (!JetValueParameterAnnotation.get(parameter).receiver()) {
continue;
}
PsiMethod psiMethod = PsiTreeUtil.getParentOfType(parameter, PsiMethod.class);
if (psiMethod != null) {
extensionNames.add(psiMethod.getName());
}
} }
ClassData classData = getClassData(psiClass);
return extensionNames; if (classData == null) return null;
return DescriptorDeserializer.classKind(Flags.CLASS_KIND.get(classData.getClassProto().getFlags()));
} }
static Collection<PsiMethod> getTopExtensionFunctionPrototypesByName(String name, Project project, GlobalSearchScope scope) {
return filterJetJavaPrototypesByName( @Nullable
name, project, scope, private static ClassData getClassData(@NotNull PsiClass psiClass) {
new Predicate<PsiMethod>() { VirtualFile virtualFile = getVirtualFileForPsiClass(psiClass);
@Override if (virtualFile == null) return null;
public boolean apply(@Nullable PsiMethod psiMethod) { return DeserializedDescriptorResolver.readClassDataNoErrorReporting(virtualFile);
assert psiMethod != null;
PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
return parameters.length > 0 && JetValueParameterAnnotation.get(parameters[0]).receiver();
}
});
} }
static Collection<PsiMethod> getTopLevelFunctionPrototypesByName(String name, Project project, GlobalSearchScope scope) { @Nullable
return filterJetJavaPrototypesByName( private static PackageData getPackageData(@NotNull PsiClass psiClass) {
name, project, scope, VirtualFile virtualFile = getVirtualFileForPsiClass(psiClass);
new Predicate<PsiMethod>() { if (virtualFile == null) return null;
@Override return DeserializedDescriptorResolver.readPackageDataNoErrorReporting(virtualFile);
public boolean apply(@Nullable PsiMethod psiMethod) { }
assert psiMethod != null;
PsiParameter[] parameters = psiMethod.getParameterList().getParameters(); //TODO: common utility
return parameters.length == 0 || !JetValueParameterAnnotation.get(parameters[0]).receiver(); //TODO: doesn't work for inner classes and stuff
} @Nullable
}); private static VirtualFile getVirtualFileForPsiClass(@NotNull PsiClass psiClass) {
PsiFile psiFile = psiClass.getContainingFile();
if (psiFile == null) {
return null;
}
VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile == null) {
return null;
}
return virtualFile;
} }
@Nullable @Nullable
@@ -165,33 +152,6 @@ class JetFromJavaDescriptorHelper {
return null; return null;
} }
private static Collection<PsiMethod> filterJetJavaPrototypesByName(
String name, Project project, GlobalSearchScope scope,
Predicate<PsiMethod> filterPredicate
) {
Set<PsiMethod> selectedMethods = new HashSet<PsiMethod>();
Collection<PsiMethod> psiMethods = JavaMethodNameIndex.getInstance().get(name, project, scope);
for (PsiMethod psiMethod : psiMethods) {
if (psiMethod == null) {
continue;
}
// Check this is top level function
PsiClass containingClass = psiMethod.getContainingClass();
if (containingClass == null || !PackageClassUtils.isPackageClass(containingClass)) {
continue;
}
// Should be parameter with JetValueParameter.receiver == true
if (filterPredicate.apply(psiMethod)) {
selectedMethods.add(psiMethod);
}
}
return selectedMethods;
}
private static Collection<PsiClass> getClassesByAnnotation( private static Collection<PsiClass> getClassesByAnnotation(
String annotationName, Project project, GlobalSearchScope scope String annotationName, Project project, GlobalSearchScope scope
) { ) {
@@ -206,4 +166,34 @@ class JetFromJavaDescriptorHelper {
} }
return classes; return classes;
} }
@NotNull
public static Collection<FqName> getTopLevelFunctionFqNames(
@NotNull Project project,
@NotNull GlobalSearchScope scope,
boolean shouldBeExtension
) {
Collection<FqName> result = Sets.newHashSet();
Collection<PsiClass> packageClasses = getClassesByAnnotation(KotlinPackage.class.getSimpleName(), project, scope);
for (PsiClass psiClass : packageClasses) {
String qualifiedName = psiClass.getQualifiedName();
if (qualifiedName == null) {
continue;
}
FqName packageFqName = new FqName(qualifiedName).parent();
PackageData data = getPackageData(psiClass);
if (data == null) {
continue;
}
NameResolver nameResolver = data.getNameResolver();
for (ProtoBuf.Callable callable : data.getPackageProto().getMemberList()) {
if (callable.hasReceiverType() == shouldBeExtension) {
Name name = nameResolver.getName(callable.getName());
result.add(packageFqName.child(name));
}
}
}
return result;
}
} }
@@ -27,6 +27,7 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache; import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.util.ArrayUtil; import com.intellij.util.ArrayUtil;
import com.intellij.util.Processor; import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet; import com.intellij.util.containers.HashSet;
import com.intellij.util.containers.MultiMap; import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NonNls;
@@ -53,6 +54,8 @@ import org.jetbrains.jet.plugin.stubindex.*;
import java.util.*; import java.util.*;
import static org.jetbrains.jet.plugin.caches.JetFromJavaDescriptorHelper.getTopLevelFunctionFqNames;
/** /**
* Will provide both java elements from jet context and some special declarations special to jet. * Will provide both java elements from jet context and some special declarations special to jet.
* All those declaration are planned to be used in completion. * All those declaration are planned to be used in completion.
@@ -87,7 +90,8 @@ public class JetShortNamesCache extends PsiShortNamesCache {
// .namespace classes can not be indexed, since they have no explicit declarations // .namespace classes can not be indexed, since they have no explicit declarations
IDELightClassGenerationSupport lightClassGenerationSupport = IDELightClassGenerationSupport.getInstanceForIDE(project); IDELightClassGenerationSupport lightClassGenerationSupport = IDELightClassGenerationSupport.getInstanceForIDE(project);
Set<String> packageClassShortNames = lightClassGenerationSupport.getAllPossiblePackageClasses(GlobalSearchScope.allScope(project)).keySet(); Set<String> packageClassShortNames =
lightClassGenerationSupport.getAllPossiblePackageClasses(GlobalSearchScope.allScope(project)).keySet();
classNames.addAll(packageClassShortNames); classNames.addAll(packageClassShortNames);
return ArrayUtil.toStringArray(classNames); return ArrayUtil.toStringArray(classNames);
@@ -125,8 +129,8 @@ public class JetShortNamesCache extends PsiShortNamesCache {
FqName fqName = JetPsiUtil.getFQName(classOrObject); FqName fqName = JetPsiUtil.getFQName(classOrObject);
if (fqName != null) { if (fqName != null) {
assert fqName.shortName().asString().equals(name) : "A declaration obtained from index has non-matching name:\n" + assert fqName.shortName().asString().equals(name) : "A declaration obtained from index has non-matching name:\n" +
"in index: " + name + "\n" + "in index: " + name + "\n" +
"declared: " + fqName.shortName() + "(" + fqName + ")"; "declared: " + fqName.shortName() + "(" + fqName + ")";
PsiClass psiClass = JavaElementFinder.getInstance(project).findClass(fqName.asString(), scope); PsiClass psiClass = JavaElementFinder.getInstance(project).findClass(fqName.asString(), scope);
if (psiClass != null) { if (psiClass != null) {
result.add(psiClass); result.add(psiClass);
@@ -161,7 +165,8 @@ public class JetShortNamesCache extends PsiShortNamesCache {
Set<String> topObjectNames = new HashSet<String>(); Set<String> topObjectNames = new HashSet<String>();
topObjectNames.addAll(JetTopLevelShortObjectNameIndex.getInstance().getAllKeys(project)); topObjectNames.addAll(JetTopLevelShortObjectNameIndex.getInstance().getAllKeys(project));
Collection<PsiClass> classObjects = JetFromJavaDescriptorHelper.getCompiledClassesForTopLevelObjects(project, GlobalSearchScope.allScope(project)); Collection<PsiClass> classObjects =
JetFromJavaDescriptorHelper.getCompiledClassesForTopLevelObjects(project, GlobalSearchScope.allScope(project));
topObjectNames.addAll(Collections2.transform(classObjects, new Function<PsiClass, String>() { topObjectNames.addAll(Collections2.transform(classObjects, new Function<PsiClass, String>() {
@Override @Override
public String apply(@Nullable PsiClass aClass) { public String apply(@Nullable PsiClass aClass) {
@@ -210,7 +215,7 @@ public class JetShortNamesCache extends PsiShortNamesCache {
@NotNull @NotNull
public Collection<FunctionDescriptor> getTopLevelFunctionDescriptorsByName( public Collection<FunctionDescriptor> getTopLevelFunctionDescriptorsByName(
@NotNull String name, @NotNull final String name,
@NotNull JetSimpleNameExpression expression, @NotNull JetSimpleNameExpression expression,
@NotNull CancelableResolveSession resolveSession, @NotNull CancelableResolveSession resolveSession,
@NotNull GlobalSearchScope scope @NotNull GlobalSearchScope scope
@@ -230,24 +235,27 @@ public class JetShortNamesCache extends PsiShortNamesCache {
Set<FunctionDescriptor> result = Sets.newHashSet(); Set<FunctionDescriptor> result = Sets.newHashSet();
Collection<PsiMethod> topLevelFunctionPrototypes = JetFromJavaDescriptorHelper.getTopLevelFunctionPrototypesByName( Collection<FqName> topLevelFunctionFqNames =
referenceName.asString(), project, scope); ContainerUtil.filter(getTopLevelFunctionFqNames(project, scope, false), new Condition<FqName>() {
for (PsiMethod method : topLevelFunctionPrototypes) { @Override
FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(method); public boolean value(FqName fqName) {
if (functionFQN != null) { return fqName.lastSegmentIs(Name.identifier(name));
JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, new ImportPath(functionFQN, false));
Collection<? extends DeclarationDescriptor> declarationDescriptors = new QualifiedExpressionResolver().analyseImportReference(
importDirective, jetScope, new BindingTraceContext(), resolveSession.getRootModuleDescriptor());
for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) {
if (declarationDescriptor instanceof FunctionDescriptor) {
result.add((FunctionDescriptor) declarationDescriptor);
} }
});
for (FqName fqName : topLevelFunctionFqNames) {
JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, new ImportPath(fqName, false));
Collection<? extends DeclarationDescriptor> declarationDescriptors = new QualifiedExpressionResolver().analyseImportReference(
importDirective, jetScope, new BindingTraceContext(), resolveSession.getRootModuleDescriptor());
for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) {
if (declarationDescriptor instanceof FunctionDescriptor) {
result.add((FunctionDescriptor) declarationDescriptor);
} }
} }
} }
Set<FqName> affectedPackages = Sets.newHashSet(); Set<FqName> affectedPackages = Sets.newHashSet();
Collection<JetNamedFunction> jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(referenceName.asString(), project, scope); Collection<JetNamedFunction> jetNamedFunctions =
JetShortFunctionNameIndex.getInstance().get(referenceName.asString(), project, scope);
for (JetNamedFunction jetNamedFunction : jetNamedFunctions) { for (JetNamedFunction jetNamedFunction : jetNamedFunctions) {
PsiFile containingFile = jetNamedFunction.getContainingFile(); PsiFile containingFile = jetNamedFunction.getContainingFile();
if (containingFile instanceof JetFile) { if (containingFile instanceof JetFile) {
@@ -269,84 +277,86 @@ public class JetShortNamesCache extends PsiShortNamesCache {
return result; return result;
} }
/** private Collection<PsiElement> getJetExtensionFunctionsByName(@NotNull String name, @NotNull GlobalSearchScope scope) {
* Get jet extensions top-level function names. Method is allowed to give invalid names - all result should be
* checked with getAllJetExtensionFunctionsByName().
*
* @return
*/
@NotNull
public Collection<String> getAllJetExtensionFunctionsNames(@NotNull GlobalSearchScope scope) {
Set<String> extensionFunctionNames = new HashSet<String>();
extensionFunctionNames.addAll(JetExtensionFunctionNameIndex.getInstance().getAllKeys(project));
extensionFunctionNames.addAll(JetFromJavaDescriptorHelper.getTopExtensionFunctionNames(project, scope));
return extensionFunctionNames;
}
public Collection<PsiElement> getJetExtensionFunctionsByName(@NotNull String name, @NotNull GlobalSearchScope scope) {
HashSet<PsiElement> functions = new HashSet<PsiElement>(); HashSet<PsiElement> functions = new HashSet<PsiElement>();
functions.addAll(JetExtensionFunctionNameIndex.getInstance().get(name, project, scope)); functions.addAll(JetExtensionFunctionNameIndex.getInstance().get(name, project, scope));
functions.addAll(JetFromJavaDescriptorHelper.getTopExtensionFunctionPrototypesByName(name, project, scope));
return functions; return functions;
} }
// TODO: Make it work for properties // TODO: Make it work for properties
@NotNull
public Collection<DeclarationDescriptor> getJetCallableExtensions( public Collection<DeclarationDescriptor> getJetCallableExtensions(
@NotNull Condition<String> acceptedNameCondition, @NotNull final Condition<String> acceptedNameCondition,
@NotNull JetSimpleNameExpression expression, @NotNull JetSimpleNameExpression expression,
@NotNull CancelableResolveSession resolveSession, @NotNull CancelableResolveSession resolveSession,
@NotNull GlobalSearchScope searchScope @NotNull GlobalSearchScope searchScope
) { ) {
Collection<DeclarationDescriptor> resultDescriptors = new ArrayList<DeclarationDescriptor>();
BindingContext context = resolveSession.resolveToElement(expression); BindingContext context = resolveSession.resolveToElement(expression);
JetExpression receiverExpression = expression.getReceiverExpression(); JetExpression receiverExpression = expression.getReceiverExpression();
if (receiverExpression != null) { if (receiverExpression == null) {
JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression); return Collections.emptyList();
JetScope scope = context.get(BindingContext.RESOLUTION_SCOPE, receiverExpression); }
JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
JetScope scope = context.get(BindingContext.RESOLUTION_SCOPE, receiverExpression);
if (expressionType != null && scope != null && !ErrorUtils.isErrorType(expressionType)) { if (expressionType == null || scope == null || ErrorUtils.isErrorType(expressionType)) {
Collection<String> extensionFunctionsNames = getAllJetExtensionFunctionsNames(searchScope); return Collections.emptyList();
}
Set<FqName> functionFQNs = new java.util.HashSet<FqName>(); Set<FqName> functionFQNs = extensionFunctionsFromSourceFqNames(acceptedNameCondition, searchScope);
functionFQNs.addAll(ContainerUtil.filter(getTopLevelFunctionFqNames(project, searchScope, true), new Condition<FqName>() {
@Override
public boolean value(FqName fqName) {
return acceptedNameCondition.value(fqName.shortName().asString());
}
}));
// Collect all possible extension function qualified names Collection<DeclarationDescriptor> resultDescriptors = new ArrayList<DeclarationDescriptor>();
for (String name : extensionFunctionsNames) { // Iterate through the function with attempt to resolve found functions
if (acceptedNameCondition.value(name)) { for (FqName functionFQN : functionFQNs) {
Collection<PsiElement> extensionFunctions = getJetExtensionFunctionsByName(name, searchScope); for (CallableDescriptor functionDescriptor : ExpressionTypingUtils.canFindSuitableCall(
functionFQN, project, receiverExpression, expressionType, scope, resolveSession.getRootModuleDescriptor())) {
for (PsiElement extensionFunction : extensionFunctions) { resultDescriptors.add(functionDescriptor);
if (extensionFunction instanceof JetNamedFunction) {
functionFQNs.add(JetPsiUtil.getFQName((JetNamedFunction) extensionFunction));
}
else if (extensionFunction instanceof PsiMethod) {
FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN((PsiMethod) extensionFunction);
if (functionFQN != null) {
functionFQNs.add(functionFQN);
}
}
}
}
}
// Iterate through the function with attempt to resolve found functions
for (FqName functionFQN : functionFQNs) {
for (CallableDescriptor functionDescriptor : ExpressionTypingUtils.canFindSuitableCall(
functionFQN, project, receiverExpression, expressionType, scope, resolveSession.getRootModuleDescriptor())) {
resultDescriptors.add(functionDescriptor);
}
}
} }
} }
return resultDescriptors; return resultDescriptors;
} }
@NotNull
private Set<FqName> extensionFunctionsFromSourceFqNames(
@NotNull Condition<String> acceptedNameCondition,
@NotNull GlobalSearchScope searchScope
) {
Set<String> extensionFunctionNames = new HashSet<String>(JetExtensionFunctionNameIndex.getInstance().getAllKeys(project));
Set<FqName> functionFQNs = new java.util.HashSet<FqName>();
// Collect all possible extension function qualified names
for (String name : extensionFunctionNames) {
if (acceptedNameCondition.value(name)) {
Collection<PsiElement> extensionFunctions = getJetExtensionFunctionsByName(name, searchScope);
for (PsiElement extensionFunction : extensionFunctions) {
if (extensionFunction instanceof JetNamedFunction) {
functionFQNs.add(JetPsiUtil.getFQName((JetNamedFunction) extensionFunction));
}
else if (extensionFunction instanceof PsiMethod) {
FqName functionFQN =
JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN((PsiMethod) extensionFunction);
if (functionFQN != null) {
functionFQNs.add(functionFQN);
}
}
}
}
}
return functionFQNs;
}
public Collection<ClassDescriptor> getJetClassesDescriptors( public Collection<ClassDescriptor> getJetClassesDescriptors(
@NotNull Condition<String> acceptedShortNameCondition, @NotNull Condition<String> acceptedShortNameCondition,
@NotNull KotlinCodeAnalyzer analyzer, @NotNull KotlinCodeAnalyzer analyzer,
@@ -397,7 +407,11 @@ public class JetShortNamesCache extends PsiShortNamesCache {
} }
@Override @Override
public boolean processMethodsWithName(@NonNls @NotNull String name, @NotNull GlobalSearchScope scope, @NotNull Processor<PsiMethod> processor) { public boolean processMethodsWithName(
@NonNls @NotNull String name,
@NotNull GlobalSearchScope scope,
@NotNull Processor<PsiMethod> processor
) {
return false; return false;
} }
@@ -24,13 +24,13 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.Consumer; import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.asJava.KotlinLightClass; import org.jetbrains.jet.asJava.KotlinLightClass;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils; import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils; import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.plugin.caches.JetFromJavaDescriptorHelper;
import org.jetbrains.jet.plugin.caches.JetShortNamesCache; import org.jetbrains.jet.plugin.caches.JetShortNamesCache;
import org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector; import org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector;
@@ -93,7 +93,7 @@ public class JetTypesCompletionHelper {
} }
if (DescriptorResolverUtils.isKotlinClass(aClass)) { if (DescriptorResolverUtils.isKotlinClass(aClass)) {
if (JetClassAnnotation.get(aClass).kind() != JvmStdlibNames.FLAG_CLASS_KIND_OBJECT) { if (JetFromJavaDescriptorHelper.getCompiledClassKind(aClass) != ClassKind.CLASS_OBJECT) {
String qualifiedName = aClass.getQualifiedName(); String qualifiedName = aClass.getQualifiedName();
if (qualifiedName != null) { if (qualifiedName != null) {
FqName fqName = new FqName(qualifiedName); FqName fqName = new FqName(qualifiedName);