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