001 /* 002 * Copyright 2010-2015 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.kotlin.codegen.context; 018 019 import org.jetbrains.annotations.NotNull; 020 import org.jetbrains.annotations.Nullable; 021 import org.jetbrains.kotlin.codegen.OwnerKind; 022 import org.jetbrains.kotlin.codegen.StackValue; 023 import org.jetbrains.kotlin.codegen.state.JetTypeMapper; 024 import org.jetbrains.kotlin.descriptors.ClassDescriptor; 025 026 import static org.jetbrains.kotlin.codegen.AsmUtil.CAPTURED_THIS_FIELD; 027 import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE; 028 import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.canHaveOuter; 029 030 public class ClassContext extends FieldOwnerContext<ClassDescriptor> { 031 private final JetTypeMapper typeMapper; 032 033 public ClassContext( 034 @NotNull JetTypeMapper typeMapper, 035 @NotNull ClassDescriptor contextDescriptor, 036 @NotNull OwnerKind contextKind, 037 @Nullable CodegenContext parentContext, 038 @Nullable LocalLookup localLookup 039 ) { 040 super(contextDescriptor, contextKind, parentContext, typeMapper.getBindingContext().get(CLOSURE, contextDescriptor), 041 contextDescriptor, localLookup); 042 043 this.typeMapper = typeMapper; 044 } 045 046 @Override 047 @Nullable 048 protected StackValue.Field computeOuterExpression() { 049 ClassDescriptor enclosingClass = getEnclosingClass(); 050 if (enclosingClass == null) return null; 051 052 if (!canHaveOuter(typeMapper.getBindingContext(), getContextDescriptor())) return null; 053 054 return StackValue.field( 055 typeMapper.mapType(enclosingClass), 056 typeMapper.mapType(getContextDescriptor()), 057 CAPTURED_THIS_FIELD, 058 /* isStatic = */ false, 059 StackValue.LOCAL_0 060 ); 061 } 062 063 @Nullable 064 public CodegenContext getCompanionObjectContext() { 065 if (getContextDescriptor().getCompanionObjectDescriptor() != null) { 066 return findChildContext(getContextDescriptor().getCompanionObjectDescriptor()); 067 } 068 return null; 069 } 070 071 @Override 072 public String toString() { 073 return "Class: " + getContextDescriptor(); 074 } 075 }