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;
018    
019    import com.intellij.openapi.util.Pair;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.asm4.Type;
022    import org.jetbrains.asm4.commons.Method;
023    import org.jetbrains.jet.descriptors.serialization.JavaProtoBufUtil;
024    import org.jetbrains.jet.descriptors.serialization.NameTable;
025    import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
026    import org.jetbrains.jet.descriptors.serialization.SerializerExtension;
027    import org.jetbrains.jet.lang.descriptors.*;
028    import org.jetbrains.jet.lang.resolve.name.Name;
029    
030    public class JavaSerializerExtension extends SerializerExtension {
031        private final MemberMap memberMap;
032    
033        public JavaSerializerExtension(@NotNull MemberMap memberMap) {
034            this.memberMap = memberMap;
035        }
036    
037        @Override
038        public void serializeCallable(
039                @NotNull CallableMemberDescriptor callable,
040                @NotNull ProtoBuf.Callable.Builder proto,
041                @NotNull NameTable nameTable
042        ) {
043            saveSignature(callable, proto, nameTable);
044            saveSrcClassName(callable, proto, nameTable);
045        }
046    
047        private void saveSignature(
048                @NotNull CallableMemberDescriptor callable,
049                @NotNull ProtoBuf.Callable.Builder proto,
050                @NotNull NameTable nameTable
051        ) {
052            if (callable instanceof FunctionDescriptor) {
053                Method method = memberMap.getMethodOfDescriptor((FunctionDescriptor) callable);
054                if (method != null) {
055                    JavaProtoBufUtil.saveMethodSignature(proto, method, nameTable);
056                }
057            }
058            else if (callable instanceof PropertyDescriptor) {
059                PropertyDescriptor property = (PropertyDescriptor) callable;
060    
061                PropertyGetterDescriptor getter = property.getGetter();
062                PropertySetterDescriptor setter = property.getSetter();
063                Method getterMethod = getter == null ? null : memberMap.getMethodOfDescriptor(getter);
064                Method setterMethod = setter == null ? null : memberMap.getMethodOfDescriptor(setter);
065    
066                Pair<Type, String> field = memberMap.getFieldOfProperty(property);
067                Type fieldType;
068                String fieldName;
069                boolean isStaticInOuter;
070                String syntheticMethodName;
071                if (field != null) {
072                    fieldType = field.first;
073                    fieldName = field.second;
074                    isStaticInOuter = memberMap.isStaticFieldInOuterClass(property);
075                    syntheticMethodName = null;
076                }
077                else {
078                    fieldType = null;
079                    fieldName = null;
080                    isStaticInOuter = false;
081                    syntheticMethodName = memberMap.getSyntheticMethodNameOfProperty(property);
082                }
083    
084                JavaProtoBufUtil.savePropertySignature(proto, fieldType, fieldName, isStaticInOuter, syntheticMethodName, getterMethod,
085                                                       setterMethod, nameTable);
086            }
087        }
088    
089        private void saveSrcClassName(
090                @NotNull CallableMemberDescriptor callable,
091                @NotNull ProtoBuf.Callable.Builder proto,
092                @NotNull NameTable nameTable
093        ) {
094            Name name = memberMap.getSrcClassNameOfCallable(callable);
095            if (name != null) {
096                JavaProtoBufUtil.saveSrcClassName(proto, name, nameTable);
097            }
098        }
099    }