org.jetbrains.kotlin.resolve.calls.util.CallMaker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-compiler-embeddable Show documentation
Show all versions of kotlin-compiler-embeddable Show documentation
the Kotlin compiler embeddable
/*
* Copyright 2010-2017 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.kotlin.resolve.calls.util;
import com.google.common.collect.Lists;
import com.intellij.lang.ASTNode;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.Call.CallType;
import org.jetbrains.kotlin.psi.debugText.DebugTextUtilKt;
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CallMaker {
private static class ExpressionValueArgument implements ValueArgument {
private final KtExpression expression;
private final KtElement reportErrorsOn;
private final boolean isExternal;
private ExpressionValueArgument(
@Nullable KtExpression expression,
@NotNull KtElement reportErrorsOn,
boolean isExternal
) {
this.expression = expression;
this.reportErrorsOn = expression == null ? reportErrorsOn : expression;
this.isExternal = isExternal;
}
@Override
public boolean isExternal() {
return isExternal;
}
@Override
public KtExpression getArgumentExpression() {
return expression;
}
@Override
public ValueArgumentName getArgumentName() {
return null;
}
@Override
public boolean isNamed() {
return false;
}
@NotNull
@Override
public KtElement asElement() {
return reportErrorsOn;
}
@Override
public LeafPsiElement getSpreadElement() {
return null;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ExpressionValueArgument argument = (ExpressionValueArgument) o;
if (expression != null ? !expression.equals(argument.expression) : argument.expression != null) return false;
return true;
}
@Override
public int hashCode() {
return expression != null ? expression.hashCode() : 0;
}
}
private static class CallImpl implements Call {
private final KtElement callElement;
private final Receiver explicitReceiver;
private final ASTNode callOperationNode;
private final KtExpression calleeExpression;
private final List extends ValueArgument> valueArguments;
private final Call.CallType callType;
private final boolean isSemanticallyEquivalentToSafeCall;
protected CallImpl(
@NotNull KtElement callElement,
@NotNull Receiver explicitReceiver,
@Nullable ASTNode callOperationNode,
@Nullable KtExpression calleeExpression,
@NotNull List extends ValueArgument> valueArguments
) {
this(callElement, explicitReceiver, callOperationNode, calleeExpression, valueArguments, CallType.DEFAULT, false);
}
protected CallImpl(
@NotNull KtElement callElement,
@Nullable Receiver explicitReceiver,
@Nullable ASTNode callOperationNode,
@Nullable KtExpression calleeExpression,
@NotNull List extends ValueArgument> valueArguments,
@NotNull CallType callType,
boolean isSemanticallyEquivalentToSafeCall
) {
this.callElement = callElement;
this.explicitReceiver = explicitReceiver;
this.callOperationNode = callOperationNode;
this.calleeExpression = calleeExpression;
this.valueArguments = valueArguments;
this.callType = callType;
this.isSemanticallyEquivalentToSafeCall = isSemanticallyEquivalentToSafeCall;
}
@Override
public ASTNode getCallOperationNode() {
return callOperationNode;
}
@Override
public boolean isSemanticallyEquivalentToSafeCall() {
return isSemanticallyEquivalentToSafeCall || Call.super.isSemanticallyEquivalentToSafeCall();
}
@Nullable
@Override
public Receiver getExplicitReceiver() {
return explicitReceiver;
}
@Nullable
@Override
public ReceiverValue getDispatchReceiver() {
return null;
}
@Override
public KtExpression getCalleeExpression() {
return calleeExpression;
}
@NotNull
@Override
public List extends ValueArgument> getValueArguments() {
return valueArguments;
}
@NotNull
@Override
public KtElement getCallElement() {
return callElement;
}
@Override
public KtValueArgumentList getValueArgumentList() {
return null;
}
@NotNull
@Override
public List getFunctionLiteralArguments() {
return Collections.emptyList();
}
@NotNull
@Override
public List getTypeArguments() {
return Collections.emptyList();
}
@Override
public KtTypeArgumentList getTypeArgumentList() {
return null;
}
@Override
public String toString() {
return getCallElement().getText();
}
@NotNull
@Override
public CallType getCallType() {
return callType;
}
}
@NotNull
public static Call makeCallWithExpressions(@NotNull KtElement callElement, @Nullable Receiver explicitReceiver,
@Nullable ASTNode callOperationNode, @NotNull KtExpression calleeExpression,
@NotNull List argumentExpressions) {
return makeCallWithExpressions(callElement, explicitReceiver, callOperationNode, calleeExpression, argumentExpressions, CallType.DEFAULT,
false);
}
@NotNull
public static Call makeCallWithExpressions(@NotNull KtElement callElement, @Nullable Receiver explicitReceiver,
@Nullable ASTNode callOperationNode, @NotNull KtExpression calleeExpression,
@NotNull List argumentExpressions, @NotNull CallType callType) {
return makeCallWithExpressions(callElement, explicitReceiver, callOperationNode, calleeExpression, argumentExpressions, callType,
false);
}
@NotNull
public static Call makeCallWithExpressions(
@NotNull KtElement callElement, @Nullable Receiver explicitReceiver,
@Nullable ASTNode callOperationNode, @NotNull KtExpression calleeExpression,
@NotNull List argumentExpressions, @NotNull CallType callType,
boolean isSemanticallyEquivalentToSafeCall
) {
List arguments;
if (argumentExpressions.isEmpty()) {
arguments = Collections.emptyList();
}
else {
arguments = new ArrayList<>(argumentExpressions.size());
for (KtExpression argumentExpression : argumentExpressions) {
arguments.add(makeValueArgument(argumentExpression, calleeExpression));
}
}
return makeCall(
callElement, explicitReceiver, callOperationNode, calleeExpression, arguments, callType, isSemanticallyEquivalentToSafeCall
);
}
@NotNull
public static Call makeCall(KtElement callElement, @Nullable Receiver explicitReceiver, @Nullable ASTNode callOperationNode, KtExpression calleeExpression, List extends ValueArgument> arguments) {
return makeCall(callElement, explicitReceiver, callOperationNode, calleeExpression, arguments, CallType.DEFAULT);
}
@NotNull
public static Call makeCall(
KtElement callElement, @Nullable Receiver explicitReceiver, @Nullable ASTNode callOperationNode,
KtExpression calleeExpression, List extends ValueArgument> arguments, CallType callType
) {
return makeCall(callElement, explicitReceiver, callOperationNode, calleeExpression, arguments, callType, false);
}
@NotNull
public static Call makeCall(
KtElement callElement,
@Nullable Receiver explicitReceiver,
@Nullable ASTNode callOperationNode,
KtExpression calleeExpression,
List extends ValueArgument> arguments,
CallType callType,
boolean isSemanticallyEquivalentToSafeCall
) {
return new CallImpl(callElement, explicitReceiver, callOperationNode, calleeExpression, arguments, callType, isSemanticallyEquivalentToSafeCall);
}
@NotNull
public static Call makeCall(@NotNull ReceiverValue leftAsReceiver, KtBinaryExpression expression) {
return makeCallWithExpressions(expression, leftAsReceiver, null, expression.getOperationReference(), Collections.singletonList(expression.getRight()));
}
@NotNull
public static Call makeCall(@NotNull ReceiverValue baseAsReceiver, KtUnaryExpression expression) {
return makeCall(expression, baseAsReceiver, null, expression.getOperationReference(), Collections.emptyList());
}
@NotNull
public static Call makeArraySetCall(@NotNull ReceiverValue arrayAsReceiver, @NotNull KtArrayAccessExpression arrayAccessExpression,
@NotNull KtExpression rightHandSide, @NotNull CallType callType) {
List arguments = Lists.newArrayList(arrayAccessExpression.getIndexExpressions());
arguments.add(rightHandSide);
return makeCallWithExpressions(arrayAccessExpression, arrayAsReceiver, null, arrayAccessExpression, arguments, callType);
}
@NotNull
public static Call makeArrayGetCall(@NotNull ReceiverValue arrayAsReceiver, @NotNull KtArrayAccessExpression arrayAccessExpression,
@NotNull CallType callType) {
return makeCallWithExpressions(arrayAccessExpression, arrayAsReceiver, null, arrayAccessExpression, arrayAccessExpression.getIndexExpressions(), callType);
}
public static Call makeCallForCollectionLiteral(@NotNull KtCollectionLiteralExpression collectionLiteralExpression) {
return makeCallWithExpressions(
collectionLiteralExpression,
null,
null,
collectionLiteralExpression,
collectionLiteralExpression.getInnerExpressions(),
CallType.DEFAULT);
}
@NotNull
public static ValueArgument makeValueArgument(@NotNull KtExpression expression) {
return makeValueArgument(expression, expression);
}
@NotNull
public static ValueArgument makeValueArgument(@Nullable KtExpression expression, @NotNull KtElement reportErrorsOn) {
return new ExpressionValueArgument(expression, reportErrorsOn, false);
}
@NotNull
public static ValueArgument makeExternalValueArgument(@NotNull KtExpression expression) {
return new ExpressionValueArgument(expression, expression, true);
}
@NotNull
public static ValueArgument makeExternalValueArgument(@NotNull KtExpression expression, @NotNull KtElement reportErrorsOn) {
return new ExpressionValueArgument(expression, reportErrorsOn, true);
}
@NotNull
public static Call makePropertyCall(@Nullable Receiver explicitReceiver, @Nullable ASTNode callOperationNode, @NotNull KtSimpleNameExpression nameExpression) {
return makeCallWithExpressions(nameExpression, explicitReceiver, callOperationNode, nameExpression, Collections.emptyList());
}
@NotNull
public static Call makeConstructorCallWithoutTypeArguments(@NotNull KtCallElement callElement) {
return new DelegatingCall(makeCall(null, null, callElement)) {
@NotNull
@Override
public List getTypeArguments() {
return Collections.emptyList();
}
@Nullable
@Override
public KtTypeArgumentList getTypeArgumentList() {
return null;
}
};
}
@NotNull
public static Call makeConstructorCallForEnumEntryWithoutInitializer(@NotNull KtSuperTypeCallEntry callElement) {
return new Call() {
@Nullable
@Override
public ASTNode getCallOperationNode() {
return null;
}
@Nullable
@Override
public Receiver getExplicitReceiver() {
return null;
}
@Nullable
@Override
public ReceiverValue getDispatchReceiver() {
return null;
}
@Nullable
@Override
public KtExpression getCalleeExpression() {
return callElement.getCalleeExpression();
}
@Nullable
@Override
public KtValueArgumentList getValueArgumentList() {
return callElement.getValueArgumentList();
}
@NotNull
@Override
public List extends ValueArgument> getValueArguments() {
return callElement.getValueArguments();
}
@NotNull
@Override
public List extends LambdaArgument> getFunctionLiteralArguments() {
return Collections.emptyList();
}
@NotNull
@Override
public List getTypeArguments() {
return Collections.emptyList();
}
@Nullable
@Override
public KtTypeArgumentList getTypeArgumentList() {
return null;
}
@NotNull
@Override
public KtElement getCallElement() {
return callElement;
}
@NotNull
@Override
public CallType getCallType() {
return CallType.DEFAULT;
}
@Override
public String toString() {
return DebugTextUtilKt.getDebugText(callElement);
}
};
}
@NotNull
public static Call makeCall(@Nullable Receiver explicitReceiver, @Nullable ASTNode callOperationNode, @NotNull KtCallElement callElement) {
return new Call() {
@Override
public ASTNode getCallOperationNode() {
return callOperationNode;
}
@Nullable
@Override
public Receiver getExplicitReceiver() {
return explicitReceiver;
}
@Nullable
@Override
public ReceiverValue getDispatchReceiver() {
return null;
}
@Override
@Nullable
public KtExpression getCalleeExpression() {
return callElement.getCalleeExpression();
}
@Override
@Nullable
public KtValueArgumentList getValueArgumentList() {
return callElement.getValueArgumentList();
}
@Override
@NotNull
public List extends ValueArgument> getValueArguments() {
return callElement.getValueArguments();
}
@Override
@NotNull
public List extends LambdaArgument> getFunctionLiteralArguments() {
return callElement.getLambdaArguments();
}
@Override
@NotNull
public List getTypeArguments() {
return callElement.getTypeArguments();
}
@Override
@Nullable
public KtTypeArgumentList getTypeArgumentList() {
return callElement.getTypeArgumentList();
}
@NotNull
@Override
public KtElement getCallElement() {
return callElement;
}
@Override
public String toString() {
return DebugTextUtilKt.getDebugText(callElement);
}
@NotNull
@Override
public CallType getCallType() {
return CallType.DEFAULT;
}
};
}
@NotNull
public static Call makeCall(@NotNull KtElement callElement, @NotNull ReceiverValue explicitReceiver) {
return new CallImpl(callElement, explicitReceiver, null, null, Collections.emptyList());
}
}