Use new annotations throughout JetFromJavaDescriptorHelper
Remove rest of JetClass annotation uses
This commit is contained in:
-60
@@ -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;
|
||||
}
|
||||
}
|
||||
+11
@@ -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;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
<orderEntry type="module" module-name="jps-plugin" scope="TEST" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="properties" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="java-i18n" level="project" />
|
||||
<orderEntry type="module" module-name="serialization" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -16,36 +16,34 @@
|
||||
|
||||
package org.jetbrains.jet.plugin.caches;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
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 jet.KotlinClass;
|
||||
import jet.KotlinPackage;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import jet.runtime.typeinfo.JetClass;
|
||||
import jet.runtime.typeinfo.JetPackageClass;
|
||||
import jet.runtime.typeinfo.JetValueParameter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.kt.JetClassAnnotation;
|
||||
import org.jetbrains.jet.lang.resolve.java.kt.JetValueParameterAnnotation;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.DeserializedDescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.util.QualifiedNamesUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Number of helper methods for searching jet element prototypes in java. Methods use java indices for search.
|
||||
*/
|
||||
class JetFromJavaDescriptorHelper {
|
||||
public class JetFromJavaDescriptorHelper {
|
||||
|
||||
private JetFromJavaDescriptorHelper() {
|
||||
}
|
||||
@@ -57,8 +55,7 @@ class JetFromJavaDescriptorHelper {
|
||||
/* Will iterate through short name caches
|
||||
Kotlin namespaces from jar a class files will be collected from java cache
|
||||
Kotlin namespaces classes from sources will be collected with JetShortNamesCache.getClassesByName */
|
||||
|
||||
return getClassesByAnnotation(JetPackageClass.class.getSimpleName(), project, scope);
|
||||
return getClassesByAnnotation(KotlinPackage.class.getSimpleName(), project, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,10 +78,14 @@ class JetFromJavaDescriptorHelper {
|
||||
static Collection<PsiClass> getCompiledClassesForTopLevelObjects(Project project, GlobalSearchScope scope) {
|
||||
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) {
|
||||
JetClassAnnotation jetAnnotation = JetClassAnnotation.get(psiClass);
|
||||
if (psiClass.getContainingClass() == null && jetAnnotation.kind() == JvmStdlibNames.FLAG_CLASS_KIND_OBJECT) {
|
||||
ClassKind kind = getCompiledClassKind(psiClass);
|
||||
if (kind == null) {
|
||||
continue;
|
||||
}
|
||||
if (psiClass.getContainingClass() == null && kind == ClassKind.OBJECT) {
|
||||
jetObjectClasses.add(psiClass);
|
||||
}
|
||||
}
|
||||
@@ -92,58 +93,44 @@ class JetFromJavaDescriptorHelper {
|
||||
return jetObjectClasses;
|
||||
}
|
||||
|
||||
static Collection<String> getTopExtensionFunctionNames(Project project, GlobalSearchScope scope) {
|
||||
|
||||
// Extension function should have an parameter of type JetValueParameter with explicit receiver parameter.
|
||||
|
||||
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());
|
||||
}
|
||||
@Nullable
|
||||
public static ClassKind getCompiledClassKind(@NotNull PsiClass psiClass) {
|
||||
if (PackageClassUtils.isPackageClass(psiClass)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return extensionNames;
|
||||
ClassData classData = getClassData(psiClass);
|
||||
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(
|
||||
name, project, scope,
|
||||
new Predicate<PsiMethod>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable PsiMethod psiMethod) {
|
||||
assert psiMethod != null;
|
||||
PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
|
||||
return parameters.length > 0 && JetValueParameterAnnotation.get(parameters[0]).receiver();
|
||||
}
|
||||
});
|
||||
|
||||
@Nullable
|
||||
private static ClassData getClassData(@NotNull PsiClass psiClass) {
|
||||
VirtualFile virtualFile = getVirtualFileForPsiClass(psiClass);
|
||||
if (virtualFile == null) return null;
|
||||
return DeserializedDescriptorResolver.readClassDataNoErrorReporting(virtualFile);
|
||||
}
|
||||
|
||||
static Collection<PsiMethod> getTopLevelFunctionPrototypesByName(String name, Project project, GlobalSearchScope scope) {
|
||||
return filterJetJavaPrototypesByName(
|
||||
name, project, scope,
|
||||
new Predicate<PsiMethod>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable PsiMethod psiMethod) {
|
||||
assert psiMethod != null;
|
||||
PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
|
||||
return parameters.length == 0 || !JetValueParameterAnnotation.get(parameters[0]).receiver();
|
||||
}
|
||||
});
|
||||
@Nullable
|
||||
private static PackageData getPackageData(@NotNull PsiClass psiClass) {
|
||||
VirtualFile virtualFile = getVirtualFileForPsiClass(psiClass);
|
||||
if (virtualFile == null) return null;
|
||||
return DeserializedDescriptorResolver.readPackageDataNoErrorReporting(virtualFile);
|
||||
}
|
||||
|
||||
//TODO: common utility
|
||||
//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
|
||||
@@ -165,33 +152,6 @@ class JetFromJavaDescriptorHelper {
|
||||
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(
|
||||
String annotationName, Project project, GlobalSearchScope scope
|
||||
) {
|
||||
@@ -206,4 +166,34 @@ class JetFromJavaDescriptorHelper {
|
||||
}
|
||||
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.util.ArrayUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -53,6 +54,8 @@ import org.jetbrains.jet.plugin.stubindex.*;
|
||||
|
||||
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.
|
||||
* 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
|
||||
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);
|
||||
|
||||
return ArrayUtil.toStringArray(classNames);
|
||||
@@ -125,8 +129,8 @@ public class JetShortNamesCache extends PsiShortNamesCache {
|
||||
FqName fqName = JetPsiUtil.getFQName(classOrObject);
|
||||
if (fqName != null) {
|
||||
assert fqName.shortName().asString().equals(name) : "A declaration obtained from index has non-matching name:\n" +
|
||||
"in index: " + name + "\n" +
|
||||
"declared: " + fqName.shortName() + "(" + fqName + ")";
|
||||
"in index: " + name + "\n" +
|
||||
"declared: " + fqName.shortName() + "(" + fqName + ")";
|
||||
PsiClass psiClass = JavaElementFinder.getInstance(project).findClass(fqName.asString(), scope);
|
||||
if (psiClass != null) {
|
||||
result.add(psiClass);
|
||||
@@ -161,7 +165,8 @@ public class JetShortNamesCache extends PsiShortNamesCache {
|
||||
Set<String> topObjectNames = new HashSet<String>();
|
||||
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>() {
|
||||
@Override
|
||||
public String apply(@Nullable PsiClass aClass) {
|
||||
@@ -210,7 +215,7 @@ public class JetShortNamesCache extends PsiShortNamesCache {
|
||||
|
||||
@NotNull
|
||||
public Collection<FunctionDescriptor> getTopLevelFunctionDescriptorsByName(
|
||||
@NotNull String name,
|
||||
@NotNull final String name,
|
||||
@NotNull JetSimpleNameExpression expression,
|
||||
@NotNull CancelableResolveSession resolveSession,
|
||||
@NotNull GlobalSearchScope scope
|
||||
@@ -230,24 +235,27 @@ public class JetShortNamesCache extends PsiShortNamesCache {
|
||||
|
||||
Set<FunctionDescriptor> result = Sets.newHashSet();
|
||||
|
||||
Collection<PsiMethod> topLevelFunctionPrototypes = JetFromJavaDescriptorHelper.getTopLevelFunctionPrototypesByName(
|
||||
referenceName.asString(), project, scope);
|
||||
for (PsiMethod method : topLevelFunctionPrototypes) {
|
||||
FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(method);
|
||||
if (functionFQN != null) {
|
||||
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);
|
||||
Collection<FqName> topLevelFunctionFqNames =
|
||||
ContainerUtil.filter(getTopLevelFunctionFqNames(project, scope, false), new Condition<FqName>() {
|
||||
@Override
|
||||
public boolean value(FqName fqName) {
|
||||
return fqName.lastSegmentIs(Name.identifier(name));
|
||||
}
|
||||
});
|
||||
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();
|
||||
Collection<JetNamedFunction> jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(referenceName.asString(), project, scope);
|
||||
Collection<JetNamedFunction> jetNamedFunctions =
|
||||
JetShortFunctionNameIndex.getInstance().get(referenceName.asString(), project, scope);
|
||||
for (JetNamedFunction jetNamedFunction : jetNamedFunctions) {
|
||||
PsiFile containingFile = jetNamedFunction.getContainingFile();
|
||||
if (containingFile instanceof JetFile) {
|
||||
@@ -269,84 +277,86 @@ public class JetShortNamesCache extends PsiShortNamesCache {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
private Collection<PsiElement> getJetExtensionFunctionsByName(@NotNull String name, @NotNull GlobalSearchScope scope) {
|
||||
HashSet<PsiElement> functions = new HashSet<PsiElement>();
|
||||
functions.addAll(JetExtensionFunctionNameIndex.getInstance().get(name, project, scope));
|
||||
functions.addAll(JetFromJavaDescriptorHelper.getTopExtensionFunctionPrototypesByName(name, project, scope));
|
||||
|
||||
return functions;
|
||||
}
|
||||
|
||||
// TODO: Make it work for properties
|
||||
@NotNull
|
||||
public Collection<DeclarationDescriptor> getJetCallableExtensions(
|
||||
@NotNull Condition<String> acceptedNameCondition,
|
||||
@NotNull final Condition<String> acceptedNameCondition,
|
||||
@NotNull JetSimpleNameExpression expression,
|
||||
@NotNull CancelableResolveSession resolveSession,
|
||||
@NotNull GlobalSearchScope searchScope
|
||||
) {
|
||||
Collection<DeclarationDescriptor> resultDescriptors = new ArrayList<DeclarationDescriptor>();
|
||||
|
||||
BindingContext context = resolveSession.resolveToElement(expression);
|
||||
JetExpression receiverExpression = expression.getReceiverExpression();
|
||||
|
||||
if (receiverExpression != null) {
|
||||
JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
|
||||
JetScope scope = context.get(BindingContext.RESOLUTION_SCOPE, receiverExpression);
|
||||
if (receiverExpression == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
|
||||
JetScope scope = context.get(BindingContext.RESOLUTION_SCOPE, receiverExpression);
|
||||
|
||||
if (expressionType != null && scope != null && !ErrorUtils.isErrorType(expressionType)) {
|
||||
Collection<String> extensionFunctionsNames = getAllJetExtensionFunctionsNames(searchScope);
|
||||
if (expressionType == null || scope == null || ErrorUtils.isErrorType(expressionType)) {
|
||||
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
|
||||
for (String name : extensionFunctionsNames) {
|
||||
if (acceptedNameCondition.value(name)) {
|
||||
Collection<PsiElement> extensionFunctions = getJetExtensionFunctionsByName(name, searchScope);
|
||||
Collection<DeclarationDescriptor> resultDescriptors = new ArrayList<DeclarationDescriptor>();
|
||||
// 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())) {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
resultDescriptors.add(functionDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
@NotNull Condition<String> acceptedShortNameCondition,
|
||||
@NotNull KotlinCodeAnalyzer analyzer,
|
||||
@@ -397,7 +407,11 @@ public class JetShortNamesCache extends PsiShortNamesCache {
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,13 +24,13 @@ import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.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.name.FqName;
|
||||
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.framework.KotlinFrameworkDetector;
|
||||
|
||||
@@ -93,7 +93,7 @@ public class JetTypesCompletionHelper {
|
||||
}
|
||||
|
||||
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();
|
||||
if (qualifiedName != null) {
|
||||
FqName fqName = new FqName(qualifiedName);
|
||||
|
||||
Reference in New Issue
Block a user