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