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
|
* @author svtk
|
||||||
*/
|
*/
|
||||||
public class FunctionDescriptorWithImplicitReceiver implements FunctionDescriptor {
|
public class FunctionDescriptorBoundToReceiver implements FunctionDescriptor {
|
||||||
|
|
||||||
private FunctionDescriptor 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.functionDescriptor = functionDescriptor;
|
||||||
this.implicitReceiver = implicitReceiver;
|
this.receiver = receiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FunctionDescriptor getFunctionDescriptor() {
|
public FunctionDescriptor getFunctionDescriptor() {
|
||||||
return functionDescriptor;
|
return functionDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeclarationDescriptor getImplicitReceiver() {
|
public DeclarationDescriptor getReceiver() {
|
||||||
return implicitReceiver;
|
return receiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
+6
-6
@@ -12,21 +12,21 @@ import java.util.Set;
|
|||||||
/**
|
/**
|
||||||
* @author svtk
|
* @author svtk
|
||||||
*/
|
*/
|
||||||
public class VariableDescriptorWithImplicitReceiver implements VariableDescriptor {
|
public class VariableDescriptorBoundToReceiver implements VariableDescriptor {
|
||||||
private VariableDescriptor 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.variableDescriptor = variableDescriptor;
|
||||||
this.implicitReceiver = implicitReceiver;
|
this.receiver = receiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VariableDescriptor getVariableDescriptor() {
|
public VariableDescriptor getVariableDescriptor() {
|
||||||
return variableDescriptor;
|
return variableDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeclarationDescriptor getImplicitReceiver() {
|
public DeclarationDescriptor getReceiver() {
|
||||||
return implicitReceiver;
|
return receiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -8,6 +8,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
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.resolve.scopes.WritableScope;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
@@ -77,12 +78,21 @@ public class ImportsResolver {
|
|||||||
descriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression) importedReference, scope);
|
descriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression) importedReference, scope);
|
||||||
}
|
}
|
||||||
if (importDirective.isAllUnder()) {
|
if (importDirective.isAllUnder()) {
|
||||||
if (firstPhase) {
|
for (DeclarationDescriptor descriptor : descriptors) {
|
||||||
for (DeclarationDescriptor descriptor : descriptors) {
|
if (firstPhase) {
|
||||||
if (descriptor instanceof NamespaceDescriptor) {
|
if (descriptor instanceof NamespaceDescriptor) {
|
||||||
namespaceScope.importScope(((NamespaceDescriptor) descriptor).getMemberScope());
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -167,7 +177,7 @@ public class ImportsResolver {
|
|||||||
trace.report(NO_CLASS_OBJECT.on(classReference, classDescriptor));
|
trace.report(NO_CLASS_OBJECT.on(classReference, classDescriptor));
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
return addImplicitReceiver(lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope()), classDescriptor);
|
return addBoundToReceiver(lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope()), classDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -176,19 +186,19 @@ public class ImportsResolver {
|
|||||||
|
|
||||||
JetType variableType = variableDescriptor.getReturnType();
|
JetType variableType = variableDescriptor.getReturnType();
|
||||||
if (variableType == null) return Collections.emptyList();
|
if (variableType == null) return Collections.emptyList();
|
||||||
return addImplicitReceiver(lookupDescriptorsForSimpleNameReference(memberReference, variableType.getMemberScope()), variableDescriptor);
|
return addBoundToReceiver(lookupDescriptorsForSimpleNameReference(memberReference, variableType.getMemberScope()), variableDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@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>() {
|
return Collections2.transform(descriptors, new Function<DeclarationDescriptor, DeclarationDescriptor>() {
|
||||||
@Override
|
@Override
|
||||||
public DeclarationDescriptor apply(@Nullable DeclarationDescriptor descriptor) {
|
public DeclarationDescriptor apply(@Nullable DeclarationDescriptor descriptor) {
|
||||||
if (descriptor instanceof FunctionDescriptor) {
|
if (descriptor instanceof FunctionDescriptor) {
|
||||||
return new FunctionDescriptorWithImplicitReceiver((FunctionDescriptor) descriptor, implicitReceiver);
|
return new FunctionDescriptorBoundToReceiver((FunctionDescriptor) descriptor, implicitReceiver);
|
||||||
}
|
}
|
||||||
if (descriptor instanceof VariableDescriptor) {
|
if (descriptor instanceof VariableDescriptor) {
|
||||||
return new VariableDescriptorWithImplicitReceiver((VariableDescriptor) descriptor, implicitReceiver);
|
return new VariableDescriptorBoundToReceiver((VariableDescriptor) descriptor, implicitReceiver);
|
||||||
}
|
}
|
||||||
return descriptor;
|
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() {
|
class F() {
|
||||||
fun 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