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.k2js.translate.reference;
018
019 import com.google.common.collect.Lists;
020 import com.google.dart.compiler.backend.js.ast.JsExpression;
021 import org.jetbrains.annotations.NotNull;
022 import org.jetbrains.annotations.Nullable;
023 import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
024 import org.jetbrains.jet.lang.resolve.BindingTraceContext;
025 import org.jetbrains.jet.lang.resolve.DescriptorUtils;
026 import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
027 import org.jetbrains.jet.lang.resolve.calls.model.MutableDataFlowInfoForArguments;
028 import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind;
029 import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate;
030 import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
031 import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
032 import org.jetbrains.jet.lang.resolve.calls.tasks.TracingStrategy;
033 import org.jetbrains.k2js.translate.context.TranslationContext;
034
035 import java.util.Arrays;
036 import java.util.List;
037
038 public final class CallBuilder {
039
040 public static CallBuilder build(@NotNull TranslationContext context) {
041 return new CallBuilder(context);
042 }
043
044 @NotNull
045 private final TranslationContext context;
046 @Nullable
047 private /*var*/ JsExpression receiver = null;
048 @NotNull
049 private final List<JsExpression> args = Lists.newArrayList();
050 @NotNull
051 private /*var*/ CallType callType = CallType.NORMAL;
052 @Nullable
053 private /*var*/ ResolvedCall<?> resolvedCall = null;
054 @Nullable
055 private /*var*/ CallableDescriptor descriptor = null;
056 @Nullable
057 private /*var*/ JsExpression callee = null;
058
059
060 private CallBuilder(@NotNull TranslationContext context) {
061 this.context = context;
062 }
063
064 @NotNull
065 public CallBuilder receiver(@Nullable JsExpression receiver) {
066 this.receiver = receiver;
067 return this;
068 }
069
070 @NotNull
071 public CallBuilder args(@NotNull List<JsExpression> args) {
072 assert this.args.isEmpty();
073 this.args.addAll(args);
074 return this;
075 }
076
077 @NotNull
078 public CallBuilder args(@NotNull JsExpression... args) {
079 return args(Arrays.asList(args));
080 }
081
082 @NotNull
083 public CallBuilder descriptor(@NotNull CallableDescriptor descriptor) {
084 this.descriptor = descriptor;
085 return this;
086 }
087
088 @NotNull
089 public CallBuilder callee(@Nullable JsExpression callee) {
090 this.callee = callee;
091 return this;
092 }
093
094 @NotNull
095 public CallBuilder resolvedCall(@NotNull ResolvedCall<?> call) {
096 this.resolvedCall = call;
097 return this;
098 }
099
100 @NotNull
101 public CallBuilder type(@NotNull CallType type) {
102 this.callType = type;
103 return this;
104 }
105
106 @NotNull
107 private CallTranslator finish() {
108 if (resolvedCall == null) {
109 assert descriptor != null;
110 resolvedCall = ResolvedCallImpl.create(ResolutionCandidate.create(descriptor, DescriptorUtils.safeGetValue(descriptor.getExpectedThisObject()),
111 DescriptorUtils.safeGetValue(descriptor.getReceiverParameter()),
112 ExplicitReceiverKind.THIS_OBJECT, false),
113 TemporaryBindingTrace.create(new BindingTraceContext(), "trace to resolve call (in js)"),
114 TracingStrategy.EMPTY,
115 MutableDataFlowInfoForArguments.WITHOUT_ARGUMENTS_CHECK);
116 }
117 if (descriptor == null) {
118 descriptor = resolvedCall.getCandidateDescriptor().getOriginal();
119 }
120 assert resolvedCall != null;
121 return new CallTranslator(receiver, callee, args, resolvedCall, descriptor, callType, context);
122 }
123
124 @NotNull
125 public JsExpression translate() {
126 return finish().translate();
127 }
128
129
130 }