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 017package org.jetbrains.jet.lang.resolve.java.resolver; 018 019import com.intellij.psi.PsiClass; 020import com.intellij.psi.PsiClassType; 021import jet.typeinfo.TypeInfoVariance; 022import org.jetbrains.annotations.NotNull; 023import org.jetbrains.annotations.Nullable; 024import org.jetbrains.jet.lang.descriptors.ClassDescriptor; 025import org.jetbrains.jet.lang.descriptors.ClassKind; 026import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; 027import org.jetbrains.jet.lang.resolve.BindingContext; 028import org.jetbrains.jet.lang.resolve.BindingTrace; 029import org.jetbrains.jet.lang.resolve.java.*; 030import org.jetbrains.jet.lang.resolve.java.provider.ClassPsiDeclarationProvider; 031import org.jetbrains.jet.lang.resolve.java.wrapper.PsiClassWrapper; 032import org.jetbrains.jet.lang.types.ErrorUtils; 033import org.jetbrains.jet.lang.types.JetType; 034import org.jetbrains.jet.lang.types.TypeUtils; 035import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; 036import org.jetbrains.jet.rt.signature.JetSignatureAdapter; 037import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter; 038import org.jetbrains.jet.rt.signature.JetSignatureReader; 039import org.jetbrains.jet.rt.signature.JetSignatureVisitor; 040 041import javax.inject.Inject; 042import java.util.ArrayList; 043import java.util.Collection; 044import java.util.List; 045 046import static org.jetbrains.jet.lang.resolve.java.provider.DeclarationOrigin.KOTLIN; 047 048public final class JavaSupertypeResolver { 049 050 private BindingTrace trace; 051 private JavaSemanticServices semanticServices; 052 private JavaTypeTransformer typeTransformer; 053 private JavaClassResolver classResolver; 054 055 @Inject 056 public void setTrace(BindingTrace trace) { 057 this.trace = trace; 058 } 059 060 @Inject 061 public void setSemanticServices(JavaSemanticServices semanticServices) { 062 this.semanticServices = semanticServices; 063 } 064 065 @Inject 066 public void setTypeTransformer(JavaTypeTransformer typeTransformer) { 067 this.typeTransformer = typeTransformer; 068 } 069 070 @Inject 071 public void setClassResolver(JavaClassResolver classResolver) { 072 this.classResolver = classResolver; 073 } 074 075 public Collection<JetType> getSupertypes( 076 @NotNull ClassDescriptor classDescriptor, 077 @NotNull PsiClassWrapper psiClass, 078 @NotNull ClassPsiDeclarationProvider classData, 079 @NotNull List<TypeParameterDescriptor> typeParameters 080 ) { 081 082 List<JetType> result = new ArrayList<JetType>(); 083 084 String context = "class " + psiClass.getQualifiedName(); 085 086 if (psiClass.getJetClass().signature().length() > 0) { 087 readSuperTypes(psiClass, typeParameters, classDescriptor, result, context); 088 } 089 else { 090 TypeVariableResolver typeVariableResolverForSupertypes = 091 TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, classDescriptor, context); 092 transformSupertypeList(result, psiClass.getPsiClass().getExtendsListTypes(), typeVariableResolverForSupertypes); 093 transformSupertypeList(result, psiClass.getPsiClass().getImplementsListTypes(), typeVariableResolverForSupertypes); 094 } 095 096 reportIncompleteHierarchyForErrorTypes(classDescriptor, result); 097 098 if (result.isEmpty()) { 099 addBaseClass(psiClass, classData, classDescriptor, result); 100 } 101 return result; 102 } 103 104 private void readSuperTypes( 105 PsiClassWrapper psiClass, 106 List<TypeParameterDescriptor> typeParameters, 107 ClassDescriptor classDescriptor, 108 final List<JetType> result, 109 String context 110 ) { 111 final TypeVariableResolver typeVariableResolver = 112 TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, classDescriptor, context); 113 114 new JetSignatureReader(psiClass.getJetClass().signature()).accept(new JetSignatureExceptionsAdapter() { 115 @Override 116 public JetSignatureVisitor visitFormalTypeParameter(String name, TypeInfoVariance variance, boolean reified) { 117 // TODO: collect 118 return new JetSignatureAdapter(); 119 } 120 121 @Override 122 public JetSignatureVisitor visitSuperclass() { 123 return new JetTypeJetSignatureReader(semanticServices, KotlinBuiltIns.getInstance(), 124 typeVariableResolver) { 125 @Override 126 protected void done(@NotNull JetType jetType) { 127 if (!jetType.equals(KotlinBuiltIns.getInstance().getAnyType())) { 128 result.add(jetType); 129 } 130 } 131 }; 132 } 133 134 @Override 135 public JetSignatureVisitor visitInterface() { 136 return visitSuperclass(); 137 } 138 }); 139 } 140 141 private void addBaseClass( 142 @NotNull PsiClassWrapper psiClass, 143 @NotNull ClassPsiDeclarationProvider classData, 144 @NotNull ClassDescriptor classDescriptor, 145 @NotNull List<JetType> result 146 ) { 147 if (classData.getDeclarationOrigin() == KOTLIN 148 || DescriptorResolverUtils.OBJECT_FQ_NAME.equalsTo(psiClass.getQualifiedName()) 149 // TODO: annotations 150 || classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS) { 151 result.add(KotlinBuiltIns.getInstance().getAnyType()); 152 } 153 else { 154 ClassDescriptor object = resolveJavaLangObject(); 155 if (object != null) { 156 result.add(object.getDefaultType()); 157 } 158 else { 159 //TODO: hack here 160 result.add(KotlinBuiltIns.getInstance().getAnyType()); 161 // throw new IllegalStateException("Could not resolve java.lang.Object"); 162 } 163 } 164 } 165 166 private void reportIncompleteHierarchyForErrorTypes(ClassDescriptor classDescriptor, List<JetType> result) { 167 for (JetType supertype : result) { 168 if (ErrorUtils.isErrorType(supertype)) { 169 trace.record(BindingContext.INCOMPLETE_HIERARCHY, classDescriptor); 170 } 171 } 172 } 173 174 private void transformSupertypeList( 175 List<JetType> result, 176 PsiClassType[] extendsListTypes, 177 TypeVariableResolver typeVariableResolver 178 ) { 179 for (PsiClassType type : extendsListTypes) { 180 PsiClass resolved = type.resolve(); 181 if (resolved != null) { 182 String qualifiedName = resolved.getQualifiedName(); 183 assert qualifiedName != null; 184 if (JvmStdlibNames.JET_OBJECT.getFqName().equalsTo(qualifiedName)) { 185 continue; 186 } 187 } 188 189 JetType transform = typeTransformer 190 .transformToType(type, TypeUsage.SUPERTYPE, typeVariableResolver); 191 if (ErrorUtils.isErrorType(transform)) { 192 continue; 193 } 194 195 result.add(TypeUtils.makeNotNullable(transform)); 196 } 197 } 198 199 200 @Nullable 201 private ClassDescriptor resolveJavaLangObject() { 202 ClassDescriptor clazz = classResolver.resolveClass(DescriptorResolverUtils.OBJECT_FQ_NAME, 203 DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN); 204 if (clazz == null) { 205 // TODO: warning 206 } 207 return clazz; 208 } 209}