001    /*
002     * Copyright 2010-2015 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.codegen;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.annotations.Nullable;
021    import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
022    import org.jetbrains.kotlin.psi.JetExpression;
023    import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
024    import org.jetbrains.org.objectweb.asm.Type;
025    
026    public abstract class CallGenerator {
027    
028        static class DefaultCallGenerator extends CallGenerator {
029    
030            private final ExpressionCodegen codegen;
031    
032            public DefaultCallGenerator(ExpressionCodegen codegen) {
033                this.codegen = codegen;
034            }
035    
036            @Override
037            public void genCallInner(
038                    @NotNull CallableMethod callableMethod,
039                    ResolvedCall<?> resolvedCall,
040                    boolean callDefault,
041                    @NotNull ExpressionCodegen codegen
042            ) {
043                if (!callDefault) {
044                    callableMethod.invokeWithNotNullAssertion(codegen.v, codegen.getState(), resolvedCall);
045                }
046                else {
047                    callableMethod.invokeDefaultWithNotNullAssertion(codegen.v, codegen.getState(), resolvedCall);
048                }
049            }
050    
051            @Override
052            public void genCallWithoutAssertions(
053                    @NotNull CallableMethod method, @NotNull ExpressionCodegen codegen
054            ) {
055                method.invokeWithoutAssertions(codegen.v);
056            }
057    
058            @Override
059            public void afterParameterPut(@NotNull Type type, StackValue stackValue, @NotNull ValueParameterDescriptor valueParameterDescriptor) {
060    
061            }
062    
063            @Override
064            public void putHiddenParams() {
065    
066            }
067    
068            @Override
069            public void genValueAndPut(
070                    @NotNull ValueParameterDescriptor valueParameterDescriptor,
071                    @NotNull JetExpression argumentExpression,
072                    @NotNull Type parameterType
073            ) {
074                StackValue value = codegen.gen(argumentExpression);
075                value.put(parameterType, codegen.v);
076            }
077    
078            @Override
079            public void putCapturedValueOnStack(
080                    @NotNull StackValue stackValue, @NotNull Type valueType, int paramIndex
081            ) {
082                stackValue.put(stackValue.type, codegen.v);
083            }
084    
085            @Override
086            public void putValueIfNeeded(
087                    @Nullable ValueParameterDescriptor valueParameterDescriptor, @NotNull Type parameterType, @NotNull StackValue value
088            ) {
089                value.put(value.type, codegen.v);
090            }
091        }
092    
093        public void genCall(@NotNull CallableMethod callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen) {
094            if (resolvedCall != null) {
095                JetExpression calleeExpression = resolvedCall.getCall().getCalleeExpression();
096                if (calleeExpression != null) {
097                    codegen.markStartLineNumber(calleeExpression);
098                }
099            }
100    
101            genCallInner(callableMethod, resolvedCall, callDefault, codegen);
102        }
103    
104        public abstract void genCallInner(@NotNull CallableMethod callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen);
105    
106        public abstract void genCallWithoutAssertions(@NotNull CallableMethod callableMethod, @NotNull ExpressionCodegen codegen);
107    
108        public abstract void afterParameterPut(@NotNull Type type, StackValue stackValue, @NotNull ValueParameterDescriptor valueParameterDescriptor);
109    
110        public abstract void genValueAndPut(
111                @NotNull ValueParameterDescriptor valueParameterDescriptor,
112                @NotNull JetExpression argumentExpression,
113                @NotNull Type parameterType
114        );
115    
116        public abstract void putValueIfNeeded(@Nullable ValueParameterDescriptor valueParameterDescriptor, @NotNull Type parameterType, @NotNull StackValue value);
117    
118        public abstract void putCapturedValueOnStack(
119                @NotNull StackValue stackValue,
120                @NotNull Type valueType, int paramIndex
121        );
122    
123        public abstract void putHiddenParams();
124    }