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 017package org.jetbrains.jet.codegen; 018 019import org.jetbrains.annotations.NotNull; 020import org.jetbrains.annotations.Nullable; 021import org.jetbrains.jet.codegen.context.ClassContext; 022import org.jetbrains.jet.codegen.context.CodegenContext; 023import org.jetbrains.jet.codegen.context.FieldOwnerContext; 024import org.jetbrains.jet.codegen.state.GenerationState; 025import org.jetbrains.jet.codegen.state.GenerationStateAware; 026import org.jetbrains.jet.lang.descriptors.ClassDescriptor; 027import org.jetbrains.jet.lang.psi.*; 028import org.jetbrains.jet.lang.resolve.BindingContext; 029import org.jetbrains.jet.lang.types.ErrorUtils; 030 031 032public class MemberCodegen extends GenerationStateAware { 033 034 @Nullable 035 private MemberCodegen parentCodegen; 036 037 public MemberCodegen(@NotNull GenerationState state, @Nullable MemberCodegen parentCodegen) { 038 super(state); 039 this.parentCodegen = parentCodegen; 040 } 041 042 @Nullable 043 public MemberCodegen getParentCodegen() { 044 return parentCodegen; 045 } 046 047 public void genFunctionOrProperty( 048 @NotNull FieldOwnerContext context, 049 @NotNull JetTypeParameterListOwner functionOrProperty, 050 @NotNull ClassBuilder classBuilder 051 ) { 052 FunctionCodegen functionCodegen = new FunctionCodegen(context, classBuilder, state); 053 if (functionOrProperty instanceof JetNamedFunction) { 054 try { 055 functionCodegen.gen((JetNamedFunction) functionOrProperty); 056 } 057 catch (CompilationException e) { 058 throw e; 059 } 060 catch (Exception e) { 061 throw new CompilationException("Failed to generate function " + functionOrProperty.getName(), e, functionOrProperty); 062 } 063 } 064 else if (functionOrProperty instanceof JetProperty) { 065 try { 066 new PropertyCodegen(context, classBuilder, functionCodegen, this).gen((JetProperty) functionOrProperty); 067 } 068 catch (CompilationException e) { 069 throw e; 070 } 071 catch (Exception e) { 072 throw new CompilationException("Failed to generate property " + functionOrProperty.getName(), e, functionOrProperty); 073 } 074 } 075 else { 076 throw new IllegalArgumentException("Unknown parameter: " + functionOrProperty); 077 } 078 } 079 080 public void genClassOrObject(CodegenContext parentContext, JetClassOrObject aClass) { 081 ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); 082 083 if (descriptor == null || ErrorUtils.isError(descriptor) || descriptor.getName().equals(JetPsiUtil.NO_NAME_PROVIDED)) { 084 if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) { 085 throw new IllegalStateException( 086 "Generating bad descriptor in ClassBuilderMode = " + state.getClassBuilderMode() + ": " + descriptor); 087 } 088 return; 089 } 090 091 ClassBuilder classBuilder = state.getFactory().forClassImplementation(descriptor, aClass.getContainingFile()); 092 ClassContext classContext = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state); 093 new ImplementationBodyCodegen(aClass, classContext, classBuilder, state, this).generate(); 094 classBuilder.done(); 095 096 if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) { 097 ClassBuilder traitBuilder = state.getFactory().forTraitImplementation(descriptor, state, aClass.getContainingFile()); 098 new TraitImplBodyCodegen(aClass, parentContext.intoClass(descriptor, OwnerKind.TRAIT_IMPL, state), traitBuilder, state) 099 .generate(); 100 traitBuilder.done(); 101 } 102 } 103}