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.binding.MutableClosure; 023 import org.jetbrains.kotlin.descriptors.ClassDescriptor; 024 import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; 025 import org.jetbrains.kotlin.descriptors.PropertyDescriptor; 026 import org.jetbrains.kotlin.load.java.JvmAbi; 027 028 import java.util.HashMap; 029 import java.util.Map; 030 031 public abstract class FieldOwnerContext<T extends DeclarationDescriptor> extends CodegenContext<T> { 032 //default property name -> map<property descriptor -> bytecode name> 033 private final Map<String, Map<PropertyDescriptor, String>> fieldNames = new HashMap<String, Map<PropertyDescriptor, String>>(); 034 035 public FieldOwnerContext( 036 @NotNull T contextDescriptor, 037 @NotNull OwnerKind contextKind, 038 @Nullable CodegenContext parentContext, 039 @Nullable MutableClosure closure, 040 @Nullable ClassDescriptor thisDescriptor, 041 @Nullable LocalLookup expressionCodegen 042 ) { 043 super(contextDescriptor, contextKind, parentContext, closure, thisDescriptor, expressionCodegen); 044 } 045 046 @NotNull 047 public String getFieldName(@NotNull PropertyDescriptor possiblySubstitutedDescriptor, boolean isDelegated) { 048 PropertyDescriptor descriptor = possiblySubstitutedDescriptor.getOriginal(); 049 assert descriptor.getKind().isReal() : "Only declared properties can have backing fields: " + descriptor; 050 051 String defaultPropertyName = JvmAbi.getDefaultFieldNameForProperty(descriptor.getName(), isDelegated); 052 053 Map<PropertyDescriptor, String> descriptor2Name = fieldNames.get(defaultPropertyName); 054 if (descriptor2Name == null) { 055 descriptor2Name = new HashMap<PropertyDescriptor, String>(); 056 fieldNames.put(defaultPropertyName, descriptor2Name); 057 } 058 059 String actualName = descriptor2Name.get(descriptor); 060 if (actualName != null) return actualName; 061 062 String newName = descriptor2Name.isEmpty() ? defaultPropertyName : defaultPropertyName + "$" + descriptor2Name.size(); 063 descriptor2Name.put(descriptor, newName); 064 return newName; 065 } 066 }