001    /*
002     * Copyright 2010-2014 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.lang.resolve.kotlin;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.jet.descriptors.serialization.JavaProtoBuf;
021    import org.jetbrains.jet.descriptors.serialization.NameResolver;
022    import org.jetbrains.jet.lang.resolve.name.FqName;
023    import org.jetbrains.jet.lang.resolve.name.Name;
024    
025    public class SignatureDeserializer {
026        // These types are ordered according to their sorts, this is significant for deserialization
027        private static final char[] PRIMITIVE_TYPES = new char[] { 'V', 'Z', 'C', 'B', 'S', 'I', 'F', 'J', 'D' };
028    
029        private final NameResolver nameResolver;
030    
031        public SignatureDeserializer(@NotNull NameResolver nameResolver) {
032            this.nameResolver = nameResolver;
033        }
034    
035        @NotNull
036        public String methodSignatureString(@NotNull JavaProtoBuf.JavaMethodSignature signature) {
037            Name name = nameResolver.getName(signature.getName());
038    
039            StringBuilder sb = new StringBuilder();
040            sb.append('(');
041            for (int i = 0, length = signature.getParameterTypeCount(); i < length; i++) {
042                typeDescriptor(signature.getParameterType(i), sb);
043            }
044            sb.append(')');
045            typeDescriptor(signature.getReturnType(), sb);
046    
047            return name.asString() + sb.toString();
048        }
049    
050        @NotNull
051        public DescriptorDeserializersStorage.MemberSignature methodSignature(@NotNull JavaProtoBuf.JavaMethodSignature signature) {
052            return DescriptorDeserializersStorage.MemberSignature.fromMethodNameAndDesc(methodSignatureString(signature));
053        }
054    
055        @NotNull
056        public String typeDescriptor(@NotNull JavaProtoBuf.JavaType type) {
057            return typeDescriptor(type, new StringBuilder()).toString();
058        }
059    
060        @NotNull
061        private StringBuilder typeDescriptor(@NotNull JavaProtoBuf.JavaType type, @NotNull StringBuilder sb) {
062            for (int i = 0; i < type.getArrayDimension(); i++) {
063                sb.append('[');
064            }
065    
066            if (type.hasPrimitiveType()) {
067                sb.append(PRIMITIVE_TYPES[type.getPrimitiveType().ordinal()]);
068            }
069            else {
070                sb.append("L");
071                sb.append(fqNameToInternalName(nameResolver.getFqName(type.getClassFqName())));
072                sb.append(";");
073            }
074    
075            return sb;
076        }
077    
078        @NotNull
079        private static String fqNameToInternalName(@NotNull FqName fqName) {
080            return fqName.asString().replace('.', '/');
081        }
082    }