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.asm4.Type;
022 import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
023 import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
024 import org.jetbrains.jet.lang.resolve.DescriptorUtils;
025 import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
026 import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
027 import org.jetbrains.jet.lang.resolve.name.FqName;
028 import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
029 import org.jetbrains.jet.lang.types.JetType;
030 import org.jetbrains.jet.lang.types.lang.PrimitiveType;
031
032 import java.util.HashMap;
033 import java.util.Map;
034
035 public class KotlinToJavaTypesMap extends JavaToKotlinClassMapBuilder {
036 private static KotlinToJavaTypesMap instance = null;
037
038 @NotNull
039 public static KotlinToJavaTypesMap getInstance() {
040 if (instance == null) {
041 instance = new KotlinToJavaTypesMap();
042 }
043 return instance;
044 }
045
046 private final Map<FqName, Type> asmTypes = new HashMap<FqName, Type>();
047 private final Map<FqName, Type> asmNullableTypes = new HashMap<FqName, Type>();
048
049 private KotlinToJavaTypesMap() {
050 init();
051 initPrimitives();
052 }
053
054 private void initPrimitives() {
055 for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
056 FqName className = jvmPrimitiveType.getPrimitiveType().getClassName();
057
058 register(className, jvmPrimitiveType.getAsmType());
059 registerNullable(className, jvmPrimitiveType.getWrapper().getAsmType());
060 }
061 for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
062 PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
063 register(primitiveType.getArrayClassName(), jvmPrimitiveType.getAsmArrayType());
064 }
065 }
066
067 @Nullable
068 public Type getJavaAnalog(@NotNull JetType jetType) {
069 ClassifierDescriptor classifier = jetType.getConstructor().getDeclarationDescriptor();
070 assert classifier != null;
071 FqNameUnsafe className = DescriptorUtils.getFQName(classifier);
072 if (!className.isSafe()) return null;
073 FqName fqName = className.toSafe();
074 if (jetType.isNullable()) {
075 Type nullableType = asmNullableTypes.get(fqName);
076 if (nullableType != null) {
077 return nullableType;
078 }
079 }
080 return asmTypes.get(fqName);
081 }
082
083 @Override
084 protected void register(@NotNull Class<?> javaClass, @NotNull ClassDescriptor kotlinDescriptor, @NotNull Direction direction) {
085 if (direction == Direction.BOTH || direction == Direction.KOTLIN_TO_JAVA) {
086 register(kotlinDescriptor, AsmTypeConstants.getType(javaClass));
087 }
088 }
089
090 @Override
091 protected void register(
092 @NotNull Class<?> javaClass,
093 @NotNull ClassDescriptor kotlinDescriptor,
094 @NotNull ClassDescriptor kotlinMutableDescriptor,
095 @NotNull Direction direction
096 ) {
097 if (direction == Direction.BOTH || direction == Direction.KOTLIN_TO_JAVA) {
098 register(javaClass, kotlinDescriptor);
099 register(javaClass, kotlinMutableDescriptor);
100 }
101 }
102
103 private void register(@NotNull ClassDescriptor kotlinDescriptor, @NotNull Type javaType) {
104 FqNameUnsafe fqName = DescriptorUtils.getFQName(kotlinDescriptor);
105 assert fqName.isSafe();
106 register(fqName.toSafe(), javaType);
107 }
108
109 private void register(@NotNull FqName fqName, @NotNull Type type) {
110 asmTypes.put(fqName, type);
111 }
112
113 private void registerNullable(@NotNull FqName fqName, @NotNull Type nullableType) {
114 asmNullableTypes.put(fqName, nullableType);
115 }
116 }