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.*;
024    import org.jetbrains.jet.lang.resolve.java.JvmAbi;
025    
026    import java.util.HashMap;
027    import java.util.Map;
028    
029    public abstract class FieldOwnerContext<T extends DeclarationDescriptor> extends CodegenContext<T> {
030    
031        //default property name -> map<property descriptor -> bytecode name>
032        private Map<String, Map<PropertyDescriptor, String>> fieldNames = new HashMap<String, Map<PropertyDescriptor, String>>();
033    
034        public FieldOwnerContext(
035                @NotNull T contextDescriptor,
036                @NotNull OwnerKind contextKind,
037                @Nullable CodegenContext parentContext,
038                @Nullable MutableClosure closure,
039                @Nullable ClassDescriptor thisDescriptor,
040                @Nullable LocalLookup expressionCodegen
041        ) {
042            super(contextDescriptor, contextKind, parentContext, closure, thisDescriptor, expressionCodegen);
043        }
044    
045        public String getFieldName(PropertyDescriptor descriptor) {
046            return getFieldName(descriptor, false);
047        }
048    
049        public String getFieldName(PropertyDescriptor descriptor, boolean isDelegated) {
050            assert descriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
051            boolean isExtension = descriptor.getReceiverParameter() != null;
052    
053            return getFieldName(descriptor, isDelegated, isExtension);
054        }
055    
056        private String getFieldName(PropertyDescriptor descriptor, boolean isDelegated, boolean isExtension) {
057            descriptor = descriptor.getOriginal();
058            String defaultPropertyName = JvmAbi.getDefaultPropertyName(descriptor.getName(), isDelegated, isExtension);
059    
060            Map<PropertyDescriptor, String> descriptor2Name = fieldNames.get(defaultPropertyName);
061            if (descriptor2Name == null) {
062                descriptor2Name = new HashMap<PropertyDescriptor, String>();
063                fieldNames.put(defaultPropertyName, descriptor2Name);
064            }
065    
066            String actualName = descriptor2Name.get(descriptor);
067            if (actualName == null) {
068                actualName = descriptor2Name.isEmpty() ? defaultPropertyName : defaultPropertyName + "$" + descriptor2Name.size();
069                descriptor2Name.put(descriptor, actualName);
070            }
071            return actualName;
072        }
073    }