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.kotlin.codegen.context.MethodContext;
021    import org.jetbrains.kotlin.codegen.state.GenerationState;
022    import org.jetbrains.kotlin.descriptors.CallableDescriptor;
023    import org.jetbrains.kotlin.psi.JetDeclarationWithBody;
024    import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
025    import org.jetbrains.org.objectweb.asm.MethodVisitor;
026    
027    public abstract class FunctionGenerationStrategy {
028        public abstract void generateBody(
029                @NotNull MethodVisitor mv,
030                @NotNull FrameMap frameMap,
031                @NotNull JvmMethodSignature signature,
032                @NotNull MethodContext context,
033                @NotNull MemberCodegen<?> parentCodegen
034        );
035    
036        public static class FunctionDefault extends CodegenBased<CallableDescriptor> {
037            private final JetDeclarationWithBody declaration;
038    
039            public FunctionDefault(
040                    @NotNull GenerationState state,
041                    @NotNull CallableDescriptor descriptor,
042                    @NotNull JetDeclarationWithBody declaration
043            ) {
044                super(state, descriptor);
045                this.declaration = declaration;
046            }
047    
048            @Override
049            public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
050                codegen.returnExpression(declaration.getBodyExpression());
051            }
052        }
053    
054        public abstract static class CodegenBased<T extends CallableDescriptor> extends FunctionGenerationStrategy {
055            protected final GenerationState state;
056            protected final T callableDescriptor;
057    
058            public CodegenBased(@NotNull GenerationState state, @NotNull T callableDescriptor) {
059                this.state = state;
060                this.callableDescriptor = callableDescriptor;
061            }
062    
063            @Override
064            public final void generateBody(
065                    @NotNull MethodVisitor mv,
066                    @NotNull FrameMap frameMap,
067                    @NotNull JvmMethodSignature signature,
068                    @NotNull MethodContext context,
069                    @NotNull MemberCodegen<?> parentCodegen
070            ) {
071                ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, signature.getReturnType(), context, state, parentCodegen);
072                doGenerateBody(codegen, signature);
073            }
074    
075            public abstract void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature);
076        }
077    }