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