From 6778b38f79e3c02f4d1a9ab4deb39ed717ed62db Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 12 Sep 2013 11:11:00 +0200 Subject: [PATCH] Delete ReceiverValueVisitor This is done because this visitor ties all ReceiverValue's together, which makes descriptors depend on PSI (ReceiverValue -> ReceiverValueVisitor -> ExpressionReceiver -> JetExpression). Descriptors will be available at runtime, but PSI is very heavy, so this dependency should be gotten rid of --- .../calls/autocasts/AutoCastReceiver.java | 6 - .../calls/autocasts/AutoCastUtils.java | 81 ++++++------- .../calls/autocasts/DataFlowValueFactory.java | 111 ++++++------------ .../scopes/receivers/ClassReceiver.java | 5 - .../scopes/receivers/ExpressionReceiver.java | 5 - .../scopes/receivers/ExtensionReceiver.java | 5 - .../scopes/receivers/ReceiverValue.java | 8 -- .../receivers/ReceiverValueVisitor.java | 31 ----- .../scopes/receivers/ScriptReceiver.java | 5 - .../scopes/receivers/TransientReceiver.java | 5 - 10 files changed, 68 insertions(+), 194 deletions(-) delete mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ReceiverValueVisitor.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/AutoCastReceiver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/AutoCastReceiver.java index 2d2c4d191d5..2ece3be430a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/AutoCastReceiver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/AutoCastReceiver.java @@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.resolve.calls.autocasts; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.resolve.scopes.receivers.AbstractReceiverValue; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; -import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValueVisitor; import org.jetbrains.jet.lang.types.JetType; public class AutoCastReceiver extends AbstractReceiverValue { @@ -41,11 +40,6 @@ public class AutoCastReceiver extends AbstractReceiverValue { return original; } - @Override - public R accept(@NotNull ReceiverValueVisitor visitor, D data) { - return original.accept(visitor, data); - } - @Override public String toString() { return "(" + original + " as " + getType() + ")"; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/AutoCastUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/AutoCastUtils.java index 2760c59c58f..70e99509583 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/AutoCastUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/AutoCastUtils.java @@ -16,15 +16,18 @@ package org.jetbrains.jet.lang.resolve.calls.autocasts; -import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTrace; -import org.jetbrains.jet.lang.resolve.scopes.receivers.*; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ThisReceiver; import org.jetbrains.jet.lang.types.JetType; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import static org.jetbrains.jet.lang.diagnostics.Errors.AUTOCAST_IMPOSSIBLE; import static org.jetbrains.jet.lang.resolve.BindingContext.AUTOCAST; @@ -37,54 +40,40 @@ public class AutoCastUtils { /** * @return variants @param receiverToCast may be cast to according to @param dataFlowInfo, @param receiverToCast itself is NOT included */ + @NotNull public static List getAutoCastVariants( - @NotNull final BindingContext bindingContext, - @NotNull final DataFlowInfo dataFlowInfo, @NotNull ReceiverValue receiverToCast + @NotNull BindingContext bindingContext, + @NotNull DataFlowInfo dataFlowInfo, + @NotNull ReceiverValue receiverToCast ) { - return receiverToCast.accept(new ReceiverValueVisitor, Object>() { - @Override - public List visitNoReceiver(ReceiverValue noReceiver, Object data) { - return Collections.emptyList(); - } - - @Override - public List visitTransientReceiver(TransientReceiver receiver, Object data) { - return Collections.emptyList(); - } - - @Override - public List visitExtensionReceiver(ExtensionReceiver receiver, Object data) { - return castThis(dataFlowInfo, receiver); - } - - @Override - public List visitClassReceiver(ClassReceiver receiver, Object data) { - return castThis(dataFlowInfo, receiver); - } - - @Override - public List visitScriptReceiver(ScriptReceiver receiver, Object data) { - return Collections.emptyList(); - } - - @Override - public List visitExpressionReceiver(ExpressionReceiver receiver, Object data) { - DataFlowValue dataFlowValue = DataFlowValueFactory.createDataFlowValue(receiver.getExpression(), receiver.getType(), - bindingContext); - List result = Lists.newArrayList(); - for (JetType possibleType : dataFlowInfo.getPossibleTypes(dataFlowValue)) { - result.add(new AutoCastReceiver(receiver, possibleType, dataFlowValue.isStableIdentifier())); - } - return result; - } - }, null); + if (receiverToCast instanceof ThisReceiver) { + ThisReceiver receiver = (ThisReceiver) receiverToCast; + assert receiver.exists(); + DataFlowValue dataFlowValue = DataFlowValueFactory.createDataFlowValue(receiver); + return collectAutoCastReceiverValues(dataFlowInfo, receiver, dataFlowValue); + } + else if (receiverToCast instanceof ExpressionReceiver) { + ExpressionReceiver receiver = (ExpressionReceiver) receiverToCast; + DataFlowValue dataFlowValue = + DataFlowValueFactory.createDataFlowValue(receiver.getExpression(), receiver.getType(), bindingContext); + return collectAutoCastReceiverValues(dataFlowInfo, receiver, dataFlowValue); + } + else if (receiverToCast instanceof AutoCastReceiver) { + return getAutoCastVariants(bindingContext, dataFlowInfo, ((AutoCastReceiver) receiverToCast).getOriginal()); + } + return Collections.emptyList(); } - private static List castThis(@NotNull DataFlowInfo dataFlowInfo, @NotNull ThisReceiver receiver) { - assert receiver.exists(); - List result = Lists.newArrayList(); - for (JetType possibleType : dataFlowInfo.getPossibleTypes(DataFlowValueFactory.createDataFlowValue(receiver))) { - result.add(new AutoCastReceiver(receiver, possibleType, true)); + @NotNull + private static List collectAutoCastReceiverValues( + @NotNull DataFlowInfo dataFlowInfo, + @NotNull ReceiverValue receiver, + @NotNull DataFlowValue dataFlowValue + ) { + Set possibleTypes = dataFlowInfo.getPossibleTypes(dataFlowValue); + List result = new ArrayList(possibleTypes.size()); + for (JetType possibleType : possibleTypes) { + result.add(new AutoCastReceiver(receiver, possibleType, dataFlowValue.isStableIdentifier())); } return result; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java index d11aa507e46..af4862cb167 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java @@ -59,44 +59,26 @@ public class DataFlowValueFactory { @NotNull public static DataFlowValue createDataFlowValue(@NotNull ReceiverValue receiverValue, @NotNull BindingContext bindingContext) { - return receiverValue.accept(new ReceiverValueVisitor() { - @Override - public DataFlowValue visitNoReceiver(ReceiverValue noReceiver, BindingContext data) { - throw new IllegalArgumentException("No DataFlowValue exists for ReceiverValue.NO_RECEIVER"); - } - - @Override - public DataFlowValue visitExtensionReceiver(ExtensionReceiver receiver, BindingContext data) { - return createDataFlowValue(receiver); - } - - @Override - public DataFlowValue visitExpressionReceiver(ExpressionReceiver receiver, BindingContext bindingContext) { - return createDataFlowValue(receiver.getExpression(), receiver.getType(), bindingContext); - } - - @Override - public DataFlowValue visitClassReceiver(ClassReceiver receiver, BindingContext data) { - return createDataFlowValue(receiver); - } - - @Override - public DataFlowValue visitTransientReceiver(TransientReceiver receiver, BindingContext data) { - return createTransientDataFlowValue(receiver); - } - - @Override - public DataFlowValue visitScriptReceiver(ScriptReceiver receiver, BindingContext data) { - return createTransientDataFlowValue(receiver); - } - - @NotNull - private DataFlowValue createTransientDataFlowValue(ReceiverValue receiver) { - JetType type = receiver.getType(); - boolean nullable = type.isNullable() || TypeUtils.hasNullableSuperType(type); - return new DataFlowValue(receiver, type, nullable, Nullability.NOT_NULL); - } - }, bindingContext); + if (receiverValue instanceof TransientReceiver || receiverValue instanceof ScriptReceiver) { + JetType type = receiverValue.getType(); + boolean nullable = type.isNullable() || TypeUtils.hasNullableSuperType(type); + return new DataFlowValue(receiverValue, type, nullable, Nullability.NOT_NULL); + } + else if (receiverValue instanceof ClassReceiver || receiverValue instanceof ExtensionReceiver) { + return createDataFlowValue((ThisReceiver) receiverValue); + } + else if (receiverValue instanceof ExpressionReceiver) { + return createDataFlowValue(((ExpressionReceiver) receiverValue).getExpression(), receiverValue.getType(), bindingContext); + } + else if (receiverValue instanceof AutoCastReceiver) { + return createDataFlowValue(((AutoCastReceiver) receiverValue).getOriginal(), bindingContext); + } + else if (receiverValue == ReceiverValue.NO_RECEIVER) { + throw new IllegalArgumentException("No DataFlowValue exists for ReceiverValue.NO_RECEIVER"); + } + else { + throw new UnsupportedOperationException("Unsupported receiver value: " + receiverValue.getClass().getName()); + } } @NotNull @@ -203,46 +185,19 @@ public class DataFlowValueFactory { } @Nullable - private static IdentifierInfo getIdForImplicitReceiver(@NotNull ReceiverValue receiverValue, @Nullable final JetExpression expression) { - return receiverValue.accept(new ReceiverValueVisitor() { - - @Override - public IdentifierInfo visitNoReceiver(ReceiverValue noReceiver, Void data) { - return null; - } - - @Override - public IdentifierInfo visitTransientReceiver(TransientReceiver receiver, Void data) { - assert false: "Transient receiver is implicit for an explicit expression: " + expression + ". Receiver: " + receiver; - return null; - } - - @Override - public IdentifierInfo visitExtensionReceiver(ExtensionReceiver receiver, Void data) { - return getIdForThisReceiver(receiver); - } - - @Override - public IdentifierInfo visitExpressionReceiver(ExpressionReceiver receiver, Void data) { - // there is an explicit "this" expression and it was analyzed earlier - return null; - } - - @Override - public IdentifierInfo visitClassReceiver(ClassReceiver receiver, Void data) { - return getIdForThisReceiver(receiver); - } - - @Override - public IdentifierInfo visitScriptReceiver(ScriptReceiver receiver, Void data) { - return getIdForThisReceiver(receiver); - } - }, null); - } - - @NotNull - private static IdentifierInfo getIdForThisReceiver(@NotNull ThisReceiver thisReceiver) { - return getIdForThisReceiver(thisReceiver.getDeclarationDescriptor()); + private static IdentifierInfo getIdForImplicitReceiver(@NotNull ReceiverValue receiverValue, @Nullable JetExpression expression) { + if (receiverValue instanceof ThisReceiver) { + return getIdForThisReceiver(((ThisReceiver) receiverValue).getDeclarationDescriptor()); + } + else if (receiverValue instanceof AutoCastReceiver) { + return getIdForImplicitReceiver(((AutoCastReceiver) receiverValue).getOriginal(), expression); + } + else { + assert !(receiverValue instanceof TransientReceiver) + : "Transient receiver is implicit for an explicit expression: " + expression + ". Receiver: " + receiverValue; + // For ExpressionReceiver there is an explicit "this" expression and it was analyzed earlier + return null; + } } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ClassReceiver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ClassReceiver.java index 14d18f71bdb..e4f891157d5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ClassReceiver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ClassReceiver.java @@ -45,11 +45,6 @@ public class ClassReceiver implements ThisReceiver { return classDescriptor; } - @Override - public R accept(@NotNull ReceiverValueVisitor visitor, D data) { - return visitor.visitClassReceiver(this, data); - } - @Override public String toString() { return "Class{" + getType() + "}"; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ExpressionReceiver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ExpressionReceiver.java index e66496b716a..2192b850338 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ExpressionReceiver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ExpressionReceiver.java @@ -34,11 +34,6 @@ public class ExpressionReceiver extends AbstractReceiverValue implements Receive return expression; } - @Override - public R accept(@NotNull ReceiverValueVisitor visitor, D data) { - return visitor.visitExpressionReceiver(this, data); - } - @Override public String toString() { return getType() + " {" + expression + ": " + expression.getText() + "}"; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ExtensionReceiver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ExtensionReceiver.java index 34eec062a94..c85273d131b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ExtensionReceiver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ExtensionReceiver.java @@ -36,11 +36,6 @@ public class ExtensionReceiver extends AbstractReceiverValue implements ThisRece return descriptor; } - @Override - public R accept(@NotNull ReceiverValueVisitor visitor, D data) { - return visitor.visitExtensionReceiver(this, data); - } - @Override public String toString() { return getType() + "Ext{" + descriptor + "}"; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ReceiverValue.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ReceiverValue.java index 5b77d821845..5ebac9b6e26 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ReceiverValue.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ReceiverValue.java @@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.types.JetType; public interface ReceiverValue { - ReceiverValue NO_RECEIVER = new ReceiverValue() { @NotNull @Override @@ -33,11 +32,6 @@ public interface ReceiverValue { return false; } - @Override - public R accept(@NotNull ReceiverValueVisitor visitor, D data) { - return visitor.visitNoReceiver(this, data); - } - @Override public String toString() { return "NO_RECEIVER"; @@ -48,6 +42,4 @@ public interface ReceiverValue { JetType getType(); boolean exists(); - - R accept(@NotNull ReceiverValueVisitor visitor, D data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ReceiverValueVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ReceiverValueVisitor.java deleted file mode 100644 index 110189c2330..00000000000 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ReceiverValueVisitor.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.lang.resolve.scopes.receivers; - -public interface ReceiverValueVisitor { - R visitNoReceiver(ReceiverValue noReceiver, D data); - - R visitTransientReceiver(TransientReceiver receiver, D data); - - R visitExtensionReceiver(ExtensionReceiver receiver, D data); - - R visitExpressionReceiver(ExpressionReceiver receiver, D data); - - R visitClassReceiver(ClassReceiver receiver, D data); - - R visitScriptReceiver(ScriptReceiver receiver, D data); -} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ScriptReceiver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ScriptReceiver.java index 5692a1dd6a6..cbf035f527c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ScriptReceiver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ScriptReceiver.java @@ -48,9 +48,4 @@ public class ScriptReceiver implements ThisReceiver { public boolean exists() { return true; } - - @Override - public R accept(@NotNull ReceiverValueVisitor visitor, D data) { - return visitor.visitScriptReceiver(this, data); - } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/TransientReceiver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/TransientReceiver.java index 3be28ead3f9..bd58b3d0949 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/TransientReceiver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/TransientReceiver.java @@ -28,11 +28,6 @@ public class TransientReceiver extends AbstractReceiverValue { super(type); } - @Override - public R accept(@NotNull ReceiverValueVisitor visitor, D data) { - return visitor.visitTransientReceiver(this, data); - } - @Override public String toString() { return "{Transient} : " + getType();