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.resolver;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
021 import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
022 import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
023 import org.jetbrains.jet.lang.resolve.java.structure.JavaClassifierType;
024 import org.jetbrains.jet.lang.resolve.name.FqName;
025 import org.jetbrains.jet.lang.types.JetType;
026 import org.jetbrains.jet.lang.types.TypeUtils;
027 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
028
029 import javax.inject.Inject;
030 import java.util.ArrayList;
031 import java.util.Collection;
032 import java.util.Collections;
033 import java.util.List;
034
035 import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES;
036
037 public final class JavaSupertypeResolver {
038 public static final FqName OBJECT_FQ_NAME = new FqName("java.lang.Object");
039
040 private JavaTypeTransformer typeTransformer;
041 private JavaClassResolver classResolver;
042
043 @Inject
044 public void setTypeTransformer(JavaTypeTransformer typeTransformer) {
045 this.typeTransformer = typeTransformer;
046 }
047
048 @Inject
049 public void setClassResolver(JavaClassResolver classResolver) {
050 this.classResolver = classResolver;
051 }
052
053 @NotNull
054 public Collection<JetType> getSupertypes(
055 @NotNull ClassDescriptor classDescriptor,
056 @NotNull JavaClass javaClass,
057 @NotNull List<TypeParameterDescriptor> typeParameters
058 ) {
059 TypeVariableResolver typeVariableResolver = new TypeVariableResolverImpl(typeParameters, classDescriptor);
060
061 List<JetType> result = transformSupertypeList(javaClass.getSupertypes(), typeVariableResolver);
062
063 return result.isEmpty() ? Collections.singletonList(getDefaultSupertype(javaClass)) : result;
064 }
065
066 @NotNull
067 private JetType getDefaultSupertype(@NotNull JavaClass javaClass) {
068 if (OBJECT_FQ_NAME.equals(javaClass.getFqName()) || javaClass.isAnnotationType()) {
069 return KotlinBuiltIns.getInstance().getAnyType();
070 }
071 else {
072 ClassDescriptor object = classResolver.resolveClass(OBJECT_FQ_NAME, IGNORE_KOTLIN_SOURCES);
073 if (object != null) {
074 return object.getDefaultType();
075 }
076 else {
077 //TODO: hack here
078 return KotlinBuiltIns.getInstance().getAnyType();
079 // throw new IllegalStateException("Could not resolve java.lang.Object");
080 }
081 }
082 }
083
084 @NotNull
085 private List<JetType> transformSupertypeList(
086 @NotNull Collection<JavaClassifierType> supertypes,
087 @NotNull TypeVariableResolver typeVariableResolver
088 ) {
089 List<JetType> result = new ArrayList<JetType>(supertypes.size());
090 for (JavaClassifierType type : supertypes) {
091 JetType transformed = typeTransformer.transformToType(type, TypeUsage.SUPERTYPE, typeVariableResolver);
092 if (transformed.isError()) {
093 // TODO: report INCOMPLETE_HIERARCHY
094 }
095 else {
096 result.add(TypeUtils.makeNotNullable(transformed));
097 }
098 }
099 return result;
100 }
101 }