resolve of import all members from objects and variables
This commit is contained in:
+6
-6
@@ -12,22 +12,22 @@ import java.util.Set;
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class FunctionDescriptorWithImplicitReceiver implements FunctionDescriptor {
|
||||
public class FunctionDescriptorBoundToReceiver implements FunctionDescriptor {
|
||||
|
||||
private FunctionDescriptor functionDescriptor;
|
||||
private DeclarationDescriptor implicitReceiver;
|
||||
private DeclarationDescriptor receiver;
|
||||
|
||||
public FunctionDescriptorWithImplicitReceiver(@NotNull FunctionDescriptor functionDescriptor, @NotNull DeclarationDescriptor implicitReceiver) {
|
||||
public FunctionDescriptorBoundToReceiver(@NotNull FunctionDescriptor functionDescriptor, @NotNull DeclarationDescriptor receiver) {
|
||||
this.functionDescriptor = functionDescriptor;
|
||||
this.implicitReceiver = implicitReceiver;
|
||||
this.receiver = receiver;
|
||||
}
|
||||
|
||||
public FunctionDescriptor getFunctionDescriptor() {
|
||||
return functionDescriptor;
|
||||
}
|
||||
|
||||
public DeclarationDescriptor getImplicitReceiver() {
|
||||
return implicitReceiver;
|
||||
public DeclarationDescriptor getReceiver() {
|
||||
return receiver;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
+6
-6
@@ -12,21 +12,21 @@ import java.util.Set;
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class VariableDescriptorWithImplicitReceiver implements VariableDescriptor {
|
||||
public class VariableDescriptorBoundToReceiver implements VariableDescriptor {
|
||||
private VariableDescriptor variableDescriptor;
|
||||
private DeclarationDescriptor implicitReceiver;
|
||||
private DeclarationDescriptor receiver;
|
||||
|
||||
public VariableDescriptorWithImplicitReceiver(VariableDescriptor variableDescriptor, DeclarationDescriptor implicitReceiver) {
|
||||
public VariableDescriptorBoundToReceiver(VariableDescriptor variableDescriptor, DeclarationDescriptor receiver) {
|
||||
this.variableDescriptor = variableDescriptor;
|
||||
this.implicitReceiver = implicitReceiver;
|
||||
this.receiver = receiver;
|
||||
}
|
||||
|
||||
public VariableDescriptor getVariableDescriptor() {
|
||||
return variableDescriptor;
|
||||
}
|
||||
|
||||
public DeclarationDescriptor getImplicitReceiver() {
|
||||
return implicitReceiver;
|
||||
public DeclarationDescriptor getReceiver() {
|
||||
return receiver;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -8,6 +8,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.ScopeBoundToReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
@@ -77,12 +78,21 @@ public class ImportsResolver {
|
||||
descriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression) importedReference, scope);
|
||||
}
|
||||
if (importDirective.isAllUnder()) {
|
||||
if (firstPhase) {
|
||||
for (DeclarationDescriptor descriptor : descriptors) {
|
||||
for (DeclarationDescriptor descriptor : descriptors) {
|
||||
if (firstPhase) {
|
||||
if (descriptor instanceof NamespaceDescriptor) {
|
||||
namespaceScope.importScope(((NamespaceDescriptor) descriptor).getMemberScope());
|
||||
}
|
||||
}
|
||||
else if (descriptor instanceof VariableDescriptor) {
|
||||
JetType type = ((VariableDescriptor) descriptor).getOutType();
|
||||
if (type != null) {
|
||||
namespaceScope.importScope(ScopeBoundToReceiver.create(descriptor, type.getMemberScope()));
|
||||
}
|
||||
}
|
||||
else if (descriptor instanceof ClassDescriptor) {
|
||||
namespaceScope.importScope(ScopeBoundToReceiver.create(descriptor, ((ClassDescriptor) descriptor).getDefaultType().getMemberScope()));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -167,7 +177,7 @@ public class ImportsResolver {
|
||||
trace.report(NO_CLASS_OBJECT.on(classReference, classDescriptor));
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return addImplicitReceiver(lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope()), classDescriptor);
|
||||
return addBoundToReceiver(lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope()), classDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -176,19 +186,19 @@ public class ImportsResolver {
|
||||
|
||||
JetType variableType = variableDescriptor.getReturnType();
|
||||
if (variableType == null) return Collections.emptyList();
|
||||
return addImplicitReceiver(lookupDescriptorsForSimpleNameReference(memberReference, variableType.getMemberScope()), variableDescriptor);
|
||||
return addBoundToReceiver(lookupDescriptorsForSimpleNameReference(memberReference, variableType.getMemberScope()), variableDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Collection<DeclarationDescriptor> addImplicitReceiver(@NotNull Collection<DeclarationDescriptor> descriptors, @NotNull final DeclarationDescriptor implicitReceiver) {
|
||||
private static Collection<DeclarationDescriptor> addBoundToReceiver(@NotNull Collection<DeclarationDescriptor> descriptors, @NotNull final DeclarationDescriptor implicitReceiver) {
|
||||
return Collections2.transform(descriptors, new Function<DeclarationDescriptor, DeclarationDescriptor>() {
|
||||
@Override
|
||||
public DeclarationDescriptor apply(@Nullable DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
return new FunctionDescriptorWithImplicitReceiver((FunctionDescriptor) descriptor, implicitReceiver);
|
||||
return new FunctionDescriptorBoundToReceiver((FunctionDescriptor) descriptor, implicitReceiver);
|
||||
}
|
||||
if (descriptor instanceof VariableDescriptor) {
|
||||
return new VariableDescriptorWithImplicitReceiver((VariableDescriptor) descriptor, implicitReceiver);
|
||||
return new VariableDescriptorBoundToReceiver((VariableDescriptor) descriptor, implicitReceiver);
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
package org.jetbrains.jet.lang.resolve.scopes;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.util.CommonSuppliers;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class ScopeBoundToReceiver implements JetScope {
|
||||
private final DeclarationDescriptor receiver;
|
||||
private final JetScope scope;
|
||||
|
||||
private SetMultimap<String, VariableDescriptor> propertiesMap;
|
||||
private SetMultimap<String, FunctionDescriptor> functionsMap;
|
||||
private Map<DeclarationDescriptor, DeclarationDescriptor> descriptorsBoundToReceiver;
|
||||
|
||||
public static ScopeBoundToReceiver create(DeclarationDescriptor implicitReceiver, JetScope memberScope) {
|
||||
return new ScopeBoundToReceiver(implicitReceiver, memberScope);
|
||||
}
|
||||
|
||||
private ScopeBoundToReceiver(DeclarationDescriptor receiver, JetScope scope) {
|
||||
this.receiver = receiver;
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public DeclarationDescriptor getReceiver() {
|
||||
return receiver;
|
||||
}
|
||||
|
||||
private SetMultimap<String, VariableDescriptor> getPropertiesMap() {
|
||||
if (propertiesMap == null) {
|
||||
propertiesMap = CommonSuppliers.newLinkedHashSetHashSetMultimap();
|
||||
}
|
||||
return propertiesMap;
|
||||
}
|
||||
|
||||
private SetMultimap<String, FunctionDescriptor> getFunctionsMap() {
|
||||
if (functionsMap == null) {
|
||||
functionsMap = CommonSuppliers.newLinkedHashSetHashSetMultimap();
|
||||
}
|
||||
return functionsMap;
|
||||
}
|
||||
|
||||
private Map<DeclarationDescriptor, DeclarationDescriptor> getDescriptorsBoundToReceiver() {
|
||||
if (descriptorsBoundToReceiver == null) {
|
||||
descriptorsBoundToReceiver = Maps.newHashMap();
|
||||
}
|
||||
return descriptorsBoundToReceiver;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ClassifierDescriptor getClassifier(@NotNull String name) {
|
||||
return scope.getClassifier(name);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public NamespaceDescriptor getNamespace(@NotNull String name) {
|
||||
return scope.getNamespace(name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<VariableDescriptor> getProperties(@NotNull String name) {
|
||||
if (getPropertiesMap().containsKey(name)) {
|
||||
return getPropertiesMap().get(name);
|
||||
}
|
||||
return getMembersBoundToReceiver(name, getPropertiesMap(), scope.getProperties(name), new Function<VariableDescriptor, VariableDescriptor>() {
|
||||
@Override
|
||||
public VariableDescriptor apply(VariableDescriptor property) {
|
||||
return new VariableDescriptorBoundToReceiver(property, receiver);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public VariableDescriptor getLocalVariable(@NotNull String name) {
|
||||
return scope.getLocalVariable(name);
|
||||
}
|
||||
|
||||
private <D extends DeclarationDescriptor> Set<D> getMembersBoundToReceiver(String name, SetMultimap<String, D> cache, Set<D> oldMembers, Function<D, D> transformation) {
|
||||
for (D oldMember : oldMembers) {
|
||||
cache.put(name, transformation.apply(oldMember));
|
||||
}
|
||||
return cache.get(name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<FunctionDescriptor> getFunctions(@NotNull String name) {
|
||||
if (getFunctionsMap().containsKey(name)) {
|
||||
return getFunctionsMap().get(name);
|
||||
}
|
||||
return getMembersBoundToReceiver(name, getFunctionsMap(), scope.getFunctions(name), new Function<FunctionDescriptor, FunctionDescriptor>() {
|
||||
@Override
|
||||
public FunctionDescriptor apply(FunctionDescriptor function) {
|
||||
return new FunctionDescriptorBoundToReceiver(function, receiver);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DeclarationDescriptor getContainingDeclaration() {
|
||||
return scope.getContainingDeclaration();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getDeclarationsByLabel(String labelName) {
|
||||
return scope.getDeclarationsByLabel(labelName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName) {
|
||||
return scope.getPropertyByFieldReference(fieldName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getAllDescriptors() {
|
||||
Collection<DeclarationDescriptor> result = Lists.newArrayList();
|
||||
Collection<DeclarationDescriptor> allDescriptors = scope.getAllDescriptors();
|
||||
for (DeclarationDescriptor descriptor : allDescriptors) {
|
||||
if (getDescriptorsBoundToReceiver().containsKey(descriptor)) {
|
||||
result.add(getDescriptorsBoundToReceiver().get(descriptor));
|
||||
continue;
|
||||
}
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
getFunctions(descriptor.getName());
|
||||
}
|
||||
else if (descriptor instanceof VariableDescriptor) {
|
||||
getProperties(descriptor.getName());
|
||||
}
|
||||
else {
|
||||
result.add(descriptor);
|
||||
continue;
|
||||
}
|
||||
if (getDescriptorsBoundToReceiver().containsKey(descriptor)) {
|
||||
result.add(getDescriptorsBoundToReceiver().get(descriptor));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getImplicitReceiver() {
|
||||
return ReceiverDescriptor.NO_RECEIVER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getImplicitReceiversHierarchy(@NotNull List<ReceiverDescriptor> result) {
|
||||
}
|
||||
}
|
||||
@@ -56,4 +56,19 @@ class E() {
|
||||
|
||||
class F() {
|
||||
fun f() {}
|
||||
}
|
||||
|
||||
//FILE:c.kt
|
||||
package c
|
||||
|
||||
import C.*
|
||||
|
||||
object C {
|
||||
fun a() {
|
||||
}
|
||||
val b = 3
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
if (b == 3) a()
|
||||
}
|
||||
Reference in New Issue
Block a user