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.load.kotlin;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf;
021 import org.jetbrains.kotlin.serialization.deserialization.NameResolver;
022 import org.jetbrains.kotlin.name.FqName;
023 import org.jetbrains.kotlin.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 JvmProtoBuf.JvmMethodSignature 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 MemberSignature methodSignature(@NotNull JvmProtoBuf.JvmMethodSignature signature) {
052 return MemberSignature.fromMethodNameAndDesc(methodSignatureString(signature));
053 }
054
055 @NotNull
056 public String typeDescriptor(@NotNull JvmProtoBuf.JvmType type) {
057 return typeDescriptor(type, new StringBuilder()).toString();
058 }
059
060 @NotNull
061 private StringBuilder typeDescriptor(@NotNull JvmProtoBuf.JvmType 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 }