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