From 7060f6ef80411bb457ca67722ab79aceffdada42 Mon Sep 17 00:00:00 2001 From: svtk Date: Tue, 27 Dec 2011 14:35:52 +0400 Subject: [PATCH] Added imports resolve from objects and variables --- ...unctionDescriptorWithImplicitReceiver.java | 123 ++++++++++++++++++ ...ariableDescriptorWithImplicitReceiver.java | 119 +++++++++++++++++ .../jet/lang/resolve/ImportsResolver.java | 30 ++++- .../lang/resolve/scopes/WritableScope.java | 4 +- .../resolve/scopes/WritableScopeImpl.java | 4 +- .../scopes/WritableScopeWithImports.java | 2 +- .../resolve/scopes/WriteThroughScope.java | 2 +- .../diagnostics/tests/scopes/Imports.jet | 29 ++++- 8 files changed, 299 insertions(+), 14 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorWithImplicitReceiver.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableDescriptorWithImplicitReceiver.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorWithImplicitReceiver.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorWithImplicitReceiver.java new file mode 100644 index 00000000000..136be2a5019 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorWithImplicitReceiver.java @@ -0,0 +1,123 @@ +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 FunctionDescriptorWithImplicitReceiver implements FunctionDescriptor { + + private FunctionDescriptor functionDescriptor; + private DeclarationDescriptor implicitReceiver; + + public FunctionDescriptorWithImplicitReceiver(@NotNull FunctionDescriptor functionDescriptor, @NotNull DeclarationDescriptor implicitReceiver) { + this.functionDescriptor = functionDescriptor; + this.implicitReceiver = implicitReceiver; + } + + public FunctionDescriptor getFunctionDescriptor() { + return functionDescriptor; + } + + public DeclarationDescriptor getImplicitReceiver() { + return implicitReceiver; + } + + @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 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 getTypeParameters() { + return functionDescriptor.getTypeParameters(); + } + + @Override + public JetType getReturnType() { + return functionDescriptor.getReturnType(); + } + + @NotNull + @Override + public List getValueParameters() { + return functionDescriptor.getValueParameters(); + } + + @NotNull + @Override + public Modality getModality() { + return functionDescriptor.getModality(); + } + + @NotNull + @Override + public Visibility getVisibility() { + return functionDescriptor.getVisibility(); + } + + @Override + public R accept(DeclarationDescriptorVisitor visitor, D data) { + return functionDescriptor.accept(visitor, data); + } + + @Override + public void acceptVoid(DeclarationDescriptorVisitor visitor) { + functionDescriptor.acceptVoid(visitor); + } + + @Override + public List getAnnotations() { + return functionDescriptor.getAnnotations(); + } + + @NotNull + @Override + public String getName() { + return functionDescriptor.getName(); + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableDescriptorWithImplicitReceiver.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableDescriptorWithImplicitReceiver.java new file mode 100644 index 00000000000..a8cbc4b3af5 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableDescriptorWithImplicitReceiver.java @@ -0,0 +1,119 @@ +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 VariableDescriptorWithImplicitReceiver implements VariableDescriptor { + private VariableDescriptor variableDescriptor; + private DeclarationDescriptor implicitReceiver; + + public VariableDescriptorWithImplicitReceiver(VariableDescriptor variableDescriptor, DeclarationDescriptor implicitReceiver) { + this.variableDescriptor = variableDescriptor; + this.implicitReceiver = implicitReceiver; + } + + public VariableDescriptor getVariableDescriptor() { + return variableDescriptor; + } + + public DeclarationDescriptor getImplicitReceiver() { + return implicitReceiver; + } + + @Override + public JetType getOutType() { + return variableDescriptor.getOutType(); + } + + @Override + public JetType getInType() { + return variableDescriptor.getInType(); + } + + @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 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 accept(DeclarationDescriptorVisitor visitor, D data) { + return variableDescriptor.accept(visitor, data); + } + + @Override + public void acceptVoid(DeclarationDescriptorVisitor visitor) { + variableDescriptor.acceptVoid(visitor); + } + + @NotNull + @Override + public List getValueParameters() { + return variableDescriptor.getValueParameters(); + } + + @NotNull + @Override + public Set getOverriddenDescriptors() { + return variableDescriptor.getOverriddenDescriptors(); + } + + @Override + public boolean isVar() { + return variableDescriptor.isVar(); + } + + @Override + public List getAnnotations() { + return variableDescriptor.getAnnotations(); + } + + @NotNull + @Override + public String getName() { + return variableDescriptor.getName(); + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java index 2735a9eb566..26e1a3c01c5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java @@ -1,5 +1,7 @@ package org.jetbrains.jet.lang.resolve; +import com.google.common.base.Function; +import com.google.common.collect.Collections2; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -101,19 +103,17 @@ public class ImportsResolver { if (firstPhase) { if (descriptor instanceof ClassifierDescriptor) { namespaceScope.importClassifierAlias(aliasName, (ClassifierDescriptor) descriptor); - return; } if (descriptor instanceof NamespaceDescriptor) { namespaceScope.importNamespaceAlias(aliasName, (NamespaceDescriptor) descriptor); - return; } + return; } if (descriptor instanceof FunctionDescriptor) { namespaceScope.importFunctionAlias(aliasName, (FunctionDescriptor) descriptor); - return; } - if (descriptor instanceof PropertyDescriptor) { - namespaceScope.importVariableAlias(aliasName, (PropertyDescriptor) descriptor); + if (descriptor instanceof VariableDescriptor) { + namespaceScope.importVariableAlias(aliasName, (VariableDescriptor) descriptor); } } @@ -167,7 +167,7 @@ public class ImportsResolver { trace.report(NO_CLASS_OBJECT.on(classReference, classDescriptor)); return Collections.emptyList(); } - return lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope()); + return addImplicitReceiver(lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope()), classDescriptor); } @NotNull @@ -176,9 +176,25 @@ public class ImportsResolver { JetType variableType = variableDescriptor.getReturnType(); if (variableType == null) return Collections.emptyList(); - return lookupDescriptorsForSimpleNameReference(memberReference, variableType.getMemberScope()); + return addImplicitReceiver(lookupDescriptorsForSimpleNameReference(memberReference, variableType.getMemberScope()), variableDescriptor); } + @NotNull + private static Collection addImplicitReceiver(@NotNull Collection descriptors, @NotNull final DeclarationDescriptor implicitReceiver) { + return Collections2.transform(descriptors, new Function() { + @Override + public DeclarationDescriptor apply(@Nullable DeclarationDescriptor descriptor) { + if (descriptor instanceof FunctionDescriptor) { + return new FunctionDescriptorWithImplicitReceiver((FunctionDescriptor) descriptor, implicitReceiver); + } + if (descriptor instanceof VariableDescriptor) { + return new VariableDescriptorWithImplicitReceiver((VariableDescriptor) descriptor, implicitReceiver); + } + return descriptor; + } + }); + } + @NotNull private Collection lookupDescriptorsForSimpleNameReference(@NotNull JetSimpleNameExpression referenceExpression, @NotNull JetScope outerScope) { List descriptors = Lists.newArrayList(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScope.java index be455d54bd6..993c9b8fb70 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScope.java @@ -21,7 +21,7 @@ public interface WritableScope extends JetScope { void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor); - void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor); + void addPropertyDescriptor(@NotNull VariableDescriptor propertyDescriptor); void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor); @@ -52,5 +52,5 @@ public interface WritableScope extends JetScope { void importFunctionAlias(@NotNull String aliasName, @NotNull FunctionDescriptor functionDescriptor); - void importVariableAlias(@NotNull String aliasName, @NotNull PropertyDescriptor variableDescriptor); + void importVariableAlias(@NotNull String aliasName, @NotNull VariableDescriptor variableDescriptor); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java index 8c73ddbe2c5..2180d9022b0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java @@ -89,7 +89,7 @@ public class WritableScopeImpl extends WritableScopeWithImports { } @Override - public void importVariableAlias(@NotNull String aliasName, @NotNull PropertyDescriptor variableDescriptor) { + public void importVariableAlias(@NotNull String aliasName, @NotNull VariableDescriptor variableDescriptor) { checkMayWrite(); addPropertyDescriptor(variableDescriptor); @@ -173,7 +173,7 @@ public class WritableScopeImpl extends WritableScopeWithImports { } @Override - public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { + public void addPropertyDescriptor(@NotNull VariableDescriptor propertyDescriptor) { addVariableDescriptor(propertyDescriptor, true); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java index 285b16ab0f1..3d26fdaa2e8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java @@ -193,7 +193,7 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement } @Override - public void importVariableAlias(@NotNull String aliasName, @NotNull PropertyDescriptor variableDescriptor) { + public void importVariableAlias(@NotNull String aliasName, @NotNull VariableDescriptor variableDescriptor) { checkMayWrite(); getCurrentIndividualImportScope().addVariableAlias(aliasName, variableDescriptor); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java index 43c5c1d1ffc..1a57a7c84bf 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java @@ -139,7 +139,7 @@ public class WriteThroughScope extends WritableScopeWithImports { } @Override - public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { + public void addPropertyDescriptor(@NotNull VariableDescriptor propertyDescriptor) { checkMayWrite(); writableWorker.addPropertyDescriptor(propertyDescriptor); diff --git a/compiler/testData/diagnostics/tests/scopes/Imports.jet b/compiler/testData/diagnostics/tests/scopes/Imports.jet index 8ff30e6834d..e36a07aa110 100644 --- a/compiler/testData/diagnostics/tests/scopes/Imports.jet +++ b/compiler/testData/diagnostics/tests/scopes/Imports.jet @@ -7,10 +7,20 @@ import b.ext //extension function import b.value //property import b.C.bar //function from class object import b.C.cValue //property from class object +import b.constant.fff //function from val +import b.constant.dValue //property from val +import b.E.f //val from class object fun test(arg: B) { foo(value) arg.ext() + + bar() + foo(cValue) + + fff(dValue) + + f.f() } //FILE:b.kt @@ -18,7 +28,7 @@ package b class B() {} -fun foo(i: Int) {} +fun foo(i: Int) = i fun B.ext() {} @@ -29,4 +39,21 @@ class C() { fun bar() {} val cValue = 1 } +} + +class D() { + fun fff(s: String) = s + val dValue = "w" +} + +val constant = D() + +class E() { + class object { + val f = F() + } +} + +class F() { + fun f() {} } \ No newline at end of file