import of members without additional bound to receiver descriptors

This commit is contained in:
svtk
2012-01-11 18:37:10 +04:00
parent cb2219e72d
commit 9902200e5e
17 changed files with 102 additions and 676 deletions
@@ -228,6 +228,7 @@ public abstract class CodegenContext {
pd.getModality(), pd.getModality(),
pd.getVisibility(), pd.getVisibility(),
pd.isVar(), pd.isVar(),
pd.isObjectDeclaration(),
pd.getName() + "$bridge$" + accessors.size() pd.getName() + "$bridge$" + accessors.size()
); );
JetType receiverType = pd.getReceiverParameter().exists() ? pd.getReceiverParameter().getType() : null; JetType receiverType = pd.getReceiverParameter().exists() ? pd.getReceiverParameter().getType() : null;
@@ -975,6 +975,7 @@ public class JavaDescriptorResolver {
isFinal && !staticMembers ? Modality.FINAL : Modality.OPEN, // TODO: abstract isFinal && !staticMembers ? Modality.FINAL : Modality.OPEN, // TODO: abstract
resolveVisibilityFromPsiModifiers(anyMember), resolveVisibilityFromPsiModifiers(anyMember),
isVar, isVar,
false,
null, null,
DescriptorUtils.getExpectedThisObjectIfNeeded(owner), DescriptorUtils.getExpectedThisObjectIfNeeded(owner),
propertyName, propertyName,
@@ -1,162 +0,0 @@
package org.jetbrains.jet.lang.descriptors;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.ImportsResolver;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* @author svtk
*/
public class ClassDescriptorBoundToReceiver implements ClassDescriptor {
private ClassDescriptor classDescriptor;
private DeclarationDescriptor receiver;
public ClassDescriptorBoundToReceiver(ClassDescriptor classDescriptor, DeclarationDescriptor receiver) {
this.classDescriptor = classDescriptor;
this.receiver = receiver;
}
public ClassDescriptor getClassDescriptor() {
return classDescriptor;
}
public DeclarationDescriptor getReceiver() {
return receiver;
}
@NotNull
@Override
public JetScope getMemberScope(List<TypeProjection> typeArguments) {
return classDescriptor.getMemberScope(typeArguments);
}
@NotNull
@Override
public JetType getSuperclassType() {
return classDescriptor.getSuperclassType();
}
@NotNull
@Override
public Set<ConstructorDescriptor> getConstructors() {
return (Set)Sets.newHashSet(ImportsResolver.ImportResolver.addBoundToReceiver((Collection)classDescriptor.getConstructors(), receiver));
}
@Override
public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
return classDescriptor.getUnsubstitutedPrimaryConstructor();
}
@Override
public boolean hasConstructors() {
return classDescriptor.hasConstructors();
}
@NotNull
@Override
public DeclarationDescriptor getOriginal() {
return classDescriptor.getOriginal();
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
return classDescriptor.getContainingDeclaration();
}
@NotNull
@Override
public TypeConstructor getTypeConstructor() {
return classDescriptor.getTypeConstructor();
}
@NotNull
@Override
public JetType getDefaultType() {
return classDescriptor.getDefaultType();
}
@NotNull
@Override
public ClassDescriptor substitute(TypeSubstitutor substitutor) {
return classDescriptor.substitute(substitutor);
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return classDescriptor.accept(visitor, data);
}
@Override
public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
classDescriptor.acceptVoid(visitor);
}
@Override
public JetType getClassObjectType() {
return classDescriptor.getClassObjectType();
}
@Override
public boolean isClassObjectAValue() {
return classDescriptor.isClassObjectAValue();
}
@NotNull
@Override
public ClassKind getKind() {
return classDescriptor.getKind();
}
@NotNull
@Override
public Modality getModality() {
return classDescriptor.getModality();
}
@NotNull
@Override
public Visibility getVisibility() {
return classDescriptor.getVisibility();
}
@NotNull
@Override
public ReceiverDescriptor getImplicitReceiver() {
return ReceiverDescriptor.NO_RECEIVER;
}
@Override
public List<AnnotationDescriptor> getAnnotations() {
return classDescriptor.getAnnotations();
}
@NotNull
@Override
public String getName() {
return classDescriptor.getName();
}
@Override
public ClassDescriptor getInnerClass(String name) {
return classDescriptor.getInnerClass(name);
}
@NotNull
@Override
public Collection<ClassDescriptor> getInnerClasses() {
return classDescriptor.getInnerClasses();
}
}
@@ -1,123 +0,0 @@
package org.jetbrains.jet.lang.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import java.util.List;
import java.util.Set;
/**
* @author svtk
*/
public class FunctionDescriptorBoundToReceiver implements FunctionDescriptor {
private FunctionDescriptor functionDescriptor;
private DeclarationDescriptor receiver;
public FunctionDescriptorBoundToReceiver(@NotNull FunctionDescriptor functionDescriptor, @NotNull DeclarationDescriptor receiver) {
this.functionDescriptor = functionDescriptor;
this.receiver = receiver;
}
public FunctionDescriptor getFunctionDescriptor() {
return functionDescriptor;
}
public DeclarationDescriptor getReceiver() {
return receiver;
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
return functionDescriptor.getContainingDeclaration();
}
@NotNull
@Override
public FunctionDescriptor getOriginal() {
return functionDescriptor.getOriginal();
}
@Override
public FunctionDescriptor substitute(TypeSubstitutor substitutor) {
return functionDescriptor.substitute(substitutor);
}
@NotNull
@Override
public Set<? extends FunctionDescriptor> getOverriddenDescriptors() {
return functionDescriptor.getOverriddenDescriptors();
}
@NotNull
@Override
public FunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) {
return functionDescriptor.copy(newOwner, makeNonAbstract);
}
@NotNull
@Override
public ReceiverDescriptor getReceiverParameter() {
return ReceiverDescriptor.NO_RECEIVER;
}
@NotNull
@Override
public ReceiverDescriptor getExpectedThisObject() {
return ReceiverDescriptor.NO_RECEIVER;
}
@NotNull
@Override
public List<TypeParameterDescriptor> getTypeParameters() {
return functionDescriptor.getTypeParameters();
}
@Override
public JetType getReturnType() {
return functionDescriptor.getReturnType();
}
@NotNull
@Override
public List<ValueParameterDescriptor> getValueParameters() {
return functionDescriptor.getValueParameters();
}
@NotNull
@Override
public Modality getModality() {
return functionDescriptor.getModality();
}
@NotNull
@Override
public Visibility getVisibility() {
return functionDescriptor.getVisibility();
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return functionDescriptor.accept(visitor, data);
}
@Override
public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
functionDescriptor.acceptVoid(visitor);
}
@Override
public List<AnnotationDescriptor> getAnnotations() {
return functionDescriptor.getAnnotations();
}
@NotNull
@Override
public String getName() {
return functionDescriptor.getName();
}
}
@@ -38,4 +38,9 @@ public class LocalVariableDescriptor extends VariableDescriptorImpl {
public boolean isVar() { public boolean isVar() {
return isVar; return isVar;
} }
@Override
public boolean isObjectDeclaration() {
return false;
}
} }
@@ -28,6 +28,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
private final Modality modality; private final Modality modality;
private final Visibility visibility; private final Visibility visibility;
private final boolean isVar; private final boolean isVar;
private final boolean isObject;
private final Set<PropertyDescriptor> overriddenProperties = Sets.newLinkedHashSet(); private final Set<PropertyDescriptor> overriddenProperties = Sets.newLinkedHashSet();
private final PropertyDescriptor original; private final PropertyDescriptor original;
@@ -44,9 +45,11 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
@NotNull Modality modality, @NotNull Modality modality,
@NotNull Visibility visibility, @NotNull Visibility visibility,
boolean isVar, boolean isVar,
boolean isObject,
@NotNull String name) { @NotNull String name) {
super(containingDeclaration, annotations, name); super(containingDeclaration, annotations, name);
this.isVar = isVar; this.isVar = isVar;
this.isObject = isObject;
this.modality = modality; this.modality = modality;
this.visibility = visibility; this.visibility = visibility;
this.original = original == null ? this : original.getOriginal(); this.original = original == null ? this : original.getOriginal();
@@ -58,8 +61,9 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
@NotNull Modality modality, @NotNull Modality modality,
@NotNull Visibility visibility, @NotNull Visibility visibility,
boolean isVar, boolean isVar,
boolean isObject,
@NotNull String name) { @NotNull String name) {
this(null, containingDeclaration, annotations, modality, visibility, isVar, name); this(null, containingDeclaration, annotations, modality, visibility, isVar, isObject, name);
} }
public PropertyDescriptor( public PropertyDescriptor(
@@ -68,12 +72,13 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
@NotNull Modality modality, @NotNull Modality modality,
@NotNull Visibility visibility, @NotNull Visibility visibility,
boolean isVar, boolean isVar,
boolean isObject,
@Nullable JetType receiverType, @Nullable JetType receiverType,
@NotNull ReceiverDescriptor expectedThisObject, @NotNull ReceiverDescriptor expectedThisObject,
@NotNull String name, @NotNull String name,
@NotNull JetType outType @NotNull JetType outType
) { ) {
this(containingDeclaration, annotations, modality, visibility, isVar, name); this(containingDeclaration, annotations, modality, visibility, isVar, isObject, name);
setType(outType, Collections.<TypeParameterDescriptor>emptyList(), expectedThisObject, receiverType); setType(outType, Collections.<TypeParameterDescriptor>emptyList(), expectedThisObject, receiverType);
} }
@@ -124,6 +129,11 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
return isVar; return isVar;
} }
@Override
public boolean isObjectDeclaration() {
return isObject;
}
@NotNull @NotNull
@Override @Override
public Modality getModality() { public Modality getModality() {
@@ -151,7 +161,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
if (originalSubstitutor.isEmpty()) { if (originalSubstitutor.isEmpty()) {
return this; return this;
} }
PropertyDescriptor substitutedDescriptor = new PropertyDescriptor(this, getContainingDeclaration(), getAnnotations(), getModality(), getVisibility(), isVar(), getName()); PropertyDescriptor substitutedDescriptor = new PropertyDescriptor(this, getContainingDeclaration(), getAnnotations(), getModality(), getVisibility(), isVar(), isObjectDeclaration(), getName());
List<TypeParameterDescriptor> substitutedTypeParameters = Lists.newArrayList(); List<TypeParameterDescriptor> substitutedTypeParameters = Lists.newArrayList();
TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(getTypeParameters(), originalSubstitutor, substitutedDescriptor, substitutedTypeParameters); TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(getTypeParameters(), originalSubstitutor, substitutedDescriptor, substitutedTypeParameters);
@@ -212,7 +222,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
PropertyDescriptor propertyDescriptor = new PropertyDescriptor( PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
newOwner, newOwner,
Lists.newArrayList(getAnnotations()), Lists.newArrayList(getAnnotations()),
DescriptorUtils.convertModality(modality, makeNonAbstract), visibility, isVar, DescriptorUtils.convertModality(modality, makeNonAbstract), visibility, isVar, isObject,
getName()); getName());
propertyDescriptor.setType(getOutType(), DescriptorUtils.copyTypeParameters(propertyDescriptor, getTypeParameters()), expectedThisObject, receiver.exists() ? receiver.getType() : null); propertyDescriptor.setType(getOutType(), DescriptorUtils.copyTypeParameters(propertyDescriptor, getTypeParameters()), expectedThisObject, receiver.exists() ? receiver.getType() : null);
@@ -99,6 +99,11 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme
return isVar; return isVar;
} }
@Override
public boolean isObjectDeclaration() {
return false;
}
@NotNull @NotNull
@Override @Override
public ValueParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner) { public ValueParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner) {
@@ -21,4 +21,6 @@ public interface VariableDescriptor extends CallableDescriptor {
VariableDescriptor substitute(TypeSubstitutor substitutor); VariableDescriptor substitute(TypeSubstitutor substitutor);
boolean isVar(); boolean isVar();
boolean isObjectDeclaration();
} }
@@ -1,114 +0,0 @@
package org.jetbrains.jet.lang.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import java.util.List;
import java.util.Set;
/**
* @author svtk
*/
public class VariableDescriptorBoundToReceiver implements VariableDescriptor {
private VariableDescriptor variableDescriptor;
private DeclarationDescriptor receiver;
public VariableDescriptorBoundToReceiver(VariableDescriptor variableDescriptor, DeclarationDescriptor receiver) {
this.variableDescriptor = variableDescriptor;
this.receiver = receiver;
}
public VariableDescriptor getVariableDescriptor() {
return variableDescriptor;
}
public DeclarationDescriptor getReceiver() {
return receiver;
}
@Override
public JetType getOutType() {
return variableDescriptor.getOutType();
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
return variableDescriptor.getContainingDeclaration();
}
@NotNull
@Override
public ReceiverDescriptor getReceiverParameter() {
return ReceiverDescriptor.NO_RECEIVER;
}
@NotNull
@Override
public ReceiverDescriptor getExpectedThisObject() {
return ReceiverDescriptor.NO_RECEIVER;
}
@NotNull
@Override
public List<TypeParameterDescriptor> getTypeParameters() {
return variableDescriptor.getTypeParameters();
}
@Override
public JetType getReturnType() {
return variableDescriptor.getReturnType();
}
@NotNull
@Override
public CallableDescriptor getOriginal() {
return variableDescriptor.getOriginal();
}
@Override
public VariableDescriptor substitute(TypeSubstitutor substitutor) {
return variableDescriptor.substitute(substitutor);
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return variableDescriptor.accept(visitor, data);
}
@Override
public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
variableDescriptor.acceptVoid(visitor);
}
@NotNull
@Override
public List<ValueParameterDescriptor> getValueParameters() {
return variableDescriptor.getValueParameters();
}
@NotNull
@Override
public Set<? extends CallableDescriptor> getOverriddenDescriptors() {
return variableDescriptor.getOverriddenDescriptors();
}
@Override
public boolean isVar() {
return variableDescriptor.isVar();
}
@Override
public List<AnnotationDescriptor> getAnnotations() {
return variableDescriptor.getAnnotations();
}
@NotNull
@Override
public String getName() {
return variableDescriptor.getName();
}
}
@@ -476,6 +476,7 @@ public class DescriptorResolver {
Modality.FINAL, Modality.FINAL,
resolveVisibilityFromModifiers(objectDeclaration.getModifierList()), resolveVisibilityFromModifiers(objectDeclaration.getModifierList()),
false, false,
true,
JetPsiUtil.safeName(objectDeclaration.getName()) JetPsiUtil.safeName(objectDeclaration.getName())
); );
@@ -518,6 +519,7 @@ public class DescriptorResolver {
resolveModalityFromModifiers(property.getModifierList(), defaultModality), resolveModalityFromModifiers(property.getModifierList(), defaultModality),
resolveVisibilityFromModifiers(property.getModifierList()), resolveVisibilityFromModifiers(property.getModifierList()),
isVar, isVar,
false,
JetPsiUtil.safeName(property.getName()) JetPsiUtil.safeName(property.getName())
); );
@@ -839,6 +841,7 @@ public class DescriptorResolver {
resolveModalityFromModifiers(parameter.getModifierList(), Modality.FINAL), resolveModalityFromModifiers(parameter.getModifierList(), Modality.FINAL),
resolveVisibilityFromModifiers(parameter.getModifierList()), resolveVisibilityFromModifiers(parameter.getModifierList()),
isMutable, isMutable,
false,
name == null ? "<no name>" : name name == null ? "<no name>" : name
); );
propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(), DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor), ReceiverDescriptor.NO_RECEIVER); propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(), DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor), ReceiverDescriptor.NO_RECEIVER);
@@ -215,34 +215,4 @@ public class DescriptorUtils {
} }
return null; return null;
} }
@NotNull
public static Function<DeclarationDescriptor, DeclarationDescriptor> getAddBoundToReceiverFunction(@NotNull final DeclarationDescriptor receiver) {
return new Function<DeclarationDescriptor, DeclarationDescriptor>() {
@Override
public DeclarationDescriptor apply(@Nullable DeclarationDescriptor descriptor) {
if (descriptor instanceof FunctionDescriptor) {
return new FunctionDescriptorBoundToReceiver((FunctionDescriptor) descriptor, receiver);
}
if (descriptor instanceof VariableDescriptor) {
return new VariableDescriptorBoundToReceiver((VariableDescriptor) descriptor, receiver);
}
if (descriptor instanceof ClassDescriptor) {
return new ClassDescriptorBoundToReceiver((ClassDescriptor) descriptor, receiver);
}
return descriptor;
}
};
}
//todo
public static boolean isObjectDescriptor(@NotNull VariableDescriptor descriptor, BindingTrace bindingTrace) {
PsiElement element = bindingTrace.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
return element instanceof JetObjectDeclarationName;
}
public static boolean isObjectDescriptor(@NotNull ClassDescriptor descriptor, BindingTrace bindingTrace) {
PsiElement element = bindingTrace.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
return element instanceof JetObjectDeclaration;
}
} }
@@ -1,13 +1,11 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
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.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;
@@ -67,7 +65,7 @@ public class ImportsResolver {
} }
JetExpression importedReference = importDirective.getImportedReference(); JetExpression importedReference = importDirective.getImportedReference();
if (importedReference == null) return; if (importedReference == null) return;
Collection<DeclarationDescriptor> descriptors; Collection<? extends DeclarationDescriptor> descriptors;
if (importedReference instanceof JetQualifiedExpression) { if (importedReference instanceof JetQualifiedExpression) {
descriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression) importedReference, descriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression) importedReference,
namespaceScope, !importDirective.isAllUnder()); namespaceScope, !importDirective.isAllUnder());
@@ -91,8 +89,8 @@ public class ImportsResolver {
if (descriptor instanceof NamespaceDescriptor) { if (descriptor instanceof NamespaceDescriptor) {
namespaceScope.importScope(((NamespaceDescriptor) descriptor).getMemberScope()); namespaceScope.importScope(((NamespaceDescriptor) descriptor).getMemberScope());
} }
if (descriptor instanceof ClassDescriptor && DescriptorUtils.isObjectDescriptor((ClassDescriptor) descriptor, trace)) { if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() == ClassKind.OBJECT) {
Collection<DeclarationDescriptor> innerClasses = getInnerClasses((ClassDescriptor) descriptor, null); Collection<? extends DeclarationDescriptor> innerClasses = getInnerClasses((ClassDescriptor) descriptor, null);
for (DeclarationDescriptor innerClass : innerClasses) { for (DeclarationDescriptor innerClass : innerClasses) {
namespaceScope.importClassifierAlias(innerClass.getName(), (ClassifierDescriptor) innerClass); namespaceScope.importClassifierAlias(innerClass.getName(), (ClassifierDescriptor) innerClass);
} }
@@ -101,12 +99,12 @@ public class ImportsResolver {
} }
if (descriptor instanceof VariableDescriptor) { if (descriptor instanceof VariableDescriptor) {
JetType type = ((VariableDescriptor) descriptor).getOutType(); JetType type = ((VariableDescriptor) descriptor).getOutType();
namespaceScope.importScope(ScopeBoundToReceiver.create(descriptor, type.getMemberScope())); namespaceScope.importScope(type.getMemberScope());
} }
else if (descriptor instanceof ClassDescriptor) { else if (descriptor instanceof ClassDescriptor) {
JetType classObjectType = ((ClassDescriptor) descriptor).getClassObjectType(); JetType classObjectType = ((ClassDescriptor) descriptor).getClassObjectType();
if (classObjectType != null) { if (classObjectType != null) {
namespaceScope.importScope(ScopeBoundToReceiver.create(descriptor, classObjectType.getMemberScope())); namespaceScope.importScope(classObjectType.getMemberScope());
} }
} }
} }
@@ -151,11 +149,11 @@ public class ImportsResolver {
} }
@NotNull @NotNull
private Collection<DeclarationDescriptor> lookupDescriptorsForQualifiedExpression( private Collection<? extends DeclarationDescriptor> lookupDescriptorsForQualifiedExpression(
@NotNull JetQualifiedExpression importedReference, @NotNull JetScope outerScope, boolean isForLastPart) { @NotNull JetQualifiedExpression importedReference, @NotNull JetScope outerScope, boolean isForLastPart) {
JetExpression receiverExpression = importedReference.getReceiverExpression(); JetExpression receiverExpression = importedReference.getReceiverExpression();
Collection<DeclarationDescriptor> declarationDescriptors; Collection<? extends DeclarationDescriptor> declarationDescriptors;
if (receiverExpression instanceof JetQualifiedExpression) { if (receiverExpression instanceof JetQualifiedExpression) {
declarationDescriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression) receiverExpression, outerScope, false); declarationDescriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression) receiverExpression, outerScope, false);
} }
@@ -171,7 +169,7 @@ public class ImportsResolver {
if (lastReference == null || !canImportMembersFrom(declarationDescriptors, lastReference)) { if (lastReference == null || !canImportMembersFrom(declarationDescriptors, lastReference)) {
return Collections.emptyList(); return Collections.emptyList();
} }
Collection<DeclarationDescriptor> result; Collection<? extends DeclarationDescriptor> result;
for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) { for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) {
if (declarationDescriptor instanceof NamespaceDescriptor) { if (declarationDescriptor instanceof NamespaceDescriptor) {
result = lookupDescriptorsForSimpleNameReference(selector, ((NamespaceDescriptor) declarationDescriptor).getMemberScope(), isForLastPart); result = lookupDescriptorsForSimpleNameReference(selector, ((NamespaceDescriptor) declarationDescriptor).getMemberScope(), isForLastPart);
@@ -190,7 +188,7 @@ public class ImportsResolver {
return Collections.emptyList(); return Collections.emptyList();
} }
private boolean canImportMembersFrom(@NotNull Collection<DeclarationDescriptor> descriptors, @NotNull JetSimpleNameExpression reference) { private boolean canImportMembersFrom(@NotNull Collection<? extends DeclarationDescriptor> descriptors, @NotNull JetSimpleNameExpression reference) {
if (firstPhase) return true; if (firstPhase) return true;
if (descriptors.size() == 1) { if (descriptors.size() == 1) {
return canImportMembersFrom(descriptors.iterator().next(), reference, trace); return canImportMembersFrom(descriptors.iterator().next(), reference, trace);
@@ -222,7 +220,7 @@ public class ImportsResolver {
} }
return true; return true;
} }
if (descriptor instanceof VariableDescriptor && DescriptorUtils.isObjectDescriptor((VariableDescriptor) descriptor, trace)) { if (descriptor instanceof VariableDescriptor && ((VariableDescriptor) descriptor).isObjectDeclaration()) {
return true; return true;
} }
trace.report(CANNOT_IMPORT_FROM_ELEMENT.on(reference, descriptor)); trace.report(CANNOT_IMPORT_FROM_ELEMENT.on(reference, descriptor));
@@ -230,21 +228,20 @@ public class ImportsResolver {
} }
@NotNull @NotNull
private Collection<DeclarationDescriptor> lookupObjectMembers(@NotNull JetSimpleNameExpression memberReference, private Collection<? extends DeclarationDescriptor> lookupObjectMembers(@NotNull JetSimpleNameExpression memberReference,
@NotNull ClassDescriptor classDescriptor) { @NotNull ClassDescriptor classDescriptor) {
if (DescriptorUtils.isObjectDescriptor(classDescriptor, trace)) { if (classDescriptor.getKind() == ClassKind.OBJECT) {
return getInnerClasses(classDescriptor, memberReference); return getInnerClasses(classDescriptor, memberReference);
} }
if (firstPhase) return Collections.emptyList(); if (firstPhase) return Collections.emptyList();
JetType classObjectType = classDescriptor.getClassObjectType(); JetType classObjectType = classDescriptor.getClassObjectType();
assert classObjectType != null; assert classObjectType != null;
Collection<DeclarationDescriptor> members = lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope(), true); return lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope(), true);
return addBoundToReceiver(members, classDescriptor);
} }
@NotNull @NotNull
private Collection<DeclarationDescriptor> getInnerClasses(@NotNull ClassDescriptor classDescriptor, @Nullable JetSimpleNameExpression memberReference) { private Collection<? extends DeclarationDescriptor> getInnerClasses(@NotNull ClassDescriptor classDescriptor, @Nullable JetSimpleNameExpression memberReference) {
if (!DescriptorUtils.isObjectDescriptor(classDescriptor, trace)) return Collections.emptyList(); if (classDescriptor.getKind() != ClassKind.OBJECT) return Collections.emptyList();
Collection<? extends DeclarationDescriptor> descriptors; Collection<? extends DeclarationDescriptor> descriptors;
if (memberReference != null) { if (memberReference != null) {
ClassDescriptor innerClass = classDescriptor.getInnerClass(memberReference.getReferencedName()); ClassDescriptor innerClass = classDescriptor.getInnerClass(memberReference.getReferencedName());
@@ -255,7 +252,7 @@ public class ImportsResolver {
else { else {
descriptors = classDescriptor.getInnerClasses(); descriptors = classDescriptor.getInnerClasses();
} }
return addBoundToReceiver(descriptors, classDescriptor); return descriptors;
} }
private Collection<DeclarationDescriptor> lookupVariableMembers(@NotNull JetSimpleNameExpression memberReference, @NotNull VariableDescriptor variableDescriptor) { private Collection<DeclarationDescriptor> lookupVariableMembers(@NotNull JetSimpleNameExpression memberReference, @NotNull VariableDescriptor variableDescriptor) {
@@ -263,14 +260,7 @@ public class ImportsResolver {
JetType variableType = variableDescriptor.getReturnType(); JetType variableType = variableDescriptor.getReturnType();
if (variableType == null) return Collections.emptyList(); if (variableType == null) return Collections.emptyList();
Collection<DeclarationDescriptor> members = lookupDescriptorsForSimpleNameReference(memberReference, variableType.getMemberScope(), true); return lookupDescriptorsForSimpleNameReference(memberReference, variableType.getMemberScope(), true);
return addBoundToReceiver(members, variableDescriptor);
}
@NotNull
public static Collection<DeclarationDescriptor> addBoundToReceiver(@NotNull Collection<? extends DeclarationDescriptor> descriptors,
@NotNull final DeclarationDescriptor receiver) {
return Collections2.transform(descriptors, DescriptorUtils.getAddBoundToReceiverFunction(receiver));
} }
@NotNull @NotNull
@@ -327,22 +317,21 @@ public class ImportsResolver {
@NotNull JetSimpleNameExpression referenceExpression, @NotNull JetSimpleNameExpression referenceExpression,
@NotNull JetScope resolutionScope, @NotNull JetScope resolutionScope,
boolean isLastPart) { boolean isLastPart) {
if (firstPhase) return;
if (!firstPhase) { if (descriptors.size() == 1 && !(isLastPart && descriptors.iterator().next() instanceof NamespaceDescriptor)) {
if (descriptors.size() == 1 && !(isLastPart && descriptors.iterator().next() instanceof NamespaceDescriptor)) { trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptors.iterator().next());
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptors.iterator().next()); }
} else if (descriptors.size() > 1) {
else if (descriptors.size() > 1) { trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression, descriptors);
trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression, descriptors); }
} else {
else { trace.report(UNRESOLVED_REFERENCE.on(referenceExpression));
trace.report(UNRESOLVED_REFERENCE.on(referenceExpression)); }
}
// If it's not an ambiguous case - store resolution scope // If it's not an ambiguous case - store resolution scope
if (descriptors.size() <= 1) { if (descriptors.size() <= 1) {
trace.record(BindingContext.RESOLUTION_SCOPE, referenceExpression, resolutionScope); trace.record(BindingContext.RESOLUTION_SCOPE, referenceExpression, resolutionScope);
}
} }
} }
} }
@@ -3,8 +3,7 @@ package org.jetbrains.jet.lang.resolve.calls;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
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.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.Call; import org.jetbrains.jet.lang.psi.Call;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetSuperExpression; import org.jetbrains.jet.lang.psi.JetSuperExpression;
@@ -14,6 +13,7 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastService;
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastServiceImpl; import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastServiceImpl;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
@@ -27,8 +27,8 @@ import java.util.List;
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER; import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
/** /**
* @author abreslav * @author abreslav
*/ */
/*package*/ abstract class TaskPrioritizer<D extends CallableDescriptor> { /*package*/ abstract class TaskPrioritizer<D extends CallableDescriptor> {
public static <D extends CallableDescriptor> void splitLexicallyLocalDescriptors( public static <D extends CallableDescriptor> void splitLexicallyLocalDescriptors(
@@ -155,14 +155,28 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
public static <D extends CallableDescriptor> Collection<ResolvedCallImpl<D>> convertWithImpliedThis(JetScope scope, Iterable<ReceiverDescriptor> receiverParameters, Collection<? extends D> descriptors) { public static <D extends CallableDescriptor> Collection<ResolvedCallImpl<D>> convertWithImpliedThis(JetScope scope, Iterable<ReceiverDescriptor> receiverParameters, Collection<? extends D> descriptors) {
Collection<ResolvedCallImpl<D>> result = Lists.newArrayList(); Collection<ResolvedCallImpl<D>> result = Lists.newArrayList();
for (ReceiverDescriptor receiverParameter : receiverParameters) { for (ReceiverDescriptor receiverParameter : receiverParameters) {
for (D extension : descriptors) { for (D descriptor : descriptors) {
ResolvedCallImpl<D> resolvedCall = ResolvedCallImpl.create(extension); ResolvedCallImpl<D> resolvedCall = ResolvedCallImpl.create(descriptor);
resolvedCall.setReceiverArgument(receiverParameter); resolvedCall.setReceiverArgument(receiverParameter);
if (setImpliedThis(scope, resolvedCall)) { if (setImpliedThis(scope, resolvedCall)) {
result.add(resolvedCall); result.add(resolvedCall);
} }
} }
} }
for (D descriptor : descriptors) {
if (descriptor.getExpectedThisObject().exists()) {
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (descriptor instanceof ConstructorDescriptor) {
assert containingDeclaration != null;
containingDeclaration = containingDeclaration.getContainingDeclaration();
}
if (containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.OBJECT) {
ResolvedCallImpl<D> resolvedCall = ResolvedCallImpl.create(descriptor);
resolvedCall.setThisObject(new ClassReceiver((ClassDescriptor) containingDeclaration));
result.add(resolvedCall);
}
}
}
return result; return result;
} }
@@ -181,7 +195,7 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
return false; return false;
} }
private void addTask(@NotNull List<ResolutionTask<D>> result, @NotNull Call call, @NotNull Collection<ResolvedCallImpl<D>> candidates, @NotNull DataFlowInfo dataFlowInfo) { private void addTask(@NotNull List<ResolutionTask<D>> result, @NotNull Call call, @NotNull Collection<ResolvedCallImpl<D>> candidates, @NotNull DataFlowInfo dataFlowInfo) {
if (candidates.isEmpty()) return; if (candidates.isEmpty()) return;
result.add(new ResolutionTask<D>(candidates, call, dataFlowInfo)); result.add(new ResolutionTask<D>(candidates, call, dataFlowInfo));
} }
@@ -1,191 +0,0 @@
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.DescriptorUtils;
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<String, ClassifierDescriptor> classMap;
private Map<DeclarationDescriptor, DeclarationDescriptor> descriptorsBoundToReceiver;
private Function<DeclarationDescriptor, DeclarationDescriptor> addBoundToReceiverFunction;
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 Function<DeclarationDescriptor, DeclarationDescriptor> getAddBoundToReceiverFunction() {
if (addBoundToReceiverFunction == null) {
addBoundToReceiverFunction = DescriptorUtils.getAddBoundToReceiverFunction(receiver);
}
return addBoundToReceiverFunction;
}
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<String, ClassifierDescriptor> getClassMap() {
if (classMap == null) {
classMap = Maps.newHashMap();
}
return classMap;
}
private Map<DeclarationDescriptor, DeclarationDescriptor> getDescriptorsBoundToReceiver() {
if (descriptorsBoundToReceiver == null) {
descriptorsBoundToReceiver = Maps.newHashMap();
}
return descriptorsBoundToReceiver;
}
@Nullable
@Override
public ClassifierDescriptor getClassifier(@NotNull String name) {
if (getClassMap().containsKey(name)) {
return getClassMap().get(name);
}
ClassifierDescriptor result = getMemberBoundToReceiver(scope.getClassifier(name));
getClassMap().put(name, result);
return result;
}
@Override
public ClassDescriptor getObjectDescriptor(@NotNull String name) {
return scope.getObjectDescriptor(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));
}
@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) {
for (D oldMember : oldMembers) {
D memberBoundToReceiver = getMemberBoundToReceiver(oldMember);
cache.put(name, memberBoundToReceiver);
getDescriptorsBoundToReceiver().put(oldMember, memberBoundToReceiver);
}
return cache.get(name);
}
private <D extends DeclarationDescriptor> D getMemberBoundToReceiver(D oldMember) {
return (D)getAddBoundToReceiverFunction().apply(oldMember);
}
@NotNull
@Override
public Set<FunctionDescriptor> getFunctions(@NotNull String name) {
if (getFunctionsMap().containsKey(name)) {
return getFunctionsMap().get(name);
}
return getMembersBoundToReceiver(name, getFunctionsMap(), scope.getFunctions(name));
}
@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) {
}
}
@@ -118,6 +118,7 @@ public class ErrorUtils {
Modality.OPEN, Modality.OPEN,
Visibility.INTERNAL, Visibility.INTERNAL,
true, true,
false,
null, null,
ReceiverDescriptor.NO_RECEIVER, ReceiverDescriptor.NO_RECEIVER,
"<ERROR PROPERTY>", "<ERROR PROPERTY>",
@@ -120,7 +120,7 @@ public class JetStandardClasses {
Collections.<AnnotationDescriptor>emptyList(), Collections.<AnnotationDescriptor>emptyList(),
true, Variance.OUT_VARIANCE, "T" + (j + 1), j); true, Variance.OUT_VARIANCE, "T" + (j + 1), j);
parameters.add(typeParameterDescriptor); parameters.add(typeParameterDescriptor);
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(classDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibility.PUBLIC, false, "_" + (j + 1)); PropertyDescriptor propertyDescriptor = new PropertyDescriptor(classDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibility.PUBLIC, false, false, "_" + (j + 1));
propertyDescriptor.setType(typeParameterDescriptor.getDefaultType(), Collections.<TypeParameterDescriptor>emptyList(), classDescriptor.getImplicitReceiver(), ReceiverDescriptor.NO_RECEIVER); propertyDescriptor.setType(typeParameterDescriptor.getDefaultType(), Collections.<TypeParameterDescriptor>emptyList(), classDescriptor.getImplicitReceiver(), ReceiverDescriptor.NO_RECEIVER);
propertyDescriptor.initialize(new PropertyGetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibility.PUBLIC, false, true), null); propertyDescriptor.initialize(new PropertyGetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibility.PUBLIC, false, true), null);
writableScope.addPropertyDescriptor(propertyDescriptor); writableScope.addPropertyDescriptor(propertyDescriptor);
@@ -0,0 +1,15 @@
import A.B.foo
import A.B.x
class A() {
class object {
class B() {
class object {
val x = 1
fun foo() = "2"
}
}
}
}
fun box() = if (x == 1 && foo() == "2") "OK" else "fail"