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.jet.codegen; 018 019 import org.jetbrains.annotations.NotNull; 020 import org.jetbrains.annotations.Nullable; 021 import org.jetbrains.asm4.MethodVisitor; 022 import org.jetbrains.jet.codegen.context.MethodContext; 023 import org.jetbrains.jet.codegen.signature.JvmMethodSignature; 024 import org.jetbrains.jet.codegen.state.GenerationState; 025 import org.jetbrains.jet.codegen.state.JetTypeMapper; 026 import org.jetbrains.jet.lang.descriptors.CallableDescriptor; 027 import org.jetbrains.jet.lang.psi.JetDeclarationWithBody; 028 029 public abstract class FunctionGenerationStrategy { 030 031 private FrameMap frameMap; 032 033 public abstract void generateBody( 034 @NotNull MethodVisitor mv, 035 @NotNull JvmMethodSignature signature, 036 @NotNull MethodContext context, 037 @Nullable MemberCodegen parentCodegen 038 ); 039 040 @NotNull 041 protected FrameMap createFrameMap(@NotNull JetTypeMapper typeMapper, @NotNull MethodContext context) { 042 return context.prepareFrame(typeMapper); 043 } 044 045 @NotNull 046 public FrameMap getFrameMap(@NotNull JetTypeMapper typeMapper, @NotNull MethodContext context) { 047 if (frameMap == null) { 048 frameMap = createFrameMap(typeMapper, context); 049 } 050 return frameMap; 051 } 052 053 public static class FunctionDefault extends CodegenBased<CallableDescriptor> { 054 private final JetDeclarationWithBody declaration; 055 056 public FunctionDefault( 057 @NotNull GenerationState state, 058 @NotNull CallableDescriptor descriptor, 059 @NotNull JetDeclarationWithBody declaration 060 ) { 061 super(state, descriptor); 062 this.declaration = declaration; 063 } 064 065 @Override 066 public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) { 067 codegen.returnExpression(declaration.getBodyExpression()); 068 } 069 } 070 071 public abstract static class CodegenBased<T extends CallableDescriptor> extends FunctionGenerationStrategy { 072 protected final GenerationState state; 073 protected final T callableDescriptor; 074 075 public CodegenBased(@NotNull GenerationState state, @NotNull T callableDescriptor) { 076 this.state = state; 077 this.callableDescriptor = callableDescriptor; 078 } 079 080 @Override 081 public final void generateBody( 082 @NotNull MethodVisitor mv, 083 @NotNull JvmMethodSignature signature, 084 @NotNull MethodContext context, 085 @Nullable MemberCodegen parentCodegen 086 ) { 087 ExpressionCodegen codegen = new ExpressionCodegen(mv, getFrameMap(state.getTypeMapper(), context), 088 signature.getReturnType(), context, state, parentCodegen); 089 doGenerateBody(codegen, signature); 090 } 091 092 public abstract void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature); 093 } 094 }