001 /*
002 * Copyright 2010-2016 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.kotlin.resolve.calls;
018
019 import com.intellij.lang.ASTNode;
020 import org.jetbrains.annotations.NotNull;
021 import org.jetbrains.annotations.Nullable;
022 import org.jetbrains.kotlin.psi.*;
023 import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall;
024 import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
025 import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
026 import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
027 import org.jetbrains.kotlin.util.OperatorNameConventions;
028
029 import java.util.Collections;
030 import java.util.List;
031
032 public class CallTransformer {
033 private CallTransformer() {}
034
035 public static Call stripCallArguments(@NotNull Call call) {
036 return new DelegatingCall(call) {
037 @Override
038 public KtValueArgumentList getValueArgumentList() {
039 return null;
040 }
041
042 @NotNull
043 @Override
044 public List<? extends ValueArgument> getValueArguments() {
045 return Collections.emptyList();
046 }
047
048 @NotNull
049 @Override
050 public List<LambdaArgument> getFunctionLiteralArguments() {
051 return Collections.emptyList();
052 }
053
054 @NotNull
055 @Override
056 public List<KtTypeProjection> getTypeArguments() {
057 return Collections.emptyList();
058 }
059
060 @Override
061 public KtTypeArgumentList getTypeArgumentList() {
062 return null;
063 }
064
065 @NotNull
066 @Override
067 public KtElement getCallElement() {
068 KtExpression calleeExpression = getCalleeExpression();
069 assert calleeExpression != null : "No callee expression: " + getCallElement().getText();
070
071 return calleeExpression;
072 }
073 };
074 }
075
076 public static Call stripReceiver(@NotNull Call variableCall) {
077 return new DelegatingCall(variableCall) {
078 @Nullable
079 @Override
080 public ASTNode getCallOperationNode() {
081 return null;
082 }
083
084 @Nullable
085 @Override
086 public ReceiverValue getExplicitReceiver() {
087 return null;
088 }
089 };
090 }
091
092 public static class CallForImplicitInvoke extends DelegatingCall {
093 private final Call outerCall;
094 private final Receiver explicitExtensionReceiver;
095 private final ExpressionReceiver calleeExpressionAsDispatchReceiver;
096 private final KtSimpleNameExpression fakeInvokeExpression;
097 public final boolean itIsVariableAsFunctionCall;
098
099 public CallForImplicitInvoke(
100 @Nullable Receiver explicitExtensionReceiver,
101 @NotNull ExpressionReceiver calleeExpressionAsDispatchReceiver,
102 @NotNull Call call,
103 boolean functionCall
104 ) {
105 super(call);
106 this.outerCall = call;
107 this.explicitExtensionReceiver = explicitExtensionReceiver;
108 this.calleeExpressionAsDispatchReceiver = calleeExpressionAsDispatchReceiver;
109 this.fakeInvokeExpression =
110 (KtSimpleNameExpression) KtPsiFactoryKt.KtPsiFactory(call.getCallElement())
111 .createExpression(OperatorNameConventions.INVOKE.asString());
112 itIsVariableAsFunctionCall = functionCall;
113 }
114
115 @Nullable
116 @Override
117 public ASTNode getCallOperationNode() {
118 // if an explicit receiver corresponds to the implicit invoke, there is a corresponding call operation node:
119 // a.b() or a?.b() (where b has an extension function type);
120 // otherwise it's implicit
121 return explicitExtensionReceiver != null ? super.getCallOperationNode() : null;
122 }
123
124 @Nullable
125 @Override
126 public Receiver getExplicitReceiver() {
127 return explicitExtensionReceiver;
128 }
129
130 @NotNull
131 @Override
132 public ExpressionReceiver getDispatchReceiver() {
133 return calleeExpressionAsDispatchReceiver;
134 }
135
136 @Override
137 public KtExpression getCalleeExpression() {
138 return fakeInvokeExpression;
139 }
140
141 @NotNull
142 @Override
143 public CallType getCallType() {
144 return CallType.INVOKE;
145 }
146
147 @NotNull
148 public Call getOuterCall() {
149 return outerCall;
150 }
151 }
152 }