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.lang.resolve.java.mapping;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.annotations.Nullable;
021 import org.jetbrains.org.objectweb.asm.Type;
022 import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
023 import org.jetbrains.jet.lang.resolve.DescriptorUtils;
024 import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
025 import org.jetbrains.jet.lang.resolve.java.JvmClassName;
026 import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
027 import org.jetbrains.jet.lang.resolve.name.FqName;
028 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
029 import org.jetbrains.jet.lang.types.lang.PrimitiveType;
030
031 import java.util.HashMap;
032 import java.util.Map;
033
034 import static org.jetbrains.jet.lang.resolve.java.mapping.PrimitiveTypesUtil.asmTypeForPrimitive;
035
036 public class KotlinToJavaTypesMap extends JavaToKotlinClassMapBuilder {
037 private static KotlinToJavaTypesMap instance = null;
038
039 @NotNull
040 public static KotlinToJavaTypesMap getInstance() {
041 if (instance == null) {
042 instance = new KotlinToJavaTypesMap();
043 }
044 return instance;
045 }
046
047 private final Map<FqName, Type> asmTypes = new HashMap<FqName, Type>();
048 private final Map<FqName, Type> asmNullableTypes = new HashMap<FqName, Type>();
049 private final Map<FqName, FqName> kotlinToJavaFqName = new HashMap<FqName, FqName>();
050
051 private KotlinToJavaTypesMap() {
052 init();
053 initPrimitives();
054 }
055
056 private void initPrimitives() {
057 FqName builtInsFqName = KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME;
058 for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
059 PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
060 Type asmType = asmTypeForPrimitive(jvmPrimitiveType);
061 FqName fqName = builtInsFqName.child(primitiveType.getTypeName());
062
063 register(fqName, asmType);
064
065 FqName wrapperFqName = jvmPrimitiveType.getWrapperFqName();
066 registerNullable(fqName, Type.getObjectType(JvmClassName.byFqNameWithoutInnerClasses(wrapperFqName).getInternalName()));
067 registerFqName(fqName, wrapperFqName);
068
069 register(builtInsFqName.child(primitiveType.getArrayTypeName()), Type.getType("[" + asmType.getDescriptor()));
070 }
071 }
072
073 @Nullable
074 public Type getJavaAnalog(@NotNull FqName fqName, boolean isNullable) {
075 if (isNullable) {
076 Type nullableType = asmNullableTypes.get(fqName);
077 if (nullableType != null) {
078 return nullableType;
079 }
080 }
081 return asmTypes.get(fqName);
082 }
083
084 /**
085 * E.g.
086 * kotlin.Throwable -> java.lang.Throwable
087 * kotlin.deprecated -> java.lang.annotation.Deprecated
088 * kotlin.Int -> java.lang.Integer
089 * kotlin.IntArray -> null
090 */
091 @Nullable
092 public FqName getKotlinToJavaFqName(@NotNull FqName fqName) {
093 return kotlinToJavaFqName.get(fqName);
094 }
095
096 @Override
097 protected void register(@NotNull Class<?> javaClass, @NotNull ClassDescriptor kotlinDescriptor, @NotNull Direction direction) {
098 if (direction == Direction.BOTH || direction == Direction.KOTLIN_TO_JAVA) {
099 FqName fqName = DescriptorUtils.getFqNameSafe(kotlinDescriptor);
100 register(fqName, AsmTypeConstants.getType(javaClass));
101 registerFqName(fqName, new FqName(javaClass.getCanonicalName()));
102 }
103 }
104
105 @Override
106 protected void register(
107 @NotNull Class<?> javaClass,
108 @NotNull ClassDescriptor kotlinDescriptor,
109 @NotNull ClassDescriptor kotlinMutableDescriptor,
110 @NotNull Direction direction
111 ) {
112 if (direction == Direction.BOTH || direction == Direction.KOTLIN_TO_JAVA) {
113 register(javaClass, kotlinDescriptor);
114 register(javaClass, kotlinMutableDescriptor);
115 }
116 }
117
118 private void register(@NotNull FqName fqName, @NotNull Type type) {
119 asmTypes.put(fqName, type);
120 }
121
122 private void registerNullable(@NotNull FqName fqName, @NotNull Type nullableType) {
123 asmNullableTypes.put(fqName, nullableType);
124 }
125
126 private void registerFqName(@NotNull FqName kotlinFqName, @NotNull FqName javaFqName) {
127 kotlinToJavaFqName.put(kotlinFqName, javaFqName);
128 }
129 }