Properly determine what classes to show in Kotlin completion:

Classes like Int and jet.Iterable should are not visible from Java
since they are erased at runtime. We call such classes non-physical,
they have to be added to completion manually.`
This commit is contained in:
Andrey Breslav
2012-10-18 17:20:23 +04:00
parent 6f4902bfbe
commit a7b6b34e29
5 changed files with 65 additions and 24 deletions
@@ -135,6 +135,8 @@ public class KotlinBuiltIns {
private final ResolveSession resolveSession;
private final ModuleDescriptor builtInsModule;
private ImmutableSet<ClassDescriptor> nonPhysicalClasses;
private final ImmutableList<ClassDescriptor> functionClasses;
private final ImmutableSet<ClassDescriptor> functionClassesSet;
@@ -183,6 +185,8 @@ public class KotlinBuiltIns {
}
private void initialize() {
nonPhysicalClasses = computeNonPhysicalClasses();
for (PrimitiveType primitive : PrimitiveType.values()) {
makePrimitive(primitive);
}
@@ -541,6 +545,63 @@ public class KotlinBuiltIns {
return getBuiltInClassByName("MutableListIterator");
}
/**
* Classes that only exist for the Kotlin compiler: they are erased at runtime.
* As a consequence they, for example, shouldn't be referred to by other languages
* (e.g. Java).
*/
@NotNull
public Set<ClassDescriptor> getNonPhysicalClasses() {
return nonPhysicalClasses;
}
@NotNull
private ImmutableSet<ClassDescriptor> computeNonPhysicalClasses() {
ImmutableSet.Builder<ClassDescriptor> nonPhysical = ImmutableSet.builder();
nonPhysical.add(
getAny(),
getNothing(),
getNumber(),
getString(),
getCharSequence(),
getThrowable(),
getBuiltInClassByName("Hashable"),
getIterator(),
getIterable(),
getCollection(),
getList(),
getListIterator(),
getSet(),
getMap(),
getMapEntry(),
getMutableIterator(),
getMutableIterable(),
getMutableCollection(),
getMutableList(),
getMutableListIterator(),
getMutableSet(),
getMutableMap(),
getMutableMapEntry(),
getVolatileAnnotationClass(),
getDataClassAnnotation(),
getAnnotation(),
getComparable(),
getEnum(),
getArray()
);
for (PrimitiveType primitiveType : values()) {
nonPhysical.add(getPrimitiveClassDescriptor(primitiveType));
nonPhysical.add(getPrimitiveArrayClassDescriptor(primitiveType));
}
return nonPhysical.build();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// GET TYPE
@@ -16,8 +16,6 @@
package org.jetbrains.jet.plugin.caches;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
@@ -29,7 +27,6 @@ import com.intellij.util.Processor;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.asJava.JavaElementFinder;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
@@ -44,7 +41,6 @@ import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.plugin.stubindex.JetExtensionFunctionNameIndex;
import org.jetbrains.jet.plugin.stubindex.JetFullClassNameIndex;
import org.jetbrains.jet.plugin.stubindex.JetShortClassNameIndex;
@@ -113,25 +109,6 @@ public class JetShortNamesCache extends PsiShortNamesCache {
destination.addAll(Arrays.asList(getAllClassNames()));
}
/**
* Types that should be visible in completion from kotlin but should be absent in java.
* @return
*/
@NotNull
public static Collection<DeclarationDescriptor> getJetOnlyTypes() {
Collection<DeclarationDescriptor> standardTypes =
Collections2.transform(KotlinBuiltIns.getInstance().getAllBuiltInClasses(),
new Function<DeclarationDescriptor, DeclarationDescriptor>() {
@Override
public DeclarationDescriptor apply(@Nullable DeclarationDescriptor classDescriptor) {
assert classDescriptor != null;
return classDescriptor;
}
});
return standardTypes;
}
/**
* Get jet non-extension top-level function names. Method is allowed to give invalid names - all result should be
* checked with getTopLevelFunctionDescriptorsByName().
@@ -32,6 +32,7 @@ import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.plugin.caches.JetCacheManager;
import org.jetbrains.jet.plugin.caches.JetShortNamesCache;
import org.jetbrains.jet.plugin.completion.handlers.JetJavaClassInsertHandler;
@@ -58,7 +59,7 @@ public class JetClassCompletionContributor extends CompletionContributor {
) {
CompletionResultSet tempResult = result.withPrefixMatcher(CompletionUtil.findReferenceOrAlphanumericPrefix(parameters));
final Collection<DeclarationDescriptor> jetOnlyClasses = JetShortNamesCache.getJetOnlyTypes();
final Collection<ClassDescriptor> jetOnlyClasses = KotlinBuiltIns.getInstance().getNonPhysicalClasses();
for (DeclarationDescriptor jetOnlyClass : jetOnlyClasses) {
consumer.consume(DescriptorLookupConverter.createLookupElement(resolveSession, jetContext, jetOnlyClass));
}
@@ -4,5 +4,6 @@ class Test {
}
}
// RUNTIME: 1
// EXIST: Any, Nothing, Tuple0, Int, Number
// EXIST: Array, Math, Hashable, OutputStream
@@ -3,5 +3,6 @@ class Test : <caret> {
}
}
// RUNTIME: 1
// EXIST: Any, Nothing, Tuple0, Int, Number
// EXIST: Array, Math, Hashable, OutputStream