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
This commit is contained in:
Alexander Udalov
2013-09-12 11:11:00 +02:00
committed by Alexander Udalov
parent 7d64b84c42
commit 6778b38f79
10 changed files with 68 additions and 194 deletions
@@ -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, D> R accept(@NotNull ReceiverValueVisitor<R, D> visitor, D data) {
return original.accept(visitor, data);
}
@Override
public String toString() {
return "(" + original + " as " + getType() + ")";
@@ -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<ReceiverValue> 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<List<ReceiverValue>, Object>() {
@Override
public List<ReceiverValue> visitNoReceiver(ReceiverValue noReceiver, Object data) {
return Collections.emptyList();
}
@Override
public List<ReceiverValue> visitTransientReceiver(TransientReceiver receiver, Object data) {
return Collections.emptyList();
}
@Override
public List<ReceiverValue> visitExtensionReceiver(ExtensionReceiver receiver, Object data) {
return castThis(dataFlowInfo, receiver);
}
@Override
public List<ReceiverValue> visitClassReceiver(ClassReceiver receiver, Object data) {
return castThis(dataFlowInfo, receiver);
}
@Override
public List<ReceiverValue> visitScriptReceiver(ScriptReceiver receiver, Object data) {
return Collections.emptyList();
}
@Override
public List<ReceiverValue> visitExpressionReceiver(ExpressionReceiver receiver, Object data) {
DataFlowValue dataFlowValue = DataFlowValueFactory.createDataFlowValue(receiver.getExpression(), receiver.getType(),
bindingContext);
List<ReceiverValue> 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<ReceiverValue> castThis(@NotNull DataFlowInfo dataFlowInfo, @NotNull ThisReceiver receiver) {
assert receiver.exists();
List<ReceiverValue> result = Lists.newArrayList();
for (JetType possibleType : dataFlowInfo.getPossibleTypes(DataFlowValueFactory.createDataFlowValue(receiver))) {
result.add(new AutoCastReceiver(receiver, possibleType, true));
@NotNull
private static List<ReceiverValue> collectAutoCastReceiverValues(
@NotNull DataFlowInfo dataFlowInfo,
@NotNull ReceiverValue receiver,
@NotNull DataFlowValue dataFlowValue
) {
Set<JetType> possibleTypes = dataFlowInfo.getPossibleTypes(dataFlowValue);
List<ReceiverValue> result = new ArrayList<ReceiverValue>(possibleTypes.size());
for (JetType possibleType : possibleTypes) {
result.add(new AutoCastReceiver(receiver, possibleType, dataFlowValue.isStableIdentifier()));
}
return result;
}
@@ -59,44 +59,26 @@ public class DataFlowValueFactory {
@NotNull
public static DataFlowValue createDataFlowValue(@NotNull ReceiverValue receiverValue, @NotNull BindingContext bindingContext) {
return receiverValue.accept(new ReceiverValueVisitor<DataFlowValue, BindingContext>() {
@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<IdentifierInfo, Void>() {
@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
@@ -45,11 +45,6 @@ public class ClassReceiver implements ThisReceiver {
return classDescriptor;
}
@Override
public <R, D> R accept(@NotNull ReceiverValueVisitor<R, D> visitor, D data) {
return visitor.visitClassReceiver(this, data);
}
@Override
public String toString() {
return "Class{" + getType() + "}";
@@ -34,11 +34,6 @@ public class ExpressionReceiver extends AbstractReceiverValue implements Receive
return expression;
}
@Override
public <R, D> R accept(@NotNull ReceiverValueVisitor<R, D> visitor, D data) {
return visitor.visitExpressionReceiver(this, data);
}
@Override
public String toString() {
return getType() + " {" + expression + ": " + expression.getText() + "}";
@@ -36,11 +36,6 @@ public class ExtensionReceiver extends AbstractReceiverValue implements ThisRece
return descriptor;
}
@Override
public <R, D> R accept(@NotNull ReceiverValueVisitor<R, D> visitor, D data) {
return visitor.visitExtensionReceiver(this, data);
}
@Override
public String toString() {
return getType() + "Ext{" + descriptor + "}";
@@ -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, D> R accept(@NotNull ReceiverValueVisitor<R, D> 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, D> R accept(@NotNull ReceiverValueVisitor<R, D> visitor, D data);
}
@@ -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, D> {
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);
}
@@ -48,9 +48,4 @@ public class ScriptReceiver implements ThisReceiver {
public boolean exists() {
return true;
}
@Override
public <R, D> R accept(@NotNull ReceiverValueVisitor<R, D> visitor, D data) {
return visitor.visitScriptReceiver(this, data);
}
}
@@ -28,11 +28,6 @@ public class TransientReceiver extends AbstractReceiverValue {
super(type);
}
@Override
public <R, D> R accept(@NotNull ReceiverValueVisitor<R, D> visitor, D data) {
return visitor.visitTransientReceiver(this, data);
}
@Override
public String toString() {
return "{Transient} : " + getType();