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