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;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
021    import org.jetbrains.kotlin.descriptors.ClassDescriptor;
022    import org.jetbrains.kotlin.load.java.JvmAbi;
023    import org.jetbrains.kotlin.resolve.DescriptorUtils;
024    import org.jetbrains.org.objectweb.asm.Type;
025    
026    public class FieldInfo {
027    
028        @NotNull
029        public static FieldInfo createForCompanionSingleton(@NotNull ClassDescriptor companionObject, @NotNull JetTypeMapper typeMapper) {
030            ClassDescriptor ownerDescriptor = DescriptorUtils.getParentOfType(companionObject, ClassDescriptor.class);
031            assert ownerDescriptor != null : "Owner not found for class: " + companionObject;
032            Type ownerType = typeMapper.mapType(ownerDescriptor);
033            return new FieldInfo(ownerType, typeMapper.mapType(companionObject), companionObject.getName().asString(), true);
034        }
035    
036        @NotNull
037        public static FieldInfo createForSingleton(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper) {
038            return createForSingleton(classDescriptor, typeMapper, false);
039        }
040    
041        @NotNull
042        public static FieldInfo createForSingleton(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper, boolean oldSingleton) {
043            if (!classDescriptor.getKind().isSingleton()) {
044                throw new UnsupportedOperationException("Can't create singleton field for class: " + classDescriptor);
045            }
046            Type type = typeMapper.mapType(classDescriptor);
047            return new FieldInfo(type, type, oldSingleton ? JvmAbi.DEPRECATED_INSTANCE_FIELD : JvmAbi.INSTANCE_FIELD, true);
048        }
049    
050        @NotNull
051        public static FieldInfo createForHiddenField(@NotNull Type owner, @NotNull Type fieldType, @NotNull String fieldName) {
052            return new FieldInfo(owner, fieldType, fieldName, false);
053        }
054    
055        private final Type fieldType;
056        private final Type ownerType;
057        private final String fieldName;
058        private final boolean isStatic;
059    
060        private FieldInfo(@NotNull Type ownerType, @NotNull Type fieldType, @NotNull String fieldName, boolean isStatic) {
061            this.ownerType = ownerType;
062            this.fieldType = fieldType;
063            this.fieldName = fieldName;
064            this.isStatic = isStatic;
065        }
066    
067        @NotNull
068        public Type getFieldType() {
069            return fieldType;
070        }
071    
072        @NotNull
073        public Type getOwnerType() {
074            return ownerType;
075        }
076    
077        @NotNull
078        public String getOwnerInternalName() {
079            return ownerType.getInternalName();
080        }
081    
082        @NotNull
083        public String getFieldName() {
084            return fieldName;
085        }
086    
087        public boolean isStatic() {
088            return isStatic;
089        }
090    
091        @Override
092        public String toString() {
093            return String.format("%s %s.%s : %s", isStatic ? "GETSTATIC" : "GETFIELD", ownerType.getInternalName(), fieldName, fieldType);
094        }
095    }