001 /*
002 * Copyright 2010-2013 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.jet.lang.resolve.calls.util;
018
019 import com.google.common.collect.Lists;
020 import com.intellij.lang.ASTNode;
021 import com.intellij.psi.PsiElement;
022 import com.intellij.psi.impl.source.tree.LeafPsiElement;
023 import org.jetbrains.annotations.NotNull;
024 import org.jetbrains.annotations.Nullable;
025 import org.jetbrains.jet.lang.psi.*;
026 import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
027 import org.jetbrains.jet.lang.psi.Call.CallType;
028 import org.jetbrains.jet.lang.psi.debugText.DebugTextPackage;
029 import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
030
031 import java.util.Collections;
032 import java.util.List;
033
034 public class CallMaker {
035
036 private static class ExpressionValueArgument implements ValueArgument {
037
038 private final JetExpression expression;
039
040 private final JetElement reportErrorsOn;
041
042 private ExpressionValueArgument(@Nullable JetExpression expression, @NotNull JetElement reportErrorsOn) {
043 this.expression = expression;
044 this.reportErrorsOn = expression == null ? reportErrorsOn : expression;
045 }
046
047 @Override
048 public JetExpression getArgumentExpression() {
049 return expression;
050 }
051
052 @Override
053 public JetValueArgumentName getArgumentName() {
054 return null;
055 }
056
057 @Override
058 public boolean isNamed() {
059 return false;
060 }
061
062 @NotNull
063 @Override
064 public JetElement asElement() {
065 return reportErrorsOn;
066 }
067
068 @Override
069 public LeafPsiElement getSpreadElement() {
070 return null;
071 }
072 }
073
074 private static class CallImpl implements Call {
075
076 private final JetElement callElement;
077 private final ReceiverValue explicitReceiver;
078 private final ASTNode callOperationNode;
079 private final JetExpression calleeExpression;
080 private final List<? extends ValueArgument> valueArguments;
081 private final Call.CallType callType;
082
083 protected CallImpl(@NotNull JetElement callElement, @NotNull ReceiverValue explicitReceiver, @Nullable ASTNode callOperationNode, @Nullable JetExpression calleeExpression, @NotNull List<? extends ValueArgument> valueArguments) {
084 this(callElement, explicitReceiver, callOperationNode, calleeExpression, valueArguments, CallType.DEFAULT);
085 }
086
087 protected CallImpl(@NotNull JetElement callElement, @NotNull ReceiverValue explicitReceiver, @Nullable ASTNode callOperationNode,
088 @Nullable JetExpression calleeExpression, @NotNull List<? extends ValueArgument> valueArguments, @NotNull CallType callType) {
089 this.callElement = callElement;
090 this.explicitReceiver = explicitReceiver;
091 this.callOperationNode = callOperationNode;
092 this.calleeExpression = calleeExpression;
093 this.valueArguments = valueArguments;
094 this.callType = callType;
095 }
096
097 @Override
098 public ASTNode getCallOperationNode() {
099 return callOperationNode;
100 }
101
102 @NotNull
103 @Override
104 public ReceiverValue getExplicitReceiver() {
105 return explicitReceiver;
106 }
107
108 @NotNull
109 @Override
110 public ReceiverValue getThisObject() {
111 return ReceiverValue.NO_RECEIVER;
112 }
113
114 @Override
115 public JetExpression getCalleeExpression() {
116 return calleeExpression;
117 }
118
119 @NotNull
120 @Override
121 public List<? extends ValueArgument> getValueArguments() {
122 return valueArguments;
123 }
124
125 @NotNull
126 @Override
127 public JetElement getCallElement() {
128 return callElement;
129 }
130
131 @Override
132 public JetValueArgumentList getValueArgumentList() {
133 return null;
134 }
135
136 @NotNull
137 @Override
138 public List<JetExpression> getFunctionLiteralArguments() {
139 return Collections.emptyList();
140 }
141 @NotNull
142 @Override
143 public List<JetTypeProjection> getTypeArguments() {
144 return Collections.emptyList();
145 }
146
147 @Override
148 public JetTypeArgumentList getTypeArgumentList() {
149 return null;
150 }
151
152 @Override
153 public String toString() {
154 return getCallElement().getText();
155 }
156
157 @NotNull
158 @Override
159 public CallType getCallType() {
160 return callType;
161 }
162 }
163
164 @NotNull
165 public static Call makeCallWithExpressions(@NotNull JetElement callElement, @NotNull ReceiverValue explicitReceiver,
166 @Nullable ASTNode callOperationNode, @NotNull JetExpression calleeExpression,
167 @NotNull List<JetExpression> argumentExpressions) {
168 return makeCallWithExpressions(callElement, explicitReceiver, callOperationNode, calleeExpression, argumentExpressions, CallType.DEFAULT);
169 }
170
171 @NotNull
172 public static Call makeCallWithExpressions(@NotNull JetElement callElement, @NotNull ReceiverValue explicitReceiver,
173 @Nullable ASTNode callOperationNode, @NotNull JetExpression calleeExpression,
174 @NotNull List<JetExpression> argumentExpressions, @NotNull CallType callType) {
175 List<ValueArgument> arguments = Lists.newArrayList();
176 for (JetExpression argumentExpression : argumentExpressions) {
177 arguments.add(makeValueArgument(argumentExpression, calleeExpression));
178 }
179 return makeCall(callElement, explicitReceiver, callOperationNode, calleeExpression, arguments, callType);
180 }
181
182 @NotNull
183 public static Call makeCall(JetElement callElement, ReceiverValue explicitReceiver, @Nullable ASTNode callOperationNode, JetExpression calleeExpression, List<? extends ValueArgument> arguments) {
184 return makeCall(callElement, explicitReceiver, callOperationNode, calleeExpression, arguments, CallType.DEFAULT);
185 }
186
187 @NotNull
188 public static Call makeCall(JetElement callElement, ReceiverValue explicitReceiver, @Nullable ASTNode callOperationNode,
189 JetExpression calleeExpression, List<? extends ValueArgument> arguments, CallType callType) {
190 return new CallImpl(callElement, explicitReceiver, callOperationNode, calleeExpression, arguments, callType);
191 }
192
193 @NotNull
194 public static Call makeCall(@NotNull ReceiverValue leftAsReceiver, JetBinaryExpression expression) {
195 return makeCallWithExpressions(expression, leftAsReceiver, null, expression.getOperationReference(), Collections.singletonList(expression.getRight()));
196 }
197
198 @NotNull
199 public static Call makeCall(@NotNull ReceiverValue baseAsReceiver, JetUnaryExpression expression) {
200 return makeCall(expression, baseAsReceiver, null, expression.getOperationReference(), Collections.<ValueArgument>emptyList());
201 }
202
203 @NotNull
204 public static Call makeArraySetCall(@NotNull ReceiverValue arrayAsReceiver, @NotNull JetArrayAccessExpression arrayAccessExpression,
205 @NotNull JetExpression rightHandSide, @NotNull CallType callType) {
206 List<JetExpression> arguments = Lists.newArrayList(arrayAccessExpression.getIndexExpressions());
207 arguments.add(rightHandSide);
208 return makeCallWithExpressions(arrayAccessExpression, arrayAsReceiver, null, arrayAccessExpression, arguments, callType);
209 }
210
211 @NotNull
212 public static Call makeArrayGetCall(@NotNull ReceiverValue arrayAsReceiver, @NotNull JetArrayAccessExpression arrayAccessExpression,
213 @NotNull CallType callType) {
214 return makeCallWithExpressions(arrayAccessExpression, arrayAsReceiver, null, arrayAccessExpression, arrayAccessExpression.getIndexExpressions(), callType);
215 }
216
217 @NotNull
218 public static ValueArgument makeValueArgument(@NotNull JetExpression expression) {
219 return makeValueArgument(expression, expression);
220 }
221
222 @NotNull
223 public static ValueArgument makeValueArgument(@Nullable JetExpression expression, @NotNull JetElement reportErrorsOn) {
224 return new ExpressionValueArgument(expression, reportErrorsOn);
225 }
226
227 @NotNull
228 public static Call makePropertyCall(@NotNull ReceiverValue explicitReceiver, @Nullable ASTNode callOperationNode, @NotNull JetSimpleNameExpression nameExpression) {
229 return makeCallWithExpressions(nameExpression, explicitReceiver, callOperationNode, nameExpression, Collections.<JetExpression>emptyList());
230 }
231
232 @NotNull
233 public static Call makeCall(@NotNull final ReceiverValue explicitReceiver, @Nullable final ASTNode callOperationNode, @NotNull final JetCallElement callElement) {
234 return new Call() {
235 @Override
236 public ASTNode getCallOperationNode() {
237 return callOperationNode;
238 }
239
240 @NotNull
241 @Override
242 public ReceiverValue getExplicitReceiver() {
243 return explicitReceiver;
244 }
245
246 @NotNull
247 @Override
248 public ReceiverValue getThisObject() {
249 return ReceiverValue.NO_RECEIVER;
250 }
251
252 @Override
253 @Nullable
254 public JetExpression getCalleeExpression() {
255 return callElement.getCalleeExpression();
256 }
257
258 @Override
259 @Nullable
260 public JetValueArgumentList getValueArgumentList() {
261 return callElement.getValueArgumentList();
262 }
263
264 @Override
265 @NotNull
266 public List<? extends ValueArgument> getValueArguments() {
267 return callElement.getValueArguments();
268 }
269
270 @Override
271 @NotNull
272 public List<JetExpression> getFunctionLiteralArguments() {
273 return callElement.getFunctionLiteralArguments();
274 }
275
276 @Override
277 @NotNull
278 public List<JetTypeProjection> getTypeArguments() {
279 return callElement.getTypeArguments();
280 }
281
282 @Override
283 @Nullable
284 public JetTypeArgumentList getTypeArgumentList() {
285 return callElement.getTypeArgumentList();
286 }
287
288 @NotNull
289 @Override
290 public JetElement getCallElement() {
291 return callElement;
292 }
293
294 @Override
295 public String toString() {
296 return DebugTextPackage.getDebugText(callElement);
297 }
298
299 @NotNull
300 @Override
301 public CallType getCallType() {
302 return CallType.DEFAULT;
303 }
304 };
305 }
306
307 @NotNull
308 public static Call makeCall(@NotNull JetElement callElement, @NotNull ReceiverValue explicitReceiver) {
309 return new CallImpl(callElement, explicitReceiver, null, null, Collections.<ValueArgument>emptyList());
310 }
311 }