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.context; 018 019 import org.jetbrains.annotations.NotNull; 020 import org.jetbrains.annotations.Nullable; 021 import org.jetbrains.jet.codegen.OwnerKind; 022 import org.jetbrains.jet.codegen.binding.MutableClosure; 023 import org.jetbrains.jet.lang.descriptors.ClassDescriptor; 024 import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; 025 import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; 026 import org.jetbrains.jet.lang.resolve.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 descriptor, boolean isDelegated) { 048 assert descriptor.getKind().isReal() : "Only declared properties can have backing fields: " + descriptor; 049 boolean isExtension = descriptor.getReceiverParameter() != null; 050 051 return getFieldName(descriptor.getOriginal(), isDelegated, isExtension); 052 } 053 054 @NotNull 055 private String getFieldName(@NotNull PropertyDescriptor descriptor, boolean isDelegated, boolean isExtension) { 056 String defaultPropertyName = JvmAbi.getDefaultPropertyName(descriptor.getName(), isDelegated, isExtension); 057 058 Map<PropertyDescriptor, String> descriptor2Name = fieldNames.get(defaultPropertyName); 059 if (descriptor2Name == null) { 060 descriptor2Name = new HashMap<PropertyDescriptor, String>(); 061 fieldNames.put(defaultPropertyName, descriptor2Name); 062 } 063 064 String actualName = descriptor2Name.get(descriptor); 065 if (actualName != null) return actualName; 066 067 String newName = descriptor2Name.isEmpty() ? defaultPropertyName : defaultPropertyName + "$" + descriptor2Name.size(); 068 descriptor2Name.put(descriptor, newName); 069 return newName; 070 } 071 }